From cc452e117943c558466c34f6ceddada454308342 Mon Sep 17 00:00:00 2001 From: sakal Date: Thu, 9 Feb 2017 04:53:45 -0800 Subject: [PATCH] Reland of Add QP sum stats for received streams. (patchset #2 id:300001 of https://codereview.webrtc.org/2680893002/ ) Reason for revert: Fix the problem. Original issue's description: > Revert of Add QP sum stats for received streams. (patchset #10 id:180001 of https://codereview.webrtc.org/2649133005/ ) > > Reason for revert: > Breaks downstream build. > > Original issue's description: > > Add QP sum stats for received streams. > > > > This is not implemented yet in any of the decoders. > > > > BUG=webrtc:6541 > > > > Review-Url: https://codereview.webrtc.org/2649133005 > > Cr-Commit-Position: refs/heads/master@{#16475} > > Committed: https://chromium.googlesource.com/external/webrtc/+/ff0e72fd165facac27f0313aa178648782e63bc4 > > TBR=hta@webrtc.org,hbos@webrtc.org,sprang@webrtc.org,magjed@webrtc.org,stefan@webrtc.org,sakal@webrtc.org > # Skipping CQ checks because original CL landed less than 1 days ago. > NOPRESUBMIT=true > NOTREECHECKS=true > NOTRY=true > BUG=webrtc:6541 > > Review-Url: https://codereview.webrtc.org/2680893002 . > Cr-Commit-Position: refs/heads/master@{#16480} > Committed: https://chromium.googlesource.com/external/webrtc/+/69fb2cca4d54f3df7ceddcd1c3e9b0ad80fa849b TBR=hta@webrtc.org,hbos@webrtc.org,sprang@webrtc.org,magjed@webrtc.org,stefan@webrtc.org,skvlad@webrtc.org BUG=webrtc:6541 Review-Url: https://codereview.webrtc.org/2681663005 Cr-Commit-Position: refs/heads/master@{#16511} --- webrtc/media/base/mediachannel.h | 1 + ...decodersoftwarefallbackwrapper_unittest.cc | 5 +++ webrtc/media/engine/webrtcvideoengine2.cc | 1 + .../engine/webrtcvideoengine2_unittest.cc | 2 ++ .../video_coding/codecs/test/videoprocessor.h | 5 +++ .../codecs/vp8/simulcast_unittest.h | 5 +++ .../codecs/vp8/test/vp8_impl_unittest.cc | 5 +++ .../modules/video_coding/generic_decoder.cc | 21 +++++++---- webrtc/modules/video_coding/generic_decoder.h | 12 ++++--- .../include/mock/mock_video_codec_interface.h | 4 +++ .../include/video_coding_defines.h | 3 +- webrtc/modules/video_coding/test/test_util.cc | 4 +-- webrtc/modules/video_coding/test/test_util.h | 17 +++------ webrtc/pc/statscollector.cc | 3 ++ webrtc/pc/statscollector_unittest.cc | 3 ++ webrtc/video/receive_statistics_proxy.cc | 17 ++++++++- webrtc/video/receive_statistics_proxy.h | 2 +- .../receive_statistics_proxy_unittest.cc | 35 ++++++++++++++++++- webrtc/video/video_receive_stream.cc | 4 --- webrtc/video/video_stream_decoder.cc | 5 ++- webrtc/video/video_stream_decoder.h | 3 +- webrtc/video_decoder.h | 9 ++++- webrtc/video_receive_stream.h | 1 + 23 files changed, 131 insertions(+), 36 deletions(-) diff --git a/webrtc/media/base/mediachannel.h b/webrtc/media/base/mediachannel.h index 4333fa4cc4..6e4011145b 100644 --- a/webrtc/media/base/mediachannel.h +++ b/webrtc/media/base/mediachannel.h @@ -781,6 +781,7 @@ struct VideoReceiverInfo : public MediaReceiverInfo { uint32_t frames_received; uint32_t frames_decoded; uint32_t frames_rendered; + rtc::Optional qp_sum; // All stats below are gathered per-VideoReceiver, but some will be correlated // across MediaStreamTracks. NOTE(hta): when sinking stats into per-SSRC diff --git a/webrtc/media/engine/videodecodersoftwarefallbackwrapper_unittest.cc b/webrtc/media/engine/videodecodersoftwarefallbackwrapper_unittest.cc index ccdf017d3d..de42545954 100644 --- a/webrtc/media/engine/videodecodersoftwarefallbackwrapper_unittest.cc +++ b/webrtc/media/engine/videodecodersoftwarefallbackwrapper_unittest.cc @@ -141,6 +141,11 @@ TEST_F(VideoDecoderSoftwareFallbackWrapperTest, RTC_NOTREACHED(); return -1; } + void Decoded(webrtc::VideoFrame& decodedImage, + rtc::Optional decode_time_ms, + rtc::Optional qp) override { + RTC_NOTREACHED(); + } } callback, callback2; VideoCodec codec = {}; diff --git a/webrtc/media/engine/webrtcvideoengine2.cc b/webrtc/media/engine/webrtcvideoengine2.cc index 955560a680..df796daedd 100644 --- a/webrtc/media/engine/webrtcvideoengine2.cc +++ b/webrtc/media/engine/webrtcvideoengine2.cc @@ -2400,6 +2400,7 @@ WebRtcVideoChannel2::WebRtcVideoReceiveStream::GetVideoReceiverInfo( stats.frame_counts.delta_frames; info.frames_decoded = stats.frames_decoded; info.frames_rendered = stats.frames_rendered; + info.qp_sum = stats.qp_sum; info.codec_name = GetCodecNameFromPayloadType(stats.current_payload_type); diff --git a/webrtc/media/engine/webrtcvideoengine2_unittest.cc b/webrtc/media/engine/webrtcvideoengine2_unittest.cc index 06973e6f45..d77c3c4806 100644 --- a/webrtc/media/engine/webrtcvideoengine2_unittest.cc +++ b/webrtc/media/engine/webrtcvideoengine2_unittest.cc @@ -3430,6 +3430,7 @@ TEST_F(WebRtcVideoChannel2Test, GetStatsTranslatesDecodeStatsCorrectly) { stats.frame_counts.delta_frames = 12; stats.frames_rendered = 13; stats.frames_decoded = 14; + stats.qp_sum = rtc::Optional(15); stream->SetStats(stats); cricket::VideoMediaInfo info; @@ -3449,6 +3450,7 @@ TEST_F(WebRtcVideoChannel2Test, GetStatsTranslatesDecodeStatsCorrectly) { info.receivers[0].frames_received); EXPECT_EQ(stats.frames_rendered, info.receivers[0].frames_rendered); EXPECT_EQ(stats.frames_decoded, info.receivers[0].frames_decoded); + EXPECT_EQ(stats.qp_sum, info.receivers[0].qp_sum); } TEST_F(WebRtcVideoChannel2Test, GetStatsTranslatesReceivePacketStatsCorrectly) { diff --git a/webrtc/modules/video_coding/codecs/test/videoprocessor.h b/webrtc/modules/video_coding/codecs/test/videoprocessor.h index a217b1132e..778cc1d599 100644 --- a/webrtc/modules/video_coding/codecs/test/videoprocessor.h +++ b/webrtc/modules/video_coding/codecs/test/videoprocessor.h @@ -250,6 +250,11 @@ class VideoProcessorImpl : public VideoProcessor { RTC_NOTREACHED(); return -1; } + void Decoded(VideoFrame& frame, + rtc::Optional decode_time_ms, + rtc::Optional qp) override { + RTC_NOTREACHED(); + } private: VideoProcessorImpl* video_processor_; diff --git a/webrtc/modules/video_coding/codecs/vp8/simulcast_unittest.h b/webrtc/modules/video_coding/codecs/vp8/simulcast_unittest.h index d140b0a529..b7e3e7d569 100644 --- a/webrtc/modules/video_coding/codecs/vp8/simulcast_unittest.h +++ b/webrtc/modules/video_coding/codecs/vp8/simulcast_unittest.h @@ -145,6 +145,11 @@ class Vp8TestDecodedImageCallback : public DecodedImageCallback { RTC_NOTREACHED(); return -1; } + void Decoded(VideoFrame& decoded_image, + rtc::Optional decode_time_ms, + rtc::Optional qp) override { + RTC_NOTREACHED(); + } int DecodedFrames() { return decoded_frames_; } private: diff --git a/webrtc/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc b/webrtc/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc index de612f0404..a47c209ad4 100644 --- a/webrtc/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc +++ b/webrtc/modules/video_coding/codecs/vp8/test/vp8_impl_unittest.cc @@ -97,6 +97,11 @@ class Vp8UnitTestDecodeCompleteCallback : public webrtc::DecodedImageCallback { RTC_NOTREACHED(); return -1; } + void Decoded(VideoFrame& frame, + rtc::Optional decode_time_ms, + rtc::Optional qp) override { + RTC_NOTREACHED(); + } bool DecodeComplete(); private: diff --git a/webrtc/modules/video_coding/generic_decoder.cc b/webrtc/modules/video_coding/generic_decoder.cc index b1059e8a1b..34500c69e2 100644 --- a/webrtc/modules/video_coding/generic_decoder.cc +++ b/webrtc/modules/video_coding/generic_decoder.cc @@ -48,6 +48,16 @@ int32_t VCMDecodedFrameCallback::Decoded(VideoFrame& decodedImage) { int32_t VCMDecodedFrameCallback::Decoded(VideoFrame& decodedImage, int64_t decode_time_ms) { + Decoded(decodedImage, + decode_time_ms >= 0 ? rtc::Optional(decode_time_ms) + : rtc::Optional(), + rtc::Optional()); + return WEBRTC_VIDEO_CODEC_OK; +} + +void VCMDecodedFrameCallback::Decoded(VideoFrame& decodedImage, + rtc::Optional decode_time_ms, + rtc::Optional qp) { TRACE_EVENT_INSTANT1("webrtc", "VCMDecodedFrameCallback::Decoded", "timestamp", decodedImage.timestamp()); // TODO(holmer): We should improve this so that we can handle multiple @@ -63,15 +73,15 @@ int32_t VCMDecodedFrameCallback::Decoded(VideoFrame& decodedImage, if (frameInfo == NULL) { LOG(LS_WARNING) << "Too many frames backed up in the decoder, dropping " "this one."; - return WEBRTC_VIDEO_CODEC_OK; + return; } const int64_t now_ms = _clock->TimeInMilliseconds(); - if (decode_time_ms < 0) { + if (!decode_time_ms) { decode_time_ms = - static_cast(now_ms - frameInfo->decodeStartTimeMs); + rtc::Optional(now_ms - frameInfo->decodeStartTimeMs); } - _timing->StopDecodeTimer(decodedImage.timestamp(), decode_time_ms, now_ms, + _timing->StopDecodeTimer(decodedImage.timestamp(), *decode_time_ms, now_ms, frameInfo->renderTimeMs); decodedImage.set_timestamp_us( @@ -80,11 +90,10 @@ int32_t VCMDecodedFrameCallback::Decoded(VideoFrame& decodedImage, // TODO(sakal): Investigate why callback is NULL sometimes and replace if // statement with a DCHECK. if (callback) { - callback->FrameToRender(decodedImage); + callback->FrameToRender(decodedImage, qp); } else { LOG(LS_WARNING) << "No callback, dropping frame."; } - return WEBRTC_VIDEO_CODEC_OK; } int32_t VCMDecodedFrameCallback::ReceivedDecodedReferenceFrame( diff --git a/webrtc/modules/video_coding/generic_decoder.h b/webrtc/modules/video_coding/generic_decoder.h index 2d0007be81..48e25196e9 100644 --- a/webrtc/modules/video_coding/generic_decoder.h +++ b/webrtc/modules/video_coding/generic_decoder.h @@ -37,11 +37,13 @@ class VCMDecodedFrameCallback : public DecodedImageCallback { void SetUserReceiveCallback(VCMReceiveCallback* receiveCallback); VCMReceiveCallback* UserReceiveCallback(); - virtual int32_t Decoded(VideoFrame& decodedImage); // NOLINT - virtual int32_t Decoded(VideoFrame& decodedImage, // NOLINT - int64_t decode_time_ms); - virtual int32_t ReceivedDecodedReferenceFrame(const uint64_t pictureId); - virtual int32_t ReceivedDecodedFrame(const uint64_t pictureId); + int32_t Decoded(VideoFrame& decodedImage) override; + int32_t Decoded(VideoFrame& decodedImage, int64_t decode_time_ms) override; + void Decoded(VideoFrame& decodedImage, + rtc::Optional decode_time_ms, + rtc::Optional qp) override; + int32_t ReceivedDecodedReferenceFrame(const uint64_t pictureId) override; + int32_t ReceivedDecodedFrame(const uint64_t pictureId) override; uint64_t LastReceivedPictureID() const; void OnDecoderImplementationName(const char* implementation_name); diff --git a/webrtc/modules/video_coding/include/mock/mock_video_codec_interface.h b/webrtc/modules/video_coding/include/mock/mock_video_codec_interface.h index 7e2076ccdc..bbf3098b65 100644 --- a/webrtc/modules/video_coding/include/mock/mock_video_codec_interface.h +++ b/webrtc/modules/video_coding/include/mock/mock_video_codec_interface.h @@ -57,6 +57,10 @@ class MockDecodedImageCallback : public DecodedImageCallback { MOCK_METHOD2(Decoded, int32_t(VideoFrame& decodedImage, // NOLINT int64_t decode_time_ms)); + MOCK_METHOD3(Decoded, + void(VideoFrame& decodedImage, // NOLINT + rtc::Optional decode_time_ms, + rtc::Optional qp)); MOCK_METHOD1(ReceivedDecodedReferenceFrame, int32_t(const uint64_t pictureId)); MOCK_METHOD1(ReceivedDecodedFrame, int32_t(const uint64_t pictureId)); diff --git a/webrtc/modules/video_coding/include/video_coding_defines.h b/webrtc/modules/video_coding/include/video_coding_defines.h index 122ddc6315..2155461ac8 100644 --- a/webrtc/modules/video_coding/include/video_coding_defines.h +++ b/webrtc/modules/video_coding/include/video_coding_defines.h @@ -63,7 +63,8 @@ struct VCMFrameCount { // rendered. class VCMReceiveCallback { public: - virtual int32_t FrameToRender(VideoFrame& videoFrame) = 0; // NOLINT + virtual int32_t FrameToRender(VideoFrame& videoFrame, // NOLINT + rtc::Optional qp) = 0; virtual int32_t ReceivedDecodedReferenceFrame(const uint64_t pictureId) { return -1; } diff --git a/webrtc/modules/video_coding/test/test_util.cc b/webrtc/modules/video_coding/test/test_util.cc index 8f5c55f9ba..386b4300a9 100644 --- a/webrtc/modules/video_coding/test/test_util.cc +++ b/webrtc/modules/video_coding/test/test_util.cc @@ -97,8 +97,8 @@ FileOutputFrameReceiver::~FileOutputFrameReceiver() { } } -int32_t FileOutputFrameReceiver::FrameToRender( - webrtc::VideoFrame& video_frame) { +int32_t FileOutputFrameReceiver::FrameToRender(webrtc::VideoFrame& video_frame, + rtc::Optional qp) { if (timing_file_ == NULL) { std::string basename; std::string extension; diff --git a/webrtc/modules/video_coding/test/test_util.h b/webrtc/modules/video_coding/test/test_util.h index 45b88b9b50..86d3ecfaba 100644 --- a/webrtc/modules/video_coding/test/test_util.h +++ b/webrtc/modules/video_coding/test/test_util.h @@ -29,26 +29,18 @@ class NullEvent : public webrtc::EventWrapper { public: virtual ~NullEvent() {} - virtual bool Set() { return true; } + bool Set() override { return true; } - virtual bool Reset() { return true; } - - virtual webrtc::EventTypeWrapper Wait(unsigned long max_time) { // NOLINT + webrtc::EventTypeWrapper Wait(unsigned long max_time) override { // NOLINT return webrtc::kEventTimeout; } - - virtual bool StartTimer(bool periodic, unsigned long time) { // NOLINT - return true; - } - - virtual bool StopTimer() { return true; } }; class NullEventFactory : public webrtc::EventFactory { public: virtual ~NullEventFactory() {} - virtual webrtc::EventWrapper* CreateEvent() { return new NullEvent; } + webrtc::EventWrapper* CreateEvent() override { return new NullEvent; } }; class FileOutputFrameReceiver : public webrtc::VCMReceiveCallback { @@ -57,7 +49,8 @@ class FileOutputFrameReceiver : public webrtc::VCMReceiveCallback { virtual ~FileOutputFrameReceiver(); // VCMReceiveCallback - virtual int32_t FrameToRender(webrtc::VideoFrame& video_frame); // NOLINT + int32_t FrameToRender(webrtc::VideoFrame& video_frame, + rtc::Optional qp) override; private: std::string out_filename_; diff --git a/webrtc/pc/statscollector.cc b/webrtc/pc/statscollector.cc index 3e0c2bf441..e91f873824 100644 --- a/webrtc/pc/statscollector.cc +++ b/webrtc/pc/statscollector.cc @@ -221,6 +221,9 @@ void ExtractStats(const cricket::VideoReceiverInfo& info, StatsReport* report) { report->AddInt64(StatsReport::kStatsValueNameCaptureStartNtpTimeMs, info.capture_start_ntp_time_ms); } + if (info.qp_sum) + report->AddInt64(StatsReport::kStatsValueNameQpSum, *info.qp_sum); + const IntForAdd ints[] = { { StatsReport::kStatsValueNameCurrentDelayMs, info.current_delay_ms }, { StatsReport::kStatsValueNameDecodeMs, info.decode_ms }, diff --git a/webrtc/pc/statscollector_unittest.cc b/webrtc/pc/statscollector_unittest.cc index e89da1c8ae..1bb6d1de4c 100644 --- a/webrtc/pc/statscollector_unittest.cc +++ b/webrtc/pc/statscollector_unittest.cc @@ -2018,6 +2018,7 @@ TEST_F(StatsCollectorTest, VerifyVideoReceiveSsrcStats) { // Construct a stats value to read. video_receiver_info.add_ssrc(1234); video_receiver_info.frames_decoded = 10; + video_receiver_info.qp_sum = rtc::Optional(11); stats_read.receivers.push_back(video_receiver_info); EXPECT_CALL(session_, video_channel()).WillRepeatedly(Return(&video_channel)); @@ -2029,6 +2030,8 @@ TEST_F(StatsCollectorTest, VerifyVideoReceiveSsrcStats) { EXPECT_EQ(rtc::ToString(video_receiver_info.frames_decoded), ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameFramesDecoded)); + EXPECT_EQ(rtc::ToString(*video_receiver_info.qp_sum), + ExtractSsrcStatsValue(reports, StatsReport::kStatsValueNameQpSum)); } } // namespace webrtc diff --git a/webrtc/video/receive_statistics_proxy.cc b/webrtc/video/receive_statistics_proxy.cc index ba9184a2d4..c847a178e8 100644 --- a/webrtc/video/receive_statistics_proxy.cc +++ b/webrtc/video/receive_statistics_proxy.cc @@ -398,11 +398,26 @@ void ReceiveStatisticsProxy::DataCountersUpdated( } } -void ReceiveStatisticsProxy::OnDecodedFrame() { +void ReceiveStatisticsProxy::OnDecodedFrame(rtc::Optional qp) { uint64_t now = clock_->TimeInMilliseconds(); rtc::CritScope lock(&crit_); ++stats_.frames_decoded; + if (qp) { + if (!stats_.qp_sum) { + if (stats_.frames_decoded != 1) { + LOG(LS_WARNING) + << "Frames decoded was not 1 when first qp value was received."; + stats_.frames_decoded = 1; + } + stats_.qp_sum = rtc::Optional(0); + } + *stats_.qp_sum += *qp; + } else if (stats_.qp_sum) { + LOG(LS_WARNING) + << "QP sum was already set and no QP was given for a frame."; + stats_.qp_sum = rtc::Optional(); + } decode_fps_estimator_.Update(1, now); stats_.decode_frame_rate = decode_fps_estimator_.Rate(now).value_or(0); } diff --git a/webrtc/video/receive_statistics_proxy.h b/webrtc/video/receive_statistics_proxy.h index e54f53aac1..0f226528ba 100644 --- a/webrtc/video/receive_statistics_proxy.h +++ b/webrtc/video/receive_statistics_proxy.h @@ -45,7 +45,7 @@ class ReceiveStatisticsProxy : public VCMReceiveStatisticsCallback, VideoReceiveStream::Stats GetStats() const; - void OnDecodedFrame(); + void OnDecodedFrame(rtc::Optional qp); void OnSyncOffsetUpdated(int64_t sync_offset_ms, double estimated_freq_khz); void OnRenderedFrame(const VideoFrame& frame); void OnIncomingPayloadType(int payload_type); diff --git a/webrtc/video/receive_statistics_proxy_unittest.cc b/webrtc/video/receive_statistics_proxy_unittest.cc index d431bc4afb..c966c1c7b0 100644 --- a/webrtc/video/receive_statistics_proxy_unittest.cc +++ b/webrtc/video/receive_statistics_proxy_unittest.cc @@ -54,11 +54,44 @@ class ReceiveStatisticsProxyTest : public ::testing::Test { TEST_F(ReceiveStatisticsProxyTest, OnDecodedFrameIncreasesFramesDecoded) { EXPECT_EQ(0u, statistics_proxy_->GetStats().frames_decoded); for (uint32_t i = 1; i <= 3; ++i) { - statistics_proxy_->OnDecodedFrame(); + statistics_proxy_->OnDecodedFrame(rtc::Optional()); EXPECT_EQ(i, statistics_proxy_->GetStats().frames_decoded); } } +TEST_F(ReceiveStatisticsProxyTest, OnDecodedFrameWithQpResetsFramesDecoded) { + EXPECT_EQ(0u, statistics_proxy_->GetStats().frames_decoded); + for (uint32_t i = 1; i <= 3; ++i) { + statistics_proxy_->OnDecodedFrame(rtc::Optional()); + EXPECT_EQ(i, statistics_proxy_->GetStats().frames_decoded); + } + statistics_proxy_->OnDecodedFrame(rtc::Optional(1u)); + EXPECT_EQ(1u, statistics_proxy_->GetStats().frames_decoded); +} + +TEST_F(ReceiveStatisticsProxyTest, OnDecodedFrameIncreasesQpSum) { + EXPECT_EQ(rtc::Optional(), statistics_proxy_->GetStats().qp_sum); + statistics_proxy_->OnDecodedFrame(rtc::Optional(3u)); + EXPECT_EQ(rtc::Optional(3u), statistics_proxy_->GetStats().qp_sum); + statistics_proxy_->OnDecodedFrame(rtc::Optional(127u)); + EXPECT_EQ(rtc::Optional(130u), + statistics_proxy_->GetStats().qp_sum); +} + +TEST_F(ReceiveStatisticsProxyTest, OnDecodedFrameWithoutQpQpSumWontExist) { + EXPECT_EQ(rtc::Optional(), statistics_proxy_->GetStats().qp_sum); + statistics_proxy_->OnDecodedFrame(rtc::Optional()); + EXPECT_EQ(rtc::Optional(), statistics_proxy_->GetStats().qp_sum); +} + +TEST_F(ReceiveStatisticsProxyTest, OnDecodedFrameWithoutQpResetsQpSum) { + EXPECT_EQ(rtc::Optional(), statistics_proxy_->GetStats().qp_sum); + statistics_proxy_->OnDecodedFrame(rtc::Optional(3u)); + EXPECT_EQ(rtc::Optional(3u), statistics_proxy_->GetStats().qp_sum); + statistics_proxy_->OnDecodedFrame(rtc::Optional()); + EXPECT_EQ(rtc::Optional(), statistics_proxy_->GetStats().qp_sum); +} + TEST_F(ReceiveStatisticsProxyTest, OnRenderedFrameIncreasesFramesRendered) { EXPECT_EQ(0u, statistics_proxy_->GetStats().frames_rendered); webrtc::VideoFrame frame( diff --git a/webrtc/video/video_receive_stream.cc b/webrtc/video/video_receive_stream.cc index 0f35fde5fa..e73fd04b71 100644 --- a/webrtc/video/video_receive_stream.cc +++ b/webrtc/video/video_receive_stream.cc @@ -376,10 +376,6 @@ void VideoReceiveStream::EnableEncodedFrameRecording(rtc::PlatformFile file, // TODO(tommi): This method grabs a lock 6 times. void VideoReceiveStream::OnFrame(const VideoFrame& video_frame) { - // TODO(tommi): OnDecodedFrame grabs a lock, incidentally the same lock - // that OnSyncOffsetUpdated() and OnRenderedFrame() below grab. - stats_proxy_.OnDecodedFrame(); - int64_t sync_offset_ms; double estimated_freq_khz; // TODO(tommi): GetStreamSyncOffsetInMs grabs three locks. One inside the diff --git a/webrtc/video/video_stream_decoder.cc b/webrtc/video/video_stream_decoder.cc index 94b0c80385..95b24f5f91 100644 --- a/webrtc/video/video_stream_decoder.cc +++ b/webrtc/video/video_stream_decoder.cc @@ -73,8 +73,11 @@ VideoStreamDecoder::~VideoStreamDecoder() { // callback won't necessarily be called from the decoding thread. The decoding // thread may have held the lock when calling VideoDecoder::Decode, Reset, or // Release. Acquiring the same lock in the path of decode callback can deadlock. -int32_t VideoStreamDecoder::FrameToRender(VideoFrame& video_frame) { // NOLINT +int32_t VideoStreamDecoder::FrameToRender(VideoFrame& video_frame, + rtc::Optional qp) { + receive_stats_callback_->OnDecodedFrame(qp); incoming_video_stream_->OnFrame(video_frame); + return 0; } diff --git a/webrtc/video/video_stream_decoder.h b/webrtc/video/video_stream_decoder.h index 0e67c1010f..b80dac68d7 100644 --- a/webrtc/video/video_stream_decoder.h +++ b/webrtc/video/video_stream_decoder.h @@ -59,7 +59,8 @@ class VideoStreamDecoder : public VCMReceiveCallback, ~VideoStreamDecoder(); // Implements VCMReceiveCallback. - int32_t FrameToRender(VideoFrame& video_frame) override; // NOLINT + int32_t FrameToRender(VideoFrame& video_frame, + rtc::Optional qp) override; int32_t ReceivedDecodedReferenceFrame(const uint64_t picture_id) override; void OnIncomingPayloadType(int payload_type) override; void OnDecoderImplementationName(const char* implementation_name) override; diff --git a/webrtc/video_decoder.h b/webrtc/video_decoder.h index b8d2c96b1b..70c09129f7 100644 --- a/webrtc/video_decoder.h +++ b/webrtc/video_decoder.h @@ -35,11 +35,18 @@ class DecodedImageCallback { // decode time excluding waiting time for any previous pending frame to // return. This is necessary for breaking positive feedback in the delay // estimation when the decoder has a single output buffer. - // TODO(perkj): Remove default implementation when chromium has been updated. virtual int32_t Decoded(VideoFrame& decodedImage, int64_t decode_time_ms) { // The default implementation ignores custom decode time value. return Decoded(decodedImage); } + // TODO(sakal): Remove other implementations when upstream projects have been + // updated. + virtual void Decoded(VideoFrame& decodedImage, + rtc::Optional decode_time_ms, + rtc::Optional qp) { + Decoded(decodedImage, + decode_time_ms ? static_cast(*decode_time_ms) : -1); + } virtual int32_t ReceivedDecodedReferenceFrame(const uint64_t pictureId) { return -1; diff --git a/webrtc/video_receive_stream.h b/webrtc/video_receive_stream.h index 374f3508a1..12629d0637 100644 --- a/webrtc/video_receive_stream.h +++ b/webrtc/video_receive_stream.h @@ -70,6 +70,7 @@ class VideoReceiveStream { int min_playout_delay_ms = 0; int render_delay_ms = 10; uint32_t frames_decoded = 0; + rtc::Optional qp_sum; int current_payload_type = -1;