media/gpu/v4l2: setup additional frame parameters for v4l2 stateless decoder
This CL sets up loop filter, quantization, segmentation, probabilities related frame parameters for v4l2_ctrl_vp9_frame_decode_params using frame header as well as Vp9Parser. This is needed for request API to make VIDIOC_S_EXT_CTRLS ioctl call. Bug: b:202847867 TEST: v4l2_stateful_decoder --video crowd_run_256X144_fr15_bd8_8buf_l1_20210312.ivf on asurada Change-Id: I139d8230dcbd8744e2f914023445ceb458a4e7ca Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3224501 Reviewed-by: Miguel Casas <mcasas@chromium.org> Commit-Queue: Steve Cho <stevecho@chromium.org> Cr-Commit-Position: refs/heads/main@{#932686}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
268aae0337
commit
5be415d687
@ -12,11 +12,14 @@
|
||||
#include "base/memory/ptr_util.h"
|
||||
#include "media/filters/ivf_parser.h"
|
||||
#include "media/filters/vp9_parser.h"
|
||||
#include "media/gpu/macros.h"
|
||||
|
||||
namespace media {
|
||||
|
||||
namespace v4l2_test {
|
||||
|
||||
#define SET_IF(bit_field, cond, mask) (bit_field) |= ((cond) ? (mask) : 0)
|
||||
|
||||
inline void conditionally_set_flag(
|
||||
struct v4l2_ctrl_vp9_frame_decode_params& params,
|
||||
bool condition,
|
||||
@ -24,6 +27,101 @@ inline void conditionally_set_flag(
|
||||
params.flags |= condition ? flag : 0;
|
||||
}
|
||||
|
||||
void FillV4L2VP9QuantizationParams(
|
||||
const Vp9QuantizationParams& vp9_quant_params,
|
||||
struct v4l2_vp9_quantization* v4l2_quant) {
|
||||
v4l2_quant->base_q_idx =
|
||||
base::checked_cast<__u8>(vp9_quant_params.base_q_idx);
|
||||
v4l2_quant->delta_q_y_dc =
|
||||
base::checked_cast<__s8>(vp9_quant_params.delta_q_y_dc);
|
||||
v4l2_quant->delta_q_uv_dc =
|
||||
base::checked_cast<__s8>(vp9_quant_params.delta_q_uv_dc);
|
||||
v4l2_quant->delta_q_uv_ac =
|
||||
base::checked_cast<__s8>(vp9_quant_params.delta_q_uv_ac);
|
||||
}
|
||||
|
||||
void FillV4L2VP9MvProbsParams(const Vp9FrameContext& vp9_ctx,
|
||||
struct v4l2_vp9_mv_probabilities* v4l2_mv_probs) {
|
||||
SafeArrayMemcpy(v4l2_mv_probs->joint, vp9_ctx.mv_joint_probs);
|
||||
SafeArrayMemcpy(v4l2_mv_probs->sign, vp9_ctx.mv_sign_prob);
|
||||
SafeArrayMemcpy(v4l2_mv_probs->class_, vp9_ctx.mv_class_probs);
|
||||
SafeArrayMemcpy(v4l2_mv_probs->class0_bit, vp9_ctx.mv_class0_bit_prob);
|
||||
SafeArrayMemcpy(v4l2_mv_probs->bits, vp9_ctx.mv_bits_prob);
|
||||
SafeArrayMemcpy(v4l2_mv_probs->class0_fr, vp9_ctx.mv_class0_fr_probs);
|
||||
SafeArrayMemcpy(v4l2_mv_probs->fr, vp9_ctx.mv_fr_probs);
|
||||
SafeArrayMemcpy(v4l2_mv_probs->class0_hp, vp9_ctx.mv_class0_hp_prob);
|
||||
SafeArrayMemcpy(v4l2_mv_probs->hp, vp9_ctx.mv_hp_prob);
|
||||
}
|
||||
|
||||
void FillV4L2VP9ProbsParams(const Vp9FrameContext& vp9_ctx,
|
||||
struct v4l2_vp9_probabilities* v4l2_probs) {
|
||||
SafeArrayMemcpy(v4l2_probs->tx8, vp9_ctx.tx_probs_8x8);
|
||||
SafeArrayMemcpy(v4l2_probs->tx16, vp9_ctx.tx_probs_16x16);
|
||||
SafeArrayMemcpy(v4l2_probs->tx32, vp9_ctx.tx_probs_32x32);
|
||||
SafeArrayMemcpy(v4l2_probs->coef, vp9_ctx.coef_probs);
|
||||
SafeArrayMemcpy(v4l2_probs->skip, vp9_ctx.skip_prob);
|
||||
SafeArrayMemcpy(v4l2_probs->inter_mode, vp9_ctx.inter_mode_probs);
|
||||
SafeArrayMemcpy(v4l2_probs->interp_filter, vp9_ctx.interp_filter_probs);
|
||||
SafeArrayMemcpy(v4l2_probs->is_inter, vp9_ctx.is_inter_prob);
|
||||
SafeArrayMemcpy(v4l2_probs->comp_mode, vp9_ctx.comp_mode_prob);
|
||||
SafeArrayMemcpy(v4l2_probs->single_ref, vp9_ctx.single_ref_prob);
|
||||
SafeArrayMemcpy(v4l2_probs->comp_ref, vp9_ctx.comp_ref_prob);
|
||||
SafeArrayMemcpy(v4l2_probs->y_mode, vp9_ctx.y_mode_probs);
|
||||
SafeArrayMemcpy(v4l2_probs->uv_mode, vp9_ctx.uv_mode_probs);
|
||||
SafeArrayMemcpy(v4l2_probs->partition, vp9_ctx.partition_probs);
|
||||
|
||||
FillV4L2VP9MvProbsParams(vp9_ctx, &v4l2_probs->mv);
|
||||
}
|
||||
|
||||
void FillV4L2VP9LoopFilterParams(const Vp9LoopFilterParams& vp9_lf_params,
|
||||
struct v4l2_vp9_loop_filter* v4l2_lf) {
|
||||
SET_IF(v4l2_lf->flags, vp9_lf_params.delta_enabled,
|
||||
V4L2_VP9_LOOP_FILTER_FLAG_DELTA_ENABLED);
|
||||
|
||||
SET_IF(v4l2_lf->flags, vp9_lf_params.delta_update,
|
||||
V4L2_VP9_LOOP_FILTER_FLAG_DELTA_UPDATE);
|
||||
|
||||
v4l2_lf->level = vp9_lf_params.level;
|
||||
v4l2_lf->sharpness = vp9_lf_params.sharpness;
|
||||
SafeArrayMemcpy(v4l2_lf->ref_deltas, vp9_lf_params.ref_deltas);
|
||||
SafeArrayMemcpy(v4l2_lf->mode_deltas, vp9_lf_params.mode_deltas);
|
||||
SafeArrayMemcpy(v4l2_lf->level_lookup, vp9_lf_params.lvl);
|
||||
}
|
||||
|
||||
void FillV4L2VP9SegmentationParams(const Vp9SegmentationParams& vp9_seg_params,
|
||||
struct v4l2_vp9_segmentation* v4l2_seg) {
|
||||
SET_IF(v4l2_seg->flags, vp9_seg_params.enabled,
|
||||
V4L2_VP9_SEGMENTATION_FLAG_ENABLED);
|
||||
SET_IF(v4l2_seg->flags, vp9_seg_params.update_map,
|
||||
V4L2_VP9_SEGMENTATION_FLAG_UPDATE_MAP);
|
||||
SET_IF(v4l2_seg->flags, vp9_seg_params.temporal_update,
|
||||
V4L2_VP9_SEGMENTATION_FLAG_TEMPORAL_UPDATE);
|
||||
SET_IF(v4l2_seg->flags, vp9_seg_params.update_data,
|
||||
V4L2_VP9_SEGMENTATION_FLAG_UPDATE_DATA);
|
||||
SET_IF(v4l2_seg->flags, vp9_seg_params.abs_or_delta_update,
|
||||
V4L2_VP9_SEGMENTATION_FLAG_ABS_OR_DELTA_UPDATE);
|
||||
|
||||
SafeArrayMemcpy(v4l2_seg->tree_probs, vp9_seg_params.tree_probs);
|
||||
SafeArrayMemcpy(v4l2_seg->pred_probs, vp9_seg_params.pred_probs);
|
||||
|
||||
static_assert(static_cast<size_t>(Vp9SegmentationParams::SEG_LVL_MAX) ==
|
||||
static_cast<size_t>(V4L2_VP9_SEGMENT_FEATURE_CNT),
|
||||
"mismatch in number of segmentation features");
|
||||
|
||||
for (size_t j = 0;
|
||||
j < std::extent<decltype(vp9_seg_params.feature_enabled), 0>::value;
|
||||
j++) {
|
||||
for (size_t i = 0;
|
||||
i < std::extent<decltype(vp9_seg_params.feature_enabled), 1>::value;
|
||||
i++) {
|
||||
if (vp9_seg_params.feature_enabled[j][i])
|
||||
v4l2_seg->feature_enabled[j] |= V4L2_VP9_SEGMENT_FEATURE_ENABLED(i);
|
||||
}
|
||||
}
|
||||
|
||||
SafeArrayMemcpy(v4l2_seg->feature_data, vp9_seg_params.feature_data);
|
||||
}
|
||||
|
||||
Vp9Decoder::Vp9Decoder(std::unique_ptr<IvfParser> ivf_parser,
|
||||
std::unique_ptr<V4L2IoctlShim> v4l2_ioctl,
|
||||
std::unique_ptr<V4L2Queue> OUTPUT_queue,
|
||||
@ -227,7 +325,6 @@ Vp9Decoder::Result Vp9Decoder::DecodeNextFrame() {
|
||||
v4l2_frame_params.frame_context_idx =
|
||||
frame_hdr.frame_context_idx_to_save_probs;
|
||||
v4l2_frame_params.bit_depth = frame_hdr.bit_depth;
|
||||
|
||||
v4l2_frame_params.interpolation_filter = frame_hdr.interpolation_filter;
|
||||
v4l2_frame_params.tile_cols_log2 = frame_hdr.tile_cols_log2;
|
||||
v4l2_frame_params.tile_rows_log2 = frame_hdr.tile_rows_log2;
|
||||
@ -246,6 +343,16 @@ Vp9Decoder::Result Vp9Decoder::DecodeNextFrame() {
|
||||
v4l2_frame_params.render_height_minus_1 = frame_hdr.render_height - 1;
|
||||
|
||||
// TODO(stevecho): fill in the rest of |v4l2_frame_params| fields.
|
||||
FillV4L2VP9QuantizationParams(frame_hdr.quant_params,
|
||||
&v4l2_frame_params.quant);
|
||||
FillV4L2VP9ProbsParams(frame_hdr.frame_context, &v4l2_frame_params.probs);
|
||||
|
||||
const Vp9Parser::Context& context = vp9_parser_->context();
|
||||
const Vp9LoopFilterParams& lf_params = context.loop_filter();
|
||||
const Vp9SegmentationParams& segm_params = context.segmentation();
|
||||
|
||||
FillV4L2VP9LoopFilterParams(lf_params, &v4l2_frame_params.lf);
|
||||
FillV4L2VP9SegmentationParams(segm_params, &v4l2_frame_params.seg);
|
||||
|
||||
return Vp9Decoder::kOk;
|
||||
}
|
||||
|
Reference in New Issue
Block a user