o
    ॵi!                     @   sx   d dl mZ d dlmZ d dlZd dlmZmZmZm	Z	m
Z
mZmZ ddlmZmZmZ G dd dZG dd	 d	ZdS )
    N)OrderedDict)CAP_PROP_FOURCCCAP_PROP_FPSCAP_PROP_FRAME_COUNTCAP_PROP_FRAME_HEIGHTCAP_PROP_FRAME_WIDTHCAP_PROP_POS_FRAMESVideoWriter_fourcc   )check_file_existmkdir_or_existtrack_progressc                   @   s>   e Zd Zdd Zedd Zedd Zdd Zdd
dZd	S )Cachec                 C   s&   t  | _t|| _|dkrtdd S )Nr   z#capacity must be a positive integer)r   _cacheint	_capacity
ValueError)selfcapacity r   f/home/ubuntu/.local/lib/python3.10/site-packages/modelscope/preprocessors/cv/video_super_resolution.py__init__   s
   
zCache.__init__c                 C      | j S N)r   r   r   r   r   r      s   zCache.capacityc                 C   s
   t | jS r   )lenr   r   r   r   r   size   s   
z
Cache.sizec                 C   s:   || j v rd S t| j | jkr| j jdd || j |< d S )NF)last)r   r   r   popitem)r   keyvalr   r   r   put   s
   
z	Cache.putNc                 C   s    || j v r| j | }|S |}|S r   )r   )r   r   defaultr    r   r   r   get&   s   z	Cache.getr   )	__name__
__module____qualname__r   propertyr   r   r!   r#   r   r   r   r   r      s    

r   c                   @   s   e Zd ZdZd3ddZedd Zedd Zed	d
 Zedd Z	edd Z
edd Zedd Zedd Zedd Zdd Zdd Zdd Zdd Zdd  Z	!	"	!	!	#d4d$d%Zd&d' Zd(d) Zd*d+ Zd,d- ZeZd.d/ Zd0d1 Zd2S )5VideoReadera  Video class with similar usage to a list object.
    This video warpper class provides convenient apis to access frames.
    There exists an issue of OpenCV's VideoCapture class that jumping to a
    certain frame may be inaccurate. It is fixed in this class by checking
    the position after jumping each time.
    Cache is used when decoding videos. So if the same frame is visited for
    the second time, there is no need to decode again if it is stored in the
    cache.
    Example:

    >>> import mmcv
    >>> v = mmcv.VideoReader('sample.mp4')
    >>> len(v)  # get the total frame number with `len()`
    120
    >>> for img in v:  # v is iterable
    >>>     mmcv.imshow(img)
    >>> v[5]  # get the 6th frame
    
   c                 C   s   | dst|d|  t|| _|dksJ t|| _d| _t| j	t
| _t| j	t| _| j	t| _t| j	t| _| j	t| _d S )N)zhttps://zhttp://zVideo file not found: r   )
startswithr   cv2VideoCapture_vcapr   r   	_positionr   r#   r   _widthr   _heightr   _fpsr   
_frame_cntr   _fourcc)r   filenamecache_capacityr   r   r   r   ?   s   

zVideoReader.__init__c                 C   r   )z5:obj:`cv2.VideoCapture`: The raw VideoCapture object.)r-   r   r   r   r   vcapN      zVideoReader.vcapc                 C   s
   | j  S )z+bool: Indicate whether the video is opened.)r-   isOpenedr   r   r   r   openedS   s   
zVideoReader.openedc                 C   r   )zint: Width of video frames.)r/   r   r   r   r   widthX   r7   zVideoReader.widthc                 C   r   )zint: Height of video frames.)r0   r   r   r   r   height]   r7   zVideoReader.heightc                 C   s   | j | jfS )z(tuple: Video resolution (width, height).)r/   r0   r   r   r   r   
resolutionb   s   zVideoReader.resolutionc                 C   r   )zfloat: FPS of the video.)r1   r   r   r   r   fpsg   r7   zVideoReader.fpsc                 C   r   )zint: Total frames of the video.)r2   r   r   r   r   	frame_cntl   r7   zVideoReader.frame_cntc                 C   r   )z(str: "Four character code" of the video.)r3   r   r   r   r   fourccq   r7   zVideoReader.fourccc                 C   r   )z7int: Current cursor position, indicating frame decoded.)r.   r   r   r   r   positionv   r7   zVideoReader.positionc                 C   s   t t| jtS r   )r   roundr-   r#   r   r   r   r   r   _get_real_position{   s   zVideoReader._get_real_positionc                 C   s<   | j t| |  }t|| D ]}| j   q|| _d S r   )r-   setr   rB   rangereadr.   )r   frame_idpos_r   r   r   _set_real_position~   s
   
