B
    %Z\rB                 @   s  d Z ddlmZmZmZ 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 eeZddd	d
ddZdZdZdd ZdZdZdZejZdZdZ dZ!dZ"dZ#ejZ$dZ%dZ&dZ'dZ(dZ)dZ*dZ+dZ,ejZ-ej.Z/ej.Z0ej1Z2G dd dej3Z4G dd dej3Z5G dd dej3Z6G d d! d!ej7Z8G d"d# d#ej3Z9G d$d% d%ej3Z:e;dej<ejej<Z=d&d' Z>d3d)d*Z?d+d, Z@G d-d. d.eZAeAd/d0d1d2ZBeCeB dS )4z Plugin for reading videos via AvBin

Would be nice if we could capture webcam with this, but unfortunately,
avbin does not currently support this.
    )absolute_importprint_functiondivisionN   )formats)Formatget_platformget_remote_fileInternetNotAllowedErrorNeedDownloadErrorzlibavbin-10-osx.dylibzavbin-10-win32.dllzavbin-10-win64.dllzlibavbin-10-linux32.sozlibavbin-10-linux64.so)Zosx64Zwin32Zwin64Zlinux32Zlinux64c             C   s   | t krtd|  | S )NzAVBin returned error code %i)AVBIN_RESULT_OKRuntimeError)x r   4lib/python3.7/site-packages/imageio/plugins/avbin.pyAVbinResult-   s    r            i             (   0   c               @   s   e Zd Zdejfdejfdefdefdejd fdejd fdejd fd	ejd fd
ejd fdejfdejfdejd fgZdS )AVbinFileInfostructure_size	n_streamsZ
start_timedurationtitlei   author	copyrightcommentZalbumZyearZtrackZgenrer   N)	__name__
__module____qualname__ctypesc_size_tc_int	TimestampZc_char_fields_r   r   r   r   r   O   s   r   c               @   s@   e Zd ZdejfdejfdejfdejfdejfdejfgZdS )_AVbinStreamInfoVideo8widthheightZsample_aspect_numZsample_aspect_denframe_rate_numframe_rate_denN)r$   r%   r&   r'   c_uintr+   r   r   r   r   r,   `   s   r,   c               @   s0   e Zd ZdejfdejfdejfdejfgZdS )_AVbinStreamInfoAudio8Zsample_formatZsample_rateZsample_bitsZchannelsN)r$   r%   r&   r'   r)   r1   r+   r   r   r   r   r2   k   s   r2   c               @   s   e Zd ZdefdefgZdS )_AVbinStreamInfoUnion8videoZaudioN)r$   r%   r&   r,   r2   r+   r   r   r   r   r3   t   s   r3   c               @   s&   e Zd ZdejfdejfdefgZdS )AVbinStreamInfo8r   typeuN)r$   r%   r&   r'   r(   r)   r3   r+   r   r   r   r   r5   x   s   r5   c               @   s<   e Zd ZdejfdefdejfdeejfdejfgZ	dS )AVbinPacketr   	timestampstream_indexdatasizeN)
r$   r%   r&   r'   r(   r*   r)   POINTERZc_uint8r+   r   r   r   r   r8      s
   r8   c             C   s   t | d S )Ni@B )float)r9   r   r   r   timestamp_from_avbin   s    r?   Fc             C   s<   t  }|r|tkstd| dt|  }t|| |d dS )a   Download the avbin library to your computer.

    Parameters
    ----------
    directory : str | None
        The directory where the file will be cached if a download was
        required to obtain the file. By default, the appdata directory
        is used. This is also the first directory that is checked for
        a local version of the file.
    force_download : bool | str
        If True, the file will be downloaded even if a local copy exists
        (and this copy will be overwritten). Can also be a YYYY-MM-DD date
        to ensure a file is up-to-date (modified date of a file on disk,
        if present, is checked).
    z*AVBIN lib is not available for platform %szavbin/)fname	directoryforce_downloadN)r   FNAME_PER_PLATFORMr   r	   )rA   rB   Zplatr@   r   r   r   download   s
    rD   c           
   C   s   t dd} | r| S t }yt| } W n  tk
rF   td| Y nX ytd|  ddS  tk
rt   tdY n2 tk
r } zt	dt
| W dd}~X Y nX dS )	z Get avbin .dll/.dylib/.so
    ZIMAGEIO_AVBIN_LIBNz,Avbin plugin is not supported on platform %szavbin/F)autozNeed avbin library. You can obtain it with either:
  - download using the command: imageio_download_bin avbin
  - download by calling (in Python): imageio.plugins.avbin.download()
