code: def _downsample_frame_indices(
      frame_indices: torch.Tensor,
      input_fps: float,
      output_num_frames: int,
      output_fps: float,
      num_samples: int,
      random_frames: bool,
  ) -> torch.Tensor:
      """Downsample frames from a frame indices at a given @output_fps and with a given
      @output_num_frames.
  
      This is used as a helper function for batch samplers that construct shorter video
      clips from a longer video clip. For example, we might load a 70-frame clip at 30fps
      and use it to construct 4 different batch samples corresponding to 8-frame clips at
      8fps.
  
      Args:
          frame_indices: A [K, N] tensor as the index of each frame, where K is the batch
              dimension, N is the number of frames.
          input_fps: The frame rate to be downsampled from.
          output_num_frames: The number of frames to output in each sample.
          output_fps: The desired fps of the output frames.
          num_samples: The number of batch samples to construct from the data.
          random_frames: If False, the input indices will be used to construct a single
              example. If True, random offsets will be applied to the frame indices as an
              augmentation.
  
      Returns:
          output_frame_indices: A [K_out, N_out] tensor as the frame indices to sample,
          where:
              - N_out = @output_num_frames
              - K_out = K * @num_samples.
      """
      if not random_frames and num_samples != 1:
          raise ValueError(
              "Frames are deterministic, so set num_samples to 1. Got num_samples={num_samples}."
          )
      assert (
          num_samples >= 1
      ), f"num_samples has to be positive, got {num_samples}."
  
      assert (
          input_fps > output_fps
      ), f"Output fps {output_fps} has to be smaller than the input fps {input_fps}."
  
      frames_per_clip = frame_indices.shape[1]
      assert (
          frames_per_clip >= output_num_frames
      ), f"Need to load more frames sample, can't sample {output_num_frames} from {frames_per_clip} frames."
  
      output_frame_indices = []
      desired_length_seconds = output_num_frames / output_fps
      num_frames_to_sample = min(
          frames_per_clip, int(desired_length_seconds * input_fps)
      )
      positions = (
          torch.linspace(0, num_frames_to_sample, output_num_frames + 1)
      ).long()
  
      for _ in range(num_samples):
          if random_frames:
              # Choose a starting timestamp for the frames.
              last_valid_idx = frames_per_clip - num_frames_to_sample
              frame_start_idx = random.randint(0, last_valid_idx)
          else:
              # We don't apply any offsets or randomness to the video frames, so we start
              # the video frames at index 0.
              frame_start_idx = 0
  
          selected_frame_indices = frame_indices[
              :,
              frame_start_idx : frame_start_idx + num_frames_to_sample,
          ]
  
          if random_frames:
              # Choose the middle of the chunk as the label. Then, choose the frame at
              # random from the time slices.
              selected_frame_locations = []
              for i in range(output_num_frames):
                  # Select a random frame in the chunk.
                  # NOTE: random.randint() is inclusive on both ends, while
                  # torch.randint() is exclusive for the higher range.
                  selection = random.randint(
                      positions[i], positions[i + 1] - 1
                  )
                  selected_frame_locations.append(selection)
          else:
              # We choose frames deterministically. Since we don't apply any offsets to
              # the video, the correct frames are at the beginning of each range.
              selected_frame_locations = positions[:-1]
  
          output_frame_indices.append(
              selected_frame_indices[:, selected_frame_locations]
          )
  
      return torch.cat(output_frame_indices)
  
imports: import argparse
  import random
  from typing import Dict, Optional, Tuple
  import av
  import numpy
  import torch
  import torch.nn.functional
  from torch import Tensor
  from data.transforms import BaseTransformation
  from data.transforms import image_pil
  from data.transforms.common import Compose
  from options.utils import extend_selected_args_with_prefix, extract_opts_with_prefix_replacement
  from utils import logger
label_desc: Use image node_id 1 for calling a global function with example usage: _downsample_frame_indices(frame_indices, input_fps, output_num_frames, output_fps, num_samples, random_frames) and returns: torch