o
    پi                     @   s|   d Z ddl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mZ ddlmZ dd	lmZ G d
d deZdS )z
AV Reader.    )absolute_importN   )VideoReader)AudioReader)cpugpu)ndarray)
bridge_outc                   @   sT   e Zd ZdZedd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S )AVReaderap  Individual audio video reader with convenient indexing function.

    Parameters
    ----------
    uri: str
        Path of file.
    ctx: decord.Context
        The context to decode the file, can be decord.cpu() or decord.gpu().
    sample_rate: int, default is -1
        Desired output sample rate of the audio, unchanged if `-1` is specified.
    mono: bool, default is True
        Desired output channel layout of the audio. `True` is mono layout. `False` is unchanged.
    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   iD  Tc	           	      C   sF   t ||||| _| j  t|dr|d t||||||| _d S )Nreadr   )r   _AVReader__audio_readeradd_paddinghasattrseekr   _AVReader__video_reader)	selfurictxsample_ratemonowidthheightnum_threads	fault_tol r   D/home/ubuntu/.local/lib/python3.10/site-packages/decord/av_reader.py__init__,   s
   


zAVReader.__init__c                 C   s
   t | 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.
        )lenr   )r   r   r   r   __len__3   s   
zAVReader.__len__c                 C   s   | j dur
| jdusJ t|tr| t|t| j  S |dk r)|t| j 7 }|t| j ks4|dk r?td	|t| j | j 
|\}}| j|}| j|}| j|| | j | fS )a  Get audio samples and video 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/list of ndarray, ndarray)
            First element is samples of shape CxS or a list of length N containing samples of shape CxS,
            where N is the number of frames, C is the number of channels, 
            S is the number of samples of the corresponding frame.

            Second element is Frame of shape HxWx3 or batch of image frames with shape NxHxWx3,
            where N is the length of the slice.
        Nr   zIndex: {} out of bound: {})r   r   
isinstanceslice	get_batchrangeindicesr   
IndexErrorformatget_frame_timestamp_time_to_sample)r   idxaudio_start_idxaudio_end_idxr   r   r   __getitem__=   s   
zAVReader.__getitem__c           
      C   s   | j dur
| jdusJ | |}g }d}d}t|D ]/}| j |\}}|r0||d kr0|}n| j|}| j|}	|| j||	  |}|	}q|| j |fS )a  Get entire batch of audio samples and video frames.

        Parameters
        ----------
        indices : list of integers
            A list of frame indices. If negative indices detected, the indices will be indexed from backward
        Returns
        -------
        (list of ndarray, ndarray)
            First element is a list of length N containing samples of shape CxS,
            where N is the number of frames, C is the number of channels, 
            S is the number of samples of the corresponding frame.

            Second element is Frame of shape HxWx3 or batch of image frames with shape NxHxWx3,
            where N is the length of the slice.

        Nr   )r   r   _validate_indiceslistr'   r(   appendr"   )
r   r$   	audio_arrprev_video_idxprev_audio_end_idxr)   frame_start_timeframe_end_timer*   r+   r   r   r   r"   \   s   
zAVReader.get_batchc                 C   s   t j| j d dfdd}t|D ]&}| j|\}}| j|}| j|}t j|| j|| 	 fdd}qt
t|| j|fS )Nr   float32)shapedtyper   )axis)npemptyr   r6   r.   r   r'   r(   concatenateasnumpyr	   _ndarrayr"   )r   slr0   r)   r*   r+   r   r   r   
_get_slice   s   "zAVReader._get_slicec                 C   s   | j dur
| jdusJ tj|tjd}||dk   t| j 7  < |dk s7td||dk  t| j  |t| j k  sNtd||t| j k |S )zTValidate int64 integers and convert negative integers to positive by backward searchN)r7   r   zInvalid negative indices: {}zOut of bound indices: {})	r   r   r9   r>   int64r   allr%   r&   )r   r$   r   r   r   r-      s   zAVReader._validate_indicesN)__name__
__module____qualname____doc__r   r   r   r,   r"   r@   r-   r   r   r   r   r
      s    
%	r
   )rF   
__future__r   ctypesnumpyr9   mathvideo_readerr   audio_readerr   r   r   r    r=   bridger	   objectr
   r   r   r   r   <module>   s    