Fix frames dropped statistics

The |frames_dropped| statistics contain not only frames that are dropped
but also frames that are in internal queues. This CL changes that so
that |frames_dropped| only contains frames that are dropped.

Bug: chromium:990317
Change-Id: If222568501b277a75bc514661c4f8f861b56aaed
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/150111
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Reviewed-by: Niels Moller <nisse@webrtc.org>
Commit-Queue: Johannes Kron <kron@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28968}
This commit is contained in:
Johannes Kron
2019-08-26 15:04:43 +02:00
committed by Commit Bot
parent 7e896d0162
commit 0c141c591a
16 changed files with 96 additions and 5 deletions

View File

@ -286,6 +286,17 @@ EncodedFrame* FrameBuffer::GetNextFrame() {
decoded_frames_history_.InsertDecoded(frame_it->first, frame->Timestamp());
// Remove decoded frame and all undecoded frames before it.
if (stats_callback_) {
unsigned int dropped_frames = std::count_if(
frames_.begin(), frame_it,
[](const std::pair<const VideoLayerFrameId, FrameInfo>& frame) {
return frame.second.frame != nullptr;
});
if (dropped_frames > 0) {
stats_callback_->OnDroppedFrames(dropped_frames);
}
}
frames_.erase(frames_.begin(), ++frame_it);
frames_out.push_back(frame);
@ -723,6 +734,16 @@ void FrameBuffer::UpdateTimingFrameInfo() {
void FrameBuffer::ClearFramesAndHistory() {
TRACE_EVENT0("webrtc", "FrameBuffer::ClearFramesAndHistory");
if (stats_callback_) {
unsigned int dropped_frames = std::count_if(
frames_.begin(), frames_.end(),
[](const std::pair<const VideoLayerFrameId, FrameInfo>& frame) {
return frame.second.frame != nullptr;
});
if (dropped_frames > 0) {
stats_callback_->OnDroppedFrames(dropped_frames);
}
}
frames_.clear();
last_continuous_frame_.reset();
frames_to_decode_.clear();

View File

@ -111,6 +111,7 @@ class VCMReceiveStatisticsCallbackMock : public VCMReceiveStatisticsCallback {
void(bool is_keyframe,
size_t size_bytes,
VideoContentType content_type));
MOCK_METHOD1(OnDroppedFrames, void(uint32_t frames_dropped));
MOCK_METHOD1(OnDiscardedPacketsUpdated, void(int discarded_packets));
MOCK_METHOD1(OnFrameCountsUpdated, void(const FrameCounts& frame_counts));
MOCK_METHOD6(OnFrameBufferTimingsUpdated,
@ -406,6 +407,8 @@ TEST_F(TestFrameBuffer2, DropTemporalLayerSlowDecoder) {
pid + i, pid + i - 1);
}
EXPECT_CALL(stats_callback_, OnDroppedFrames(1)).Times(3);
for (int i = 0; i < 10; ++i) {
ExtractFrame();
clock_.AdvanceTimeMilliseconds(70);
@ -423,6 +426,41 @@ TEST_F(TestFrameBuffer2, DropTemporalLayerSlowDecoder) {
CheckNoFrame(9);
}
TEST_F(TestFrameBuffer2, DropFramesIfSystemIsStalled) {
uint16_t pid = Rand();
uint32_t ts = Rand();
InsertFrame(pid, 0, ts, false, true, kFrameSize);
InsertFrame(pid + 1, 0, ts + 1 * kFps10, false, true, kFrameSize, pid);
InsertFrame(pid + 2, 0, ts + 2 * kFps10, false, true, kFrameSize, pid + 1);
InsertFrame(pid + 3, 0, ts + 3 * kFps10, false, true, kFrameSize);
ExtractFrame();
// Jump forward in time, simulating the system being stalled for some reason.
clock_.AdvanceTimeMilliseconds(3 * kFps10);
// Extract one more frame, expect second and third frame to be dropped.
EXPECT_CALL(stats_callback_, OnDroppedFrames(2)).Times(1);
ExtractFrame();
CheckFrame(0, pid + 0, 0);
CheckFrame(1, pid + 3, 0);
}
TEST_F(TestFrameBuffer2, DroppedFramesCountedOnClear) {
uint16_t pid = Rand();
uint32_t ts = Rand();
InsertFrame(pid, 0, ts, false, true, kFrameSize);
for (int i = 1; i < 5; ++i) {
InsertFrame(pid + i, 0, ts + i * kFps10, false, true, kFrameSize,
pid + i - 1);
}
// All frames should be dropped when Clear is called.
EXPECT_CALL(stats_callback_, OnDroppedFrames(5)).Times(1);
buffer_->Clear();
}
TEST_F(TestFrameBuffer2, InsertLateFrame) {
uint16_t pid = Rand();
uint32_t ts = Rand();

View File

@ -78,6 +78,7 @@ void VCMDecodedFrameCallback::Decoded(VideoFrame& decodedImage,
if (frameInfo == NULL) {
RTC_LOG(LS_WARNING) << "Too many frames backed up in the decoder, dropping "
"this one.";
_receiveCallback->OnDroppedFrames(1);
return;
}
@ -163,6 +164,7 @@ int32_t VCMDecodedFrameCallback::Pop(uint32_t timestamp) {
if (_timestampMap.Pop(timestamp) == NULL) {
return VCM_GENERAL_ERROR;
}
_receiveCallback->OnDroppedFrames(1);
return VCM_OK;
}

View File

@ -67,6 +67,8 @@ class VCMReceiveCallback {
return FrameToRender(videoFrame, qp, content_type);
}
virtual void OnDroppedFrames(uint32_t frames_dropped);
// Called when the current receive codec changes.
virtual void OnIncomingPayloadType(int payload_type);
virtual void OnDecoderImplementationName(const char* implementation_name);
@ -83,6 +85,8 @@ class VCMReceiveStatisticsCallback {
size_t size_bytes,
VideoContentType content_type) = 0;
virtual void OnDroppedFrames(uint32_t frames_dropped) = 0;
virtual void OnFrameBufferTimingsUpdated(int max_decode_ms,
int current_delay_ms,
int target_delay_ms,

View File

@ -12,6 +12,7 @@
namespace webrtc {
void VCMReceiveCallback::OnDroppedFrames(uint32_t frames_dropped) {}
void VCMReceiveCallback::OnIncomingPayloadType(int payload_type) {}
void VCMReceiveCallback::OnDecoderImplementationName(
const char* implementation_name) {}