o
    ϯi'                     @  s   d dl mZ d dlZd dlZd dlZd dlZd dlZd dlmZm	Z	m
Z
mZ d dlZd dlZd dlZd dlmZ d dlmZ ddlmZ ddlmZ zd dlZW n ey[   d	ZY nw d
ZeeZG dd deZ	
ddddZdS )    )annotationsN)CallableDictListOptional)	g_pathmgr)optional_threaded_foreach   )thwc_to_cthw)VideoFTc                   @  s   e Zd ZdZ			d,d-ddZe			d.d/ddZe		d0d1ddZed2ddZ	ed2ddZ
d3d d!Z	d4d5d'd(Zd6d*d+ZdS )7
FrameVideoz
    FrameVideo is an abstractions for accessing clips based on their start and end
    time for a video where each frame is stored as an image. PathManager is used for
    frame image reading, allowing non-local uri's to be used.
    NFdurationfloatfpsvideo_frame_to_path_fnCallable[[int], str]video_frame_paths	List[str]multithreaded_ioboolreturnNonec                 C  sd   t std|| _|| _|| _|du |du ksJ d|| _|| _tj	tj
| jdd| _dS )az  
        Args:
            duration (float): the duration of the video in seconds.
            fps (float): the target fps for the video. This is needed to link the frames
                to a second timestamp in the video.
            video_frame_to_path_fn (Callable[[int], str]): a function that maps from a frame
                index integer to the file path where the frame is located.
            video_frame_paths (List[str]): Dictionary of frame paths for each index of a video.
            multithreaded_io (bool):  controls whether parllelizable io operations are
                performed across multiple threads.
        zVopencv2 is required to use FrameVideo. Please install with 'pip install opencv-python'NzGOnly one of video_frame_to_path_fn or video_frame_paths can be providedr   )frame_index)_HAS_CV2ImportError	_duration_fps_multithreaded_io_video_frame_to_path_fn_video_frame_pathsospathbasenamedirname_video_frame_to_path_name)selfr   r   r   r   r    r'   Q/home/ubuntu/.local/lib/python3.10/site-packages/pytorchvideo/data/frame_video.py__init__(   s"   
zFrameVideo.__init__      >@r!   strpath_order_cacheOptional[Dict[str, List[str]]]c                   s   |dur |v r|  |  ||S t sJ   dt }dd }|j|d  fdd|D }|dur=|| < |  |||S )a6  
        Args:
            path (str): path to frame video directory.
            fps (float): the target fps for the video. This is needed to link the frames
                to a second timestamp in the video.
            multithreaded_io (bool):  controls whether parllelizable io operations are
                performed across multiple threads.
            path_order_cache (dict): An optional mapping from directory-path to list
                of frames in the directory in numerical order. Used for speedup by
                caching the frame paths.
        Nz is not a directoryc                 S  s   dd t d| D S )Nc                 S  s    g | ]}|  rt|n|qS r'   )isdigitint).0cr'   r'   r(   
<listcomp>j   s     zCFrameVideo.from_directory.<locals>.natural_keys.<locals>.<listcomp>z(\d+))resplit)textr'   r'   r(   natural_keysi   s   z/FrameVideo.from_directory.<locals>.natural_keys)keyc                   s   g | ]	}t j |qS r'   )r    r!   join)r0   fr!   r'   r(   r2   m   s    z-FrameVideo.from_directory.<locals>.<listcomp>)from_frame_pathsr   isdirlssort)clsr!   r   r   r,   rel_frame_pathsr6   frame_pathsr'   r:   r(   from_directoryP   s   
zFrameVideo.from_directoryc                 C  s,   t |dks
J d| t || |||dS )a  
        Args:
            video_frame_paths (List[str]): a list of paths to each frames in the video.
            fps (float): the target fps for the video. This is needed to link the frames
                to a second timestamp in the video.
            multithreaded_io (bool):  controls whether parllelizable io operations are
                performed across multiple threads.
        r   zvideo_frame_paths is empty)r   r   )len)r?   r   r   r   r'   r'   r(   r;   r   s   
zFrameVideo.from_frame_pathsc                 C     | j S N)r%   r&   r'   r'   r(   name   s   zFrameVideo.namec                 C  rD   )zZ
        Returns:
            duration: the video's duration/end-time in seconds.
        )r   rF   r'   r'   r(   r      s   zFrameVideo.durationtime_secr/   c                 C  s   t | j| S rE   )mathceilr   )r&   rH   r'   r'   r(   _get_frame_index_for_time   s   z$FrameVideo._get_frame_index_for_time	start_secend_secframe_filter*Optional[Callable[[List[int]], List[int]]]!Dict[str, Optional[torch.Tensor]]c           	   	     s   |dk s	| j krtd| d| d j  d dS t| j } |}t |t j}tt||}|r>||} fdd|D }t	| j