z Could not download avbin lib:
%s)osgetenvr   rC   KeyErrorr   r	   r   r
   IOErrorstr)libplatformerrr   r   r   get_avbin_lib   s    
rN   c               @   sD   e Zd ZdZdd Zdd Zdd Zdd	d
ZG dd dej	Z	dS )AvBinFormata   
    The AvBinFormat uses the AvBin library (based on libav) to read
    video files.
    
    This plugin is more efficient than the ffmpeg plugin, because it
    uses ctypes (rather than a pipe like the ffmpeg plugin does).
    Further, it supports reading images into a given numpy array.
    
    The limitations of this plugin are that seeking, writing and camera
    feeds are not supported. See the ffmpeg format for these features.

    The avbin plugin requires an `avbin` binary. If this binary is
    not available on the system, it can be downloaded manually from
    <https://github.com/imageio/imageio-binaries> by either
    
    - the command line script ``imageio_download_bin avbin``
    - the Python method ``imageio.plugins.avbin.download()``.

    Parameters for reading
    ----------------------
    loop : bool
        If True, the video will rewind as soon as a frame is requested
        beyond the last frame. Otherwise, IndexError is raised. Default False.
    stream : int
        Specifies which video stream to read. Default 0.
    videoformat : str | None
        Specifies the video format (e.g. 'avi', or 'mp4'). If this is None
        (default) the format is auto-detected.
    
    Parameters for get_data
    -----------------------
    out : np.ndarray
        destination for the data retrieved. This can be used to save 
        time-consuming memory allocations when reading multiple image
        sequntially. The shape of out must be (width, height, 3), the
        dtype must be np.uint8 and it must be C-contiguous.
        
        Use the create_empty_image() method of the reader object
        to create an array that is suitable for get_data.
    c             O   s   d | _ tj| f|| d S )N)_avbinr   __init__)selfargskwargsr   r   r   rQ      s    zAvBinFormat.__init__c             C   s(   |j d | jd kr$|j| jkr$dS d S )Nr   ?T)modeZmodes	extension
extensions)rR   requestr   r   r   	_can_read   s    zAvBinFormat._can_readc             C   s   dS )NFr   )rR   rY   r   r   r   
_can_write   s    zAvBinFormat._can_writeNc             C   s  | j d k	r|d kr| j S td |d kr0t }tj| | _ }tj|j_	tj|j
_	tj|j_	tj|j_	tjg|j_t|j_	t|j_	tg|j_tg|j_t|j_	tjg|j_t|j_	tjtjg|j_tg|j_ttg|j_tttg|j_ttjttg|j _tj!|j"_	ttjg|j"_t#g|j$_ttt%g|j&_t|j&_	tj|j'_	t#tj!tjtj!ttjg|j'_tj|j(_	t#tj!tjtj!g|j(_|  |t) | j S )NzjThe imageio avbin plugin is deprecated and will be removed in a future version. Please use ffmpeg instead.)*rP   loggerZwarningrN   r'   ZcdllZLoadLibraryr)   avbin_get_versionZrestypeZavbin_get_ffmpeg_revisionr(   Zavbin_get_audio_buffer_sizeZavbin_have_featurec_char_pZargtypesr   Z
avbin_initZavbin_set_log_levelAVbinLogLevelAVbinLogCallbackZavbin_set_log_callback
AVbinFilePavbin_open_filenameavbin_open_filename_with_formatavbin_close_filer*   Zavbin_seek_filer=   r   avbin_file_infor5   avbin_stream_infoc_void_pavbin_open_streamAVbinStreamPZavbin_close_streamr8   
avbin_readZavbin_decode_audioavbin_decode_videoAVBIN_LOG_QUIET)rR   Zlibpathavbinr   r   r   avbinlib   s\    











zAvBinFormat.avbinlibc               @   sH   e Zd ZdddZdd Zdd	 Zd
d Zdd ZdddZdd Z	dS )zAvBinFormat.ReaderFr   Nc             C   sL   t || _t|| _|| _t || _| j | _d | _	ddi| _
|   d S )NZpluginrm   )bool	_arg_loopint_arg_stream_arg_videoformat_arg_skipemptyrY   Zget_local_filename	_filename_file_meta_init_video)rR   ZloopstreamZvideoformatZ	skipemptyr   r   r   _openG  s    



