o
    diLR                     @   s  d dl Z d dl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
 d dlmZ d dlmZ ddlmZ ddlmZmZmZm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"m#Z#m$Z$ ddl%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4 ddl5m6Z6m7Z7m8Z8 ddl9m:Z:m;Z; e<e=Z>de j?dej@de j@ddfddZAG dd dZBG dd dZCG dd deZDG dd dZEe
G d d! d!ZFe
G d"d# d#ZGG d$d% d%ZHdS )&    N)Callable)	dataclass)Optional)Frame   )clock)	depayloadget_capabilitiesget_decoderis_rtx)InvalidStateError)JitterBuffer)MediaStreamErrorMediaStreamTrack)RemoteBitrateEstimator)RTCDtlsTransport)RTCRtpCapabilitiesRTCRtpCodecParametersRTCRtpReceiveParameters)RTCP_PSFB_APPRTCP_PSFB_PLIRTCP_RTPFB_NACKRTP_HISTORY_SIZEAnyRtcpPacketRtcpByePacketRtcpPsfbPacketRtcpReceiverInfoRtcpRrPacketRtcpRtpfbPacketRtcpSrPacket	RtpPacketclamp_packets_lostpack_remb_fci
unwrap_rtx)RTCInboundRtpStreamStatsRTCRemoteOutboundRtpStreamStatsRTCStatsReport)
uint16_add	uint16_gtloopinput_qoutput_qreturnc           	      C   s   d }d }	 |  }|d u rt|d |  n"|\}}|j|kr't|}|j}||D ]}t|||  q,q|d ur@~d S d S N)getasynciorun_coroutine_threadsafeputnamer
   decode)	r)   r*   r+   
codec_namedecodertaskcodecencoded_frameframe r:   I/home/ubuntu/.local/lib/python3.10/site-packages/aiortc/rtcrtpreceiver.pydecoder_worker5   s"   
r<   c                   @   s2   e Zd Zd
ddZdedefddZd
dd	ZdS )NackGeneratorr,   Nc                 C   s   d | _ t | _d S r-   )max_seqsetmissingselfr:   r:   r;   __init__P   s   zNackGenerator.__init__packetc                 C   s   d}| j du r|j| _ |S t|j| j r8t| j d}t|j|r3| j| d}t|d}t|j|s |j| _ n| j|j |   |S )zL
        Mark a new packet as received, and deduce missing packets.
        FNr   T)r>   sequence_numberr(   r'   r@   adddiscardtruncate)rB   rD   missedseqr:   r:   r;   rF   T   s   


zNackGenerator.addc                 C   sF   | j durt| j t }t| jD ]}t||r| j| qdS dS )z
        Limit the number of missing packets we track.

        Otherwise, the size of RTCP FB messages grows indefinitely.
        N)r>   r'   r   listr@   r(   rG   )rB   min_seqrJ   r:   r:   r;   rH   n   s   

zNackGenerator.truncater,   N)__name__
__module____qualname__rC   r    boolrF   rH   r:   r:   r:   r;   r=   O   s    
r=   c                   @   sx   e Zd ZdeddfddZdeddfddZedefd	d
ZedefddZ	edefddZ
edefddZdS )StreamStatistics	clockrater,   Nc                 C   s@   d | _ d | _d| _d| _|| _d| _d | _d | _d| _d| _	d S )Nr   )
base_seqr>   cyclespackets_received
_clockrate
_jitter_q4_last_arrival_last_timestamp_expected_prior_received_prior)rB   rS   r:   r:   r;   rC   |   s   
zStreamStatistics.__init__rD   c                 C   s   | j d u pt|j| j }|  jd7  _| jd u r|j| _|rltt | j }| j d ur9|j| j k r9|  jd7  _|j| _ |j	| j
krc| jdkrct|| j |j	| j
  }|  j|| jd d?  7  _|| _|j	| _
d S d S )Nr            )r>   r(   rE   rV   rT   inttimerW   rU   	timestamprZ   absrY   rX   )rB   rD   in_orderarrivaldiffr:   r:   r;   rF      s*   

zStreamStatistics.addc                 C   sP   | j | j }| j | _| j| j }| j| _|| }|dks |dkr"dS |d> | S )Nr   r^   )packets_expectedr[   rV   r\   )rB   expected_intervalreceived_intervallost_intervalr:   r:   r;   fraction_lost   s   zStreamStatistics.fraction_lostc                 C   s
   | j d? S )Nr_   )rX   rA   r:   r:   r;   jitter   s   
