o
    ]iI                     @   s   d dl Z d dlmZ d dlZd dlmZ d dlmZ d dl	m
Z
mZ d dlmZ d dlmZ d dlmZ d d	lmZ d d
lmZmZ d dlmZmZ d dlmZ ejdefddZejG dd de ZdS )    N)Fraction)libav)Codec)CodecContextwrap_codec_context)StreamContainer)_Dictionary)	err_check)Packet)Streamwrap_stream)dict_to_avdictto_avrational)
Dictionaryselfc                 C   s   t  | _| jrL| jsNz&| t| j W | jd u r,| jj	j
tj@ s,tt| jj d| _d S | jd u rH| jj	j
tj@ sHtt| jj d| _w d S d S )NT)r   streams_started_doner	   libav_write_trailerptrfileoformatflagsAVFMT_NOFILEavio_closepcythonaddresspbr    r    G/home/ubuntu/.local/lib/python3.10/site-packages/av/container/output.pyclose_output   s   
r"   c                   @   s   e Zd Zdd Zdd Zd(dedB fddZ	d)d	ed
edB fddZ	d	edefddZ
dededefddZd(dedB fddZej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%efd&d'ZdS )*OutputContainerc                 O   sD   t  | _i | _tj t | _W d    d S 1 sw   Y  d S N)r   r   metadatar   nogilr   av_packet_alloc
packet_ptr)r   argskwargsr    r    r!   	__cinit__#   s
   "zOutputContainer.__cinit__c                 C   sF   t |  tj tt| j W d    d S 1 sw   Y  d S r$   )r"   r   r&   r   av_packet_freer   r(   r   r    r    r!   __dealloc__)   s   "zOutputContainer.__dealloc__Noptionsc                 K   s4  t |d}|j}t| jj|jtjs t| jj	d|j	dt
| j|}t|}|jtjkr~tj|_|dd|_|dd|_|dd	|_|d
d|_zt|dt|j W n	 tyi   Y nw t|pndt|j |j|_|j|_nV|jtjkr|jd	 |_|dd	|_|d
d|_zt|dt|j W n	 ty   Y nw |du rd|_nt|t u r||_nt!d|j|_t"t|j#d | jjj$tj%@ r| j$tj&O  _$t't(|j)| t*||d}	t+| ||	}
| j,-|
 |r|
j./| |0 D ]\}}t1|
|| q|
S )a  add_stream(codec_name, rate=None)

        Creates a new stream from a codec name and returns it.
        Supports video, audio, and subtitle streams.

        :param codec_name: The name of a codec.
        :type codec_name: str
        :param dict options: Stream options.
        :param \**kwargs: Set attributes for the stream.
        :rtype: The new :class:`~av.stream.Stream`.

        w format does not support  codecwidthi  heighti  bit_rater   bit_rate_tolerancei  	time_base   i }  Ni  z'audio stream `rate` must be: int | None   )2r   r   r   avformat_query_codecr   idFF_COMPLIANCE_NORMAL
ValueErrorformatnameavformat_new_streamavcodec_alloc_context3typeAVMEDIA_TYPE_VIDEOAV_PIX_FMT_YUV420Ppix_fmtpopr2   r3   r4   r5   r   r   r   r6   KeyError	framerateavg_frame_rateAVMEDIA_TYPE_AUDIOsample_fmts
sample_fmtsample_rateint	TypeErrorav_channel_layout_default	ch_layoutr   AVFMT_GLOBALHEADERAV_CODEC_FLAG_GLOBAL_HEADERr	   avcodec_parameters_from_contextcodecparr   r   r   
add_streamr.   updateitemssetattr)r   
codec_namerater.   r*   	codec_objcodecstreamctxpy_codec_context	py_streamkvr    r    r!   rU   .   sf   


