Stop using inter_layer_predicted flag for VP9.

Instead of signaling an inter layer dependency with the inter_layer_prediction flag we instead flatten the frame IDs so that an inter layer dependency can be signaled as a regular frame reference.

Bug: webrtc:12206, webrtc:12221
Change-Id: I0390fd3d0f5494cde59eece227db938dbc5d7992
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/196648
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Commit-Queue: Philip Eliasson <philipel@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#32808}
This commit is contained in:
philipel
2020-12-08 17:36:53 +01:00
committed by Commit Bot
parent 9795306330
commit 0cb7326b54
6 changed files with 196 additions and 225 deletions

View File

@ -394,49 +394,6 @@ void FrameBuffer::CancelCallback() {
callback_checker_.Detach();
}
bool FrameBuffer::IsCompleteSuperFrame(const EncodedFrame& frame) {
if (frame.inter_layer_predicted) {
// Check that all previous spatial layers are already inserted.
VideoLayerFrameId id = frame.id;
RTC_DCHECK_GT(id.spatial_layer, 0);
--id.spatial_layer;
FrameMap::iterator prev_frame = frames_.find(id);
if (prev_frame == frames_.end() || !prev_frame->second.frame)
return false;
while (prev_frame->second.frame->inter_layer_predicted) {
if (prev_frame == frames_.begin())
return false;
--prev_frame;
--id.spatial_layer;
if (!prev_frame->second.frame ||
prev_frame->first.picture_id != id.picture_id ||
prev_frame->first.spatial_layer != id.spatial_layer) {
return false;
}
}
}
if (!frame.is_last_spatial_layer) {
// Check that all following spatial layers are already inserted.
VideoLayerFrameId id = frame.id;
++id.spatial_layer;
FrameMap::iterator next_frame = frames_.find(id);
if (next_frame == frames_.end() || !next_frame->second.frame)
return false;
while (!next_frame->second.frame->is_last_spatial_layer) {
++next_frame;
++id.spatial_layer;
if (next_frame == frames_.end() || !next_frame->second.frame ||
next_frame->first.picture_id != id.picture_id ||
next_frame->first.spatial_layer != id.spatial_layer) {
return false;
}
}
}
return true;
}
int64_t FrameBuffer::InsertFrame(std::unique_ptr<EncodedFrame> frame) {
TRACE_EVENT0("webrtc", "FrameBuffer::InsertFrame");
RTC_DCHECK(frame);
@ -523,7 +480,9 @@ int64_t FrameBuffer::InsertFrame(std::unique_ptr<EncodedFrame> frame) {
if (!frame->delayed_by_retransmission())
timing_->IncomingTimestamp(frame->Timestamp(), frame->ReceivedTime());
if (stats_callback_ && IsCompleteSuperFrame(*frame)) {
// It can happen that a frame will be reported as fully received even if a
// lower spatial layer frame is missing.
if (stats_callback_ && frame->is_last_spatial_layer) {
stats_callback_->OnCompleteFrame(frame->is_keyframe(), frame->size(),
frame->contentType());
}
@ -736,14 +695,14 @@ EncodedFrame* FrameBuffer::CombineAndDeleteFrames(
}
auto encoded_image_buffer = EncodedImageBuffer::Create(total_length);
uint8_t* buffer = encoded_image_buffer->data();
first_frame->SetSpatialLayerFrameSize(first_frame->id.spatial_layer,
first_frame->SetSpatialLayerFrameSize(first_frame->SpatialIndex().value_or(0),
first_frame->size());
memcpy(buffer, first_frame->data(), first_frame->size());
buffer += first_frame->size();
// Spatial index of combined frame is set equal to spatial index of its top
// spatial layer.
first_frame->SetSpatialIndex(last_frame->id.spatial_layer);
first_frame->SetSpatialIndex(last_frame->SpatialIndex().value_or(0));
first_frame->id.spatial_layer = last_frame->id.spatial_layer;
first_frame->video_timing_mutable()->network2_timestamp_ms =
@ -754,8 +713,8 @@ EncodedFrame* FrameBuffer::CombineAndDeleteFrames(
// Append all remaining frames to the first one.
for (size_t i = 1; i < frames.size(); ++i) {
EncodedFrame* next_frame = frames[i];
first_frame->SetSpatialLayerFrameSize(next_frame->id.spatial_layer,
next_frame->size());
first_frame->SetSpatialLayerFrameSize(
next_frame->SpatialIndex().value_or(0), next_frame->size());
memcpy(buffer, next_frame->data(), next_frame->size());
buffer += next_frame->size();
delete next_frame;