U
    ­Ê¹j:=  ã                   @   s*  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
mZmZmZ d dlZd dlZddlmZ ddlmZ z4d dlZej ejj¡ eejjjdƒs®ed	ƒZW n ek
rÌ   ed
ƒZY nX 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&„Z+de
e' d$œd'd(„Z,d.e#e#ee
e' ee% f d)œd*d+„Z-dS )/é    N)ÚFraction)ÚAnyÚDictÚListÚOptionalÚTupleÚUnioné   )Ú_log_api_usage_onceé   )Ú
_video_optÚ	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.
z¼PyAV 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   úS/var/www/html/bwave/python/venv/lib/python3.8/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_available,   s    r   é
   Úlibx264)
ÚfilenameÚvideo_arrayÚfpsÚvideo_codecÚoptionsÚaudio_arrayÚ	audio_fpsÚaudio_codecÚaudio_optionsr   c	                 C   sÚ  t j ¡ st j ¡ sttƒ tƒ  t j|t jd� 	¡ }t
|tƒrJt |¡}tj| dd���v}	|	j||d�}
|jd |
_|jd |
_|dkrŽdnd	|
_|pši |
_|d
k	�rtdddddddddddœ
}|	j||d�}|pÖi |_|jd }|dkrðdnd}|	jjd jj}t || ¡}t  |¡ 	¡  |¡}tjj|||d�}||_| |¡D ]}|	  |¡ �qH| ¡ D ]}|	  |¡ �qb|D ]8}tj!j|d	d�}d|_"|
 |¡D ]}|	  |¡ �qœ�qx|
 ¡ D ]}|	  |¡ �qºW 5 Q R X d
S )a|  
    Writes a 4d tensor in [T, H, W, C] format in a video file

    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
        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
    ©ÚdtypeÚ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stereoÚmono)ÚformatZlayout)r+   ÚNONE)#ÚtorchÚjitÚis_scriptingÚ
is_tracingr
   Úwrite_videor   Ú	as_tensorÚuint8Únumpyr   ÚfloatÚnpÚroundr   ÚopenZ
add_streamÚshapeÚwidthÚheightZpix_fmtr   ÚstreamsÚaudior+   Únamer$   ZastypeZ
AudioFrameZfrom_ndarrayZsample_rateÚencodeZmuxÚ
VideoFramer   )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ÚpacketZimgr   r   r   r1   5   sX    



ö

r1   zav.container.Containerzav.stream.Stream.zav.frame.Frame)rA   Ústart_offsetÚ
end_offsetÚpts_unitrB   Ú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}|ræd|kræ| d¡}	||	d … }
t d	|
¡}|d krÐt d
|
¡}|d k	ræ| d¡dk}ˆ}t|d dƒ}|�rt|| dƒ}z| j|dd|d� W n tjk
�r>   g  Y S X d}zXt| jf |ŽƒD ]B\}}|ˆ|j< |jˆ k�rV|�r�||k �r�|d7 }�qV �qš�qVW n tjk
�r´   Y nX ‡ ‡‡fdd„tˆƒD ƒ}tˆƒdk�r*ˆdk�r*ˆˆk�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backwardrB   c                    s2   g | ]*}ˆˆ| j   kr"ˆ krn qˆ| ‘qS r   ©Úpts©Ú.0Úi©rF   ÚframesrE   r   r   Ú
<listcomp>Ñ   s
        z%_read_from_stream.<locals>.<listcomp>c                    s   g | ]}|ˆ k r|‘qS r   r   rQ   )rE   r   r   rV   Ö   s      )Ú_CALLED_TIMESÚ_GC_COLLECTION_INTERVALÚgcZcollectÚintÚmathÚfloorÚ	time_baser5   ÚceilÚwarningsÚwarnÚtypeÚcodec_contextÚ	extradataÚfindÚreÚsearchÚgroupÚmaxÚseekr   ÚAVErrorÚ	enumerateÚdecoderP   ÚsortedÚlenÚinsert)rA   rE   rF   rG   rB   rH   Zshould_bufferÚmax_buffer_sizerc   ÚposÚdÚoZseek_offsetZbuffer_countZ_idxrC   ÚresultZpreceding_framesZfirst_frame_ptsr   rT   r   Ú_read_from_stream�   s^    	




