o
    i                     @   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 ddlm	Z	 ddl
mZ ddlmZ ddlmZ eeZG d	d
 d
ZG dd dZdS )    N)deque)OptionalUnion   )
VideoFrame)
AudioFrame)AudioSource)VideoSourcec                   @   s   e Zd ZdZddddedededed	ef
d
dZ	d"dee	e
f dee ddfddZd#ddZd#ddZd#ddZd#ddZd#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 )$AVSynchronizerah  Synchronize audio and video capture.

    Usage:
        av_sync = AVSynchronizer(
            audio_source=audio_source,
            video_source=video_source,
            video_fps=video_fps,
        )

        async for video_frame, audio_frame in video_generator:
            await av_sync.push(video_frame)
            await av_sync.push(audio_frame)
    d   ,  )video_queue_size_ms_max_delay_tolerance_msaudio_sourcevideo_source	video_fpsr   r   c                C   s   || _ || _|| _|| _|| _d| _d| _d| _t| j| j d | _	| jdkr/t
d| j	| _	tjtttt f  | j	d| _t| j| jd| _t|  | _d S )NFr     r   )maxsize)expected_fpsmax_delay_tolerance_ms)_audio_source_video_source
_video_fps_video_queue_size_msr   _stopped_last_video_time_last_audio_timeint_video_queue_max_sizemaxasyncioQueuetupler   r   float_video_queue_FPSController_fps_controllercreate_task_capture_video_capture_video_task)selfr   r   r   r   r    r+   Z/var/www/html/livekit_bhavya/venv/lib/python3.10/site-packages/livekit/rtc/synchronizer.py__init__   s&   	
zAVSynchronizer.__init__Nframe	timestampreturnc                    sJ   t |tr| j|I dH  |dur|| _dS | j||fI dH  dS )a  Push a frame to the synchronizer

        Args:
            frame: The video or audio frame to push.
            timestamp: (optional) The timestamp of the frame, for logging purposes for now.
                For AudioFrame, it should be the end time of the frame.
        N)
isinstancer   r   capture_framer   r$   putr*   r.   r/   r+   r+   r,   pushA   s   

zAVSynchronizer.pushc                    sB   | j   | j s| j I d H  | j  | j rd S d S N)r   clear_queuer$   emptyget	task_doner*   r+   r+   r,   r7   S   s   


zAVSynchronizer.clear_queuec                    s$   t | j | j I dH  dS )z5Wait until all video and audio frames are played out.N)r    gatherr   wait_for_playoutr$   joinr;   r+   r+   r,   r=   Y   s
   zAVSynchronizer.wait_for_playoutc                 C   s   | j   d S r6   )r&   resetr;   r+   r+   r,   r?   `   s   zAVSynchronizer.resetc              	      s   | j sB| j I d H \}}| j4 I d H  | j| |d ur#|| _W d   I d H  n1 I d H s3w   Y  | j  | j rd S d S r6   )r   r$   r9   r&   r   r2   r   r:   r4   r+   r+   r,   r(   c   s   (
zAVSynchronizer._capture_videoc                    s    d| _ | jr| j  d S d S )NT)r   r)   cancelr;   r+   r+   r,   aclosel   s
   zAVSynchronizer.aclosec                 C   s   | j jS r6   )r&   
actual_fpsr;   r+   r+   r,   rB   q   s   zAVSynchronizer.actual_fpsc                 C      | j S )z)The time of the last video frame captured)r   r;   r+   r+   r,   last_video_timeu   s   zAVSynchronizer.last_video_timec                 C   s   | j | jj S )z+The time of the last audio frame played out)r   r   queued_durationr;   r+   r+   r,   last_audio_timez   s   zAVSynchronizer.last_audio_timer6   r0   N)__name__
__module____qualname____doc__r   r	   r#   r-   r   r   r   r   r5   r7   r=   r?   r(   rA   propertyrB   rD   rF   r+   r+   r+   r,   r
      sD    
#






	r
   c                   @   s~   e Zd ZdddededdfddZdd	d
ZdddZdddZdddZdddZ	e
defddZe
defddZdS )r%   r   )r   r   r   r0   Nc                C   sF   || _ d| | _|d | _d| _tdtd| | _t| jd| _dS )aT  Controls frame rate by adjusting sleep time based on actual FPS.

        Usage:
            async with _FPSController(expected_fps=30):
                # process frame
                pass

        Args:
            expected_fps: Target frames per second
            max_delay_tolerance_ms: Maximum delay tolerance in milliseconds
        g      ?r   N   )maxlen)	_expected_fps_frame_interval_max_delay_tolerance_secs_next_frame_timer   r   _fps_calc_winsizer   _send_timestamps)r*   r   r   r+   r+   r,   r-      s   

z_FPSController.__init__c                    s   |   I d H  d S r6   )wait_next_processr;   r+   r+   r,   
__aenter__   s   z_FPSController.__aenter__c                    s   |    d S r6   )after_process)r*   exc_typeexc_valexc_tbr+   r+   r,   	__aexit__   s   z_FPSController.__aexit__c                 C   s   d | _ | j  d S r6   )rR   rT   clearr;   r+   r+   r,   r?      s   z_FPSController.resetc                    sx   t  }| jdu r|| _| j| }|dkr t|I dH  dS | | jkr:td| d dd t  | _dS dS )zzWait until it's time for the next frame.

        Adjusts sleep time based on actual FPS to maintain target rate.
        Nr   z&Frame capture was behind schedule for r   z.2fz ms)timeperf_counterrR   r    sleeprQ   loggerwarning)r*   current_time
sleep_timer+   r+   r,   rU      s   

z _FPSController.wait_next_processc                 C   s6   | j dus	J d| jt  |  j | j7  _ dS )z3Update timing information after processing a frame.Nz&wait_next_process must be called first)rR   rT   appendr]   r^   rP   r;   r+   r+   r,   rW      s   z_FPSController.after_processc                 C   rC   r6   )rO   r;   r+   r+   r,   r      s   z_FPSController.expected_fpsc                 C   s4   t | jdk r	dS t | jd | jd | jd   S )zGet current average FPS.rM   r   r   )lenrT   r;   r+   r+   r,   rB      s
   z_FPSController.actual_fpsrG   )rH   rI   rJ   r#   r-   rV   r[   r?   rU   rW   rL   r   rB   r+   r+   r+   r,   r%      s    





r%   )r    loggingr]   collectionsr   typingr   r   video_framer   audio_framer   r   r   r   r	   	getLoggerrH   r`   r
   r%   r+   r+   r+   r,   <module>   s    
p