[WebRTC] Request keyframe when switching video decoder 14/318014/2
authorJakub Gajownik <j.gajownik2@samsung.com>
Tue, 17 Sep 2024 08:18:44 +0000 (10:18 +0200)
committerBot Blink <blinkbot@samsung.com>
Mon, 23 Sep 2024 19:05:18 +0000 (19:05 +0000)
When different video decoder instance is used, first frame
we should provide is keyframe. That is because reference
frame for current buffer might not be in decoder and it
results in decoding artifacts.

Such situation is not handled by switchable video decoder
which checks for keyframe after switching diffrent decoder
and requests one if needed.

Bug: https://jira-eu.sec.samsung.net/browse/VDGAME-575
Change-Id: I2a34a3f41f8932f9b4a3a0d4b5e7ea9b889e6638
Signed-off-by: Jakub Gajownik <j.gajownik2@samsung.com>
tizen_src/chromium_impl/third_party/blink/renderer/platform/peerconnection/switchable_video_decoder_wrapper.cc

index 1576646500b9592f06ef97573e74d3284ccb05ac..52c8bc4679ff036bc5b386b565b7a2c32990b3f4 100644 (file)
@@ -73,6 +73,7 @@ class SwitchableVideoDecoderWrapper final
   webrtc::VideoDecoder& active_decoder() const;
 
   DecodingMode decoding_mode_ = DecodingMode::kNone;
+  bool expects_keyframe_ = true;
 
   bool hw_decoder_configured_ = false;
   std::unique_ptr<VideoDecoder> hw_decoder_;
@@ -147,9 +148,21 @@ int32_t SwitchableVideoDecoderWrapper::Decode(
     const webrtc::EncodedImage& input_image,
     bool missing_frames,
     int64_t render_time_ms) {
+  if (decoding_mode_ == DecodingMode::kNone) {
+    return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
+  }
+
+  if (expects_keyframe_) {
+    if (input_image.FrameType() != webrtc::VideoFrameType::kVideoFrameKey) {
+      return WEBRTC_VIDEO_CODEC_OK_REQUEST_KEYFRAME;
+    }
+    expects_keyframe_ = false;
+  }
+
   switch (decoding_mode_) {
     case DecodingMode::kNone:
-      return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
+      // Already handled above.
+      break;
     case DecodingMode::kHardware: {
       int32_t ret = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
       ret = hw_decoder_->Decode(input_image, missing_frames, render_time_ms);
@@ -176,6 +189,10 @@ int32_t SwitchableVideoDecoderWrapper::Decode(
         return ret;
       }
       decoding_mode_ = DecodingMode::kSoftwareFallback;
+      if (input_image.FrameType() != webrtc::VideoFrameType::kVideoFrameKey) {
+        expects_keyframe_ = true;
+        return WEBRTC_VIDEO_CODEC_OK_REQUEST_KEYFRAME;
+      }
       return sw_decoder_->Decode(input_image, missing_frames, render_time_ms);
     }
     case DecodingMode::kSoftware:
@@ -248,6 +265,7 @@ void SwitchableVideoDecoderWrapper::OnStateChange(suspend_resume::State state) {
           LOG(ERROR) << "Error initializing software decoder";
         }
         decoding_mode_ = DecodingMode::kSoftware;
+        expects_keyframe_ = true;
       }
       break;
     case suspend_resume::State::RESUMED:
@@ -256,6 +274,7 @@ void SwitchableVideoDecoderWrapper::OnStateChange(suspend_resume::State state) {
           LOG(ERROR) << "Error initializing hardware decoder";
         }
         decoding_mode_ = DecodingMode::kHardware;
+        expects_keyframe_ = true;
       }
       break;
   }