From 11376fb992f2b6f080f550e419e6558b1d953701 Mon Sep 17 00:00:00 2001 From: Byoungchan Lee Date: Wed, 18 Oct 2023 16:35:27 +0900 Subject: [PATCH] Reset H.264 SVC Controller on key frame Sometimes OpenH264 returns a key frame even though we have not requested one. However, SVC controller does not know about this and will not reset its state. Since we are comparing expected tid from SVC controller with actual tid from OpenH264, and drop frames if they do not match, that causes a missing frame. This CL resets the SVC controller state on key frames, ensuring that it accurately maintains its state and does not drop frames. Also, changes the message of the error log to be more descriptive. Now, it will print the expected tid and actual tid. Bug: webrtc:14877 Change-Id: I6c9e7532b2478773f03e5707bf7a1ca56e4f7b99 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/324001 Commit-Queue: Philip Eliasson Reviewed-by: Philip Eliasson Cr-Commit-Position: refs/heads/main@{#40972} --- .../video_coding/codecs/h264/h264_encoder_impl.cc | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/modules/video_coding/codecs/h264/h264_encoder_impl.cc b/modules/video_coding/codecs/h264/h264_encoder_impl.cc index 7a9f640ce6..ee69b9befb 100644 --- a/modules/video_coding/codecs/h264/h264_encoder_impl.cc +++ b/modules/video_coding/codecs/h264/h264_encoder_impl.cc @@ -565,10 +565,20 @@ int32_t H264EncoderImpl::Encode( codec_specific.codecSpecific.H264.base_layer_sync = tid > 0 && tid < tl0sync_limit_[i]; if (svc_controllers_[i]) { + if (encoded_images_[i]._frameType == VideoFrameType::kVideoFrameKey) { + // Reset the ScalableVideoController on key frame + // to reset the expected dependency structure. + layer_frames = + svc_controllers_[i]->NextFrameConfig(/* restart= */ true); + RTC_CHECK_EQ(layer_frames.size(), 1); + RTC_DCHECK_EQ(layer_frames[0].TemporalId(), 0); + RTC_DCHECK_EQ(layer_frames[0].IsKeyframe(), true); + } + if (layer_frames[0].TemporalId() != tid) { RTC_LOG(LS_WARNING) - << "Encoder produced a frame for layer S" << (i + 1) << "T" - << tid + 1 << " that wasn't requested."; + << "Encoder produced a frame with temporal id " << tid + << ", expected " << layer_frames[0].TemporalId() << "."; continue; } encoded_images_[i].SetTemporalIndex(tid);