diff --git a/talk/app/webrtc/java/jni/androidmediadecoder_jni.cc b/talk/app/webrtc/java/jni/androidmediadecoder_jni.cc index fa111968f6..fbe5b5ca78 100644 --- a/talk/app/webrtc/java/jni/androidmediadecoder_jni.cc +++ b/talk/app/webrtc/java/jni/androidmediadecoder_jni.cc @@ -89,6 +89,9 @@ class MediaCodecVideoDecoder : public webrtc::VideoDecoder, int32_t Release() override; int32_t Reset() override; + + bool PrefersLateDecoding() const override { return true; } + // rtc::MessageHandler implementation. void OnMessage(rtc::Message* msg) override; diff --git a/webrtc/modules/video_coding/codec_database.cc b/webrtc/modules/video_coding/codec_database.cc index be7f5ca376..20a1143272 100644 --- a/webrtc/modules/video_coding/codec_database.cc +++ b/webrtc/modules/video_coding/codec_database.cc @@ -85,12 +85,9 @@ VCMDecoderMapItem::VCMDecoderMapItem(VideoCodec* settings, VCMExtDecoderMapItem::VCMExtDecoderMapItem( VideoDecoder* external_decoder_instance, - uint8_t payload_type, - bool internal_render_timing) + uint8_t payload_type) : payload_type(payload_type), - external_decoder_instance(external_decoder_instance), - internal_render_timing(internal_render_timing) { -} + external_decoder_instance(external_decoder_instance) {} VCMCodecDataBase::VCMCodecDataBase( VideoEncoderRateObserver* encoder_rate_observer, @@ -419,13 +416,11 @@ bool VCMCodecDataBase::DeregisterExternalDecoder(uint8_t payload_type) { // Add the external encoder object to the list of external decoders. // Won't be registered as a receive codec until RegisterReceiveCodec is called. -void VCMCodecDataBase::RegisterExternalDecoder( - VideoDecoder* external_decoder, - uint8_t payload_type, - bool internal_render_timing) { +void VCMCodecDataBase::RegisterExternalDecoder(VideoDecoder* external_decoder, + uint8_t payload_type) { // Check if payload value already exists, if so - erase old and insert new. - VCMExtDecoderMapItem* ext_decoder = new VCMExtDecoderMapItem( - external_decoder, payload_type, internal_render_timing); + VCMExtDecoderMapItem* ext_decoder = + new VCMExtDecoderMapItem(external_decoder, payload_type); DeregisterExternalDecoder(payload_type); dec_external_map_[payload_type] = ext_decoder; } @@ -524,12 +519,10 @@ void VCMCodecDataBase::ReleaseDecoder(VCMGenericDecoder* decoder) const { } } -bool VCMCodecDataBase::SupportsRenderScheduling() const { - const VCMExtDecoderMapItem* ext_item = FindExternalDecoderItem( - receive_codec_.plType); - if (!ext_item) +bool VCMCodecDataBase::PrefersLateDecoding() const { + if (!ptr_decoder_) return true; - return ext_item->internal_render_timing; + return ptr_decoder_->PrefersLateDecoding(); } bool VCMCodecDataBase::MatchesCurrentResolution(int width, int height) const { diff --git a/webrtc/modules/video_coding/codec_database.h b/webrtc/modules/video_coding/codec_database.h index c39474f6a2..62ec30a46e 100644 --- a/webrtc/modules/video_coding/codec_database.h +++ b/webrtc/modules/video_coding/codec_database.h @@ -36,12 +36,10 @@ struct VCMDecoderMapItem { struct VCMExtDecoderMapItem { public: VCMExtDecoderMapItem(VideoDecoder* external_decoder_instance, - uint8_t payload_type, - bool internal_render_timing); + uint8_t payload_type); uint8_t payload_type; VideoDecoder* external_decoder_instance; - bool internal_render_timing; }; class VCMCodecDataBase { @@ -90,12 +88,8 @@ class VCMCodecDataBase { bool DeregisterExternalDecoder(uint8_t payload_type); // Registers an external decoder object to the payload type |payload_type|. - // |internal_render_timing| is set to true if the |external_decoder| has - // built in rendering which is able to obey the render timestamps of the - // encoded frames. void RegisterExternalDecoder(VideoDecoder* external_decoder, - uint8_t payload_type, - bool internal_render_timing); + uint8_t payload_type); bool DecoderRegistered() const; @@ -124,10 +118,9 @@ class VCMCodecDataBase { // deep copies returned by CreateDecoderCopy(). void ReleaseDecoder(VCMGenericDecoder* decoder) const; - // Returns true if the currently active decoder supports render scheduling, - // that is, it is able to render frames according to the render timestamp of - // the encoded frames. - bool SupportsRenderScheduling() const; + // Returns true if the currently active decoder prefer to decode frames late. + // That means that frames must be decoded near the render times stamp. + bool PrefersLateDecoding() const; bool MatchesCurrentResolution(int width, int height) const; diff --git a/webrtc/modules/video_coding/generic_decoder.cc b/webrtc/modules/video_coding/generic_decoder.cc index 08282f9e6c..dc78ec21f2 100644 --- a/webrtc/modules/video_coding/generic_decoder.cc +++ b/webrtc/modules/video_coding/generic_decoder.cc @@ -198,4 +198,8 @@ bool VCMGenericDecoder::External() const { return _isExternal; } +bool VCMGenericDecoder::PrefersLateDecoding() const { + return _decoder->PrefersLateDecoding(); +} + } // namespace diff --git a/webrtc/modules/video_coding/generic_decoder.h b/webrtc/modules/video_coding/generic_decoder.h index c633519853..40a9845c94 100644 --- a/webrtc/modules/video_coding/generic_decoder.h +++ b/webrtc/modules/video_coding/generic_decoder.h @@ -97,6 +97,7 @@ public: int32_t RegisterDecodeCompleteCallback(VCMDecodedFrameCallback* callback); bool External() const; + bool PrefersLateDecoding() const; private: VCMDecodedFrameCallback* _callback; diff --git a/webrtc/modules/video_coding/include/video_coding.h b/webrtc/modules/video_coding/include/video_coding.h index 5f5961c71e..880180d5b9 100644 --- a/webrtc/modules/video_coding/include/video_coding.h +++ b/webrtc/modules/video_coding/include/video_coding.h @@ -333,11 +333,9 @@ public: // - externalDecoder : The external decoder/renderer object. // - payloadType : The payload type which this decoder should be // registered to. - // - internalRenderTiming : True if the internal renderer (if any) of the decoder - // object can make sure to render at a given time in ms. + // virtual void RegisterExternalDecoder(VideoDecoder* externalDecoder, - uint8_t payloadType, - bool internalRenderTiming) = 0; + uint8_t payloadType) = 0; // Register a receive callback. Will be called whenever there is a new frame ready // for rendering. diff --git a/webrtc/modules/video_coding/receiver.cc b/webrtc/modules/video_coding/receiver.cc index 5314b30767..fe05b86825 100644 --- a/webrtc/modules/video_coding/receiver.cc +++ b/webrtc/modules/video_coding/receiver.cc @@ -96,7 +96,7 @@ void VCMReceiver::TriggerDecoderShutdown() { VCMEncodedFrame* VCMReceiver::FrameForDecoding(uint16_t max_wait_time_ms, int64_t& next_render_time_ms, - bool render_timing) { + bool prefer_late_decoding) { const int64_t start_time_ms = clock_->TimeInMilliseconds(); uint32_t frame_timestamp = 0; // Exhaust wait time to get a complete frame for decoding. @@ -140,7 +140,7 @@ VCMEncodedFrame* VCMReceiver::FrameForDecoding(uint16_t max_wait_time_ms, return NULL; } - if (!render_timing) { + if (prefer_late_decoding) { // Decode frame as close as possible to the render timestamp. const int32_t available_wait_time = max_wait_time_ms - static_cast(clock_->TimeInMilliseconds() - start_time_ms); diff --git a/webrtc/modules/video_coding/receiver.h b/webrtc/modules/video_coding/receiver.h index bc2e026fef..a30d16c8c6 100644 --- a/webrtc/modules/video_coding/receiver.h +++ b/webrtc/modules/video_coding/receiver.h @@ -47,7 +47,7 @@ class VCMReceiver { uint16_t frame_height); VCMEncodedFrame* FrameForDecoding(uint16_t max_wait_time_ms, int64_t& next_render_time_ms, - bool render_timing = true); + bool prefer_late_decoding); void ReleaseFrame(VCMEncodedFrame* frame); void ReceiveStatistics(uint32_t* bitrate, uint32_t* framerate); uint32_t DiscardedPackets() const; diff --git a/webrtc/modules/video_coding/receiver_unittest.cc b/webrtc/modules/video_coding/receiver_unittest.cc index 82345c8d59..d51b004a9b 100644 --- a/webrtc/modules/video_coding/receiver_unittest.cc +++ b/webrtc/modules/video_coding/receiver_unittest.cc @@ -14,6 +14,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "webrtc/base/checks.h" +#include "webrtc/modules/video_coding/encoded_frame.h" #include "webrtc/modules/video_coding/packet.h" #include "webrtc/modules/video_coding/receiver.h" #include "webrtc/modules/video_coding/test/stream_generator.h" @@ -141,7 +142,8 @@ TEST_F(TestVCMReceiver, RenderBufferSize_NoKeyFrame) { EXPECT_GE(InsertFrame(kVideoFrameDelta, true), kNoError); } int64_t next_render_time_ms = 0; - VCMEncodedFrame* frame = receiver_.FrameForDecoding(10, next_render_time_ms); + VCMEncodedFrame* frame = + receiver_.FrameForDecoding(10, next_render_time_ms, false); EXPECT_TRUE(frame == NULL); receiver_.ReleaseFrame(frame); EXPECT_GE(InsertFrame(kVideoFrameDelta, false), kNoError); @@ -523,4 +525,60 @@ TEST_F(VCMReceiverTimingTest, FrameForDecoding) { } } +// Test whether VCMReceiver::FrameForDecoding handles parameter +// |prefer_late_decoding| and |max_wait_time_ms| correctly: +// 1. The function execution should never take more than |max_wait_time_ms|. +// 2. If the function exit before now + |max_wait_time_ms|, a frame must be +// returned and the end time must be equal to the render timestamp - delay +// for decoding and rendering. +TEST_F(VCMReceiverTimingTest, FrameForDecodingPreferLateDecoding) { + const size_t kNumFrames = 100; + const int kFramePeriod = 40; + + int64_t arrive_timestamps[kNumFrames]; + int64_t render_timestamps[kNumFrames]; + int64_t next_render_time; + + int render_delay_ms; + int max_decode_ms; + int dummy; + timing_.GetTimings(&dummy, &max_decode_ms, &dummy, &dummy, &dummy, &dummy, + &render_delay_ms); + + // Construct test samples. + // render_timestamps are the timestamps stored in the Frame; + // arrive_timestamps controls when the Frame packet got received. + for (size_t i = 0; i < kNumFrames; i++) { + // Preset frame rate to 25Hz. + // But we add a reasonable deviation to arrive_timestamps to mimic Internet + // fluctuation. + arrive_timestamps[i] = + (i + 1) * kFramePeriod + (i % 10) * ((i % 2) ? 1 : -1); + render_timestamps[i] = (i + 1) * kFramePeriod; + } + + clock_.SetFrames(arrive_timestamps, render_timestamps, kNumFrames); + + // Record how many frames we finally get out of the receiver. + size_t num_frames_return = 0; + const int64_t kMaxWaitTime = 30; + bool prefer_late_decoding = true; + while (num_frames_return < kNumFrames) { + int64_t start_time = clock_.TimeInMilliseconds(); + + VCMEncodedFrame* frame = + receiver_.FrameForDecoding(kMaxWaitTime, next_render_time, + prefer_late_decoding); + int64_t end_time = clock_.TimeInMilliseconds(); + if (frame) { + EXPECT_EQ(frame->RenderTimeMs() - max_decode_ms - render_delay_ms, + end_time); + receiver_.ReleaseFrame(frame); + ++num_frames_return; + } else { + EXPECT_EQ(kMaxWaitTime, end_time - start_time); + } + } +} + } // namespace webrtc diff --git a/webrtc/modules/video_coding/video_coding_impl.cc b/webrtc/modules/video_coding/video_coding_impl.cc index c9ed6f4461..64cc090a70 100644 --- a/webrtc/modules/video_coding/video_coding_impl.cc +++ b/webrtc/modules/video_coding/video_coding_impl.cc @@ -197,10 +197,8 @@ class VideoCodingModuleImpl : public VideoCodingModule { } void RegisterExternalDecoder(VideoDecoder* externalDecoder, - uint8_t payloadType, - bool internalRenderTiming) override { - receiver_.RegisterExternalDecoder(externalDecoder, payloadType, - internalRenderTiming); + uint8_t payloadType) override { + receiver_.RegisterExternalDecoder(externalDecoder, payloadType); } int32_t RegisterReceiveCallback( diff --git a/webrtc/modules/video_coding/video_coding_impl.h b/webrtc/modules/video_coding/video_coding_impl.h index cfa0f92b73..2134e4d533 100644 --- a/webrtc/modules/video_coding/video_coding_impl.h +++ b/webrtc/modules/video_coding/video_coding_impl.h @@ -151,8 +151,7 @@ class VideoReceiver { bool requireKeyFrame); void RegisterExternalDecoder(VideoDecoder* externalDecoder, - uint8_t payloadType, - bool internalRenderTiming); + uint8_t payloadType); int32_t RegisterReceiveCallback(VCMReceiveCallback* receiveCallback); int32_t RegisterReceiveStatisticsCallback( VCMReceiveStatisticsCallback* receiveStats); diff --git a/webrtc/modules/video_coding/video_coding_robustness_unittest.cc b/webrtc/modules/video_coding/video_coding_robustness_unittest.cc index d5a179dccb..4111109e60 100644 --- a/webrtc/modules/video_coding/video_coding_robustness_unittest.cc +++ b/webrtc/modules/video_coding/video_coding_robustness_unittest.cc @@ -44,7 +44,7 @@ class VCMRobustnessTest : public ::testing::Test { ASSERT_EQ(0, vcm_->RegisterPacketRequestCallback(&request_callback_)); ASSERT_EQ(VCM_OK, vcm_->Codec(kVideoCodecVP8, &video_codec_)); ASSERT_EQ(VCM_OK, vcm_->RegisterReceiveCodec(&video_codec_, 1)); - vcm_->RegisterExternalDecoder(&decoder_, video_codec_.plType, true); + vcm_->RegisterExternalDecoder(&decoder_, video_codec_.plType); } virtual void TearDown() { @@ -204,7 +204,7 @@ TEST_F(VCMRobustnessTest, TestModeNoneWithErrors) { InsertPacket(0, 0, true, false, kVideoFrameKey); InsertPacket(0, 1, false, false, kVideoFrameKey); InsertPacket(0, 2, false, true, kVideoFrameKey); - EXPECT_EQ(VCM_OK, vcm_->Decode(0)); // Decode timestamp 0. + EXPECT_EQ(VCM_OK, vcm_->Decode(33)); // Decode timestamp 0. EXPECT_EQ(VCM_OK, vcm_->Process()); // Expect no NACK list. clock_->AdvanceTimeMilliseconds(33); @@ -222,7 +222,7 @@ TEST_F(VCMRobustnessTest, TestModeNoneWithErrors) { EXPECT_EQ(VCM_OK, vcm_->Process()); // Expect no NACK list. clock_->AdvanceTimeMilliseconds(10); - EXPECT_EQ(VCM_OK, vcm_->Decode(0)); // Decode timestamp 6000 complete. + EXPECT_EQ(VCM_OK, vcm_->Decode(23)); // Decode timestamp 6000 complete. EXPECT_EQ(VCM_OK, vcm_->Process()); // Expect no NACK list. clock_->AdvanceTimeMilliseconds(23); @@ -231,6 +231,6 @@ TEST_F(VCMRobustnessTest, TestModeNoneWithErrors) { InsertPacket(9000, 9, true, false, kVideoFrameDelta); InsertPacket(9000, 10, false, false, kVideoFrameDelta); InsertPacket(9000, 11, false, true, kVideoFrameDelta); - EXPECT_EQ(VCM_OK, vcm_->Decode(0)); // Decode timestamp 9000 complete. + EXPECT_EQ(VCM_OK, vcm_->Decode(33)); // Decode timestamp 9000 complete. } } // namespace webrtc diff --git a/webrtc/modules/video_coding/video_receiver.cc b/webrtc/modules/video_coding/video_receiver.cc index c347baa7b8..f7ac4bc862 100644 --- a/webrtc/modules/video_coding/video_receiver.cc +++ b/webrtc/modules/video_coding/video_receiver.cc @@ -235,11 +235,9 @@ int32_t VideoReceiver::RegisterDecoderTimingCallback( return VCM_OK; } -// Register an externally defined decoder/render object. -// Can be a decoder only or a decoder coupled with a renderer. +// Register an externally defined decoder object. void VideoReceiver::RegisterExternalDecoder(VideoDecoder* externalDecoder, - uint8_t payloadType, - bool internalRenderTiming) { + uint8_t payloadType) { CriticalSectionScoped cs(_receiveCritSect); if (externalDecoder == NULL) { // Make sure the VCM updates the decoder next time it decodes. @@ -247,8 +245,7 @@ void VideoReceiver::RegisterExternalDecoder(VideoDecoder* externalDecoder, RTC_CHECK(_codecDataBase.DeregisterExternalDecoder(payloadType)); return; } - _codecDataBase.RegisterExternalDecoder(externalDecoder, payloadType, - internalRenderTiming); + _codecDataBase.RegisterExternalDecoder(externalDecoder, payloadType); } // Register a frame type request callback. @@ -281,14 +278,14 @@ void VideoReceiver::TriggerDecoderShutdown() { // Should be called as often as possible to get the most out of the decoder. int32_t VideoReceiver::Decode(uint16_t maxWaitTimeMs) { int64_t nextRenderTimeMs; - bool supports_render_scheduling; + bool prefer_late_decoding = false; { CriticalSectionScoped cs(_receiveCritSect); - supports_render_scheduling = _codecDataBase.SupportsRenderScheduling(); + prefer_late_decoding = _codecDataBase.PrefersLateDecoding(); } VCMEncodedFrame* frame = _receiver.FrameForDecoding( - maxWaitTimeMs, nextRenderTimeMs, supports_render_scheduling); + maxWaitTimeMs, nextRenderTimeMs, prefer_late_decoding); if (frame == NULL) { return VCM_FRAME_NOT_READY; @@ -369,13 +366,7 @@ int32_t VideoReceiver::Decode(const VCMEncodedFrame& frame) { "type", frame.FrameType()); // Change decoder if payload type has changed - const bool renderTimingBefore = _codecDataBase.SupportsRenderScheduling(); _decoder = _codecDataBase.GetDecoder(frame, &_decodedFrameCallback); - if (renderTimingBefore != _codecDataBase.SupportsRenderScheduling()) { - // Make sure we reset the decode time estimate since it will - // be zero for codecs without render timing. - _timing.ResetDecodeTime(); - } if (_decoder == NULL) { return VCM_NO_CODEC_REGISTERED; } diff --git a/webrtc/modules/video_coding/video_receiver_unittest.cc b/webrtc/modules/video_coding/video_receiver_unittest.cc index 049f6007b4..8fd46ecc80 100644 --- a/webrtc/modules/video_coding/video_receiver_unittest.cc +++ b/webrtc/modules/video_coding/video_receiver_unittest.cc @@ -34,7 +34,7 @@ class TestVideoReceiver : public ::testing::Test { virtual void SetUp() { receiver_.reset(new VideoReceiver(&clock_, &event_factory_)); - receiver_->RegisterExternalDecoder(&decoder_, kUnusedPayloadType, true); + receiver_->RegisterExternalDecoder(&decoder_, kUnusedPayloadType); const size_t kMaxNackListSize = 250; const int kMaxPacketAgeToNack = 450; receiver_->SetNackSettings(kMaxNackListSize, kMaxPacketAgeToNack, 0); @@ -55,7 +55,7 @@ class TestVideoReceiver : public ::testing::Test { } EXPECT_EQ(0, receiver_->Process()); EXPECT_CALL(decoder_, Decode(_, _, _, _, _)).Times(0); - EXPECT_EQ(VCM_FRAME_NOT_READY, receiver_->Decode(0)); + EXPECT_EQ(VCM_FRAME_NOT_READY, receiver_->Decode(100)); } void InsertAndVerifyDecodableFrame(const uint8_t* payload, @@ -67,7 +67,7 @@ class TestVideoReceiver : public ::testing::Test { EXPECT_CALL(packet_request_callback_, ResendPackets(_, _)).Times(0); EXPECT_EQ(0, receiver_->Process()); EXPECT_CALL(decoder_, Decode(_, _, _, _, _)).Times(1); - EXPECT_EQ(0, receiver_->Decode(0)); + EXPECT_EQ(0, receiver_->Decode(100)); } SimulatedClock clock_; diff --git a/webrtc/video/video_decoder.cc b/webrtc/video/video_decoder.cc index fa1f2ee878..2a0151d750 100644 --- a/webrtc/video/video_decoder.cc +++ b/webrtc/video/video_decoder.cc @@ -131,4 +131,10 @@ int32_t VideoDecoderSoftwareFallbackWrapper::Reset() { return decoder_->Reset(); } +bool VideoDecoderSoftwareFallbackWrapper::PrefersLateDecoding() const { + if (fallback_decoder_) + return fallback_decoder_->PrefersLateDecoding(); + return decoder_->PrefersLateDecoding(); +} + } // namespace webrtc diff --git a/webrtc/video/video_receive_stream.cc b/webrtc/video/video_receive_stream.cc index 9d1664e678..7779fddd56 100644 --- a/webrtc/video/video_receive_stream.cc +++ b/webrtc/video/video_receive_stream.cc @@ -39,8 +39,6 @@ std::string VideoReceiveStream::Decoder::ToString() const { ss << "{decoder: " << (decoder != nullptr ? "(VideoDecoder)" : "nullptr"); ss << ", payload_type: " << payload_type; ss << ", payload_name: " << payload_name; - ss << ", is_renderer: " << (is_renderer ? "yes" : "no"); - ss << ", expected_delay_ms: " << expected_delay_ms; ss << '}'; return ss.str(); @@ -269,11 +267,8 @@ VideoReceiveStream::VideoReceiveStream( << "Duplicate payload type (" << decoder.payload_type << ") for different decoders."; decoder_payload_types.insert(decoder.payload_type); - RTC_CHECK_EQ(0, - vie_channel_->RegisterExternalDecoder( - decoder.payload_type, decoder.decoder, decoder.is_renderer, - decoder.is_renderer ? decoder.expected_delay_ms - : config.render_delay_ms)); + vie_channel_->RegisterExternalDecoder(decoder.payload_type, + decoder.decoder); VideoCodec codec = CreateDecoderVideoCodec(decoder); @@ -283,6 +278,7 @@ VideoReceiveStream::VideoReceiveStream( incoming_video_stream_.reset(new IncomingVideoStream( 0, config.renderer ? config.renderer->SmoothsRenderedFrames() : false)); incoming_video_stream_->SetExpectedRenderDelay(config.render_delay_ms); + vie_channel_->SetExpectedRenderDelay(config.render_delay_ms); incoming_video_stream_->SetExternalCallback(this); vie_channel_->SetIncomingVideoStream(incoming_video_stream_.get()); diff --git a/webrtc/video/vie_channel.cc b/webrtc/video/vie_channel.cc index 4097a8b846..54bc72bd16 100644 --- a/webrtc/video/vie_channel.cc +++ b/webrtc/video/vie_channel.cc @@ -430,14 +430,10 @@ int32_t ViEChannel::SetReceiveCodec(const VideoCodec& video_codec) { return 0; } - -int32_t ViEChannel::RegisterExternalDecoder(const uint8_t pl_type, - VideoDecoder* decoder, - bool buffered_rendering, - int32_t render_delay) { +void ViEChannel::RegisterExternalDecoder(const uint8_t pl_type, + VideoDecoder* decoder) { RTC_DCHECK(!sender_); - vcm_->RegisterExternalDecoder(decoder, pl_type, buffered_rendering); - return vcm_->SetRenderDelay(render_delay); + vcm_->RegisterExternalDecoder(decoder, pl_type); } int32_t ViEChannel::ReceiveCodecStatistics(uint32_t* num_key_frames, @@ -456,6 +452,10 @@ int ViEChannel::ReceiveDelay() const { return vcm_->Delay(); } +void ViEChannel::SetExpectedRenderDelay(int delay_ms) { + vcm_->SetRenderDelay(delay_ms); +} + void ViEChannel::SetRTCPMode(const RtcpMode rtcp_mode) { for (RtpRtcp* rtp_rtcp : rtp_rtcp_modules_) rtp_rtcp->SetRTCPStatus(rtcp_mode); diff --git a/webrtc/video/vie_channel.h b/webrtc/video/vie_channel.h index ed0712ba42..8f99260bb3 100644 --- a/webrtc/video/vie_channel.h +++ b/webrtc/video/vie_channel.h @@ -86,14 +86,8 @@ class ViEChannel : public VCMFrameTypeCallback, // type has changed and we should start a new RTP stream. int32_t SetSendCodec(const VideoCodec& video_codec, bool new_stream = true); int32_t SetReceiveCodec(const VideoCodec& video_codec); - // Registers an external decoder. |buffered_rendering| means that the decoder - // will render frames after decoding according to the render timestamp - // provided by the video coding module. |render_delay| indicates the time - // needed to decode and render a frame. - int32_t RegisterExternalDecoder(const uint8_t pl_type, - VideoDecoder* decoder, - bool buffered_rendering, - int32_t render_delay); + // Registers an external decoder. + void RegisterExternalDecoder(const uint8_t pl_type, VideoDecoder* decoder); int32_t ReceiveCodecStatistics(uint32_t* num_key_frames, uint32_t* num_delta_frames); uint32_t DiscardedPackets() const; @@ -101,6 +95,8 @@ class ViEChannel : public VCMFrameTypeCallback, // Returns the estimated delay in milliseconds. int ReceiveDelay() const; + void SetExpectedRenderDelay(int delay_ms); + void SetRTCPMode(const RtcpMode rtcp_mode); void SetProtectionMode(bool enable_nack, bool enable_fec, diff --git a/webrtc/video_decoder.h b/webrtc/video_decoder.h index 3d0410429f..30e27792e9 100644 --- a/webrtc/video_decoder.h +++ b/webrtc/video_decoder.h @@ -73,6 +73,11 @@ class VideoDecoder { virtual int32_t Release() = 0; virtual int32_t Reset() = 0; + + // Returns true if the decoder prefer to decode frames late. + // That is, it can not decode infinite number of frames before the decoded + // frame is consumed. + virtual bool PrefersLateDecoding() const { return true; } }; // Class used to wrap external VideoDecoders to provide a fallback option on @@ -97,6 +102,7 @@ class VideoDecoderSoftwareFallbackWrapper : public webrtc::VideoDecoder { int32_t Release() override; int32_t Reset() override; + bool PrefersLateDecoding() const override; private: bool InitFallbackDecoder(); diff --git a/webrtc/video_receive_stream.h b/webrtc/video_receive_stream.h index 6be2c5a86e..cd1434caee 100644 --- a/webrtc/video_receive_stream.h +++ b/webrtc/video_receive_stream.h @@ -43,15 +43,6 @@ class VideoReceiveStream : public ReceiveStream { // Name of the decoded payload (such as VP8). Maps back to the depacketizer // used to unpack incoming packets. std::string payload_name; - - // 'true' if the decoder handles rendering as well. - bool is_renderer = false; - - // The expected delay for decoding and rendering, i.e. the frame will be - // delivered this many milliseconds, if possible, earlier than the ideal - // render time. - // Note: Ignored if 'renderer' is false. - int expected_delay_ms = 0; }; struct Stats {