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:

committed by
Commit Bot

parent
8b4e92d0a5
commit
3c30c9cb9f
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user