diff --git a/api/test/mock_video_decoder.h b/api/test/mock_video_decoder.h index 6dee76097a..56ff5463fd 100644 --- a/api/test/mock_video_decoder.h +++ b/api/test/mock_video_decoder.h @@ -41,9 +41,10 @@ class MockVideoDecoder : public VideoDecoder { MOCK_METHOD2(InitDecode, int32_t(const VideoCodec* codecSettings, int32_t numberOfCores)); - MOCK_METHOD3(Decode, + MOCK_METHOD4(Decode, int32_t(const EncodedImage& inputImage, bool missingFrames, + const CodecSpecificInfo* codecSpecificInfo, int64_t renderTimeMs)); MOCK_METHOD1(RegisterDecodeCompleteCallback, int32_t(DecodedImageCallback* callback)); diff --git a/api/video_codecs/test/video_decoder_software_fallback_wrapper_unittest.cc b/api/video_codecs/test/video_decoder_software_fallback_wrapper_unittest.cc index 0e97173d07..06b893c2ad 100644 --- a/api/video_codecs/test/video_decoder_software_fallback_wrapper_unittest.cc +++ b/api/video_codecs/test/video_decoder_software_fallback_wrapper_unittest.cc @@ -49,6 +49,7 @@ class VideoDecoderSoftwareFallbackWrapperTest : public ::testing::Test { int32_t Decode(const EncodedImage& input_image, bool missing_frames, + const CodecSpecificInfo* codec_specific_info, int64_t render_time_ms) override { ++decode_count_; return decode_return_code_; @@ -88,7 +89,7 @@ TEST_F(VideoDecoderSoftwareFallbackWrapperTest, InitializesDecoder) { EncodedImage encoded_image; encoded_image._frameType = kVideoFrameKey; - fallback_wrapper_->Decode(encoded_image, false, -1); + fallback_wrapper_->Decode(encoded_image, false, nullptr, -1); EXPECT_EQ(1, fake_decoder_->init_decode_count_) << "Initialized decoder should not be reinitialized."; EXPECT_EQ(1, fake_decoder_->decode_count_); @@ -103,7 +104,7 @@ TEST_F(VideoDecoderSoftwareFallbackWrapperTest, EncodedImage encoded_image; encoded_image._frameType = kVideoFrameKey; - fallback_wrapper_->Decode(encoded_image, false, -1); + fallback_wrapper_->Decode(encoded_image, false, nullptr, -1); EXPECT_EQ(1, fake_decoder_->init_decode_count_) << "Should not have attempted reinitializing the fallback decoder on " "keyframe."; @@ -119,12 +120,12 @@ TEST_F(VideoDecoderSoftwareFallbackWrapperTest, IsSoftwareFallbackSticky) { fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE; EncodedImage encoded_image; - fallback_wrapper_->Decode(encoded_image, false, -1); + fallback_wrapper_->Decode(encoded_image, false, nullptr, -1); EXPECT_EQ(1, fake_decoder_->decode_count_); // Software fallback should be sticky, fake_decoder_ shouldn't be used. encoded_image._frameType = kVideoFrameKey; - fallback_wrapper_->Decode(encoded_image, false, -1); + fallback_wrapper_->Decode(encoded_image, false, nullptr, -1); EXPECT_EQ(1, fake_decoder_->decode_count_) << "Decoder shouldn't be used after failure."; @@ -138,10 +139,10 @@ TEST_F(VideoDecoderSoftwareFallbackWrapperTest, DoesNotFallbackOnEveryError) { fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_ERROR; EncodedImage encoded_image; EXPECT_EQ(fake_decoder_->decode_return_code_, - fallback_wrapper_->Decode(encoded_image, false, -1)); + fallback_wrapper_->Decode(encoded_image, false, nullptr, -1)); EXPECT_EQ(1, fake_decoder_->decode_count_); - fallback_wrapper_->Decode(encoded_image, false, -1); + fallback_wrapper_->Decode(encoded_image, false, nullptr, -1); EXPECT_EQ(2, fake_decoder_->decode_count_) << "Decoder should be active even though previous decode failed."; } @@ -152,14 +153,14 @@ TEST_F(VideoDecoderSoftwareFallbackWrapperTest, UsesHwDecoderAfterReinit) { fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE; EncodedImage encoded_image; - fallback_wrapper_->Decode(encoded_image, false, -1); + fallback_wrapper_->Decode(encoded_image, false, nullptr, -1); EXPECT_EQ(1, fake_decoder_->decode_count_); fallback_wrapper_->Release(); fallback_wrapper_->InitDecode(&codec, 2); fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_OK; - fallback_wrapper_->Decode(encoded_image, false, -1); + fallback_wrapper_->Decode(encoded_image, false, nullptr, -1); EXPECT_EQ(2, fake_decoder_->decode_count_) << "Should not be using fallback after reinit."; } @@ -173,7 +174,7 @@ TEST_F(VideoDecoderSoftwareFallbackWrapperTest, ForwardsReleaseCall) { fallback_wrapper_->InitDecode(&codec, 2); fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE; EncodedImage encoded_image; - fallback_wrapper_->Decode(encoded_image, false, -1); + fallback_wrapper_->Decode(encoded_image, false, nullptr, -1); EXPECT_EQ(2, fake_decoder_->release_count_) << "Decoder should be released during fallback."; fallback_wrapper_->Release(); @@ -211,7 +212,7 @@ TEST_F(VideoDecoderSoftwareFallbackWrapperTest, fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE; EncodedImage encoded_image; - fallback_wrapper_->Decode(encoded_image, false, -1); + fallback_wrapper_->Decode(encoded_image, false, nullptr, -1); // Hard coded expected value since libvpx is the software implementation name // for VP8. Change accordingly if the underlying implementation does. EXPECT_STREQ("libvpx (fallback from: fake-decoder)", @@ -242,7 +243,7 @@ TEST_F(ForcedSoftwareDecoderFallbackTest, UsesForcedFallback) { EncodedImage encoded_image; encoded_image._frameType = kVideoFrameKey; - fallback_wrapper_->Decode(encoded_image, false, -1); + fallback_wrapper_->Decode(encoded_image, false, nullptr, -1); EXPECT_EQ(1, sw_fallback_decoder_->init_decode_count_); EXPECT_EQ(1, sw_fallback_decoder_->decode_count_); diff --git a/api/video_codecs/video_decoder.cc b/api/video_codecs/video_decoder.cc index 32725b9850..b5fff32e5f 100644 --- a/api/video_codecs/video_decoder.cc +++ b/api/video_codecs/video_decoder.cc @@ -33,19 +33,6 @@ int32_t DecodedImageCallback::ReceivedDecodedFrame(const uint64_t pictureId) { return -1; } -int32_t VideoDecoder::Decode(const EncodedImage& input_image, - bool missing_frames, - int64_t render_time_ms) { - return Decode(input_image, missing_frames, nullptr, render_time_ms); -} - -int32_t VideoDecoder::Decode(const EncodedImage& input_image, - bool missing_frames, - const CodecSpecificInfo* codec_specific_info, - int64_t render_time_ms) { - return Decode(input_image, missing_frames, render_time_ms); -} - bool VideoDecoder::PrefersLateDecoding() const { return true; } diff --git a/api/video_codecs/video_decoder.h b/api/video_codecs/video_decoder.h index 3403987eba..36cf80fe84 100644 --- a/api/video_codecs/video_decoder.h +++ b/api/video_codecs/video_decoder.h @@ -55,16 +55,10 @@ class RTC_EXPORT VideoDecoder { virtual int32_t InitDecode(const VideoCodec* codec_settings, int32_t number_of_cores) = 0; - virtual int32_t Decode(const EncodedImage& input_image, - bool missing_frames, - int64_t render_time_ms); - - // TODO(bugs.webrtc.org/10379): Deprecated. Delete, and make above method pure - // virtual, as soon as downstream applications are updated. virtual int32_t Decode(const EncodedImage& input_image, bool missing_frames, const CodecSpecificInfo* codec_specific_info, - int64_t render_time_ms); + int64_t render_time_ms) = 0; virtual int32_t RegisterDecodeCompleteCallback( DecodedImageCallback* callback) = 0; diff --git a/api/video_codecs/video_decoder_software_fallback_wrapper.cc b/api/video_codecs/video_decoder_software_fallback_wrapper.cc index 9bf1dfd399..0bbce3e640 100644 --- a/api/video_codecs/video_decoder_software_fallback_wrapper.cc +++ b/api/video_codecs/video_decoder_software_fallback_wrapper.cc @@ -40,6 +40,7 @@ class VideoDecoderSoftwareFallbackWrapper final : public VideoDecoder { int32_t Decode(const EncodedImage& input_image, bool missing_frames, + const CodecSpecificInfo* codec_specific_info, int64_t render_time_ms) override; int32_t RegisterDecodeCompleteCallback( @@ -146,6 +147,7 @@ bool VideoDecoderSoftwareFallbackWrapper::InitFallbackDecoder() { int32_t VideoDecoderSoftwareFallbackWrapper::Decode( const EncodedImage& input_image, bool missing_frames, + const CodecSpecificInfo* codec_specific_info, int64_t render_time_ms) { TRACE_EVENT0("webrtc", "VideoDecoderSoftwareFallbackWrapper::Decode"); switch (decoder_type_) { @@ -153,7 +155,8 @@ int32_t VideoDecoderSoftwareFallbackWrapper::Decode( return WEBRTC_VIDEO_CODEC_UNINITIALIZED; case DecoderType::kHardware: { int32_t ret = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE; - ret = hw_decoder_->Decode(input_image, missing_frames, render_time_ms); + ret = hw_decoder_->Decode(input_image, missing_frames, + codec_specific_info, render_time_ms); if (ret != WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE) { return ret; } @@ -169,7 +172,7 @@ int32_t VideoDecoderSoftwareFallbackWrapper::Decode( } case DecoderType::kFallback: return fallback_decoder_->Decode(input_image, missing_frames, - render_time_ms); + codec_specific_info, render_time_ms); default: RTC_NOTREACHED(); return WEBRTC_VIDEO_CODEC_ERROR; diff --git a/media/engine/fake_webrtc_video_engine.cc b/media/engine/fake_webrtc_video_engine.cc index c8be0b0acb..d4de300e0d 100644 --- a/media/engine/fake_webrtc_video_engine.cc +++ b/media/engine/fake_webrtc_video_engine.cc @@ -57,6 +57,7 @@ int32_t FakeWebRtcVideoDecoder::InitDecode(const webrtc::VideoCodec*, int32_t) { int32_t FakeWebRtcVideoDecoder::Decode(const webrtc::EncodedImage&, bool, + const webrtc::CodecSpecificInfo*, int64_t) { num_frames_received_++; return WEBRTC_VIDEO_CODEC_OK; diff --git a/media/engine/fake_webrtc_video_engine.h b/media/engine/fake_webrtc_video_engine.h index dcd723afbb..3ab924aca4 100644 --- a/media/engine/fake_webrtc_video_engine.h +++ b/media/engine/fake_webrtc_video_engine.h @@ -46,6 +46,7 @@ class FakeWebRtcVideoDecoder : public webrtc::VideoDecoder { int32_t InitDecode(const webrtc::VideoCodec*, int32_t) override; int32_t Decode(const webrtc::EncodedImage&, bool, + const webrtc::CodecSpecificInfo*, int64_t) override; int32_t RegisterDecodeCompleteCallback( webrtc::DecodedImageCallback*) override; diff --git a/modules/video_coding/codecs/h264/h264_decoder_impl.cc b/modules/video_coding/codecs/h264/h264_decoder_impl.cc index d72ef06067..e5d31ed34d 100644 --- a/modules/video_coding/codecs/h264/h264_decoder_impl.cc +++ b/modules/video_coding/codecs/h264/h264_decoder_impl.cc @@ -228,6 +228,7 @@ int32_t H264DecoderImpl::RegisterDecodeCompleteCallback( int32_t H264DecoderImpl::Decode(const EncodedImage& input_image, bool /*missing_frames*/, + const CodecSpecificInfo* codec_specific_info, int64_t /*render_time_ms*/) { if (!IsInitialized()) { ReportError(); @@ -244,6 +245,11 @@ int32_t H264DecoderImpl::Decode(const EncodedImage& input_image, ReportError(); return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; } + if (codec_specific_info && + codec_specific_info->codecType != kVideoCodecH264) { + ReportError(); + return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; + } // FFmpeg requires padding due to some optimized bitstream readers reading 32 // or 64 bits at once and could read over the end. See avcodec_decode_video2. diff --git a/modules/video_coding/codecs/h264/h264_decoder_impl.h b/modules/video_coding/codecs/h264/h264_decoder_impl.h index f9325689c6..a709177946 100644 --- a/modules/video_coding/codecs/h264/h264_decoder_impl.h +++ b/modules/video_coding/codecs/h264/h264_decoder_impl.h @@ -49,6 +49,7 @@ class H264DecoderImpl : public H264Decoder { // |missing_frames|, |fragmentation| and |render_time_ms| are ignored. int32_t Decode(const EncodedImage& input_image, bool /*missing_frames*/, + const CodecSpecificInfo* codec_specific_info = nullptr, int64_t render_time_ms = -1) override; const char* ImplementationName() const override; diff --git a/modules/video_coding/codecs/h264/test/h264_impl_unittest.cc b/modules/video_coding/codecs/h264/test/h264_impl_unittest.cc index 12357f593d..57c3a9fbf1 100644 --- a/modules/video_coding/codecs/h264/test/h264_impl_unittest.cc +++ b/modules/video_coding/codecs/h264/test/h264_impl_unittest.cc @@ -71,7 +71,8 @@ TEST_F(TestH264Impl, MAYBE_EncodeDecode) { ASSERT_TRUE(WaitForEncodedFrame(&encoded_frame, &codec_specific_info)); // First frame should be a key frame. encoded_frame._frameType = kVideoFrameKey; - EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, false, 0)); + EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, + decoder_->Decode(encoded_frame, false, nullptr, 0)); std::unique_ptr decoded_frame; absl::optional decoded_qp; ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp)); @@ -97,7 +98,8 @@ TEST_F(TestH264Impl, MAYBE_DecodedQpEqualsEncodedQp) { ASSERT_TRUE(WaitForEncodedFrame(&encoded_frame, &codec_specific_info)); // First frame should be a key frame. encoded_frame._frameType = kVideoFrameKey; - EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, false, 0)); + EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, + decoder_->Decode(encoded_frame, false, nullptr, 0)); std::unique_ptr decoded_frame; absl::optional decoded_qp; ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp)); @@ -138,7 +140,8 @@ TEST_F(TestH264Impl, MAYBE_DecodedColorSpaceEqualsEncodedColorSpace) { // Add color space to encoded frame. ColorSpace color_space = CreateTestColorSpace(/*with_hdr_metadata=*/false); encoded_frame.SetColorSpace(color_space); - EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, false, 0)); + EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, + decoder_->Decode(encoded_frame, false, nullptr, 0)); std::unique_ptr decoded_frame; absl::optional decoded_qp; ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp)); diff --git a/modules/video_coding/codecs/multiplex/include/multiplex_decoder_adapter.h b/modules/video_coding/codecs/multiplex/include/multiplex_decoder_adapter.h index 8976250fc5..73b67c94d8 100644 --- a/modules/video_coding/codecs/multiplex/include/multiplex_decoder_adapter.h +++ b/modules/video_coding/codecs/multiplex/include/multiplex_decoder_adapter.h @@ -35,6 +35,7 @@ class MultiplexDecoderAdapter : public VideoDecoder { int32_t number_of_cores) override; int32_t Decode(const EncodedImage& input_image, bool missing_frames, + const CodecSpecificInfo* codec_specific_info, int64_t render_time_ms) override; int32_t RegisterDecodeCompleteCallback( DecodedImageCallback* callback) override; diff --git a/modules/video_coding/codecs/multiplex/multiplex_decoder_adapter.cc b/modules/video_coding/codecs/multiplex/multiplex_decoder_adapter.cc index d1c8220ce9..0facbe4896 100644 --- a/modules/video_coding/codecs/multiplex/multiplex_decoder_adapter.cc +++ b/modules/video_coding/codecs/multiplex/multiplex_decoder_adapter.cc @@ -130,6 +130,7 @@ int32_t MultiplexDecoderAdapter::InitDecode(const VideoCodec* codec_settings, int32_t MultiplexDecoderAdapter::Decode( const EncodedImage& input_image, bool missing_frames, + const CodecSpecificInfo* codec_specific_info, int64_t render_time_ms) { MultiplexImage image = MultiplexEncodedImagePacker::Unpack(input_image); @@ -153,7 +154,7 @@ int32_t MultiplexDecoderAdapter::Decode( int32_t rv = 0; for (size_t i = 0; i < image.image_components.size(); i++) { rv = decoders_[image.image_components[i].component_index]->Decode( - image.image_components[i].encoded_image, missing_frames, + image.image_components[i].encoded_image, missing_frames, nullptr, render_time_ms); if (rv != WEBRTC_VIDEO_CODEC_OK) return rv; diff --git a/modules/video_coding/codecs/multiplex/test/multiplex_adapter_unittest.cc b/modules/video_coding/codecs/multiplex/test/multiplex_adapter_unittest.cc index 8b4b837f85..3aa7c2883a 100644 --- a/modules/video_coding/codecs/multiplex/test/multiplex_adapter_unittest.cc +++ b/modules/video_coding/codecs/multiplex/test/multiplex_adapter_unittest.cc @@ -225,7 +225,8 @@ TEST_P(TestMultiplexAdapter, EncodeDecodeI420Frame) { ASSERT_TRUE(WaitForEncodedFrame(&encoded_frame, &codec_specific_info)); EXPECT_EQ(kVideoCodecMultiplex, codec_specific_info.codecType); - EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, false, -1)); + EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, + decoder_->Decode(encoded_frame, false, &codec_specific_info, -1)); std::unique_ptr decoded_frame; absl::optional decoded_qp; ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp)); @@ -242,7 +243,8 @@ TEST_P(TestMultiplexAdapter, EncodeDecodeI420AFrame) { ASSERT_TRUE(WaitForEncodedFrame(&encoded_frame, &codec_specific_info)); EXPECT_EQ(kVideoCodecMultiplex, codec_specific_info.codecType); - EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, false, 0)); + EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, + decoder_->Decode(encoded_frame, false, nullptr, 0)); std::unique_ptr decoded_frame; absl::optional decoded_qp; ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp)); diff --git a/modules/video_coding/codecs/test/videoprocessor.cc b/modules/video_coding/codecs/test/videoprocessor.cc index a9dacbe779..7458006cb0 100644 --- a/modules/video_coding/codecs/test/videoprocessor.cc +++ b/modules/video_coding/codecs/test/videoprocessor.cc @@ -529,7 +529,7 @@ void VideoProcessor::DecodeFrame(const EncodedImage& encoded_image, frame_stat->decode_start_ns = rtc::TimeNanos(); frame_stat->decode_return_code = - decoders_->at(spatial_idx)->Decode(encoded_image, false, 0); + decoders_->at(spatial_idx)->Decode(encoded_image, false, nullptr, 0); } const webrtc::EncodedImage* VideoProcessor::BuildAndStoreSuperframe( diff --git a/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.cc b/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.cc index 0b26e8b293..d7258c9c28 100644 --- a/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.cc +++ b/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.cc @@ -153,6 +153,7 @@ int LibvpxVp8Decoder::InitDecode(const VideoCodec* inst, int number_of_cores) { int LibvpxVp8Decoder::Decode(const EncodedImage& input_image, bool missing_frames, + const CodecSpecificInfo* codec_specific_info, int64_t /*render_time_ms*/) { if (!inited_) { return WEBRTC_VIDEO_CODEC_UNINITIALIZED; diff --git a/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.h b/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.h index 2fa9a8f49b..a6ddfefb0b 100644 --- a/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.h +++ b/modules/video_coding/codecs/vp8/libvpx_vp8_decoder.h @@ -34,6 +34,7 @@ class LibvpxVp8Decoder : public VideoDecoder { int Decode(const EncodedImage& input_image, bool missing_frames, + const CodecSpecificInfo* codec_specific_info, int64_t /*render_time_ms*/) override; int RegisterDecodeCompleteCallback(DecodedImageCallback* callback) override; diff --git a/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc b/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc index f2e826b3c9..05e2f05fd5 100644 --- a/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc +++ b/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc @@ -210,7 +210,8 @@ TEST_F(TestVp8Impl, DecodedQpEqualsEncodedQp) { // First frame should be a key frame. encoded_frame._frameType = kVideoFrameKey; - EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, false, -1)); + EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, + decoder_->Decode(encoded_frame, false, nullptr, -1)); std::unique_ptr decoded_frame; absl::optional decoded_qp; ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp)); @@ -229,7 +230,8 @@ TEST_F(TestVp8Impl, DecodedColorSpaceEqualsEncodedColorSpace) { // Encoded frame with explicit color space information. ColorSpace color_space = CreateTestColorSpace(/*with_hdr_metadata=*/false); encoded_frame.SetColorSpace(color_space); - EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, false, -1)); + EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, + decoder_->Decode(encoded_frame, false, nullptr, -1)); std::unique_ptr decoded_frame; absl::optional decoded_qp; ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp)); @@ -323,7 +325,8 @@ TEST_F(TestVp8Impl, MAYBE_AlignedStrideEncodeDecode) { // First frame should be a key frame. encoded_frame._frameType = kVideoFrameKey; encoded_frame.ntp_time_ms_ = kTestNtpTimeMs; - EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, false, -1)); + EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, + decoder_->Decode(encoded_frame, false, nullptr, -1)); std::unique_ptr decoded_frame; absl::optional decoded_qp; @@ -349,15 +352,16 @@ TEST_F(TestVp8Impl, MAYBE_DecodeWithACompleteKeyFrame) { // Setting complete to false -> should return an error. encoded_frame._completeFrame = false; EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR, - decoder_->Decode(encoded_frame, false, -1)); + decoder_->Decode(encoded_frame, false, nullptr, -1)); // Setting complete back to true. Forcing a delta frame. encoded_frame._frameType = kVideoFrameDelta; encoded_frame._completeFrame = true; EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR, - decoder_->Decode(encoded_frame, false, -1)); + decoder_->Decode(encoded_frame, false, nullptr, -1)); // Now setting a key frame. encoded_frame._frameType = kVideoFrameKey; - EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, false, -1)); + EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, + decoder_->Decode(encoded_frame, false, nullptr, -1)); std::unique_ptr decoded_frame; absl::optional decoded_qp; ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp)); diff --git a/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc b/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc index c7ae176351..cd29915b9c 100644 --- a/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc +++ b/modules/video_coding/codecs/vp9/test/vp9_impl_unittest.cc @@ -128,7 +128,8 @@ TEST_F(TestVp9Impl, EncodeDecode) { ASSERT_TRUE(WaitForEncodedFrame(&encoded_frame, &codec_specific_info)); // First frame should be a key frame. encoded_frame._frameType = kVideoFrameKey; - EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, false, 0)); + EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, + decoder_->Decode(encoded_frame, false, nullptr, 0)); std::unique_ptr decoded_frame; absl::optional decoded_qp; ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp)); @@ -197,7 +198,8 @@ TEST_F(TestVp9Impl, DecodedColorSpaceEqualsEncodedColorSpace) { ASSERT_TRUE(WaitForEncodedFrame(&encoded_frame, &codec_specific_info)); // Encoded frame without explicit color space information. - EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, false, 0)); + EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, + decoder_->Decode(encoded_frame, false, nullptr, 0)); std::unique_ptr decoded_frame; absl::optional decoded_qp; ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp)); @@ -210,7 +212,8 @@ TEST_F(TestVp9Impl, DecodedColorSpaceEqualsEncodedColorSpace) { // Encoded frame with explicit color space information. ColorSpace color_space = CreateTestColorSpace(/*with_hdr_metadata=*/true); encoded_frame.SetColorSpace(color_space); - EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, false, 0)); + EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, + decoder_->Decode(encoded_frame, false, nullptr, 0)); ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp)); ASSERT_TRUE(decoded_frame); ASSERT_TRUE(decoded_frame->color_space()); @@ -225,7 +228,8 @@ TEST_F(TestVp9Impl, DecodedQpEqualsEncodedQp) { ASSERT_TRUE(WaitForEncodedFrame(&encoded_frame, &codec_specific_info)); // First frame should be a key frame. encoded_frame._frameType = kVideoFrameKey; - EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, false, 0)); + EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, + decoder_->Decode(encoded_frame, false, nullptr, 0)); std::unique_ptr decoded_frame; absl::optional decoded_qp; ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp)); @@ -1427,7 +1431,8 @@ TEST_F(TestVp9ImplProfile2, EncodeDecode) { ASSERT_TRUE(WaitForEncodedFrame(&encoded_frame, &codec_specific_info)); // First frame should be a key frame. encoded_frame._frameType = kVideoFrameKey; - EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Decode(encoded_frame, false, 0)); + EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, + decoder_->Decode(encoded_frame, false, nullptr, 0)); std::unique_ptr decoded_frame; absl::optional decoded_qp; ASSERT_TRUE(WaitForDecodedFrame(&decoded_frame, &decoded_qp)); diff --git a/modules/video_coding/codecs/vp9/vp9_impl.cc b/modules/video_coding/codecs/vp9/vp9_impl.cc index 4b0461a3f4..e39e9bbbe1 100644 --- a/modules/video_coding/codecs/vp9/vp9_impl.cc +++ b/modules/video_coding/codecs/vp9/vp9_impl.cc @@ -1507,6 +1507,7 @@ int VP9DecoderImpl::InitDecode(const VideoCodec* inst, int number_of_cores) { int VP9DecoderImpl::Decode(const EncodedImage& input_image, bool missing_frames, + const CodecSpecificInfo* codec_specific_info, int64_t /*render_time_ms*/) { if (!inited_) { return WEBRTC_VIDEO_CODEC_UNINITIALIZED; diff --git a/modules/video_coding/codecs/vp9/vp9_impl.h b/modules/video_coding/codecs/vp9/vp9_impl.h index 7ca4b55ee0..3fc5398c53 100644 --- a/modules/video_coding/codecs/vp9/vp9_impl.h +++ b/modules/video_coding/codecs/vp9/vp9_impl.h @@ -184,6 +184,7 @@ class VP9DecoderImpl : public VP9Decoder { int Decode(const EncodedImage& input_image, bool missing_frames, + const CodecSpecificInfo* codec_specific_info, int64_t /*render_time_ms*/) override; int RegisterDecodeCompleteCallback(DecodedImageCallback* callback) override; diff --git a/modules/video_coding/generic_decoder.cc b/modules/video_coding/generic_decoder.cc index f6f23da284..6ef4c361be 100644 --- a/modules/video_coding/generic_decoder.cc +++ b/modules/video_coding/generic_decoder.cc @@ -230,7 +230,7 @@ int32_t VCMGenericDecoder::Decode(const VCMEncodedFrame& frame, int64_t nowMs) { _nextFrameInfoIdx = (_nextFrameInfoIdx + 1) % kDecoderFrameMemoryLength; int32_t ret = decoder_->Decode(frame.EncodedImage(), frame.MissingFrame(), - frame.RenderTimeMs()); + frame.CodecSpecific(), frame.RenderTimeMs()); _callback->OnDecoderImplementationName(decoder_->ImplementationName()); if (ret < WEBRTC_VIDEO_CODEC_OK) { diff --git a/modules/video_coding/utility/simulcast_test_fixture_impl.cc b/modules/video_coding/utility/simulcast_test_fixture_impl.cc index 12220bcb82..edef45d17a 100644 --- a/modules/video_coding/utility/simulcast_test_fixture_impl.cc +++ b/modules/video_coding/utility/simulcast_test_fixture_impl.cc @@ -832,9 +832,9 @@ void SimulcastTestFixtureImpl::TestStrideEncodeDecode() { EncodedImage encoded_frame; // Only encoding one frame - so will be a key frame. encoder_callback.GetLastEncodedKeyFrame(&encoded_frame); - EXPECT_EQ(0, decoder_->Decode(encoded_frame, false, 0)); + EXPECT_EQ(0, decoder_->Decode(encoded_frame, false, NULL, 0)); encoder_callback.GetLastEncodedFrame(&encoded_frame); - decoder_->Decode(encoded_frame, false, 0); + decoder_->Decode(encoded_frame, false, NULL, 0); EXPECT_EQ(2, decoder_callback.DecodedFrames()); } @@ -875,7 +875,7 @@ void SimulcastTestFixtureImpl::TestDecodeWidthHeightSet() { EXPECT_EQ(decodedImage.width(), kDefaultWidth / 4); EXPECT_EQ(decodedImage.height(), kDefaultHeight / 4); })); - EXPECT_EQ(0, decoder_->Decode(encoded_frame[0], false, 0)); + EXPECT_EQ(0, decoder_->Decode(encoded_frame[0], false, NULL, 0)); EXPECT_CALL(decoder_callback, Decoded(_, _, _)) .WillOnce(testing::Invoke([](VideoFrame& decodedImage, @@ -884,7 +884,7 @@ void SimulcastTestFixtureImpl::TestDecodeWidthHeightSet() { EXPECT_EQ(decodedImage.width(), kDefaultWidth / 2); EXPECT_EQ(decodedImage.height(), kDefaultHeight / 2); })); - EXPECT_EQ(0, decoder_->Decode(encoded_frame[1], false, 0)); + EXPECT_EQ(0, decoder_->Decode(encoded_frame[1], false, NULL, 0)); EXPECT_CALL(decoder_callback, Decoded(_, _, _)) .WillOnce(testing::Invoke([](VideoFrame& decodedImage, @@ -893,7 +893,7 @@ void SimulcastTestFixtureImpl::TestDecodeWidthHeightSet() { EXPECT_EQ(decodedImage.width(), kDefaultWidth); EXPECT_EQ(decodedImage.height(), kDefaultHeight); })); - EXPECT_EQ(0, decoder_->Decode(encoded_frame[2], false, 0)); + EXPECT_EQ(0, decoder_->Decode(encoded_frame[2], false, NULL, 0)); } } // namespace test diff --git a/modules/video_coding/video_receiver_unittest.cc b/modules/video_coding/video_receiver_unittest.cc index 2cf6c36adf..0d26fc515d 100644 --- a/modules/video_coding/video_receiver_unittest.cc +++ b/modules/video_coding/video_receiver_unittest.cc @@ -75,7 +75,7 @@ class TestVideoReceiver : public ::testing::Test { ++header->header.sequenceNumber; } receiver_.Process(); - EXPECT_CALL(decoder_, Decode(_, _, _)).Times(0); + EXPECT_CALL(decoder_, Decode(_, _, _, _)).Times(0); EXPECT_EQ(VCM_FRAME_NOT_READY, receiver_.Decode(kMaxWaitTimeMs)); } @@ -87,7 +87,7 @@ class TestVideoReceiver : public ::testing::Test { EXPECT_CALL(packet_request_callback_, ResendPackets(_, _)).Times(0); receiver_.Process(); - EXPECT_CALL(decoder_, Decode(_, _, _)).Times(1); + EXPECT_CALL(decoder_, Decode(_, _, _, _)).Times(1); EXPECT_EQ(0, receiver_.Decode(kMaxWaitTimeMs)); } diff --git a/sdk/objc/unittests/objc_video_decoder_factory_tests.mm b/sdk/objc/unittests/objc_video_decoder_factory_tests.mm index 312e78ef60..9d2d4848c0 100644 --- a/sdk/objc/unittests/objc_video_decoder_factory_tests.mm +++ b/sdk/objc/unittests/objc_video_decoder_factory_tests.mm @@ -71,16 +71,20 @@ TEST(ObjCVideoDecoderFactoryTest, DecodeReturnsOKOnSuccess) { std::unique_ptr decoder = GetObjCDecoder(CreateOKDecoderFactory()); webrtc::EncodedImage encoded_image; + webrtc::CodecSpecificInfo info; + info.codecType = webrtc::kVideoCodecH264; - EXPECT_EQ(decoder->Decode(encoded_image, false, 0), WEBRTC_VIDEO_CODEC_OK); + EXPECT_EQ(decoder->Decode(encoded_image, false, &info, 0), WEBRTC_VIDEO_CODEC_OK); } TEST(ObjCVideoDecoderFactoryTest, DecodeReturnsErrorOnFail) { std::unique_ptr decoder = GetObjCDecoder(CreateErrorDecoderFactory()); webrtc::EncodedImage encoded_image; + webrtc::CodecSpecificInfo info; + info.codecType = webrtc::kVideoCodecH264; - EXPECT_EQ(decoder->Decode(encoded_image, false, 0), WEBRTC_VIDEO_CODEC_ERROR); + EXPECT_EQ(decoder->Decode(encoded_image, false, &info, 0), WEBRTC_VIDEO_CODEC_ERROR); } TEST(ObjCVideoDecoderFactoryTest, ReleaseDecodeReturnsOKOnSuccess) { diff --git a/test/fake_decoder.cc b/test/fake_decoder.cc index 10ac8512cc..70fe085335 100644 --- a/test/fake_decoder.cc +++ b/test/fake_decoder.cc @@ -39,6 +39,7 @@ int32_t FakeDecoder::InitDecode(const VideoCodec* config, int32_t FakeDecoder::Decode(const EncodedImage& input, bool missing_frames, + const CodecSpecificInfo* codec_specific_info, int64_t render_time_ms) { if (input._encodedWidth > 0 && input._encodedHeight > 0) { width_ = input._encodedWidth; @@ -76,6 +77,7 @@ const char* FakeDecoder::ImplementationName() const { int32_t FakeH264Decoder::Decode(const EncodedImage& input, bool missing_frames, + const CodecSpecificInfo* codec_specific_info, int64_t render_time_ms) { uint8_t value = 0; for (size_t i = 0; i < input.size(); ++i) { @@ -91,7 +93,8 @@ int32_t FakeH264Decoder::Decode(const EncodedImage& input, } ++value; } - return FakeDecoder::Decode(input, missing_frames, render_time_ms); + return FakeDecoder::Decode(input, missing_frames, codec_specific_info, + render_time_ms); } } // namespace test diff --git a/test/fake_decoder.h b/test/fake_decoder.h index 8fe7427377..1176feb46c 100644 --- a/test/fake_decoder.h +++ b/test/fake_decoder.h @@ -31,6 +31,7 @@ class FakeDecoder : public VideoDecoder { int32_t Decode(const EncodedImage& input, bool missing_frames, + const CodecSpecificInfo* codec_specific_info, int64_t render_time_ms) override; int32_t RegisterDecodeCompleteCallback( @@ -54,6 +55,7 @@ class FakeH264Decoder : public FakeDecoder { int32_t Decode(const EncodedImage& input, bool missing_frames, + const CodecSpecificInfo* codec_specific_info, int64_t render_time_ms) override; }; diff --git a/test/fake_vp8_decoder.cc b/test/fake_vp8_decoder.cc index faaa554259..7a244ca09d 100644 --- a/test/fake_vp8_decoder.cc +++ b/test/fake_vp8_decoder.cc @@ -46,6 +46,7 @@ int32_t FakeVp8Decoder::InitDecode(const VideoCodec* config, int32_t FakeVp8Decoder::Decode(const EncodedImage& input, bool missing_frames, + const CodecSpecificInfo* codec_specific_info, int64_t render_time_ms) { constexpr size_t kMinPayLoadHeaderLength = 10; if (input.size() < kMinPayLoadHeaderLength) { diff --git a/test/fake_vp8_decoder.h b/test/fake_vp8_decoder.h index 4f0fa3d8a9..36ff3b36d2 100644 --- a/test/fake_vp8_decoder.h +++ b/test/fake_vp8_decoder.h @@ -31,6 +31,7 @@ class FakeVp8Decoder : public VideoDecoder { int32_t Decode(const EncodedImage& input, bool missing_frames, + const CodecSpecificInfo* codec_specific_info, int64_t render_time_ms) override; int32_t RegisterDecodeCompleteCallback( diff --git a/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.cc b/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.cc index 829418944d..e9161437ba 100644 --- a/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.cc +++ b/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.cc @@ -53,6 +53,7 @@ int32_t QualityAnalyzingVideoDecoder::InitDecode( int32_t QualityAnalyzingVideoDecoder::Decode( const EncodedImage& input_image, bool missing_frames, + const CodecSpecificInfo* codec_specific_info, int64_t render_time_ms) { // Image extractor extracts id from provided EncodedImage and also returns // the image with the original buffer. Buffer can be modified in place, so @@ -94,8 +95,8 @@ int32_t QualityAnalyzingVideoDecoder::Decode( // the map only after |delegate_| Decode method will be invoked. Image will be // removed inside DecodedImageCallback, which can be done on separate thread. analyzer_->OnFrameReceived(out.id, *origin_image); - int32_t result = - delegate_->Decode(*origin_image, missing_frames, render_time_ms); + int32_t result = delegate_->Decode(*origin_image, missing_frames, + codec_specific_info, render_time_ms); if (result != WEBRTC_VIDEO_CODEC_OK) { // If delegate decoder failed, then cleanup data for this image. { diff --git a/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.h b/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.h index c1ebcaa688..a32393774e 100644 --- a/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.h +++ b/test/pc/e2e/analyzer/video/quality_analyzing_video_decoder.h @@ -63,6 +63,7 @@ class QualityAnalyzingVideoDecoder : public VideoDecoder { int32_t number_of_cores) override; int32_t Decode(const EncodedImage& input_image, bool missing_frames, + const CodecSpecificInfo* codec_specific_info, int64_t render_time_ms) override; int32_t RegisterDecodeCompleteCallback( DecodedImageCallback* callback) override; diff --git a/test/video_decoder_proxy_factory.h b/test/video_decoder_proxy_factory.h index b58c399a86..250750cb11 100644 --- a/test/video_decoder_proxy_factory.h +++ b/test/video_decoder_proxy_factory.h @@ -50,8 +50,10 @@ class VideoDecoderProxyFactory final : public VideoDecoderFactory { private: int32_t Decode(const EncodedImage& input_image, bool missing_frames, + const CodecSpecificInfo* codec_specific_info, int64_t render_time_ms) override { - return decoder_->Decode(input_image, missing_frames, render_time_ms); + return decoder_->Decode(input_image, missing_frames, codec_specific_info, + render_time_ms); } int32_t InitDecode(const VideoCodec* config, int32_t number_of_cores) override { diff --git a/video/frame_dumping_decoder.cc b/video/frame_dumping_decoder.cc index 09cf3e9d75..f42edce9fc 100644 --- a/video/frame_dumping_decoder.cc +++ b/video/frame_dumping_decoder.cc @@ -26,16 +26,17 @@ FrameDumpingDecoder::~FrameDumpingDecoder() = default; int32_t FrameDumpingDecoder::InitDecode(const VideoCodec* codec_settings, int32_t number_of_cores) { - codec_type_ = codec_settings->codecType; return decoder_->InitDecode(codec_settings, number_of_cores); } int32_t FrameDumpingDecoder::Decode( const EncodedImage& input_image, bool missing_frames, + const CodecSpecificInfo* codec_specific_info, int64_t render_time_ms) { - int32_t ret = decoder_->Decode(input_image, missing_frames, render_time_ms); - writer_->WriteFrame(input_image, codec_type_); + int32_t ret = decoder_->Decode(input_image, missing_frames, + codec_specific_info, render_time_ms); + writer_->WriteFrame(input_image, codec_specific_info->codecType); return ret; } diff --git a/video/frame_dumping_decoder.h b/video/frame_dumping_decoder.h index 5bb22717dd..9f3ed89147 100644 --- a/video/frame_dumping_decoder.h +++ b/video/frame_dumping_decoder.h @@ -32,6 +32,7 @@ class FrameDumpingDecoder : public VideoDecoder { int32_t number_of_cores) override; int32_t Decode(const EncodedImage& input_image, bool missing_frames, + const CodecSpecificInfo* codec_specific_info, int64_t render_time_ms) override; int32_t RegisterDecodeCompleteCallback( DecodedImageCallback* callback) override; @@ -41,7 +42,6 @@ class FrameDumpingDecoder : public VideoDecoder { private: std::unique_ptr decoder_; - VideoCodecType codec_type_ = VideoCodecType::kVideoCodecGeneric; std::unique_ptr writer_; }; diff --git a/video/video_receive_stream.cc b/video/video_receive_stream.cc index 6c158dd43f..904e0a509d 100644 --- a/video/video_receive_stream.cc +++ b/video/video_receive_stream.cc @@ -102,6 +102,7 @@ class NullVideoDecoder : public webrtc::VideoDecoder { int32_t Decode(const webrtc::EncodedImage& input_image, bool missing_frames, + const webrtc::CodecSpecificInfo* codec_specific_info, int64_t render_time_ms) override { RTC_LOG(LS_ERROR) << "The NullVideoDecoder doesn't support decoding."; return WEBRTC_VIDEO_CODEC_OK; diff --git a/video/video_receive_stream_unittest.cc b/video/video_receive_stream_unittest.cc index 84b0302373..642143a967 100644 --- a/video/video_receive_stream_unittest.cc +++ b/video/video_receive_stream_unittest.cc @@ -50,9 +50,10 @@ class MockVideoDecoder : public VideoDecoder { public: MOCK_METHOD2(InitDecode, int32_t(const VideoCodec* config, int32_t number_of_cores)); - MOCK_METHOD3(Decode, + MOCK_METHOD4(Decode, int32_t(const EncodedImage& input, bool missing_frames, + const CodecSpecificInfo* codec_specific_info, int64_t render_time_ms)); MOCK_METHOD1(RegisterDecodeCompleteCallback, int32_t(DecodedImageCallback* callback)); @@ -140,7 +141,7 @@ TEST_F(VideoReceiveStreamTest, CreateFrameFromH264FmtpSpropAndIdr) { })); EXPECT_CALL(mock_h264_video_decoder_, RegisterDecodeCompleteCallback(_)); video_receive_stream_->Start(); - EXPECT_CALL(mock_h264_video_decoder_, Decode(_, false, _)); + EXPECT_CALL(mock_h264_video_decoder_, Decode(_, false, _, _)); RtpPacketReceived parsed_packet; ASSERT_TRUE(parsed_packet.Parse(rtppacket.data(), rtppacket.size())); rtp_stream_receiver_controller_.OnRtpPacket(parsed_packet);