zVideoReader._set_real_positionc                 C   s   | j r0| j | j}|durd}n&| j|  kr| | j | j \}}|r/| j | j| n| j \}}|r@|  jd7  _|S )a  Read the next frame.
        If the next frame have been decoded before and in the cache, then
        return it directly, otherwise decode, cache and return it.
        Returns:
            ndarray or None: Return the frame if successful, otherwise None.
        NTr
   )r   r#   r.   rB   rI   r-   rE   r!   )r   imgretr   r   r   rE      s   zVideoReader.readc                 C   s   |dk s	|| j krtd| j d  || jkr|  S | jr0| j|}|dur0|d | _|S | | | j \}}|rP| jrI| j| j| |  jd7  _|S )zGet frame by index.
        Args:
            frame_id (int): Index of the expected frame, 0-based.
        Returns:
            ndarray or None: Return the frame if successful, otherwise None.
        r   z!"frame_id" must be between 0 and r
   N)	r2   
IndexErrorr.   rE   r   r#   rI   r-   r!   )r   rF   rJ   rK   r   r   r   	get_frame   s$   


zVideoReader.get_framec                 C   s    | j dkrdS | j| j d S )zGet the current frame (frame that is just visited).
        Returns:
            ndarray or None: If the video is fresh, return None, otherwise
                return the frame.
        r   Nr
   )r.   r   r#   r   r   r   r   current_frame   s   
zVideoReader.current_framer   
{:06d}.jpgTc           
         s   t  |dkrj| }ntj| |}|dkrtd|dkr'|  fdd}|r=t|t|||  dS t|D ]}	|||	  qAdS )a  Convert a video to frame images.
        Args:
            frame_dir (str): Output directory to store all the frame images.
            file_start (int): Filenames will start from the specified number.
            filename_tmpl (str): Filename template with the index as the
                placeholder.
            start (int): The starting frame index.
            max_num (int): Maximum number of frames to be written.
            show_progress (bool): Whether to show a progress bar.
        r   z*start must be less than total frame numberc                    s6     }|d u r
d S t | }t|| d S r   )rE   ospjoinformatr+   imwrite)file_idxrJ   r4   filename_tmpl	frame_dirr   r   r   write_frame   s
   z+VideoReader.cvt2frames.<locals>.write_frameN)r   r>   minr   rI   r   rD   )
r   rW   
file_startrV   startmax_numshow_progresstask_numrX   ir   rU   r   
cvt2frames   s    

zVideoReader.cvt2framesc                 C   r   r   )r>   r   r   r   r   __len__   s   zVideoReader.__len__c                    sT   t |tr fddt| j D S |dk r%| j7 }|dk r%td |S )Nc                    s   g | ]}  |qS r   )rM   ).0r_   r   r   r   
<listcomp>   s    z+VideoReader.__getitem__.<locals>.<listcomp>r   zindex out of range)
isinstanceslicerD   indicesr>   rL   rM   )r   indexr   r   r   __getitem__   s   



zVideoReader.__getitem__c                 C   s   |  d | S )Nr   )rI   r   r   r   r   __iter__   s   
zVideoReader.__iter__c                 C   s   |   }|d ur
|S tr   )rE   StopIteration)r   rJ   r   r   r   __next__   s   zVideoReader.__next__c                 C   s   | S r   r   r   r   r   r   	__enter__  s   zVideoReader.__enter__c                 C   s   | j   d S r   )r-   release)r   exc_type	exc_value	tracebackr   r   r   __exit__	  s   zVideoReader.__exit__N)r)   )r   rO   r   r   T)r$   r%   r&   __doc__r   r'   r6   r9   r:   r;   r<   r=   r>   r?   r@   rB   rI   rE   rM   rN   r`   ra   rh   ri   rk   nextrl   rq   r   r   r   r   r(   +   sN    










)r(   )os.pathpathrP   collectionsr   r+   r   r   r   r   r   r   r	   utilr   r   r   r   r(   r   r   r   r   <module>   s   $