Skip to content

Commit dbab1be

Browse files
Philipel-WebRTCWebRTC LUCI CQ
authored andcommitted
Always unwrap VP9 TL0PicIdx forward if the frame is newer.
Bug: webrtc:12979 Change-Id: Idcc14f8f61b04f9eb194b55ffa40fb95319a881c Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/226463 Reviewed-by: Danil Chapovalov <[email protected]> Reviewed-by: Ilya Nikolaevskiy <[email protected]> Reviewed-by: Mirko Bonadei <[email protected]> Commit-Queue: Philip Eliasson <[email protected]> Cr-Commit-Position: refs/heads/master@{#34513}
1 parent 9f2a20f commit dbab1be

File tree

3 files changed

+44
-8
lines changed

3 files changed

+44
-8
lines changed

modules/video_coding/rtp_vp9_ref_finder.cc

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,21 @@ RtpVp9RefFinder::FrameDecision RtpVp9RefFinder::ManageFrameInternal(
7777
}
7878

7979
GofInfo* info;
80-
int64_t unwrapped_tl0 =
81-
tl0_unwrapper_.Unwrap(codec_header.tl0_pic_idx & 0xFF);
80+
81+
// The VP9 `tl0_pic_idx` is 8 bits and therefor wraps often. In the case of
82+
// packet loss the next received frame could have a `tl0_pic_idx` that looks
83+
// older than the previously received frame. Always wrap forward if |frame| is
84+
// newer in RTP packet sequence number order.
85+
int64_t unwrapped_tl0;
86+
auto tl0_it = gof_info_.rbegin();
87+
if (tl0_it != gof_info_.rend() &&
88+
AheadOf(frame->last_seq_num(), tl0_it->second.last_seq_num)) {
89+
unwrapped_tl0 =
90+
tl0_unwrapper_.UnwrapForward(codec_header.tl0_pic_idx & 0xFF);
91+
} else {
92+
unwrapped_tl0 = tl0_unwrapper_.Unwrap(codec_header.tl0_pic_idx & 0xFF);
93+
}
94+
8295
if (codec_header.ss_data_available) {
8396
if (codec_header.temporal_idx != 0) {
8497
RTC_LOG(LS_WARNING) << "Received scalability structure on a non base "
@@ -104,9 +117,9 @@ RtpVp9RefFinder::FrameDecision RtpVp9RefFinder::ManageFrameInternal(
104117
current_ss_idx_ = Add<kMaxGofSaved>(current_ss_idx_, 1);
105118
scalability_structures_[current_ss_idx_] = gof;
106119
scalability_structures_[current_ss_idx_].pid_start = frame->Id();
107-
gof_info_.emplace(
108-
unwrapped_tl0,
109-
GofInfo(&scalability_structures_[current_ss_idx_], frame->Id()));
120+
gof_info_.emplace(unwrapped_tl0,
121+
GofInfo(&scalability_structures_[current_ss_idx_],
122+
frame->Id(), frame->last_seq_num()));
110123
}
111124

112125
const auto gof_info_it = gof_info_.find(unwrapped_tl0);
@@ -147,7 +160,8 @@ RtpVp9RefFinder::FrameDecision RtpVp9RefFinder::ManageFrameInternal(
147160
if (codec_header.temporal_idx == 0) {
148161
gof_info_it = gof_info_
149162
.emplace(unwrapped_tl0,
150-
GofInfo(gof_info_it->second.gof, frame->Id()))
163+
GofInfo(gof_info_it->second.gof, frame->Id(),
164+
frame->last_seq_num()))
151165
.first;
152166
}
153167

modules/video_coding/rtp_vp9_ref_finder.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,13 @@ class RtpVp9RefFinder {
4242
enum FrameDecision { kStash, kHandOff, kDrop };
4343

4444
struct GofInfo {
45-
GofInfo(GofInfoVP9* gof, uint16_t last_picture_id)
46-
: gof(gof), last_picture_id(last_picture_id) {}
45+
GofInfo(GofInfoVP9* gof, uint16_t last_picture_id, uint16_t last_seq_num)
46+
: gof(gof),
47+
last_picture_id(last_picture_id),
48+
last_seq_num(last_seq_num) {}
4749
GofInfoVP9* gof;
4850
uint16_t last_picture_id;
51+
uint16_t last_seq_num;
4952
};
5053

5154
FrameDecision ManageFrameInternal(RtpFrameObject* frame);

modules/video_coding/rtp_vp9_ref_finder_unittest.cc

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ using ::testing::Matches;
2323
using ::testing::MatchResultListener;
2424
using ::testing::Pointee;
2525
using ::testing::Property;
26+
using ::testing::SizeIs;
2627
using ::testing::UnorderedElementsAreArray;
2728

2829
namespace webrtc {
@@ -661,6 +662,24 @@ TEST_F(RtpVp9RefFinderTest, GofTl0Jump) {
661662
Insert(Frame().Pid(1).SidAndTid(0, 0).Tl0(0).Gof(&ss));
662663
}
663664

665+
TEST_F(RtpVp9RefFinderTest, DontDiscardNewerFramesWithWrappedTl0) {
666+
GofInfoVP9 ss;
667+
ss.SetGofInfoVP9(kTemporalStructureMode1);
668+
669+
Insert(
670+
Frame().Pid(0).SidAndTid(0, 0).Tl0(0).SeqNum(0, 0).AsKeyFrame().Gof(&ss));
671+
// ... 254 frames are lost ...
672+
Insert(Frame()
673+
.Pid(255)
674+
.SidAndTid(0, 0)
675+
.Tl0(255)
676+
.SeqNum(255, 255)
677+
.AsKeyFrame()
678+
.Gof(&ss));
679+
680+
EXPECT_THAT(frames_, SizeIs(2));
681+
}
682+
664683
TEST_F(RtpVp9RefFinderTest, GofTidTooHigh) {
665684
const int kMaxTemporalLayers = 5;
666685
GofInfoVP9 ss;

0 commit comments

Comments
 (0)