U
    ­Ê¹j¨B  ã                   @   sì   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mZmZmZ d dlZd dlmZmZmZmZ ddlmZ edƒZejfeeeeedœd	d
„Zdejeeeejdœdd„ZG dd„ dƒZeedœdd„ZG dd„ dƒZdS )é    N©ÚFraction)	ÚAnyÚCallableÚcastÚDictÚListÚOptionalÚTupleÚTypeVarÚUnion)Ú_probe_video_from_fileÚ_read_video_from_fileÚ
read_videoÚread_video_timestampsé   )ÚtqdmÚT)ÚptsÚtimebase_fromÚtimebase_toÚ
round_funcÚreturnc                 C   s   t | dƒ| | }||ƒS )zèconvert pts between different time bases
    Args:
        pts: presentation timestamp, float
        timebase_from: original timebase. Fraction
        timebase_to: new timebase. Fraction
        round_func: rounding function.
    r   r   )r   r   r   r   Znew_pts© r   ú_/var/www/html/bwave/python/venv/lib/python3.8/site-packages/torchvision/datasets/video_utils.pyÚpts_convert   s    r   )ÚtensorÚsizeÚstepÚdilationr   c                 C   s‚   |   ¡ dkrtd|   ¡ › �ƒ‚|  d¡}|  ¡ }|| || f}|||d  d  | d |f}|d dk rtd|f}t | ||¡S )a   
    similar to tensor.unfold, but with the dilation
    and specialized for 1d tensors

    Returns all consecutive windows of `size` elements, with
    `step` between windows. The distance between each element
    in a window is given by `dilation`.
    r   z*tensor should have 1 dimension instead of r   )ÚdimÚ
ValueErrorZstrideÚnumelÚtorchZ
as_strided)r   r   r   r   Zo_strider"   Z
new_strideÚnew_sizer   r   r   Úunfold   s    	
 r%   c                   @   sR   e Zd ZdZee ddœdd„Zedœdd„Zee	ee e
e f d	œd
d„ZdS )Ú_VideoTimestampsDatasetzÚ
    Dataset used to parallelize the reading of the timestamps
    of a list of videos, given their paths in the filesystem.

    Used in VideoClips and defined at top level, so it can be
    pickled when forking.
    N)Úvideo_pathsr   c                 C   s
   || _ d S ©N©r'   )Úselfr'   r   r   r   Ú__init__8   s    z _VideoTimestampsDataset.__init__©r   c                 C   s
   t | jƒS r(   ©Úlenr'   ©r*   r   r   r   Ú__len__;   s    z_VideoTimestampsDataset.__len__©Úidxr   c                 C   s   t | j| ƒS r(   )r   r'   )r*   r2   r   r   r   Ú__getitem__>   s    z#_VideoTimestampsDataset.__getitem__)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   Ústrr+   Úintr0   r
   r	   Úfloatr3   r   r   r   r   r&   /   s   r&   )Úxr   c                 C   s   | S )zH
    Dummy collate function to be used with _VideoTimestampsDataset
    r   )r;   r   r   r   Ú_collate_fnB   s    r<   c                   @   s²  e Zd ZdZd.ee eeee eeee	f  eeeeeeeeddœdd	„Z
dd
œdd„Zeee	f ddœdd„Zeeee	f d
œdd„ƒZee d dœdd„Zed/ejeeeee eejeee ejf f dœdd„ƒZd0eeee ddœdd„Zed
œdd„Zed
œdd„Zed
œdd „Zeeeef d!œd"d#„Zeeeeeeejf d$œd%d&„ƒZeeejejeee	f ef d!œd'd(„Zeee	f d
œd)d*„Zeee	f dd+œd,d-„ZdS )1Ú
VideoClipsaC  
    Given a list of video files, computes all consecutive subvideos of size
    `clip_length_in_frames`, where the distance between each subvideo in the
    same video is defined by `frames_between_clips`.
    If `frame_rate` is specified, it will also resample all the videos to have
    the same frame rate, and the clips will refer to this frame rate.

    Creating this instance the first time is time-consuming, as it needs to
    decode all the videos in `video_paths`. It is recommended that you
    cache the results after instantiation of the class.

    Recreating the clips for different clip lengths is fast, and can be done
    with the `compute_clips` method.

    Args:
        video_paths (List[str]): paths to the video files
        clip_length_in_frames (int): size of a clip in number of frames
        frames_between_clips (int): step (in frames) between each clip
        frame_rate (int, optional): if specified, it will resample the video
            so that it has `frame_rate`, and then the clips will be defined
            on the resampled video
        num_workers (int): how many subprocesses to use for data loading.
            0 means that the data will be loaded in the main process. (default: 0)
        output_format (str): The format of the output video tensors. Can be either "THWC" (default) or "TCHW".
    é   r   Nr   ÚTHWC)r'   Úclip_length_in_framesÚframes_between_clipsÚ