"ru   )Ú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   )rP   r9   rZ   )
rv   rw   rx   ry   ÚstartÚendZtotal_aframesZstep_per_aframeZs_idxZe_idxr   r   r   Ú_align_audio_framesÝ   s    
r}   rP   ÚTHWC)r   Ú	start_ptsÚend_ptsrG   Úoutput_formatr   c              	   C   s†  t j ¡ st j ¡ sttƒ | ¡ }|dkr<td|› d�ƒ‚ddlm	} t
j | ¡sbtd| › �ƒ‚|ƒ dkr†t | |||¡\}}}�nÜtƒ  |dkrœtd	ƒ}||k r¸td
|› d|› �ƒ‚i }g }	g }
tj}zºtj| dd��¢}|jjrò|jjd j}|jj�r>t|||||jjd ddiƒ}	|jjd j}|dk	�r>t|ƒ|d< |jj�rxt|||||jjd ddiƒ}
|jjd j|d< W 5 Q R X W n tjk
�rœ   Y nX dd„ |	D ƒ}dd„ |
D ƒ}|�rÒt  t |¡¡}nt j dt j!d�}|�rRt "|d¡}t  |¡}|dk�rBt#t$ %|d|  ¡ƒ}|td	ƒk�rBt#t$ &|d|  ¡ƒ}t'||
||ƒ}nt j dt j(d�}|dk�r|| )dddd¡}|||fS )a   
    Reads a video from a file, returning both the video frames and the audio frames

    Args:
        filename (str): path to the video file
        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_backendzFile not found: ÚpyavNrJ   z7end_pts should be larger than start_pts, got start_pts=z and end_pts=Úignore©Zmetadata_errorsrL   Ú	video_fpsr=   r    c                 S   s   g | ]}|  ¡  ¡ ‘qS r   )Zto_rgbÚ
to_ndarray©rR   rC   r   r   r   rV   D  s     zread_video.<locals>.<listcomp>c                 S   s   g | ]}|  ¡ ‘qS r   )rŠ   r‹   r   r   r   rV   E  s     )r   r   r   rM   r#   r   rI   )r   r   r‚   rM   r	   )*r-   r.   r/   r0   r
   Ú
read_videoÚupperÚ
ValueErrorÚtorchvisionr…   ÚosÚpathÚexistsÚRuntimeErrorr   Z_read_videor   r5   Zdefault_timebaser   r8   r<   r=   r]   rL   ru   Úaverage_rater'   rj   r2   r6   ÚstackÚemptyr3   ZconcatenaterZ   r[   r\   r^   r}   Zfloat32Zpermute)r   r   r€   rG   r�   r…   Zvframesrv   ÚinfoZvideo_framesrw   Zaudio_timebaserA   r‰   Zvframes_listZaframes_listr   r   r   rŒ   ì   s„    
ÿ

ú


ú 


rŒ   )rA   r   c                 C   s*   | j d jj}|d krdS d|kr&dS dS )Nr   Fs   LavcT)r<   rb   rc   )rA   rc   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 k	r|j ‘qS r   rO   ©rR   Úxr   r   r   rV   j  s     
 z,_decode_video_timestamps.<locals>.<listcomp>r   )rL   c                 S   s   g | ]}|j d k	r|j ‘qS r   rO   r™   r   r   r   rV   l  s     
 )r˜   Zdemuxrl   )rA   r   r   r   Ú_decode_video_timestampsg  s    r›   )r   rG   r   c           	   
      s2  t j ¡ st j ¡ sttƒ ddlm} |ƒ dkr>t 	| |¡S t
ƒ  d}g }zvtj| dd��^}|jjr¶|jjd }|j‰ zt|ƒ}W n& tjk
rª   t d| › �¡ Y nX t|jƒ}W 5 Q R X W nB tjk
�r } z d| › d	|› �}t |t¡ W 5 d}~X Y nX | ¡  |d
k�r*‡ fdd„|D ƒ}||fS )a   
    List the video frames timestamps.

    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: rI   c                    s   g | ]}|ˆ  ‘qS r   r   r™   ©Zvideo_time_baser   r   rV   �  s     z)read_video_timestamps.<locals>.<listcomp>)r-   r.   r/   r0   r
   Úread_video_timestampsr�   r…   r   Z_read_video_timestampsr   r   r8   r<   rL   r]   r›   rj   r_   r`   r5   r”   ÚRuntimeWarningÚsort)	r   rG   r…   r‰   rP   rA   Zvideo_streamÚeÚmsgr   rœ   r   r�   o  s2    

r�   )r   NNNNN)r   NrP   r~   )rP   ).rY   r[   r�   re   r_   Ú	fractionsr   Útypingr   r   r   r   r   r   r4   r6   r-   Úutilsr
   Ú r   r   ÚloggingZ	set_levelÚERRORÚhasattrrL   rC   r@   ÚImportErrorr   Úboolr   rW   rX   ÚstrZTensorr5   r1   rZ   ru   r}   rŒ   r˜   r›   r�   r   r   r   r   Ú<module>   s�    ÿ	ÿ
	      ÷öY$ùQ   þ    û
úr	