zAvBinFormat.Reader._openc             C   s&  | j  }| jt }| jd k	r<||| jd| _n|	|| _| js\t
d| j t | _t| j| j_|| jt| j t| | jd< | jjd| jd< | jjd| jd< t| jj| jd< d}x&t| jjD ] }t }t||_|| j|| |jtkr q|| j kr6|d	7 }q|!| j|| _"|| _#|j$j%j&| _'|j$j%j(| _)| j'| j)f| jd
< | j'| j)f| jd< t*|j$j%j+t*|j$j%j, | jd< | jd  d| jd  8  < t-| jd | jd  | jd< || _.P qW t
d| j | jf t/ | _0t| j0| j0_d| _1d S )NasciizCould not open "%s"Zavbin_versionzutf-8r    r!   r   r   r   r<   source_sizeZfpsg      ?nframeszStream #%d not found in %r)2formatrn   ru   encodesysgetfilesystemencodingrs   rc   rv   rb   rI   r   Z_infor'   Zsizeofr   re   byrefrJ   r]   rw   r    decoder!   r?   r   ranger   r5   rf   r6   AVBIN_STREAM_TYPE_VIDEOrr   rh   _streamZ_stream_infor7   r4   r-   _widthr.   _heightr>   r/   r0   rq   _stream_indexr8   _packet_framecounter)rR   rm   Zfilename_bytesZvideo_stream_counteriinfor   r   r   rx   V  sT    

zAvBinFormat.Reader._init_videoc             C   s*   | j d k	r&| j }|| j  d | _ d S )N)rv   r~   rn   rd   )rR   rm   r   r   r   _close  s    

zAvBinFormat.Reader._closec             C   s
   | j d S )Nr}   )rw   )rR   r   r   r   _get_length  s    zAvBinFormat.Reader._get_lengthc             C   s   t j| j| jdft jdS )Nr   )dtype)npZzerosr   r   uint8)rR   r   r   r   create_empty_image  s    z%AvBinFormat.Reader.create_empty_imagec             C   s  | j  }| jd r:| jd tdk r:| jr:|| jd  }|dk rLtdnL|| jd krdtdn4|| jkr|dkr|   |   | 	dS td|  jd7  _|d kr| 
 }|jtjkr|jjr|j| j| jdfkstxy|| jt| j W n tk
r   td	Y nX | jj| jkr0qy|jj}W n$ tk
r`   |jd
 d }Y nX || j | jj| jj!|}| j"r|dkrP qW |t#| jj$dfS )Nr}   infr   zFrame index must be > 0zReached end of videozAvbin format cannot seekr   r   zReached end of video too soonr;   r   )r9   )%r~   rn   rw   r>   rp   
IndexErrorr   r   rx   	_get_datar   r   r   r   flagsc_contiguousshaper   r   AssertionErrorrj   rv   r'   r   r   r   r:   r   r;   	ExceptionZ__array_interface__rk   r   r<   rt   dictr9   )rR   indexoutrm   Zptrresultr   r   r   r     sH    




zAvBinFormat.Reader._get_datac             C   s   | j S )N)rw   )rR   r   r   r   r   _get_meta_data  s    z!AvBinFormat.Reader._get_meta_data)Fr   NF)N)
r$   r%   r&   rz   rx   r   r   r   r   r   r   r   r   r   ReaderF  s   
I
<r   )N)
r$   r%   r&   __doc__rQ   rZ   r[   rn   r   r   r   r   r   r   rO      s   (
GrO   rm   z2Many video formats (via AvBin, i.e. libav library)zmov avi mp4 mpg mpeg mkvI)NF)Dr   Z
__future__r   r   r   Znumpyr   Zloggingr'   r   rF    r   Zcorer   r   r	   r
   r   Z	getLoggerr$   r\   rC   ZAVBIN_RESULT_ERRORr   r   ZAVBIN_STREAM_TYPE_UNKNOWNr   ZAVBIN_STREAM_TYPE_AUDIOr)   ZAVbinStreamTypeZAVBIN_SAMPLE_FORMAT_U8ZAVBIN_SAMPLE_FORMAT_S16ZAVBIN_SAMPLE_FORMAT_S24ZAVBIN_SAMPLE_FORMAT_S32ZAVBIN_SAMPLE_FORMAT_FLOATZAVbinSampleFormatrl   ZAVBIN_LOG_PANICZAVBIN_LOG_FATALZAVBIN_LOG_ERRORZAVBIN_LOG_WARNINGZAVBIN_LOG_INFOZAVBIN_LOG_VERBOSEZAVBIN_LOG_DEBUGr_   rg   ra   ri   Zc_int64r*   Z	Structurer   r,   r2   ZUnionr3   r5   r8   Z	CFUNCTYPEr^   r`   r?   rD   rN   rO   r~   Z
add_formatr   r   r   r   <module>   sv   	
	

  (