Decode base reference frame if current layer was dropped.

If frame of current layer was dropped, pass base frame to decoder if
non_ref_for_inter_layer_pred is set to true.

Bug: none
Change-Id: If7bf5220b74f424106edf74867c9afa8cc2b1ec5
Reviewed-on: https://webrtc-review.googlesource.com/73440
Reviewed-by: Rasmus Brandt <brandtr@webrtc.org>
Commit-Queue: Sergey Silkin <ssilkin@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#23074}
This commit is contained in:
Sergey Silkin
2018-05-02 09:18:48 +02:00
committed by Commit Bot
parent 8b4e92d0a5
commit 3c30c9cb9f
3 changed files with 14 additions and 6 deletions

View File

@ -33,6 +33,7 @@ std::string FrameStatistics::ToString() const {
ss << " spatial_idx " << spatial_idx;
ss << " temporal_idx " << temporal_idx;
ss << " inter_layer_predicted " << inter_layer_predicted;
ss << " non_ref_for_inter_layer_pred " << non_ref_for_inter_layer_pred;
ss << " frame_type " << frame_type;
ss << " length_bytes " << length_bytes;
ss << " qp " << qp;

View File

@ -43,6 +43,7 @@ struct FrameStatistics {
size_t spatial_idx = 0;
size_t temporal_idx = 0;
bool inter_layer_predicted = false;
bool non_ref_for_inter_layer_pred = true;
// H264 specific.
size_t max_nalu_size_bytes = 0;

View File

@ -354,14 +354,16 @@ void VideoProcessor::FrameEncoded(
frame_stat->qp = encoded_image.qp_;
const size_t num_spatial_layers = config_.NumberOfSpatialLayers();
// TODO(ssilkin): Get actual value. For now assume inter-layer prediction
// is enabled for all frames.
const bool inter_layer_prediction = num_spatial_layers > 1;
bool end_of_picture = false;
if (codec_type == kVideoCodecVP9) {
const CodecSpecificInfoVP9& vp9_info = codec_specific.codecSpecific.VP9;
frame_stat->inter_layer_predicted = vp9_info.inter_layer_predicted;
frame_stat->non_ref_for_inter_layer_pred =
vp9_info.non_ref_for_inter_layer_pred;
end_of_picture = vp9_info.end_of_picture;
} else {
frame_stat->inter_layer_predicted = false;
frame_stat->non_ref_for_inter_layer_pred = true;
}
const webrtc::EncodedImage* encoded_image_for_decode = &encoded_image;
@ -376,20 +378,24 @@ void VideoProcessor::FrameEncoded(
if (config_.decode) {
DecodeFrame(*encoded_image_for_decode, spatial_idx);
if (end_of_picture && inter_layer_prediction) {
if (end_of_picture && num_spatial_layers > 1) {
// If inter-layer prediction is enabled and upper layer was dropped then
// base layer should be passed to upper layer decoder. Otherwise decoder
// won't be able to decode next superframe.
const EncodedImage* base_image = nullptr;
const FrameStatistics* base_stat = nullptr;
for (size_t i = 0; i < num_spatial_layers; ++i) {
const bool layer_dropped = last_decoded_frame_num_[i] < frame_number;
const bool layer_dropped = (first_decoded_frame_[i] ||
last_decoded_frame_num_[i] < frame_number);
// Ensure current layer was decoded.
RTC_CHECK(layer_dropped == false || i != spatial_idx);
if (!layer_dropped) {
base_image = &merged_encoded_frames_[i];
} else if (base_image) {
base_stat =
stats_->GetFrameWithTimestamp(encoded_image._timeStamp, i);
} else if (base_image && !base_stat->non_ref_for_inter_layer_pred) {
DecodeFrame(*base_image, i);
}
}