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 <philipel@webrtc.org>
Reviewed-by: Philip Eliasson <philipel@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#40972}
diff --git a/modules/video_coding/codecs/h264/h264_encoder_impl.cc b/modules/video_coding/codecs/h264/h264_encoder_impl.cc
index 7a9f640..ee69b9b 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 @@
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);