zOutputContainer.add_streamtemplateopaquec                 K   s:  |du r	|j dk}|jdu r| j|fi |S |r|jj}nt|jjjd}|j}t| jj	|j
tjsAt| jjd|jdt| j|}t|}tt||jj d|_| jj	jtj@ rj| jtjO  _|sq|jj|_tt|j| t||d}t| ||}	| j|	 | D ]
\}
}t|	|
| q|	S )a  
        Creates a new stream from a template. Supports video, audio, subtitle, data and attachment streams.

        :param template: Copy codec from another :class:`~av.stream.Stream` instance.
        :param opaque: If True, copy opaque data from the template's codec context.
        :param \**kwargs: Set attributes for the stream.
        :rtype: The new :class:`~av.stream.Stream`.
        Nvideor/   r0   r1   r   )rA   codec_context'_add_stream_without_codec_from_templater\   r   r>   r   r   r9   r   r:   r;   r<   r=   r?   r@   r	   avcodec_parameters_to_contextrT   	codec_tagr   rQ   rR   rS   r   r   r   rU   rW   rX   )r   rc   rd   r*   r[   r\   r]   r^   r_   r`   ra   rb   r    r    r!   add_stream_from_template   s:   




z(OutputContainer.add_stream_from_templatereturnc                 K   s   |j jj}|tjtjhvrtd|j dt| j t	j
}|t	j
kr'tdtt|j|j j |j j|_|j j|_|j j|_|j j|_t| |d }| j| t|j|_| D ]
\}}t||| q\|S )Nztemplate stream of type  has no codec contextCould not allocate stream)r   rT   
codec_typer   AVMEDIA_TYPE_ATTACHMENTAVMEDIA_TYPE_DATAr<   rA   r?   r   NULLMemoryErrorr	   avcodec_parameters_copyr6   
start_timedurationdispositionr   r   rU   dictr%   rW   rX   )r   rc   r*   rn   r]   r`   ra   rb   r    r    r!   rg      s*   





z7OutputContainer._add_stream_without_codec_from_templater>   mimetypedatac                 C   s  t | jtj}|tjkrtdt j|j_t j	|j_
t|}|rTttjt |d }|tjkr6tdt|D ]}|| ||< q:d||< ttj||j_||j_t|j}tt |d| d | }	tt |d|	d t| |d}
| j|
 |
S )a  
        Create an attachment stream and embed its payload into the container header.

        - Only supported by formats that support attachments (e.g. Matroska).
        - No per-packet muxing is required; attachments are written at header time.
        rm      z"Could not allocate attachment datar   s   filenames   mimetypeN)r   r?   r   r   rq   rr   ro   rT   rn   AV_CODEC_ID_NONEcodec_idlencastp_uchar	av_mallocrange	extradataextradata_sizer   r%   r	   av_dict_setencoder   r   rU   )r   r>   rx   ry   r]   payload_sizebufimeta_ptr
mime_bytesr`   r    r    r!   add_attachment   s0   



zOutputContainer.add_attachmentc           
      C   s  t j}t j}|durVt| }|t jkrt| }|t jkr5t| }|t jkr5td| |t jkr=|jn|j}t	| j
j|tjsVt| jjd|dt| j
|}|t jkrftdt j}|t jkrt|}|t jkr|td| j
jjtj@ r| jtjO  _tt|j| ntj|j_|t jkr|j|j_d}|t jkrt||d}t| ||}	| j|	 |r|	j | |	S )a4  add_data_stream(codec_name=None)

        Creates a new data stream and returns it.

        :param codec_name: Optional name of the data codec (e.g. 'klv')
        :type codec_name: str | None
        :param dict options: Stream options.
        :rtype: The new :class:`~av.data.stream.DataStream`.
        NzUnknown data codec: r0   r1   rm   z Could not allocate codec context)!r   rq   r   avcodec_find_encoder_by_namer   avcodec_find_decoder_by_nameavcodec_descriptor_get_by_namer<   r:   r9   r   r   r;   r=   r>   r?   rr   r@   r   rQ   rR   r	   rS   rT   rp   rn   r|   r   r   r   rU   r.   rV   )