frame_rateÚ_precomputed_metadataÚnum_workersÚ_video_widthÚ_video_heightÚ_video_min_dimensionÚ_video_max_dimensionÚ_audio_samplesÚ_audio_channelsÚoutput_formatr   c                 C   s‚   || _ || _|| _|| _|	| _|
| _|| _|| _| ¡ | _	| j	dkrTt
d|› d�ƒ‚|d krf|  ¡  n
|  |¡ |  |||¡ d S )N)r?   ÚTCHWz5output_format should be either 'THWC' or 'TCHW', got Ú.)r'   rD   rE   rF   rG   rH   rI   rJ   ÚupperrK   r!   Ú_compute_frame_ptsÚ_init_from_metadataÚcompute_clips)r*   r'   r@   rA   rB   rC   rD   rE   rF   rG   rH   rI   rJ   rK   r   r   r   r+   d   s    



zVideoClips.__init__r,   c              	      sž   g | _ g | _dd l‰ ˆ jjjt| jƒd| jt	d�}t
t|ƒd��T}|D ]H}| d¡ tt|Ž ƒ\}}‡ fdd„|D ƒ}| j  |¡ | j |¡ qFW 5 Q R X d S )Nr   r>   )Z
batch_sizerD   Z
collate_fn)Útotalr   c                    s   g | ]}ˆ j |ˆ jd �‘qS )©Zdtype)Ú	as_tensorÚlong)Ú.0Úc©r#   r   r   Ú
<listcomp>Ÿ   s     z1VideoClips._compute_frame_pts.<locals>.<listcomp>)Ú	video_ptsÚ	video_fpsZtorch.utils.dataÚutilsÚdataZ
DataLoaderr&   r'   rD   r<   r   r.   ÚupdateÚlistÚzipÚextend)r*   ÚdlZpbarÚbatchÚclipsÚfpsr   rX   r   rO   ‰   s     ü
zVideoClips._compute_frame_pts)Úmetadatar   c                 C   sV   |d | _ t| j ƒt|d ƒks$t‚|d | _t| j ƒt|d ƒksHt‚|d | _d S )Nr'   rZ   r[   )r'   r.   ÚAssertionErrorrZ   r[   )r*   rf   r   r   r   rP   £   s
    

zVideoClips._init_from_metadatac                 C   s   | j | j| jdœ}|S )N©r'   rZ   r[   rh   )r*   Ú	_metadatar   r   r   rf   ª   s
    ýzVideoClips.metadata)Úindicesr   c                    s~   ‡ fdd„|D ƒ}‡ fdd„|D ƒ}‡ fdd„|D ƒ}|||dœ}t ˆ ƒ|ˆ jˆ jˆ j|ˆ jˆ jˆ jˆ jˆ jˆ j	ˆ j
