a
    hG                     @   sL  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 d dlmZm	Z	m
Z
 d dlZd dlZddlmZ ddlmZ ddlmZ zXd dlZejejj eejjjd	sed
Zz
ejZW n ey   ejZY n0 W n ey   edZY n0 ddddZ e!dddZ"d a#da$d-e%ej&e'e%e	e(e%ef  e	ej& e	e' e	e% e	e(e%ef  dd
ddZ)de'e'e%de(e%e	e
e*e+e*df e,e* f  f e,d dddZ-ej&e,d e*e'ej&dddZ.d.e%e
e'ef e	e
e'ef  e%e%e+ej&ej&e(e%ef f d"d#d$Z/de!d%d&d'Z0de,e* d%d(d)Z1d/e%e%e+e,e* e	e' f d*d+d,Z2dS )0    N)Fraction)AnyOptionalUnion   )_log_api_usage_once   )
_video_opt) _raise_video_deprecation_warning	pict_typea+  Your version of PyAV is too old for the necessary video operations in torchvision.
If you are on Python 3.5, you will have to build from source (the conda-forge
packages are not up-to-date).  See
https://github.com/mikeboers/PyAV#installation for instructions on how to
install PyAV on your system.
zPyAV is not installed, and is necessary for the video operations in torchvision.
See https://github.com/mikeboers/PyAV#installation for instructions on how to
install PyAV on your system.
)returnc                   C   s   t ttrtd S N
isinstanceav	Exception r   r   B/var/www/auris/lib/python3.9/site-packages/torchvision/io/video.py_check_av_available,   s    
r   c                   C   s   t tt S r   r   r   r   r   r   _av_available1   s    r   
   libx264)
filenamevideo_arrayfpsvideo_codecoptionsaudio_array	audio_fpsaudio_codecaudio_optionsr   c	                 C   s0  t   tj s"tj s"tt t  tj|tj	dj
dd}t|trXtt|}tj| dd}	|	j||d}
|jd |
_|jd |
_|d	krd
nd|
_|pi |
_|durddddddddddd
}|	j||d}|pi |_|jd }|dkrdnd}|	jjd jj}t|| }t|j
dd|}tjj|||d}||_ |!|D ]}|	"| qZ|! D ]}|	"| qt|D ]f}tj#j|dd}z
d|_$W n( t%y   ddl&m'} |j(|_$Y n0 |
!|D ]}|	"| qܐq|
! D ]}|	"| qW d   n1 s"0    Y  dS )a~  
    [DEPRECATED] Writes a 4d tensor in [T, H, W, C] format in a video file.

    .. warning::

        DEPRECATED: All the video decoding and encoding capabilities of torchvision
        are deprecated from version 0.22 and will be removed in version 0.24.  We
        recommend that you migrate to
        `TorchCodec <https://github.com/pytorch/torchcodec>`__, where we'll
        consolidate the future decoding/encoding capabilities of PyTorch

    This function relies on PyAV (therefore, ultimately FFmpeg) to encode
    videos, you can get more fine-grained control by referring to the other
    options at your disposal within `the FFMpeg wiki
    <http://trac.ffmpeg.org/wiki#Encoding>`_.

    Args:
        filename (str): path where the video will be saved
        video_array (Tensor[T, H, W, C]): tensor containing the individual frames,
            as a uint8 tensor in [T, H, W, C] format
        fps (Number): video frames per second
        video_codec (str): the name of the video codec, i.e. "libx264", "h264", etc.
        options (Dict): dictionary containing options to be passed into the PyAV video stream.
            The list of options is codec-dependent and can all
            be found from `the FFMpeg wiki <http://trac.ffmpeg.org/wiki#Encoding>`_.
        audio_array (Tensor[C, N]): tensor containing the audio, where C is the number of channels
            and N is the number of samples
        audio_fps (Number): audio sample rate, typically 44100 or 48000
        audio_codec (str): the name of the audio codec, i.e. "mp3", "aac", etc.
        audio_options (Dict): dictionary containing options to be passed into the PyAV audio stream.
            The list of options is codec-dependent and can all
            be found from `the FFMpeg wiki <http://trac.ffmpeg.org/wiki#Encoding>`_.

    Examples::
        >>> # Creating libx264 video with CRF 17, for visually lossless footage:
        >>>
        >>> from torchvision.io import write_video
        >>> # 1000 frames of 100x100, 3-channel image.
        >>> vid = torch.randn(1000, 100, 100, 3, dtype = torch.uint8)
        >>> write_video("video.mp4", options = {"crf": "17"})

    dtypeT)forcew)mode)rater   r   Z
