Skip to content

Commit

Permalink
Bug 1812154 - Vendor libwebrtc from 93081d594f
Browse files Browse the repository at this point in the history
Upstream commit: https://webrtc.googlesource.com/src/+/93081d594f7efff72958a79251f53731b99e902b
    [Merge M108] Ensure video frame buffer is still decodable before decoding

    This ensures that if for some reason, the frame buffer becomes
    undecodable while waiting to decode a frame, the decoding is halted.
    This also guards against receiving an empty temporal unit from the frame
    buffer, even though this should never happen when the frame buffer has a
    decodable temporal unit.

    (cherry picked from commit 8fe5579136c82b558022fe7d1393fa248b151eae)

    Bug: chromium:1378253, chromium:1361623
    Change-Id: I8c4c897bf474d5cbda5f0f357781bf1dc0701fe4
    Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/280701
    Commit-Queue: Evan Shrubsole <eshr@webrtc.org>
    Reviewed-by: Erik Språng <sprang@webrtc.org>
    Cr-Original-Commit-Position: refs/heads/main@{#38494}
    Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/281720
    Cr-Commit-Position: refs/branch-heads/5359@{#5}
    Cr-Branched-From: fb3bd4a01d7c840dfe7b3efa144c0fbcb6a97fef-refs/heads/main@{#38387}
  • Loading branch information
Drekabi committed Feb 6, 2023
1 parent f7cb591 commit 1456d7e
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 7 deletions.
3 changes: 3 additions & 0 deletions third_party/libwebrtc/README.moz-ff-commit
Original file line number Diff line number Diff line change
Expand Up @@ -18753,3 +18753,6 @@ ffceb9b4ad
# MOZ_LIBWEBRTC_SRC=/Users/danielbaker/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh
# base of lastest vendoring
1cd97e2602
# MOZ_LIBWEBRTC_SRC=/Users/danielbaker/moz-libwebrtc MOZ_LIBWEBRTC_BRANCH=mozpatches bash dom/media/webrtc/third_party_build/fast-forward-libwebrtc.sh
# base of lastest vendoring
93081d594f
2 changes: 2 additions & 0 deletions third_party/libwebrtc/README.mozilla
Original file line number Diff line number Diff line change
Expand Up @@ -12524,3 +12524,5 @@ libwebrtc updated from /Users/danielbaker/moz-libwebrtc commit mozpatches on 202
libwebrtc updated from /Users/danielbaker/moz-libwebrtc commit mozpatches on 2023-02-06T15:22:04.298603.
# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /Users/danielbaker/moz-libwebrtc --commit mozpatches libwebrtc
libwebrtc updated from /Users/danielbaker/moz-libwebrtc commit mozpatches on 2023-02-06T15:23:21.330562.
# ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /Users/danielbaker/moz-libwebrtc --commit mozpatches libwebrtc
libwebrtc updated from /Users/danielbaker/moz-libwebrtc commit mozpatches on 2023-02-06T15:32:35.264724.
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ void TaskQueueFrameDecodeScheduler::ScheduleFrame(
SafeTask(task_safety_.flag(),
[this, rtp, schedule, cb = std::move(cb)]() mutable {
RTC_DCHECK_RUN_ON(bookkeeping_queue_);
// If the next frame rtp has changed since this task was
// this scheduled release should be skipped.
// If the next frame rtp has changed since this task was
// this scheduled release should be skipped.
if (scheduled_rtp_ != rtp)
return;
scheduled_rtp_ = absl::nullopt;
Expand Down
29 changes: 24 additions & 5 deletions third_party/libwebrtc/video/video_stream_buffer_controller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,8 @@ void VideoStreamBufferController::OnFrameReady(
absl::InlinedVector<std::unique_ptr<EncodedFrame>, 4> frames,
Timestamp render_time) {
RTC_DCHECK_RUN_ON(&worker_sequence_checker_);
RTC_DCHECK(!frames.empty());
RTC_CHECK(!frames.empty())
<< "Callers must ensure there is at least one frame to decode.";

timeout_tracker_.OnEncodedFrameReleased();

Expand Down Expand Up @@ -284,11 +285,29 @@ void VideoStreamBufferController::OnTimeout(TimeDelta delay) {
void VideoStreamBufferController::FrameReadyForDecode(uint32_t rtp_timestamp,
Timestamp render_time) {
RTC_DCHECK_RUN_ON(&worker_sequence_checker_);
auto frames = buffer_->ExtractNextDecodableTemporalUnit();
RTC_DCHECK(frames[0]->Timestamp() == rtp_timestamp)
// Check that the frame to decode is still valid before passing the frame for
// decoding.
auto decodable_tu_info = buffer_->DecodableTemporalUnitsInfo();
if (!decodable_tu_info) {
RTC_LOG(LS_ERROR)
<< "The frame buffer became undecodable during the wait "
"to decode frame with rtp-timestamp "
<< rtp_timestamp
<< ". Cancelling the decode of this frame, decoding "
"will resume when the frame buffers become decodable again.";
return;
}
RTC_DCHECK_EQ(rtp_timestamp, decodable_tu_info->next_rtp_timestamp)
<< "Frame buffer's next decodable frame was not the one sent for "
"extraction rtp="
<< rtp_timestamp << " extracted rtp=" << frames[0]->Timestamp();
"extraction.";
auto frames = buffer_->ExtractNextDecodableTemporalUnit();
if (frames.empty()) {
RTC_LOG(LS_ERROR)
<< "The frame buffer should never return an empty temporal until list "
"when there is a decodable temporal unit.";
RTC_DCHECK_NOTREACHED();
return;
}
OnFrameReady(std::move(frames), render_time);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -754,6 +754,50 @@ TEST_P(VideoStreamBufferControllerTest, NextFrameWithOldTimestamp) {
EXPECT_THAT(WaitForFrameOrTimeout(kFps30Delay), Frame(test::WithId(2)));
}

TEST_P(VideoStreamBufferControllerTest,
FrameNotSetForDecodedIfFrameBufferBecomesNonDecodable) {
// This can happen if the frame buffer receives non-standard input. This test
// will simply clear the frame buffer to replicate this.
StartNextDecodeForceKeyframe();
// Initial keyframe.
buffer_->InsertFrame(WithReceiveTimeFromRtpTimestamp(
test::FakeFrameBuilder().Id(0).Time(0).SpatialLayer(1).AsLast().Build()));
EXPECT_THAT(WaitForFrameOrTimeout(TimeDelta::Zero()), Frame(test::WithId(0)));

// Insert a frame that will become non-decodable.
buffer_->InsertFrame(WithReceiveTimeFromRtpTimestamp(test::FakeFrameBuilder()
.Id(11)
.Time(kFps30Rtp)
.Refs({0})
.SpatialLayer(1)
.AsLast()
.Build()));
StartNextDecode();
// Second layer inserted after last layer for the same frame out-of-order.
// This second frame requires some older frame to be decoded and so now the
// super-frame is no longer decodable despite already being scheduled.
buffer_->InsertFrame(WithReceiveTimeFromRtpTimestamp(test::FakeFrameBuilder()
.Id(10)
.Time(kFps30Rtp)
.SpatialLayer(0)
.Refs({2})
.Build()));
EXPECT_THAT(WaitForFrameOrTimeout(kMaxWaitForFrame), TimedOut());

// Ensure that this frame can be decoded later.
StartNextDecode();
buffer_->InsertFrame(WithReceiveTimeFromRtpTimestamp(test::FakeFrameBuilder()
.Id(2)
.Time(kFps30Rtp / 2)
.SpatialLayer(0)
.Refs({0})
.AsLast()
.Build()));
EXPECT_THAT(WaitForFrameOrTimeout(kFps30Delay), Frame(test::WithId(2)));
StartNextDecode();
EXPECT_THAT(WaitForFrameOrTimeout(kFps30Delay), Frame(test::WithId(10)));
}

INSTANTIATE_TEST_SUITE_P(VideoStreamBufferController,
VideoStreamBufferControllerTest,
::testing::Combine(::testing::Bool(),
Expand Down

0 comments on commit 1456d7e

Please sign in to comment.