blob: 42ef4ae1e0bbde6530df2a681c197b8d70cb5408 [file] [log] [blame]
/*
* Copyright 2025 The WebRTC project authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "video/corruption_detection/evaluation/av1_qp_parser.h"
#include <cstdint>
#include <optional>
#include "api/array_view.h"
#include "third_party/libgav1/src/src/buffer_pool.h"
#include "third_party/libgav1/src/src/gav1/status_code.h"
#include "third_party/libgav1/src/src/obu_parser.h"
namespace webrtc {
std::optional<uint32_t> Av1QpParser::Parse(ArrayView<const uint8_t> frame_data,
int operating_point) {
libgav1::RefCountedBufferPtr curr_frame;
libgav1::ObuParser parser(frame_data.data(), frame_data.size(),
operating_point, &buffer_pool_, &decoder_state_);
uint8_t highest_acceptable_spatial_layers_qp;
// Since the temporal unit can have more than 1 frame in scalable coding, we
// go through all the frame's.
while (parser.HasData()) {
// If the frame is not a keyframe, the `parser` must know the information
// from `sequence_header` to parse the OBU properly.
if (sequence_header_) {
parser.set_sequence_header(*sequence_header_);
}
if (parser.ParseOneFrame(&curr_frame) != libgav1::kStatusOk) {
return std::nullopt;
}
// Get QP from frame header.
const auto& frame_header = parser.frame_header();
// frame_header.quantizer.base_index returns 0 if based on `operating_point`
// we are not interested in higher spatial layer's QP values.
if (frame_header.quantizer.base_index != 0) {
highest_acceptable_spatial_layers_qp = frame_header.quantizer.base_index;
}
// Update the state for the next frame.
if (parser.sequence_header_changed()) {
sequence_header_ = parser.sequence_header();
}
decoder_state_.UpdateReferenceFrames(curr_frame,
frame_header.refresh_frame_flags);
}
return highest_acceptable_spatial_layers_qp;
}
} // namespace webrtc