libx264rgbZyuv420pZrgb24Nz<f8z<f4z<i2z<i4u1)
ZdblZdblpZfltZfltpZs16Zs16pZs32Zs32pu8Zu8pr   ZstereoZmono)formatZlayout)r)   NONE)PictureType))r
   torchjitis_scripting
is_tracingr   write_videor   	as_tensoruint8numpyr   floatintnproundr   openZ
add_streamshapewidthheightZpix_fmtr   streamsaudior)   namer"   ZastypeZ
AudioFrameZfrom_ndarrayZsample_rateencodeZmux
VideoFramer   	TypeErrorZav.video.framer+   r*   )r   r   r   r   r   r   r   r   r    	containerstreamZaudio_format_dtypesZa_streamZnum_channelsZaudio_layoutZaudio_sample_fmtZformat_dtypeframepacketimgr+   r   r   r   r0   :   sb    5





r0   zav.container.Containerzav.stream.Stream.zav.frame.Frame)rB   start_offset
end_offsetpts_unitrC   stream_namer   c                    s*  t d7 a t t td kr t  |dkrfttd|j   tdkrptt	 d|j   n
t
d i d}d}|jdkr|jj}|rd|v r|d}	||	d  }
td	|
}|d u rtd
|
}|d ur|ddk}}t|d d}|rt|| d}z| j|dd|d W n ty:   g  Y S 0 d}z\t| jf i |D ]B\}}||j< |j krV|r||k r|d7 }qV qqVW n ty   Y n0  fddtD }tdkr&dkr&vr&fddD }t|dkr&t|}|d|  |S )Nr   secinfzBThe pts_unit 'pts' gives wrong results. Please use pts_unit 'sec'.T   videos   DivXs   DivX(\d+)Build(\d+)(\w)s   DivX(\d+)b(\d+)(\w)      pr   F)Z	any_frameZbackwardrC   c                    s2   g | ]*}| j   kr" krn q| qS r   pts.0irH   framesrG   r   r   
<listcomp>       z%_read_from_stream.<locals>.<listcomp>c                    s   g | ]}| k r|qS r   r   rS   )rG   r   r   rX      rY   )_CALLED_TIMES_GC_COLLECTION_INTERVALgcZcollectr5   mathfloor	time_baser4   ceilwarningswarntypecodec_context	extradatafindresearchgroupmaxseekFFmpegError	enumeratedecoderR   sortedleninsert)rB   rG   rH   rI   rC   rJ   Zshould_buffermax_buffer_sizere   posdoZseek_offsetZbuffer_countZ_idxrD   resultZpreceding_framesZfirst_frame_ptsr   rV   r   _read_from_stream   s^    	




"rw   )aframesaudio_frames	ref_startref_endr   c           
      C   s|   |d j |d j  }}| jd }|| d | }d}|}	||k rPt|| | }||krht|| | }	| d d ||	f S )Nr   r   )rR   r9   r5   )
rx   ry   rz   r{   startendZtotal_aframesZstep_per_aframeZs_idxZe_idxr   r   r   _align_audio_frames  s    
r   rR   THWC)r   	start_ptsend_ptsrI   output_formatr   c              	   C   s  t   tj s"tj s"tt | }|dvrBtd| dddl	m
} | dkrtj| srtd|  t| |||\}}}nt  |du rtd	}||k rtd
| d| i }g }	g }
tj}ztj| dd}|jjr|jjd j}|jjrDt|||||jjd ddi}	|jjd j}|durDt||d< |jjr~t|||||jjd ddi}
|jjd j|d< W d   n1 s0    Y  W n ty   Y n0 dd |	D }dd |
D }|rtt |}ntj!dtj"d}|rjt#|d}t|}|dkrZt$t%&|d|  }|td	krZt$t%'|d|  }t(||
||}ntj!dtj)d}|dkr|*dddd}|||fS )a  [DEPRECATED] Reads a video from a file, returning both the video frames and the audio frames

    .. warning::

        DEPRECATED: All the video decoding and encoding capabilities of torchvision
        are deprecated from version 0.22 and will be removed in version 0.24.  We
        recommend that you migrate to
        `TorchCodec <https://github.com/pytorch/torchcodec>`__, where we'll
        consolidate the future decoding/encoding capabilities of PyTorch

    Args:
        filename (str): path to the video file. If using the pyav backend, this can be whatever ``av.open`` accepts.
        start_pts (int if pts_unit = 'pts', float / Fraction if pts_unit = 'sec', optional):
            The start presentation time of the video
        end_pts (int if pts_unit = 'pts', float / Fraction if pts_unit = 'sec', optional):
            The end presentation time
        pts_unit (str, optional): unit in which start_pts and end_pts values will be interpreted,
            either 'pts' or 'sec'. Defaults to 'pts'.
        output_format (str, optional): The format of the output video tensors. Can be either "THWC" (default) or "TCHW".

    Returns:
        vframes (Tensor[T, H, W, C] or Tensor[T, C, H, W]): the `T` video frames
        aframes (Tensor[K, L]): the audio frames, where `K` is the number of channels and `L` is the number of points
        info (Dict): metadata for the video and audio. Can contain the fields video_fps (float) and audio_fps (int)
    )r   TCHWz5output_format should be either 'THWC' or 'TCHW', got .r   get_video_backendpyavzFile not found: NrL   z7end_pts should be larger than start_pts, got start_pts=z and end_pts=ignoreZmetadata_errorsrN   	video_fpsr=   r   c                 S   s   g | ]}|   qS r   )Zto_rgb
