docstr: Test the case when video is already in memory, and decoder reads data in memory.
  In addition, decoder takes meaningful start- and end PTS as input, and decode
  frames within that interval
docstr_tok: ["Test","the","case","when","video","is","already","in","memory",",","and","decoder","reads","data","in","memory",".","In","addition",",","decoder","takes","meaningful","start-","and","end","PTS","as","input",",","and","decode","frames","within","that","interval"]
code: def test_read_video_in_range_from_memory(
      self, test_video, config, num_frames
  ):
      """
      Test the case when video is already in memory, and decoder reads data in memory.
      In addition, decoder takes meaningful start- and end PTS as input, and decode
      frames within that interval
      """
      full_path, video_tensor = _get_video_tensor(VIDEO_DIR, test_video)
      # video related
      width, height, min_dimension, max_dimension = 0, 0, 0, 0
      video_start_pts, video_end_pts = 0, -1
      video_timebase_num, video_timebase_den = 0, 1
      # audio related
      samples, channels = 0, 0
      audio_start_pts, audio_end_pts = 0, -1
      audio_timebase_num, audio_timebase_den = 0, 1
      # pass 1: decode all frames using new decoder
      tv_result = torch.ops.video_reader.read_video_from_memory(
          video_tensor,
          SEEK_FRAME_MARGIN,
          0,  # getPtsOnly
          1,  # readVideoStream
          width,
          height,
          min_dimension,
          max_dimension,
          video_start_pts,
          video_end_pts,
          video_timebase_num,
          video_timebase_den,
          1,  # readAudioStream
          samples,
          channels,
          audio_start_pts,
          audio_end_pts,
          audio_timebase_num,
          audio_timebase_den,
      )
      (
          vframes,
          vframe_pts,
          vtimebase,
          vfps,
          vduration,
          aframes,
          aframe_pts,
          atimebase,
          asample_rate,
          aduration,
      ) = tv_result
      assert abs(config.video_fps - vfps.item()) < 0.01
  
      start_pts_ind_max = vframe_pts.size(0) - num_frames
      if start_pts_ind_max <= 0:
          return
      # randomly pick start pts
      start_pts_ind = randint(0, start_pts_ind_max)
      end_pts_ind = start_pts_ind + num_frames - 1
      video_start_pts = vframe_pts[start_pts_ind]
      video_end_pts = vframe_pts[end_pts_ind]
  
      video_timebase_num, video_timebase_den = (
          vtimebase[0],
          vtimebase[1],
      )
      if len(atimebase) > 0:
          # when audio stream is available
          audio_timebase_num, audio_timebase_den = (
              atimebase[0],
              atimebase[1],
          )
          audio_start_pts = _pts_convert(
              video_start_pts.item(),
              Fraction(
                  video_timebase_num.item(), video_timebase_den.item()
              ),
              Fraction(
                  audio_timebase_num.item(), audio_timebase_den.item()
              ),
              math.floor,
          )
          audio_end_pts = _pts_convert(
              video_end_pts.item(),
              Fraction(
                  video_timebase_num.item(), video_timebase_den.item()
              ),
              Fraction(
                  audio_timebase_num.item(), audio_timebase_den.item()
              ),
              math.ceil,
          )
  
      # pass 2: decode frames in the randomly generated range
      tv_result = torch.ops.video_reader.read_video_from_memory(
          video_tensor,
          SEEK_FRAME_MARGIN,
          0,  # getPtsOnly
          1,  # readVideoStream
          width,
          height,
          min_dimension,
          max_dimension,
          video_start_pts,
          video_end_pts,
          video_timebase_num,
          video_timebase_den,
          1,  # readAudioStream
          samples,
          channels,
          audio_start_pts,
          audio_end_pts,
          audio_timebase_num,
          audio_timebase_den,
      )
  
      # pass 3: decode frames in range using PyAv
      video_timebase_av, audio_timebase_av = _get_timebase_by_av_module(
          full_path
      )
  
      video_start_pts_av = _pts_convert(
          video_start_pts.item(),
          Fraction(
              video_timebase_num.item(), video_timebase_den.item()
          ),
          Fraction(
              video_timebase_av.numerator, video_timebase_av.denominator
          ),
          math.floor,
      )
      video_end_pts_av = _pts_convert(
          video_end_pts.item(),
          Fraction(
              video_timebase_num.item(), video_timebase_den.item()
          ),
          Fraction(
              video_timebase_av.numerator, video_timebase_av.denominator
          ),
          math.ceil,
      )
      if audio_timebase_av:
          audio_start_pts = _pts_convert(
              video_start_pts.item(),
              Fraction(
                  video_timebase_num.item(), video_timebase_den.item()
              ),
              Fraction(
                  audio_timebase_av.numerator,
                  audio_timebase_av.denominator,
              ),
              math.floor,
          )
          audio_end_pts = _pts_convert(
              video_end_pts.item(),
              Fraction(
                  video_timebase_num.item(), video_timebase_den.item()
              ),
              Fraction(
                  audio_timebase_av.numerator,
                  audio_timebase_av.denominator,
              ),
              math.ceil,
          )
  
      pyav_result = _decode_frames_by_av_module(
          full_path,
          video_start_pts_av,
          video_end_pts_av,
          audio_start_pts,
          audio_end_pts,
      )
  
      assert tv_result[0].size(0) == num_frames
      if pyav_result.vframes.size(0) == num_frames:
          # if PyAv decodes a different number of video frames, skip
          # comparing the decoding results between Torchvision video reader
          # and PyAv
          self.compare_decoding_result(tv_result, pyav_result, config)
  
imports: import collections
  import math
  import os
  from fractions import Fraction
  import numpy
  import pytest
  import torch
  import torchvision.io
  from common_utils import assert_equal
  from numpy.random import randint
  from pytest import approx
  from torchvision import set_video_backend
  from torchvision.io import _HAS_VIDEO_OPT
label_desc: Use image node_id 18 for calling the TestVideoReader obj's underlying member method code with example usage: obj.test_read_video_in_range_from_memory(test_video, config, num_frames) without return types