    def encode_vision(self, image, test=False):
        """encode image / videos as features.

        Args:
            image (torch.Tensor): The input images.
            test (bool): Whether testing.

        Returns: tuple.
            - vision_embeds (torch.Tensor): The output features. Shape: [B,N,C].
            - pooled_vision_embeds (torch.Tensor): The pooled output features. Shape: [B,1,C].
            - student_output (torch.Tensor): The features of alignment. Shape: [K,B,N,C].
            - clip_output (torch.Tensor): The features of clip. Shape: [K,B,N,C].

        """
        T = image.shape[1]
        use_image = True if T == 1 else False
        image = image.permute(0, 2, 1, 3, 4) # [B,T,C,H,W] -> [B,C,T,H,W]
        # whether save temporal dimension
        keep_temporal=self.config.model.vision_encoder.keep_temporal
        if test:
            vision_embeds, pooled_vision_embeds, _ = self.vision_encoder(
                image, None, use_image, keep_temporal,
            )
            return vision_embeds, pooled_vision_embeds
        else:
            mask, clip_output = self.encode_teacher(image)
            if mask is not None and (self.video_mask_type != 'tube' or self.image_mask_type != 'tube'):
                keep_temporal = False
            vision_embeds, pooled_vision_embeds, student_output = self.vision_encoder(
                image, mask, use_image, keep_temporal
            )
            return vision_embeds, pooled_vision_embeds, student_output, clip_output
encode image / videos as features.

Args:
image (torch.Tensor): The input images.
test (bool): Whether testing.

Returns: tuple.
- vision_embeds (torch.Tensor): The output features. Shape: [B,N,C].
- pooled_vision_embeds (torch.Tensor): The pooled output features. Shape: [B,1,C].
- student_output (torch.Tensor): The features of alignment. Shape: [K,B,N,C].
- clip_output (torch.Tensor): The features of clip. Shape: [K,B,N,C].
videomamba/video_mm/models/umt.py