d	}t|tj}||dd
S )a  
        Retrieves frames from the stored video at the specified start and end times
        in seconds (the video always starts at 0 seconds). Returned frames will be
        in [start_sec, end_sec). Given that PathManager may
        be fetching the frames from network storage, to handle transient errors, frame
        reading is retried N times.  Note that as end_sec is exclusive, so you may need
        to use `get_clip(start_sec, duration + EPS)` to get the last frame.

        Args:
            start_sec (float): the clip start time in seconds
            end_sec (float): the clip end time in seconds
            frame_filter (Optional[Callable[List[int], List[int]]]):
                function to subsample frames in a clip before loading.
                If None, no subsampling is peformed.
        Returns:
            clip_frames: A tensor of the clip's RGB frames with shape:
                (channel, time, height, width). The frames are of type torch.float32 and
                in the range [0 - 255]. Raises an exception if unable to load images.

            clip_data:
                "video": A tensor of the clip's RGB frames with shape:
                (channel, time, height, width). The frames are of type torch.float32 and
                in the range [0 - 255]. Raises an exception if unable to load images.

                "frame_indices": A list of indices for each frame relative to all frames in the
                video.

            Returns None if no frames are found.
        r   zNo frames found within z and z, seconds. Video startsat time 0 and ends at .Nc                   s   g | ]}  |qS r'   )r$   r0   irF   r'   r(   r2      s    z'FrameVideo.get_clip.<locals>.<listcomp>)multithreaded)videoframe_indicesaudio)r   loggerwarningminrK   rC   r   listrange_load_images_with_retriesr   r
   totorchfloat32)	r&   rL   rM   rN   start_frame_indexend_frame_indexrV   
clip_pathsclip_framesr'   rF   r(   get_clip   s*   #
zFrameVideo.get_clipr   c                 C  s(   | j r|  |S | jr| j| S td)Nz@One of _video_frame_to_path_fn or _video_frame_paths must be set)r   r   	Exception)r&   r   r'   r'   r(   r$      s   

zFrameVideo._video_frame_to_path)NNF)r   r   r   r   r   r   r   r   r   r   r   r   )r*   FN)r!   r+   r   r   r,   r-   )r*   F)r   r   r   r   r   r   )r   r   )rH   r   r   r/   rE   )rL   r   rM   r   rN   rO   r   rP   )r   r/   r   r+   )__name__
__module____qualname____doc__r)   classmethodrB   r;   propertyrG   r   rK   re   r$   r'   r'   r'   r(   r   !   s.    
(!
<r   
   image_pathsr   num_retriesr/   rT   r   r   torch.Tensorc                   s^   dd | D  d fd	d
}t |t| | tdd  D r'td| tt S )aW  
    Loads the given image paths using PathManager, decodes them as RGB images and
    returns them as a stacked tensors.
    Args:
        image_paths (List[str]): a list of paths to images.
        num_retries (int): number of times to retry image reading to handle transient error.
        multithreaded (bool): if images are fetched via multiple threads in parallel.
    Returns:
        A tensor of the clip's RGB frames with shape:
        (time, height, width, channel). The frames are of type torch.uint8 and
        in the range [0 - 255]. Raises an exception if unable to load images.
    c                 S  s   g | ]}d qS rE   r'   rR   r'   r'   r(   r2      s    z-_load_images_with_retries.<locals>.<listcomp>image_indexr/   
image_pathr+   r   r   c              	     s   t D ]L}t|d }t| tj}tj|tj	d}t
|tj}W d    n1 s/w   Y  |d ur?| | <  d S td| d d td qd S )Nrb)flagszReading attempt /z failed.gư>)r\   r   opennp
frombufferreaduint8cv2imdecodeIMREAD_COLORcvtColorCOLOR_BGR2RGBloggingrY   timesleep)rq   rr   rS   r9   img_strimg_bgrimg_rgbimgsro   r'   r(   fetch_image   s   z._load_images_with_retries.<locals>.fetch_imagec                 s  s    | ]}|d u V  qd S rE   r'   )r0   imgr'   r'   r(   	<genexpr>   s    z,_load_images_with_retries.<locals>.<genexpr>zFailed to load images from {}N)rq   r/   rr   r+   r   r   )	r   	enumerateanyrf   formatr_   	as_tensorrw   stack)rn   ro   rT   r   r'   r   r(   r]      s   r]   )rm   T)rn   r   ro   r/   rT   r   r   rp   ) 
__future__r   r   rI   r    r3   r   typingr   r   r   r   numpyrw   r_   torch.utils.dataiopath.common.file_ior   pytorchvideo.data.utilsr   utilsr
   rU   r   r{   r   r   	getLoggerrg   rX   r   r]   r'   r'   r'   r(   <module>   s2   
 @