@@ -1737,19 +1737,6 @@ static inline void send_interleaved(struct obs_output *output)
17371737 }
17381738 pthread_mutex_unlock (& output -> pkt_callbacks_mutex );
17391739
1740- /* Iterate the registered packet callback(s) and invoke
1741- * each one. The caption track logic further above should
1742- * eventually migrate to the packet callback mechanism.
1743- */
1744- pthread_mutex_lock (& output -> pkt_callbacks_mutex );
1745- for (size_t i = 0 ; i < output -> pkt_callbacks .num ; ++ i ) {
1746- struct packet_callback * const callback = & output -> pkt_callbacks .array [i ];
1747- // Packet interleave request timestamp
1748- ept_local .pir = os_gettime_ns ();
1749- callback -> packet_cb (output , & out , found_ept ? & ept_local : NULL , callback -> param );
1750- }
1751- pthread_mutex_unlock (& output -> pkt_callbacks_mutex );
1752-
17531740 output -> info .encoded_packet (output -> context .data , & out );
17541741 obs_encoder_packet_release (& out );
17551742}
@@ -2606,6 +2593,15 @@ static inline void pair_encoders(obs_output_t *output)
26062593 obs_weak_encoder_t * weak_video = obs_encoder_get_weak_encoder (video );
26072594 da_push_back (video -> paired_encoders , & weak_audio );
26082595 da_push_back (audio -> paired_encoders , & weak_video );
2596+
2597+ /*
2598+ * Audio output routing is canvas-aware. In multi-canvas sessions an
2599+ * audio encoder without an associated video mix gets fed once per
2600+ * canvas, which duplicates audio blocks at the same timestamp. Have
2601+ * the audio encoder follow the paired video encoder's canvas so it
2602+ * only receives the intended mix.
2603+ */
2604+ audio -> video = video -> video ;
26092605 }
26102606 pthread_mutex_unlock (& audio -> init_mutex );
26112607 }
0 commit comments