to_ndarrayrT   rD   r   r   r   rX   q  rY   zread_video.<locals>.<listcomp>c                 S   s   g | ]}|  qS r   )r   r   r   r   r   rX   r  rY   )r   r   r   rO   r!   r   rK   )r   r   r   rO   r   )+r
   r,   r-   r.   r/   r   
read_videoupper
ValueErrortorchvisionr   ospathexistsRuntimeErrorr	   Z_read_videor   r4   Zdefault_timebaser   r8   r<   r=   r_   rN   rw   average_rater&   rl   r1   r6   stackemptyr2   Zconcatenater5   r]   r^   r`   r   float32Zpermute)r   r   r   rI   r   r   Zvframesrx   infoZvideo_framesry   Zaudio_timebaserB   r   Zvframes_listZaframes_listr   r   r   r     s     





6


r   )rB   r   c                 C   s*   | j d jj}|d u rdS d|v r&dS dS )Nr   Fs   LavcT)r<   rd   re   )rB   re   r   r   r   !_can_read_timestamps_from_packets  s    r   c                 C   s8   t | rdd | jddD S dd | jddD S d S )Nc                 S   s   g | ]}|j d ur|j qS r   rQ   rT   xr   r   r   rX     rY   z,_decode_video_timestamps.<locals>.<listcomp>r   )rN   c                 S   s   g | ]}|j d ur|j qS r   rQ   r   r   r   r   rX     rY   )r   Zdemuxrn   )rB   r   r   r   _decode_video_timestamps  s    r   )r   rI   r   c           	   
      sH  t   tj s"tj s"tt ddlm} | dkrDt	
| |S t  d}g }ztj| ddd}|jjr|jjd }|j zt|}W n" ty   td|   Y n0 t|j}W d   n1 s0    Y  W nB ty } z(d|  d	| }t|t W Y d}~n
d}~0 0 |  |d
kr@ fdd|D }||fS )a  [DEPREACTED] List the video frames timestamps.

    .. warning::

        DEPRECATED: All the video decoding and encoding capabilities of torchvision
        are deprecated from version 0.22 and will be removed in version 0.24.  We
        recommend that you migrate to
        `TorchCodec <https://github.com/pytorch/torchcodec>`__, where we'll
        consolidate the future decoding/encoding capabilities of PyTorch

    Note that the function decodes the whole video frame-by-frame.

    Args:
        filename (str): path to the video file
        pts_unit (str, optional): unit in which timestamp values will be returned
            either 'pts' or 'sec'. Defaults to 'pts'.

    Returns:
        pts (List[int] if pts_unit = 'pts', List[Fraction] if pts_unit = 'sec'):
            presentation timestamps for each one of the frames in the video.
        video_fps (float, optional): the frame rate for the video

    r   r   r   Nr   r   z Failed decoding frames for file zFailed to open container for z; Caught error: rK   c                    s   g | ]}|  qS r   r   r   Zvideo_time_baser   r   rX     rY   z)read_video_timestamps.<locals>.<listcomp>)r
   r,   r-   r.   r/   r   read_video_timestampsr   r   r	   Z_read_video_timestampsr   r   r8   r<   rN   r_   r   rl   ra   rb   r4   r   RuntimeWarningsort)	r   rI   r   r   rR   rB   Zvideo_streamemsgr   r   r   r     s4    
,"
r   )r   NNNNN)r   NrR   r   )rR   )3r\   r]   r   rg   ra   Z	fractionsr   typingr   r   r   r3   r6   r,   utilsr    r	   Z_video_deprecation_warningr
   r   loggingZ	set_levelERRORhasattrrN   rD   r@   ImportErrorrl   AttributeErrorZAVErrorr   boolr   rZ   r[   strZTensorr4   dictr0   r5   tuplelistrw   r   r   r   r   r   r   r   r   r   <module>   s   	

	      z$Q    
y	