+
    ~j                         ^ RI t ^ RIt^ RIt^ RIHt ^ RIHtHt ^RIH	t	 ^RI
Ht ^RIHt ^RIHt ]P                   ! ]4      t ! R R	4      t ! R
 R4      tR# )    N)deque)OptionalUnion)
VideoFrame)
AudioFrame)AudioSource)VideoSourcec                     a  ] tR t^t o RtR^dRR/V 3R lR lltRV 3R lR	 lltV 3R
 lR ltV 3R lR ltV 3R lR lt	V 3R lR lt
V 3R lR lt]V 3R lR l4       t]V 3R lR l4       t]V 3R lR l4       tRtV tR# )AVSynchronizera@  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)
video_queue_size_ms_max_delay_tolerance_ms,  c          
      8   < V ^8  d   QhRS[ RS[RS[RS[RS[/# )   audio_sourcevideo_source	video_fpsr   r   )r   r	   float)format__classdict__s   "m/Users/mitch_tango/dev/rabbit-r1-livekit/agent/.venv/lib/python3.14/site-packages/livekit/rtc/synchronizer.py__annotate__AVSynchronizer.__annotate__   sF      N  N " N "	 N
  N # N "' N    c               `   Wn         W n        W0n        W@n        WPn        R V n        ^ V n        ^ V n        \        V P                  V P                  ,          R,          4      V n	        V P                  ^ 8  d   \        ^V P                  4      V n	        \        P                  \        \        \        \         ,          3,          ,          ! V P                  R7      V n        \%        V P                  V P                  R7      V n        \        P(                  ! V P+                  4       4      V n        R# )F  )maxsize)expected_fpsmax_delay_tolerance_msN)_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   r   _video_queue_FPSController_fps_controllercreate_task_capture_video_capture_video_task)selfr   r   r   r   r   s   &$$$$$r   __init__AVSynchronizer.__init__   s     *)#$7!'>$'('(%(4;T;T)TW[)[%\"$$q(),Q0J0J)KD&#MM%
HUO0K*LM..
  .#'#?#? 
 $+#6#6t7J7J7L#M r   Nc                P   < V ^8  d   QhRS[ S[S[3,          RS[S[,          RR/# )r   frame	timestampreturnN)r   r   r   r   r   )r   r   s   "r   r   r   A   s3     8 8:z128?G8	8r   c                   "   \        V\        4      '       d0   V P                  P                  V4      G Rj  xL
  Ve   W n        R# V P
                  P                  W34      G Rj  xL
  R#  L6 L5i)zPush 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r3   r7   r8   s   &&&r   pushAVSynchronizer.pushA   sd      eZ(($$225999$(1%##U$6777 :
 	8s!   5A2A./A2'A0(A20A2c                   < V ^8  d   QhRR/# r   r9   N )r   r   s   "r   r   r   S   s     * *4 *r   c                  "   V P                   P                  4        V P                  P                  4       '       g?   V P                  P	                  4       G R j  xL
  V P                  P                  4        K^  R #  L"5iN)r    clear_queuer-   emptyget	task_doner3   s   &r   rF   AVSynchronizer.clear_queueS   s^     &&(##))++##'')))'') ,)s   :A?A?A=#A?c                   < V ^8  d   QhRR/# rB   rC   )r   r   s   "r   r   r   Y   s     
 
 
r   c                   "   \         P                  ! V P                  P                  4       V P                  P                  4       4      G Rj  xL
  R#  L5i)z5Wait until all video and audio frames are played out.N)r*   gatherr    wait_for_playoutr-   joinrJ   s   &r   rO   AVSynchronizer.wait_for_playoutY   s?     nn//1""$
 	
 	
s   AAAAc                   < V ^8  d   QhRR/# rB   rC   )r   r   s   "r   r   r   `   s     % %t %r   c                :    V P                   P                  4        R # rE   )r/   resetrJ   s   &r   rT   AVSynchronizer.reset`   s    ""$r   c                   < V ^8  d   QhRR/# rB   rC   )r   r   s   "r   r   r   c   s     * *d *r   c                  "   V P                   '       g   V P                  P                  4       G R j  xL
 w  rV P                  ;_uu_4       GR j  xL
  V P                  P                  V4       Ve   W n        R R R 4      GR j  xL
  V P                  P                  4        K  R #  Lv LY L&  + GR j  xL 
 '       g   i     L=; i5irE   )r$   r-   rH   r/   r!   r<   r%   rI   r>   s   &  r   r1   AVSynchronizer._capture_videoc   s     ---%)%6%6%:%:%<<E++++""007(,5) ,+ '')  <++++sb   CCB)CB+C&B/;CB-#C+C-C/C	5B86
C	C	Cc                   < V ^8  d   QhRR/# rB   rC   )r   r   s   "r   r   r   l   s     . .d .r   c                x   "   R V n         V P                  '       d   V P                  P                  4        R# R# 5i)TN)r$   r2   cancelrJ   s   &r   acloseAVSynchronizer.aclosel   s/     ###$$++- $s   8:c                    < V ^8  d   QhRS[ /# r   r9   r   )r   r   s   "r   r   r   r   s     / /E /r   c                .    V P                   P                  # rE   )r/   
actual_fpsrJ   s   &r   rb   AVSynchronizer.actual_fpsq   s    ##...r   c                    < V ^8  d   QhRS[ /# r_   r`   )r   r   s   "r   r   r   v   s     % % %r   c                    V P                   # )z)The time of the last video frame captured)r%   rJ   s   &r   last_video_timeAVSynchronizer.last_video_timeu   s     $$$r   c                    < V ^8  d   QhRS[ /# r_   r`   )r   r   s   "r   r   r   {   s     J J Jr   c                P    V P                   V P                  P                  ,
          # )z+The time of the last audio frame played out)r&   r    queued_durationrJ   s   &r   last_audio_timeAVSynchronizer.last_audio_timez   s!     $$t'9'9'I'IIIr   )r    r2   r/   r&   r%   r   r$   r"   r-   r(   r#   r!   rE   )__name__
__module____qualname____firstlineno____doc__r4   r?   rF   rO   rT   r1   r\   propertyrb   rf   rk   __static_attributes____classdictcell__r   s   @r   r   r      s      N &) N *- N  ND8 8$* *
 
% %* *. .
 / / % % J Jr   r   c                      a  ] tR t^t o RR/V 3R lR lltV 3R lR ltV 3R lR ltV 3R	 lR
 ltV 3R lR ltV 3R lR lt	]
V 3R lR l4       t]
V 3R lR l4       tRtV tR# )r.   r   r   c                *   < V ^8  d   QhRS[ RS[ RR/# )r   r   r   r9   Nr`   )r   r   s   "r   r   _FPSController.__annotate__   s(     S S Su SW[ Sr   c                   Wn         RV,          V n        VR,          V n        RV n        \	        ^\        RV,          4      4      V n        \        V P                  R7      V n        R# )a  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)r3   r   r   s   &$$r   r4   _FPSController.__init__   sX     *"\1)?$)F&15!$QC,,>(?!@.34;Q;Q.Rr   c                   < V ^8  d   QhRR/# rB   rC   )r   r   s   "r   r   rx      s     ' '$ 'r   c                B   "   V P                  4       G R j  xL
  R #  L5irE   )wait_next_processrJ   s   &r   
__aenter___FPSController.__aenter__   s     $$&&&s   c                   < V ^8  d   QhRR/# rB   rC   )r   r   s   "r   r   rx      s      D r   c                .   "   V P                  4        R # 5irE   )after_process)r3   exc_typeexc_valexc_tbs   &&&&r   	__aexit___FPSController.__aexit__   s     s   c                   < V ^8  d   QhRR/# rB   rC   )r   r   s   "r   r   rx      s     & &t &r   c                H    R V n         V P                  P                  4        R # rE   )r~   r   clearrJ   s   &r   rT   _FPSController.reset   s     $##%r   c                   < V ^8  d   QhRR/# rB   rC   )r   r   s   "r   r   rx      s     < < <r   c                x  "   \         P                  ! 4       pV P                  f   Wn        V P                  V,
          pV^ 8  d!   \        P                  ! V4      G Rj  xL
  R# V) V P
                  8  d?   \        P                  RV) R,          R R24       \         P                  ! 4       V n        R# R#  LX5i)zjWait until it's time for the next frame.