ˆ jd�S )Nc                    s   g | ]}ˆ j | ‘qS r   r)   ©rV   Úir/   r   r   rY   ´   s     z%VideoClips.subset.<locals>.<listcomp>c                    s   g | ]}ˆ j | ‘qS r   )rZ   rk   r/   r   r   rY   µ   s     c                    s   g | ]}ˆ j | ‘qS r   )r[   rk   r/   r   r   rY   ¶   s     rh   )r@   rA   rB   rC   rD   rE   rF   rG   rH   rI   rJ   rK   )ÚtypeÚ
num_framesr   rB   rD   rE   rF   rG   rH   rI   rJ   rK   )r*   rj   r'   rZ   r[   rf   r   r/   r   Úsubset³   s,    ýózVideoClips.subset)rZ   rn   r   re   rB   r   c           	      C   s˜   |d krd}|d kr|}t | ƒt|ƒ|  }t tt |¡ƒ||¡}| | } t| ||ƒ}| ¡ sjt	 
d¡ t|tƒr„|gt |ƒ }nt|||ƒ}||fS )Nr   z¥There aren't enough frames in the current video to get a clip for the given clip length and frames between clips. The video (and potentially others) will be skipped.)r.   r:   r=   Ú_resample_video_idxr9   ÚmathÚfloorr%   r"   ÚwarningsÚwarnÚ
isinstanceÚslice)	rZ   rn   r   re   rB   Ztotal_framesZ_idxsrd   Úidxsr   r   r   Úcompute_clips_for_videoÌ   s     ÿ
z"VideoClips.compute_clips_for_video)rn   r   rB   r   c           	      C   sŽ   || _ || _|| _g | _g | _t| j| jƒD ]6\}}|  |||||¡\}}| j 	|¡ | j 	|¡ q,t
 dd„ | jD ƒ¡}| d¡ ¡ | _dS )a„  
        Compute all consecutive sequences of clips from video_pts.
        Always returns clips of size `num_frames`, meaning that the
        last few frames in a video can potentially be dropped.

        Args:
            num_frames (int): number of frames for the clip
            step (int): distance between two clips
            frame_rate (int, optional): The frame rate
        c                 S   s   g | ]}t |ƒ‘qS r   ©r.   ©rV   Úvr   r   r   rY   ú   s     z,VideoClips.compute_clips.<locals>.<listcomp>r   N)rn   r   rB   rd   Úresampling_idxsr`   rZ   r[   rx   Úappendr#   rT   ZcumsumÚtolistÚcumulative_sizes)	r*   rn   r   rB   rZ   re   rd   rw   Zclip_lengthsr   r   r   rQ   æ   s    zVideoClips.compute_clipsc                 C   s   |   ¡ S r(   )Ú	num_clipsr/   r   r   r   r0   ý   s    zVideoClips.__len__c                 C   s
   t | jƒS r(   r-   r/   r   r   r   Ú
num_videos   s    zVideoClips.num_videosc                 C   s
   | j d S )zJ
        Number of subclips that are available in the video list.
        éÿÿÿÿ)r   r/   r   r   r   r€     s    zVideoClips.num_clipsr1   c                 C   s6   t  | j|¡}|dkr|}n|| j|d   }||fS )zw
        Converts a flattened representation of the indices into a video_idx, clip_idx
        representation.
        r   r   )ÚbisectÚbisect_rightr   )r*   r2   Ú	video_idxÚclip_idxr   r   r   Úget_clip_location	  s
    zVideoClips.get_clip_location)rn   Úoriginal_fpsÚnew_fpsr   c                 C   sP   t |ƒ| }| ¡ r(t|ƒ}td d |ƒS tj| tjd�| }| ¡  tj	¡}|S )NrS   )
r:   Ú
is_integerr9   rv   r#   ZarangeZfloat32rr   ÚtoÚint64)rn   rˆ   r‰   r   rw   r   r   r   rp     s    zVideoClips._resample_video_idxc                 C   st  ||   ¡ kr&td|› d|   ¡ › d�ƒ‚|  |¡\}}| j| }| j| | }ddlm} |ƒ }|dkrÀ| jdkrxtdƒ‚| j	dkrŠtdƒ‚| j
dkrœtd	ƒ‚| jdkr®td
ƒ‚| jdkrÀtdƒ‚|dkrô|d  ¡ }|d  ¡ }	t|||	ƒ\}
}}nìt|ƒ}|j}d}tt|d  ¡ ƒ}tt|d  ¡ ƒ}d\}}tddƒ}t|jj|jjƒ}|j�rŽt|jj|jjƒ}t|||tjƒ}t|||tjƒ}|j}t|| j| j	| j
| j||f|| j| j||f|d�\}
}}d|i}|dk	�rà||d< | j dk	�r&| j!| | }t"|t#j$ƒ�r||d  }|
| }
| j |d< t%|
ƒ| j&k�sLt'|
j(› d| j&› �ƒ‚| j)dk�rh|
 *dddd¡}
|
|||fS )a7  
        Gets a subclip from a list of videos.

        Args:
            idx (int): index of the subclip. Must be between 0 and num_clips().

        Returns:
            video (Tensor)
            audio (Tensor)
            info (Dict)
            video_idx (int): index of the video in `video_paths`
        zIndex z out of range (z number of clips)r   )Úget_video_backendZpyavz.pyav backend doesn't support _video_width != 0z/pyav backend doesn't support _video_height != 0z6pyav backend doesn't support _video_min_dimension != 0z6pyav backend doesn't support _video_max_dimension != 0z0pyav backend doesn't support _audio_samples != 0r‚   N)r   r‚   r   )
Zvideo_widthZvideo_heightZvideo_min_dimensionZvideo_max_dimensionZvideo_pts_rangeÚvideo_timebaseZaudio_samplesZaudio_channelsZaudio_pts_rangeÚaudio_timebaser[   Ú	audio_fpsz x rL   é   é   )+r€   Ú
IndexErrorr‡   r'   rd   Ztorchvisionr�   rE   r!   rF   rG   rH   rI   Úitemr   r   r[   r   r9   r   rŽ   Ú	numeratorÚdenominatorZ	has_audior�   r   rq   rr   ÚceilZaudio_sample_rater   rJ   rB   r|   ru   r#   ÚTensorr.   rn   rg   ÚshaperK   Zpermute)r*   r2   r…   r†   Z
video_pathZclip_ptsr�   ÚbackendZ	start_ptsZend_ptsZvideoZaudioÚinfoÚ_infor[   r�   Zvideo_start_ptsZvideo_end_ptsZaudio_start_ptsZaudio_end_ptsr�   rŽ   Ú_Zresampling_idxr   r   r   Úget_clip!  sz    






õ

&zVideoClips.get_clipc                 C   sn   dd„ | j D ƒ}dd„ | j D ƒ}|r6t |¡}| ¡ }| j ¡ }||d< ||d< |d= |d= |d= d	|d
< |S )Nc                 S   s   g | ]}t |ƒ‘qS r   ry   rz   r   r   r   rY   z  s     z+VideoClips.__getstate__.<locals>.<listcomp>c                 S   s   g | ]}|  tj¡‘qS r   )r‹   r#   rŒ   )rV   r;   r   r   r   rY     s     Úvideo_pts_sizesrZ   rd   r|   r   r’   Ú_version)rZ   r#   ÚcatÚnumpyÚ__dict__Úcopy)r*   rŸ   rZ   Údr   r   r   Ú__getstate__y  s    

zVideoClips.__getstate__)r¥   r   c                 C   sf   d|kr|| _ d S tj|d tjd�}tj||d dd�}|d= ||d< || _ |  | j| j| j¡ d S )Nr    rZ   rS   rŸ   r   )r    )	r£   r#   rT   rŒ   ÚsplitrQ   rn   r   rB   )r*   r¥   rZ   r   r   r   Ú__setstate__•  s    zVideoClips.__setstate__)r>   r   NNr   r   r   r   r   r   r   r?   )N)N) r4   r5   r6   r7   r   r8   r9   r	   r   r   r+   rO   rP   Úpropertyrf   ro   Ústaticmethodr#   r˜   r
   r   rv   rx   rQ   r0   r�   r€   r‡   rp   rž   r¦   r¨   r   r   r   r   r=   I   sl               òñ% ÿ    þ (Xr=   )r   ) rƒ   rq   rs   Ú	fractionsr   Útypingr   r   r   r   r   r	   r
   r   r   r#   Ztorchvision.ior   r   r   r   r\   r   r   rr   r9   r   r˜   r%   r&   r<   r=   r   r   r   r   Ú<module>   s   ,