zStreamStatistics.jitterc                 C   s   | j | j | j d S )Nr   )rU   r>   rT   rA   r:   r:   r;   rg      s   z!StreamStatistics.packets_expectedc                 C   s   t | j| j S r-   )r!   rg   rV   rA   r:   r:   r;   packets_lost   s   zStreamStatistics.packets_lost)rN   rO   rP   r`   rC   r    rF   propertyrk   rl   rg   rm   r:   r:   r:   r;   rR   {   s    rR   c                       s>   e Zd Zd	dedee ddf fddZdefddZ  ZS )
RemoteStreamTrackNkindidr,   c                    s,   t    || _|d ur|| _t | _d S r-   )superrC   rp   _idr/   Queue_queue)rB   rp   rq   	__class__r:   r;   rC      s
   
zRemoteStreamTrack.__init__c                    s8   | j dkrt| j I dH }|du r|   t|S )z)
        Receive the next frame.
        liveN)
readyStater   ru   r.   stop)rB   r9   r:   r:   r;   recv   s   
zRemoteStreamTrack.recvr-   )	rN   rO   rP   strr   rC   r   r{   __classcell__r:   r:   rv   r;   ro      s     ro   c                   @   s(   e Zd ZdddZdedefddZdS )	TimestampMapperr,   Nc                 C   s   d | _ d | _d S r-   )_last_originrA   r:   r:   r;   rC      s   
zTimestampMapper.__init__rb   c                 C   s:   | j d u r	|| _ n|| jk r|  j d8  _ || _|| j  S )Nl        )r   r   )rB   rb   r:   r:   r;   map   s   


zTimestampMapper.maprM   )rN   rO   rP   rC   r`   r   r:   r:   r:   r;   r~      s    
r~   c                   @   &   e Zd ZU dZejed< 	 eed< dS )RTCRtpContributingSourcezw
    The :class:`RTCRtpContributingSource` dictionary contains information about
    a contributing source (CSRC).
    rb   sourceNrN   rO   rP   __doc__datetime__annotations__r`   r:   r:   r:   r;   r         
 
r   c                   @   r   )RTCRtpSynchronizationSourcez}
    The :class:`RTCRtpSynchronizationSource` dictionary contains information about
    a synchronization source (SSRC).
    rb   r   Nr   r:   r:   r:   r;   r      r   r   c                   @   sH  e Zd ZdZdededdfddZedefdd	Z	edefd
dZ
ededee fddZdefddZdee fddZdeddfddZdeddfddZd0ddZd0ddZdeddfddZdededdfdd Zd0d!d"Zdeddfd#d$Zd%ed&ee ddfd'd(Z d%eddfd)d*Z!d+eddfd,d-Z"d0d.d/Z#dS )1RTCRtpReceiverz
    The :class:`RTCRtpReceiver` interface manages the reception and decoding
    of data for a :class:`MediaStreamTrack`.

    :param kind: The kind of media (`'audio'` or `'video'`).
    :param transport: An :class:`RTCDtlsTransport`.
    rp   	transportr,   Nc                    s   |j dkrtd _i  _i  _t  _d  _| _	|dkr-t
ddd _d  _d  _nt
ddd _t  _t  _d  _t  _t  _d  _i  _d	 _t  _t  _| _i  _i  _i  _d  _ d
d  _!t"#t$j%r} fdd _!d S d S )NclosedTaudio   r_   )capacityprefetch   )r   is_videoFc                  W   s   d S r-   r:   )argsr:   r:   r;   <lambda>,  s    z)RTCRtpReceiver.__init__.<locals>.<lambda>c                    s   t jd|   jg|R  S )NzRTCRtpReceiver(%s) )loggerdebug_RTCRtpReceiver__kind)msgr   rA   r:   r;   r   .  s
    )&stater   _enabled_RTCRtpReceiver__active_ssrc_RTCRtpReceiver__codecsqueuert   _RTCRtpReceiver__decoder_queue_RTCRtpReceiver__decoder_threadr   r   _RTCRtpReceiver__jitter_buffer_RTCRtpReceiver__nack_generator)_RTCRtpReceiver__remote_bitrate_estimatorr=   r   _trackr/   Event_RTCRtpReceiver__rtcp_exited_RTCRtpReceiver__rtcp_started_RTCRtpReceiver__rtcp_task_RTCRtpReceiver__rtx_ssrc_RTCRtpReceiver__startedr&   _RTCRtpReceiver__statsr~   !_RTCRtpReceiver__timestamp_mapper_RTCRtpReceiver__transport_RTCRtpReceiver__lsr_RTCRtpReceiver__lsr_time_RTCRtpReceiver__remote_streams_RTCRtpReceiver__rtcp_ssrc_RTCRtpReceiver__log_debugr   isEnabledForloggingDEBUG)rB   rp   r   r:   rA   r;   rC   	  s@   




zRTCRtpReceiver.__init__c                 C      | j S )zW
        The :class:`MediaStreamTrack` which is being handled by the receiver.
        )r   rA   r:   r:   r;   track2  s   zRTCRtpReceiver.trackc                 C   r   )zr
        The :class:`RTCDtlsTransport` over which the media for the receiver's
        track is received.
        r   rA   r:   r:   r;   r   9  s   zRTCRtpReceiver.transportc                 C   s   t |S )z
        Returns the most optimistic view of the system's capabilities for
        receiving media of the given `kind`.

        :rtype: :class:`RTCRtpCapabilities`
        )r	   )rB   rp   r:   r:   r;   getCapabilitiesA  s   zRTCRtpReceiver.getCapabilitiesc                    sl   | j  D ]#\}}| jtt ddtt|  || j	| j
j|j|j|jd	 q| j| j
  | jS )ze
        Returns statistics about the RTP receiver.

        :rtype: :class:`RTCStatsReport`
        zinbound-rtpzinbound-rtp_)	rb   typerq   ssrcrp   transportIdpacketsReceivedpacketsLostrl   )r   itemsr   rF   r$   r   current_datetimer|   rq   r   r   	_stats_idrV   rm   rl   update
_get_stats)rB   r   streamr:   r:   r;   getStatsK  s"   zRTCRtpReceiver.getStatsc                 C   sJ   t  tjdd }g }| j D ]\}}||kr"|t||d q|S )z
        Returns a :class:`RTCRtpSynchronizationSource` for each unique SSRC identifier
        received in the last 10 seconds.
        
   )seconds)r   rb   )r   r   r   	timedeltar   r   appendr   )rB   cutoffsourcesr   rb   r:   r:   r;   getSynchronizationSourcesg  s   
z(RTCRtpReceiver.getSynchronizationSources
parametersc                    s   | j sN|jD ]}|| j|j< q|jD ]}|jr |j| j|jj< qtj	t
| jd t | j| jjfd| _| j  | j| | t|  | _d| _ dS dS )z
        Attempt to set the parameters controlling the receiving of media.

        :param parameters: The :class:`RTCRtpParameters` for the receiver.
        z-decoder)targetr2   r   TN)r   codecsr   payloadType	encodingsrtxr   r   	threadingThreadr<   r   r/   get_event_loopr   r   ru   r   startr   _register_rtp_receiverensure_future	_run_rtcpr   )rB   r   r7   encodingr:   r:   r;   receiveu  s*   


	
zRTCRtpReceiver.receivec                 C   
   || _ d S r-   r   )rB   r   r:   r:   r;   setTransport     
zRTCRtpReceiver.setTransportc                    sN   | j r%| j|  |   | j I dH  | j  | j I dH  dS dS )z1
        Irreversibly stop the receiver.
        N)	r   r   _unregister_rtp_receiver_RTCRtpReceiver__stop_decoderr   waitr   cancelr   rA   r:   r:   r;   rz     s   
zRTCRtpReceiver.stopc                 C   s   |    d S r-   )r   rA   r:   r:   r;   _handle_disconnect  s   z!RTCRtpReceiver._handle_disconnectrD   c                    s   |  d| t|trG| jtt ddt|  |j	| j
| jj|jj|jjt|jjd	 |jjd? d@ | j|j	< t | j|j	< d S t|trR|   d S d S )N< %szremote-outbound-rtpzremote-outbound-rtp_)	rb   r   rq   r   rp   r   packetsSent	bytesSentremoteTimestampr   l    )r   
isinstancer   r   rF   r%   r   r   rq   r   r   r   r   sender_infopacket_countoctet_countdatetime_from_ntpntp_timestampr   ra   r   r   r   rB   rD   r:   r:   r;   _handle_rtcp_packet  s2   


z"RTCRtpReceiver._handle_rtcp_packetarrival_time_msc              
      sZ  |  d| | jsdS | jdurF|jjdurF| jj|jj|t|j|j |j	d}| j
durF|durFtt| j
dt| d}| |I dH  t | j|j	< | j|j}|du rb|  d|j dS |j	| jvrqt|j| j|j	< | j|j	 | t|r| j|j	}|du r|  d|j	 dS |jd}t|jd	k st|tr|| jvrdS t|||d
}| j| }| jdur| j|r| |j	t | jj!I dH  z|jrt"||j|_#nd|_#W n t$y } z|  d| W Y d}~dS d}~ww | j%|\}	}
|	r| &|j	I dH  |
dur)| j'r+| j()|
j*|
_*| j+,||
f dS dS dS )z0
        Handle an incoming RTP packet.
        r   N)abs_send_timer   payload_sizer   r   )fmtr   
media_ssrcfciz)x RTP packet with unknown payload type %dz!x RTX packet from unknown SSRC %dapt   )payload_typer       z x RTP payload parsing failed: %s)-r   r   r   
extensionsr   rF   lenpayloadpadding_sizer   r   r   r   r"   
_send_rtcpr   r   r   r   r.   r   r   rR   	clockRater   r   r   r   r`   r#   r   _send_rtcp_nacksortedr@   r   _data
ValueErrorr   _send_rtcp_plir   r   r   rb   r   r1   )rB   rD   r   rembrtcp_packetr7   original_ssrcr   excpli_flagr8   r:   r:   r;   _handle_rtp_packet  s   



