o
    پi!                     @   s   d Z ddlmZ ddlZddlZddlmZmZ ddl	m
Z
 ddlmZ ddlmZ dd	lmZ dd
lmZmZ ddlmZ ejZG dd deZe
d dS )zVideo Reader.    )absolute_importN   )c_arrayc_str)	_init_api)DECORDContext)DECORDError)ndarray)cpugpu)
bridge_outc                   @   s   e Zd ZdZedddddfddZdd Zdd	 Zd
d Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zd ddZdS )!VideoReadera  Individual video reader with convenient indexing and seeking functions.

    Parameters
    ----------
    uri : str
        Path of video file.
    ctx : decord.Context
        The context to decode the video file, can be decord.cpu() or decord.gpu().
    width : int, default is -1
        Desired output width of the video, unchanged if `-1` is specified.
    height : int, default is -1
        Desired output height of the video, unchanged if `-1` is specified.
    num_threads : int, default is 0
        Number of decoding thread, auto if `0` is specified.
    fault_tol : int, default is -1
        The threshold of corupted and recovered frames. This is to prevent silent fault
        tolerance when for example 50% frames of a video cannot be decoded and duplicate
        frames are returned. You may find the fault tolerant feature sweet in many cases,
        but not for training models. Say `N = # recovered frames`
        If `fault_tol` < 0, nothing will happen.
        If 0 < `fault_tol` < 1.0, if N > `fault_tol * len(video)`, raise `DECORDLimitReachedError`.
        If 1 < `fault_tol`, if N > `fault_tol`, raise `DECORDLimitReachedError`.


    r   c              	   C   s   d | _ t|ts
J t|}t|dr/t| }dt|}t	||j
|j|||d|| _ nt	||j
|j|||d|| _ | j d u rJtd| d t| j | _| jdks]J d| jd | _d | _d | _d S )Nreadz{} bytes   r   zError reading z...zInvalid frame count: {})_handle
isinstancer   strhasattr	bytearrayr   formatlen_CAPI_VideoReaderGetVideoReaderdevice_type	device_idRuntimeError_CAPI_VideoReaderGetFrameCount
_num_frame_key_indices
_frame_pts_avg_fps)selfurictxwidthheightnum_threads	fault_tolba r)   G/home/ubuntu/.local/lib/python3.10/site-packages/decord/video_reader.py__init__,   s&   


zVideoReader.__init__c                 C   s6   z| j d urt| j  W d S W d S  ty   Y d S w )N)r   _CAPI_VideoReaderFree	TypeErrorr!   r)   r)   r*   __del__@   s   
zVideoReader.__del__c                 C   s   | j S )zGet length of the video. Note that sometimes FFMPEG reports inaccurate number of frames,
        we always follow what FFMPEG reports.

        Returns
        -------
        int
            The number of frames in the video file.

        )r   r.   r)   r)   r*   __len__G   s   
zVideoReader.__len__c                 C   sj   t |tr| t|t|  S |dk r|| j7 }|| jks#|dk r,td|| j| 	| | 
 S )a  Get frame at `idx`.

        Parameters
        ----------
        idx : int or slice
            The frame index, can be negative which means it will index backwards,
            or slice of frame indices.

        Returns
        -------
        ndarray
            Frame of shape HxWx3 or batch of image frames with shape NxHxWx3,
            where N is the length of the slice.
        r   zIndex: {} out of bound: {})r   slice	get_batchrangeindicesr   r   
IndexErrorr   seek_accuratenextr!   idxr)   r)   r*   __getitem__S   s   


zVideoReader.__getitem__c                 C   s,   | j dusJ t| j }|jst t|S )zsGrab the next frame.

        Returns
        -------
        ndarray
            Frame with shape HxWx3.

        N)r   _CAPI_VideoReaderNextFrameshapeStopIterationr   )r!   arrr)   r)   r*   r7   k   s
   	