r   rY   r.   r\   codec_descriptorr|   r]   r^   r_   r`   r    r    r!   add_data_stream  sR   











zOutputContainer.add_data_streamc                    s  | j rdS t  | jD ]D}|j}|du r#|jdvr"td|j dn(|jsK| j	 D ]\}}|j
|| q+|  | jD ]}||jvrJ | q>|  qt| jdu rZ| jnd}|}| jjtjkr}| jjjtj@ s}ttt| jj|tj tt| jj| j| j | j!d t"| j| j#}|$ }| t%| jt|j |D ]}||vr | q fdd| j	 D }	|	rd	dl&}
|
't(}|)d
|	  d| _ dS )z,Write the file header! Called automatically.N>   ry   
attachmentzStream rl    )encodingerrorsc                    s   i | ]\}}| vr||qS r    r    ).0ra   rb   used_optionsr    r!   
<dictcomp>  s    z2OutputContainer.start_encoding.<locals>.<dictcomp>r   zSome options were not used: %sT)*r   setr   rf   rA   r<   indexis_openr.   rW   
setdefaultopenadd_finalize_for_outputosfsencoder   r>   r   r   r   rq   r   r   r   r   r	   	avio_openr   AVIO_FLAG_WRITEr   r%   metadata_encodingmetadata_errorsr   container_optionscopyavformat_write_headerlogging	getLogger__name__warning)r   r]   r^   ra   rb   name_objr>   all_optionsr.   unused_optionsr   logr    r   r!   start_encodingT  sZ   









zOutputContainer.start_encodingc                 C   s\   t  }tj}tj}	 tt|}|tjkr	 |S t| jj|j	tj
dkr-||j q
)zC
        Returns a set of all codecs this format supports.
        Trz   )r   r   rq   r   av_codec_iterater   r9   r   r   r:   r;   r   r>   )r   resultr\   rd   r    r    r!   supported_codecs  s   

z OutputContainer.supported_codecsc                 C      t | jjjS )zL
        Returns the default video codec this container recommends.
        )r   avcodec_get_namer=   optrvideo_codecr   r    r    r!   default_video_codec     z#OutputContainer.default_video_codecc                 C   r   )zL
        Returns the default audio codec this container recommends.
        )r   r   r=   r   audio_codecr   r    r    r!   default_audio_codec  r   z#OutputContainer.default_audio_codecc                 C   r   )zO
        Returns the default subtitle codec this container recommends.
        )r   r   r=   r   subtitle_codecr   r    r    r!   default_subtitle_codec  r   z&OutputContainer.default_subtitle_codecc                 C   s   t |  d S r$   )r"   r   r    r    r!   close  s   zOutputContainer.closec                 C   s0   t |tr| | d S |D ]}| | qd S r$   )
isinstancer
   mux_one)r   packetspacketr    r    r!   mux  s
   
zOutputContainer.muxr   c                 C   s   |    |jjdk sttj|jj| jjkrtd| jj|jj }|	|j
 | t| j|j tj t| j| j}W d    n1 sJw   Y  | | d S )Nr   zBad Packet stream_index.)r   r   stream_indexr   r~   uint
nb_streamsr<   r   _rebase_timer6   r	   r   av_packet_refr(   r&   av_interleaved_write_frame)r   r   r]   retr    r    r!   r     s   zOutputContainer.mux_one)NNr$   )r   
__module____qualname__r+   r-   rw   rU   r   boolrj   rg   strbytesr   r   r   ccallr   propertyr   r   r   r   r   r   r
   r   r    r    r    r!   r#   !   s<    X
@
!(F
C



	r#   )!r   	fractionsr   r   cython.cimportsr   r   cython.cimports.av.codec.codecr    cython.cimports.av.codec.contextr   r   $cython.cimports.av.container.streamsr   cython.cimports.av.dictionaryr   cython.cimports.av.errorr	   cython.cimports.av.packetr
   cython.cimports.av.streamr   r   cython.cimports.av.utilsr   r   av.dictionaryr   cfuncr#   r"   cclass	Containerr    r    r    r!   <module>   s"    