@@ -275,12 +275,10 @@ void VideoWorker::run() {
275275 continue ;
276276 }
277277
278- /* timestamp fix, can be removed if solved
279278 int64_t nal_ts = stream.pack [stream.packCount - 1 ].timestamp ;
280279 struct timeval encoder_time;
281280 encoder_time.tv_sec = nal_ts / 1000000 ;
282281 encoder_time.tv_usec = nal_ts % 1000000 ;
283- */
284282
285283 for (uint32_t i = 0 ; i < stream.packCount ; ++i) {
286284 bool recorder_active = channel_recorder.isActive ();
@@ -439,10 +437,10 @@ void VideoWorker::run() {
439437 if (global_video[encChn]->hasDataCallback ) {
440438 H264NALUnit nalu;
441439
442- /* timestamp fix, can be removed if solved
443- nalu.imp_ts = stream.pack[i]. timestamp;
444- nalu.time = encoder_time;
445- */
440+ // Use the frame-level timestamp (from last pack) for all NALs
441+ // in this GetStream() call. SPS/PPS packs may carry timestamp=0
442+ // which would cause a DTS discontinuity in the RTP stream.
443+ nalu. imp_ts = nal_ts;
446444
447445 // We use start+4 because the encoder inserts 4-byte MPEG
448446 // 'startcodes' at the beginning of each NAL. Live555 complains.
@@ -467,13 +465,21 @@ void VideoWorker::run() {
467465
468466 if (global_video[encChn]->idr == true ) {
469467 bool delivered = false ;
470- // Use write_wait() to apply backpressure instead of silent drops
468+ // Use non-blocking write() to avoid stalling encoder on slow clients
469+ // (go2rtc-inspired: drop oldest frame rather than block producer)
471470 try {
472- global_video[encChn]->msgChannel ->write_wait (nalu);
473- delivered = true ;
474- std::unique_lock<std::mutex> lock_stream{global_video[encChn]->onDataCallbackLock };
475- if (global_video[encChn]->onDataCallback )
476- global_video[encChn]->onDataCallback ();
471+ delivered = global_video[encChn]->msgChannel ->write (nalu);
472+ if (delivered) {
473+ std::unique_lock<std::mutex> lock_stream{global_video[encChn]->onDataCallbackLock };
474+ if (global_video[encChn]->onDataCallback )
475+ global_video[encChn]->onDataCallback ();
476+ } else {
477+ LOG_DDEBUG (" video channel:" << encChn << " msgChannel full, dropped oldest NAL" );
478+ // Still notify so consumer processes queued data
479+ std::unique_lock<std::mutex> lock_stream{global_video[encChn]->onDataCallbackLock };
480+ if (global_video[encChn]->onDataCallback )
481+ global_video[encChn]->onDataCallback ();
482+ }
477483 } catch (const std::exception& e) {
478484 LOG_ERROR (" video channel:" << encChn << " , frame_id:" << nalu.frame_id
479485 << " , packet:" << nalu.packet_index << " /" << nalu.packet_count
@@ -496,10 +502,16 @@ void VideoWorker::run() {
496502 }
497503 }
498504 if (!delivered) {
499- LOG_ERROR (" video channel:" << encChn << " , "
500- << " frame_id:" << nalu.frame_id << " , "
501- << " package:" << i << " of " << stream.packCount << " , "
502- << " packageSize:" << nalu.data .size () << " - msgChannel sink clogged!" );
505+ static uint32_t clog_count[NUM_VIDEO_CHANNELS] = {};
506+ static uint64_t clog_last_log_ms[NUM_VIDEO_CHANNELS] = {};
507+ clog_count[encChn]++;
508+ uint64_t now_ms = monotonic_ms ();
509+ if (now_ms - clog_last_log_ms[encChn] >= 5000 ) {
510+ LOG_WARN (" video channel:" << encChn << " - msgChannel sink clogged, "
511+ << clog_count[encChn] << " frames dropped in last 5s" );
512+ clog_count[encChn] = 0 ;
513+ clog_last_log_ms[encChn] = now_ms;
514+ }
503515 }
504516 }
505517#if defined(USE_AUDIO_STREAM_REPLICATOR)
0 commit comments