Adjusts sleep time based on actual FPS to maintain target rate.
Nz&Frame capture was behind schedule for r   z.2fz ms)timeperf_counterr~   r*   sleepr}   loggerwarning)r3   current_time
sleep_times   &  r   r    _FPSController.wait_next_process   s     
 ((*   ($0! **\9
>--
+++ {T;;;!GVZHZ[^G__bcd(,(9(9(;% < ,s   AB:B8 AB:c                   < V ^8  d   QhRR/# rB   rC   )r   r   s   "r   r   rx      s     6 6t 6r   c                    V P                   f   Q R4       hV P                  P                  \        P                  ! 4       4       V ;P                   V P
                  ,          un         R# )z3Update timing information after processing a frame.Nz&wait_next_process must be called first)r~   r   appendr   r   r|   rJ   s   &r   r   _FPSController.after_process   sR    $$0Z2ZZ0 	$$T%6%6%89 	!5!55r   c                    < V ^8  d   QhRS[ /# r_   r`   )r   r   s   "r   r   rx      s     " "e "r   c                    V P                   # rE   )r{   rJ   s   &r   r   _FPSController.expected_fps   s    !!!r   c                    < V ^8  d   QhRS[ /# r_   r`   )r   r   s   "r   r   rx      s     
 
E 
r   c                    \        V P                  4      ^8  d   ^ # \        V P                  4      ^,
          V P                  R,          V P                  ^ ,          ,
          ,          # )zGet current average FPS.)lenr   rJ   s   &r   rb   _FPSController.actual_fps   sU     t$$%)D))*Q.!!"%(=(=a(@@
 	
r   )r{   r   r|   r}   r~   r   N)rm   rn   ro   rp   r4   r   r   rT   r   r   rr   r   rb   rs   rt   ru   s   @r   r.   r.      ss     Ss S S(' ' & &< <*6 6 " " 
 
r   r.   )r*   loggingr   collectionsr   typingr   r   video_framer   audio_framer   r   r   r   r	   	getLoggerrm   r   r   r.   rC   r   r   <module>r      sM        " # # % % 
		8	$mJ mJ`J
 J
r   