zVideoReader.nextc                 C   s   | j dusJ tj|tjd}||dk   | j7  < |dk s.td||dk  | j || jk  sAtd||| jk |S )zTValidate int64 integers and convert negative integers to positive by backward searchN)dtyper   zInvalid negative indices: {}zOut of bound indices: {})r   nparrayint64r   allr5   r   )r!   r4   r)   r)   r*   _validate_indicesz   s   zVideoReader._validate_indicesc                 C   sf   | j dusJ t|tr| t|t|  }| |}| jdu r*t	| j 
 | _| j|ddf S )a  Get frame playback timestamp in unit(second).

        Parameters
        ----------
        indices: list of integers or slice
            A list of frame indices. If negative indices detected, the indices will be indexed from backward.

        Returns
        -------
        numpy.ndarray
            numpy.ndarray of shape (N, 2), where N is the size of indices. The format is `(start_second, end_second)`.
        N)r   r   r1   r2   r3   r4   r   rD   r   _CAPI_VideoReaderGetFramePTSasnumpyr8   r)   r)   r*   get_frame_timestamp   s   


zVideoReader.get_frame_timestampc                 C   s2   | j dusJ t| |}t| j |}t|S )a!  Get entire batch of images. `get_batch` is optimized to handle seeking internally.
        Duplicate frame indices will be optmized by copying existing frames rather than decode
        from video again.

        Parameters
        ----------
        indices : list of integers
            A list of frame indices. If negative indices detected, the indices will be indexed from backward

        Returns
        -------
        ndarray
            An entire batch of image frames with shape NxHxWx3, where N is the length of `indices`.

        N)r   _ndrA   rD   _CAPI_VideoReaderGetBatchr   )r!   r4   r>   r)   r)   r*   r2      s   zVideoReader.get_batchc                 C   s$   | j du rt| j  | _ | j S )z}Get list of key frame indices.

        Returns
        -------
        list
            List of key frame indices.

        N)r   _CAPI_VideoReaderGetKeyIndicesr   rF   tolistr.   r)   r)   r*   get_key_indices   s   
	zVideoReader.get_key_indicesc                 C   s   | j du rt| j| _ | j S )ztGet average FPS(frame per second).

        Returns
        -------
        float
            Average FPS.

        N)r    _CAPI_VideoReaderGetAverageFPSr   r.   r)   r)   r*   get_avg_fps   s   
	zVideoReader.get_avg_fpsc                 C   F   | j dusJ |dkr|| jk sJ t| j |}|s!td|dS )zFast seek to frame position, this does not guarantee accurate position.
        To obtain accurate seeking, see `accurate_seek`.

        Parameters
        ----------
        pos : integer
            Non negative seeking position.

        Nr   zFailed to seek to frame {})r   r   _CAPI_VideoReaderSeekr   r   r!   possuccessr)   r)   r*   seek      
zVideoReader.seekc                 C   rO   )zAccurately seek to frame position, this is slower than `seek`
        but guarantees accurate position.

        Parameters
        ----------
        pos : integer
            Non negative seeking position.

        Nr   z#Failed to seek_accurate to frame {})r   r   _CAPI_VideoReaderSeekAccurater   r   rQ   r)   r)   r*   r6      rU   zVideoReader.seek_accurater   c                 C   s*   | j dusJ |dksJ t| j | dS )a  Skip reading multiple frames. Skipped frames will still be decoded
        (required by following frames) but it can save image resize/copy operations.


        Parameters
        ----------
        num : int, default is 1
            The number of frames to be skipped.

        Nr   )r   _CAPI_VideoReaderSkipFrames)r!   numr)   r)   r*   skip_frames   s   zVideoReader.skip_framesN)r   )__name__
__module____qualname____doc__r
   r+   r/   r0   r:   r7   rD   rG   r2   rL   rN   rT   r6   rY   r)   r)   r)   r*   r      s    r   zdecord.video_reader)r]   
__future__r   ctypesnumpyr@   	_ffi.baser   r   _ffi.functionr   _ffi.ndarrayr   baser    r	   rH   r
   r   bridger   c_void_pVideoReaderHandleobjectr   r)   r)   r)   r*   <module>   s     j