z!RTCRtpReceiver._handle_rtp_packetc                    s  |  d | j  zg	 tdt  I d H  g }| j D ];\}}d}d}|| jv rI| j| }t		 | j
|  }|dkrI|dk rIt|d }|t||j|j|j|j||d q | jd urr|rrt| j|d}| |I d H  q tjy|   Y nw |  d | j  d S )	Nz- RTCP startedTg      ?r   r]   )r   rk   rm   highest_sequencerl   lsrdlsr)r   reportsz- RTCP finished)r   r   r?   r/   sleeprandomr   r   r   ra   r   r`   r   r   rk   rm   r>   rl   r   r   r   CancelledErrorr   )rB   r  r   r   r  r  delayrD   r:   r:   r;   r     sF   



 
zRTCRtpReceiver._run_rtcpc                    s@   |  d| z| jt|I d H  W d S  ty   Y d S w )Nz> %s)r   r   	_send_rtpbytesConnectionErrorr   r:   r:   r;   r   J  s   zRTCRtpReceiver._send_rtcpr   lostc                    s:   | j durtt| j |d}||_| |I dH  dS dS )zD
        Send an RTCP packet to report missing RTP packets.
        Nr   r   r   )r   r   r   r  r   )rB   r   r  rD   r:   r:   r;   r   Q  s   
zRTCRtpReceiver._send_rtcp_nackc                    s4   | j durtt| j |d}| |I dH  dS dS )z=
        Send an RTCP packet to report picture loss.
        Nr  )r   r   r   r   )rB   r   rD   r:   r:   r;   r  \  s   
zRTCRtpReceiver._send_rtcp_plir   c                 C   r   r-   )r   )rB   r   r:   r:   r;   _set_rtcp_ssrcf  r   zRTCRtpReceiver._set_rtcp_ssrcc                 C   s*   | j r| jd | j   d| _ dS dS )zM
        Stop the decoder thread, which will in turn stop the track.
        N)r   r   r1   joinrA   r:   r:   r;   __stop_decoderi  s
   

zRTCRtpReceiver.__stop_decoderrM   )$rN   rO   rP   r   r|   r   rC   rn   r   r   r   classmethodr   r   r   r&   r   rK   r   r   r   r   r   rz   r   r   r   r    r`   r
  r   r   r   r  r  r   r:   r:   r:   r;   r      s.    )	


\+
r   )Ir/   r   r   r   r  r   ra   collections.abcr   dataclassesr   typingr   av.framer    r   r   r   r	   r
   r   
exceptionsr   jitterbufferr   mediastreamsr   r   rater   rtcdtlstransportr   rtcrtpparametersr   r   r   rtpr   r   r   r   r   r   r   r   r   r   r   r    r!   r"   r#   statsr$   r%   r&   utilsr'   r(   	getLoggerrN   r   AbstractEventLooprt   r<   r=   rR   ro   r~   r   r   r   r:   r:   r:   r;   <module>   sR    D

,D