The libva AV1 layouts, the AuPlan conversion and the Linux rung's AV1 arm, completing AV1 across all three hardware backends. Pin-only. Layouts measured, not transcribed: the committed probe grew the AV1 structures and every size and offset it printed against libva 2.23.0 is a compile-time assertion. Three that a hand-count gets wrong — the picture buffer is align 8 because anchor_frames_list is a pointer, inserting seven bytes of padding; seg_info and film_grain_info carry their own padding tails inside the parent; and THREE of AV1's six bit-field unions are narrower than a word (one uint8_t, two uint16_t), so a u32 packer over any of them writes through its neighbour. This is the fifth way this program has had to spell "which pictures does this frame use", and it is unlike the other four: ref_frame_map is indexed by SLOT and holds actual VASurfaceIDs rather than indices into anything, ref_frame_idx is indexed by NAME and holds slots taken from the header — not from the plan's refs, where a lost reference leaves a hole and a hole is not a slot — global motion is picture-level, and there is no per-reference size field at all. Established from va_dec_av1.h and libavcodec's vaapi_av1.c, and stated in the module docs so the next reader does not re-derive it. Review verified the whole happy path — every layout assertion re-measured, every packer width and bit position, the reference convention, the num_elements buffer shape — and found both defects on FAILURE paths, neither reachable on the vendored vector. A conversion refusal permanently desynced the ledger. The mutation block sat after the tile walk, so any tile-shape refusal left the planner holding a picture with no ledger slot — and the resulting UnresolvedReference fires before that block too, so it never repaired. Every later access unit hard-errored until a shown key frame: one lost packet costing a GOP. The arm's own doc already warned that skipping conversion would desynchronise the slot map; the refusal door did exactly what the skip door was written to avoid. The block is hoisted, and a tile-shape refusal on an already-damaged plan is now concealed rather than refused. Fixing that exposed a sharper edge: the conversion can release a slot and reassign it to the refused picture in one call, so the binding would still hold the PREVIOUS picture's surface — a wrong reference rather than a missing one, which nothing downstream could notice. The caller now clears the binding unconditionally on the refusal path. And a damaged frame's surface was never written yet was bound as a reference and left in pending, so a later clean show_existing_frame would claim it with damaged = false and ship uninitialised GPU memory to the presenter — on several drivers another client's framebuffer. The justification quoted half of va_dec_av1.h; its next sentence gives the remedy, which is to point the problematic index at an alternative buffer. Damaged frames now submit as they do on the other two arms, with live surfaces substituted for invalid entries and reported as a bitmask — preferring a reference that really decoded over the decode target, and keeping libavcodec's deliberate all-invalid map on a shown key frame. Film grain is refused rather than decoded wrong: libva wants two surfaces, one ungrained for prediction and one grained for output, and libavcodec allocates a second frame for exactly that. The gate now sits after the mutation block so a grained frame costs itself rather than the GOP, and stays per-AU rather than per-sequence because a stream that merely DECLARES the tool decodes here perfectly. ⚠ Residual, flagged not fixed: a picture decoded from substituted references can still be shown by a later show_existing_frame. It is decoded memory now rather than uninitialised, and it is what the H.264/H.265 arms do, but tracking "this was concealed" through to display needs new session state. Gates: macOS fmt/clippy/125 tests/cargo-doc, container clippy -D warnings over seven crates and 548 tests, workspace check. pf-bitstream's diff is comment-only — verified — so the Vulkan rung's 250/250 stands untouched. Nothing here has decoded a frame: no VAAPI hardware is reachable.
510 lines
26 KiB
C
510 lines
26 KiB
C
/*
|
|
* Layout probe for the hand-declared libva structures in `src/va.rs`,
|
|
* `src/va_h265.rs` and `src/va_av1.rs`.
|
|
*
|
|
* Those modules declare VAAPI's decode buffers as `#[repr(C)]` Rust structs, because
|
|
* this crate must build on macOS and in the Linux container where libva headers need
|
|
* not exist. This file is how those declarations were CHECKED rather than eyeballed,
|
|
* and it is committed so the check is reproducible instead of a claim in a commit
|
|
* message.
|
|
*
|
|
* Run it against real headers (no Linux box required):
|
|
*
|
|
* docker run --rm --platform linux/amd64 -v "$PWD/crates/pf-vaadec:/w" -w /w \
|
|
* pf-lxcheck2 bash -lc 'apt-get update -qq && apt-get install -y -qq libva-dev \
|
|
* && gcc -w -O0 layout-probe.c -o /tmp/probe && /tmp/probe'
|
|
*
|
|
* Every number it prints is pinned as a `const` assertion at the bottom of
|
|
* `src/va.rs`, so a transcription mistake is a compile error. The bit-field section
|
|
* exists because C bit-field allocation order is ABI-defined, not standardised:
|
|
* it PROVES least-significant-bit-first on this ABI rather than assuming it.
|
|
*
|
|
* Last run against libva 2.23.0-1ubuntu1, x86_64-linux-gnu.
|
|
*/
|
|
#include <stdio.h>
|
|
#include <stddef.h>
|
|
#include <va/va.h>
|
|
#include <va/va_dec_hevc.h>
|
|
#include <va/va_dec_av1.h>
|
|
#include <va/va_drmcommon.h>
|
|
|
|
#define S(t) printf("size %-34s %zu align %zu\n", #t, sizeof(t), _Alignof(t))
|
|
#define O(t, f) printf("off %-20s %-28s %zu\n", #t, #f, offsetof(t, f))
|
|
|
|
int main(void) {
|
|
S(VAPictureH264);
|
|
O(VAPictureH264, picture_id);
|
|
O(VAPictureH264, frame_idx);
|
|
O(VAPictureH264, flags);
|
|
O(VAPictureH264, TopFieldOrderCnt);
|
|
O(VAPictureH264, BottomFieldOrderCnt);
|
|
O(VAPictureH264, va_reserved);
|
|
|
|
S(VAPictureParameterBufferH264);
|
|
O(VAPictureParameterBufferH264, CurrPic);
|
|
O(VAPictureParameterBufferH264, ReferenceFrames);
|
|
O(VAPictureParameterBufferH264, picture_width_in_mbs_minus1);
|
|
O(VAPictureParameterBufferH264, picture_height_in_mbs_minus1);
|
|
O(VAPictureParameterBufferH264, bit_depth_luma_minus8);
|
|
O(VAPictureParameterBufferH264, bit_depth_chroma_minus8);
|
|
O(VAPictureParameterBufferH264, num_ref_frames);
|
|
O(VAPictureParameterBufferH264, seq_fields);
|
|
O(VAPictureParameterBufferH264, num_slice_groups_minus1);
|
|
O(VAPictureParameterBufferH264, slice_group_map_type);
|
|
O(VAPictureParameterBufferH264, slice_group_change_rate_minus1);
|
|
O(VAPictureParameterBufferH264, pic_init_qp_minus26);
|
|
O(VAPictureParameterBufferH264, pic_init_qs_minus26);
|
|
O(VAPictureParameterBufferH264, chroma_qp_index_offset);
|
|
O(VAPictureParameterBufferH264, second_chroma_qp_index_offset);
|
|
O(VAPictureParameterBufferH264, pic_fields);
|
|
O(VAPictureParameterBufferH264, frame_num);
|
|
O(VAPictureParameterBufferH264, va_reserved);
|
|
|
|
S(VAIQMatrixBufferH264);
|
|
O(VAIQMatrixBufferH264, ScalingList4x4);
|
|
O(VAIQMatrixBufferH264, ScalingList8x8);
|
|
O(VAIQMatrixBufferH264, va_reserved);
|
|
|
|
S(VASliceParameterBufferH264);
|
|
O(VASliceParameterBufferH264, slice_data_size);
|
|
O(VASliceParameterBufferH264, slice_data_offset);
|
|
O(VASliceParameterBufferH264, slice_data_flag);
|
|
O(VASliceParameterBufferH264, slice_data_bit_offset);
|
|
O(VASliceParameterBufferH264, first_mb_in_slice);
|
|
O(VASliceParameterBufferH264, slice_type);
|
|
O(VASliceParameterBufferH264, direct_spatial_mv_pred_flag);
|
|
O(VASliceParameterBufferH264, num_ref_idx_l0_active_minus1);
|
|
O(VASliceParameterBufferH264, num_ref_idx_l1_active_minus1);
|
|
O(VASliceParameterBufferH264, cabac_init_idc);
|
|
O(VASliceParameterBufferH264, slice_qp_delta);
|
|
O(VASliceParameterBufferH264, disable_deblocking_filter_idc);
|
|
O(VASliceParameterBufferH264, slice_alpha_c0_offset_div2);
|
|
O(VASliceParameterBufferH264, slice_beta_offset_div2);
|
|
O(VASliceParameterBufferH264, RefPicList0);
|
|
O(VASliceParameterBufferH264, RefPicList1);
|
|
O(VASliceParameterBufferH264, luma_log2_weight_denom);
|
|
O(VASliceParameterBufferH264, chroma_log2_weight_denom);
|
|
O(VASliceParameterBufferH264, luma_weight_l0_flag);
|
|
O(VASliceParameterBufferH264, luma_weight_l0);
|
|
O(VASliceParameterBufferH264, luma_offset_l0);
|
|
O(VASliceParameterBufferH264, chroma_weight_l0_flag);
|
|
O(VASliceParameterBufferH264, chroma_weight_l0);
|
|
O(VASliceParameterBufferH264, chroma_offset_l0);
|
|
O(VASliceParameterBufferH264, luma_weight_l1_flag);
|
|
O(VASliceParameterBufferH264, luma_weight_l1);
|
|
O(VASliceParameterBufferH264, luma_offset_l1);
|
|
O(VASliceParameterBufferH264, chroma_weight_l1_flag);
|
|
O(VASliceParameterBufferH264, chroma_weight_l1);
|
|
O(VASliceParameterBufferH264, chroma_offset_l1);
|
|
O(VASliceParameterBufferH264, va_reserved);
|
|
|
|
/* Bit-field allocation order: prove LSB-first rather than assume it. */
|
|
{
|
|
VAPictureParameterBufferH264 p;
|
|
p.seq_fields.value = 0;
|
|
p.seq_fields.bits.chroma_format_idc = 3;
|
|
printf("bits seq_fields.chroma_format_idc=3 -> value 0x%08x\n", p.seq_fields.value);
|
|
p.seq_fields.value = 0;
|
|
p.seq_fields.bits.log2_max_frame_num_minus4 = 0xf;
|
|
printf("bits seq_fields.log2_max_frame_num_minus4=0xf -> value 0x%08x\n", p.seq_fields.value);
|
|
p.pic_fields.value = 0;
|
|
p.pic_fields.bits.reference_pic_flag = 1;
|
|
printf("bits pic_fields.reference_pic_flag=1 -> value 0x%08x\n", p.pic_fields.value);
|
|
p.pic_fields.value = 0;
|
|
p.pic_fields.bits.weighted_bipred_idc = 3;
|
|
printf("bits pic_fields.weighted_bipred_idc=3 -> value 0x%08x\n", p.pic_fields.value);
|
|
}
|
|
|
|
/* ---- HEVC (va_dec_hevc.h) ---- */
|
|
S(VAPictureHEVC);
|
|
O(VAPictureHEVC, picture_id);
|
|
O(VAPictureHEVC, pic_order_cnt);
|
|
O(VAPictureHEVC, flags);
|
|
O(VAPictureHEVC, va_reserved);
|
|
|
|
S(VAPictureParameterBufferHEVC);
|
|
O(VAPictureParameterBufferHEVC, CurrPic);
|
|
O(VAPictureParameterBufferHEVC, ReferenceFrames);
|
|
O(VAPictureParameterBufferHEVC, pic_width_in_luma_samples);
|
|
O(VAPictureParameterBufferHEVC, pic_height_in_luma_samples);
|
|
O(VAPictureParameterBufferHEVC, pic_fields);
|
|
O(VAPictureParameterBufferHEVC, sps_max_dec_pic_buffering_minus1);
|
|
O(VAPictureParameterBufferHEVC, bit_depth_luma_minus8);
|
|
O(VAPictureParameterBufferHEVC, bit_depth_chroma_minus8);
|
|
O(VAPictureParameterBufferHEVC, pcm_sample_bit_depth_luma_minus1);
|
|
O(VAPictureParameterBufferHEVC, pcm_sample_bit_depth_chroma_minus1);
|
|
O(VAPictureParameterBufferHEVC, log2_min_luma_coding_block_size_minus3);
|
|
O(VAPictureParameterBufferHEVC, log2_diff_max_min_luma_coding_block_size);
|
|
O(VAPictureParameterBufferHEVC, log2_min_transform_block_size_minus2);
|
|
O(VAPictureParameterBufferHEVC, log2_diff_max_min_transform_block_size);
|
|
O(VAPictureParameterBufferHEVC, log2_min_pcm_luma_coding_block_size_minus3);
|
|
O(VAPictureParameterBufferHEVC, log2_diff_max_min_pcm_luma_coding_block_size);
|
|
O(VAPictureParameterBufferHEVC, max_transform_hierarchy_depth_intra);
|
|
O(VAPictureParameterBufferHEVC, max_transform_hierarchy_depth_inter);
|
|
O(VAPictureParameterBufferHEVC, init_qp_minus26);
|
|
O(VAPictureParameterBufferHEVC, diff_cu_qp_delta_depth);
|
|
O(VAPictureParameterBufferHEVC, pps_cb_qp_offset);
|
|
O(VAPictureParameterBufferHEVC, pps_cr_qp_offset);
|
|
O(VAPictureParameterBufferHEVC, log2_parallel_merge_level_minus2);
|
|
O(VAPictureParameterBufferHEVC, num_tile_columns_minus1);
|
|
O(VAPictureParameterBufferHEVC, num_tile_rows_minus1);
|
|
O(VAPictureParameterBufferHEVC, column_width_minus1);
|
|
O(VAPictureParameterBufferHEVC, row_height_minus1);
|
|
O(VAPictureParameterBufferHEVC, slice_parsing_fields);
|
|
O(VAPictureParameterBufferHEVC, log2_max_pic_order_cnt_lsb_minus4);
|
|
O(VAPictureParameterBufferHEVC, num_short_term_ref_pic_sets);
|
|
O(VAPictureParameterBufferHEVC, num_long_term_ref_pic_sps);
|
|
O(VAPictureParameterBufferHEVC, num_ref_idx_l0_default_active_minus1);
|
|
O(VAPictureParameterBufferHEVC, num_ref_idx_l1_default_active_minus1);
|
|
O(VAPictureParameterBufferHEVC, pps_beta_offset_div2);
|
|
O(VAPictureParameterBufferHEVC, pps_tc_offset_div2);
|
|
O(VAPictureParameterBufferHEVC, num_extra_slice_header_bits);
|
|
O(VAPictureParameterBufferHEVC, st_rps_bits);
|
|
O(VAPictureParameterBufferHEVC, va_reserved);
|
|
|
|
S(VASliceParameterBufferHEVC);
|
|
O(VASliceParameterBufferHEVC, slice_data_size);
|
|
O(VASliceParameterBufferHEVC, slice_data_offset);
|
|
O(VASliceParameterBufferHEVC, slice_data_flag);
|
|
O(VASliceParameterBufferHEVC, slice_data_byte_offset);
|
|
O(VASliceParameterBufferHEVC, slice_segment_address);
|
|
O(VASliceParameterBufferHEVC, RefPicList);
|
|
O(VASliceParameterBufferHEVC, LongSliceFlags);
|
|
O(VASliceParameterBufferHEVC, collocated_ref_idx);
|
|
O(VASliceParameterBufferHEVC, num_ref_idx_l0_active_minus1);
|
|
O(VASliceParameterBufferHEVC, num_ref_idx_l1_active_minus1);
|
|
O(VASliceParameterBufferHEVC, slice_qp_delta);
|
|
O(VASliceParameterBufferHEVC, slice_cb_qp_offset);
|
|
O(VASliceParameterBufferHEVC, slice_cr_qp_offset);
|
|
O(VASliceParameterBufferHEVC, slice_beta_offset_div2);
|
|
O(VASliceParameterBufferHEVC, slice_tc_offset_div2);
|
|
O(VASliceParameterBufferHEVC, luma_log2_weight_denom);
|
|
O(VASliceParameterBufferHEVC, delta_chroma_log2_weight_denom);
|
|
O(VASliceParameterBufferHEVC, delta_luma_weight_l0);
|
|
O(VASliceParameterBufferHEVC, luma_offset_l0);
|
|
O(VASliceParameterBufferHEVC, delta_chroma_weight_l0);
|
|
O(VASliceParameterBufferHEVC, ChromaOffsetL0);
|
|
O(VASliceParameterBufferHEVC, delta_luma_weight_l1);
|
|
O(VASliceParameterBufferHEVC, luma_offset_l1);
|
|
O(VASliceParameterBufferHEVC, delta_chroma_weight_l1);
|
|
O(VASliceParameterBufferHEVC, ChromaOffsetL1);
|
|
O(VASliceParameterBufferHEVC, five_minus_max_num_merge_cand);
|
|
O(VASliceParameterBufferHEVC, num_entry_point_offsets);
|
|
O(VASliceParameterBufferHEVC, entry_offset_to_subset_array);
|
|
O(VASliceParameterBufferHEVC, slice_data_num_emu_prevn_bytes);
|
|
O(VASliceParameterBufferHEVC, va_reserved);
|
|
|
|
S(VAIQMatrixBufferHEVC);
|
|
O(VAIQMatrixBufferHEVC, ScalingList4x4);
|
|
O(VAIQMatrixBufferHEVC, ScalingList8x8);
|
|
O(VAIQMatrixBufferHEVC, ScalingList16x16);
|
|
O(VAIQMatrixBufferHEVC, ScalingList32x32);
|
|
O(VAIQMatrixBufferHEVC, ScalingListDC16x16);
|
|
O(VAIQMatrixBufferHEVC, ScalingListDC32x32);
|
|
O(VAIQMatrixBufferHEVC, va_reserved);
|
|
|
|
{
|
|
VAPictureParameterBufferHEVC h;
|
|
h.pic_fields.value = 0;
|
|
h.pic_fields.bits.chroma_format_idc = 3;
|
|
printf("bits hevc pic_fields.chroma_format_idc=3 -> 0x%08x\n", h.pic_fields.value);
|
|
h.pic_fields.value = 0;
|
|
h.pic_fields.bits.NoBiPredFlag = 1;
|
|
printf("bits hevc pic_fields.NoBiPredFlag=1 -> 0x%08x\n", h.pic_fields.value);
|
|
h.slice_parsing_fields.value = 0;
|
|
h.slice_parsing_fields.bits.IntraPicFlag = 1;
|
|
printf("bits hevc slice_parsing_fields.IntraPicFlag=1 -> 0x%08x\n", h.slice_parsing_fields.value);
|
|
VASliceParameterBufferHEVC s;
|
|
s.LongSliceFlags.value = 0;
|
|
s.LongSliceFlags.fields.slice_type = 3;
|
|
printf("bits hevc LongSliceFlags.slice_type=3 -> 0x%08x\n", s.LongSliceFlags.value);
|
|
s.LongSliceFlags.value = 0;
|
|
s.LongSliceFlags.fields.slice_loop_filter_across_slices_enabled_flag = 1;
|
|
printf("bits hevc LongSliceFlags.slice_loop_filter_across=1 -> 0x%08x\n", s.LongSliceFlags.value);
|
|
}
|
|
|
|
/* ---- AV1 (va_dec_av1.h) ----
|
|
*
|
|
* Three things make this codec's layout worth measuring rather than counting:
|
|
* a POINTER member (`anchor_frames_list`) that forces eight-byte alignment and
|
|
* therefore padding nothing in the field list suggests; two bit-field unions
|
|
* that are NOT 32 bits wide (`loop_filter_info_fields` is a uint8_t,
|
|
* `qmatrix_fields` and `loop_restoration_fields` are uint16_t), so a u32 `pack`
|
|
* would write over the neighbouring field; and three nested structs whose own
|
|
* VA_PADDING_LOW tails sit inside the picture-parameter buffer.
|
|
*/
|
|
S(VASegmentationStructAV1);
|
|
O(VASegmentationStructAV1, segment_info_fields);
|
|
O(VASegmentationStructAV1, feature_data);
|
|
O(VASegmentationStructAV1, feature_mask);
|
|
O(VASegmentationStructAV1, va_reserved);
|
|
|
|
S(VAFilmGrainStructAV1);
|
|
O(VAFilmGrainStructAV1, film_grain_info_fields);
|
|
O(VAFilmGrainStructAV1, grain_seed);
|
|
O(VAFilmGrainStructAV1, num_y_points);
|
|
O(VAFilmGrainStructAV1, point_y_value);
|
|
O(VAFilmGrainStructAV1, point_y_scaling);
|
|
O(VAFilmGrainStructAV1, num_cb_points);
|
|
O(VAFilmGrainStructAV1, point_cb_value);
|
|
O(VAFilmGrainStructAV1, point_cb_scaling);
|
|
O(VAFilmGrainStructAV1, num_cr_points);
|
|
O(VAFilmGrainStructAV1, point_cr_value);
|
|
O(VAFilmGrainStructAV1, point_cr_scaling);
|
|
O(VAFilmGrainStructAV1, ar_coeffs_y);
|
|
O(VAFilmGrainStructAV1, ar_coeffs_cb);
|
|
O(VAFilmGrainStructAV1, ar_coeffs_cr);
|
|
O(VAFilmGrainStructAV1, cb_mult);
|
|
O(VAFilmGrainStructAV1, cb_luma_mult);
|
|
O(VAFilmGrainStructAV1, cb_offset);
|
|
O(VAFilmGrainStructAV1, cr_mult);
|
|
O(VAFilmGrainStructAV1, cr_luma_mult);
|
|
O(VAFilmGrainStructAV1, cr_offset);
|
|
O(VAFilmGrainStructAV1, va_reserved);
|
|
|
|
S(VAWarpedMotionParamsAV1);
|
|
O(VAWarpedMotionParamsAV1, wmtype);
|
|
O(VAWarpedMotionParamsAV1, wmmat);
|
|
O(VAWarpedMotionParamsAV1, invalid);
|
|
O(VAWarpedMotionParamsAV1, va_reserved);
|
|
|
|
S(VADecPictureParameterBufferAV1);
|
|
O(VADecPictureParameterBufferAV1, profile);
|
|
O(VADecPictureParameterBufferAV1, order_hint_bits_minus_1);
|
|
O(VADecPictureParameterBufferAV1, bit_depth_idx);
|
|
O(VADecPictureParameterBufferAV1, matrix_coefficients);
|
|
O(VADecPictureParameterBufferAV1, seq_info_fields);
|
|
O(VADecPictureParameterBufferAV1, current_frame);
|
|
O(VADecPictureParameterBufferAV1, current_display_picture);
|
|
O(VADecPictureParameterBufferAV1, anchor_frames_num);
|
|
O(VADecPictureParameterBufferAV1, anchor_frames_list);
|
|
O(VADecPictureParameterBufferAV1, frame_width_minus1);
|
|
O(VADecPictureParameterBufferAV1, frame_height_minus1);
|
|
O(VADecPictureParameterBufferAV1, output_frame_width_in_tiles_minus_1);
|
|
O(VADecPictureParameterBufferAV1, output_frame_height_in_tiles_minus_1);
|
|
O(VADecPictureParameterBufferAV1, ref_frame_map);
|
|
O(VADecPictureParameterBufferAV1, ref_frame_idx);
|
|
O(VADecPictureParameterBufferAV1, primary_ref_frame);
|
|
O(VADecPictureParameterBufferAV1, order_hint);
|
|
O(VADecPictureParameterBufferAV1, seg_info);
|
|
O(VADecPictureParameterBufferAV1, film_grain_info);
|
|
O(VADecPictureParameterBufferAV1, tile_cols);
|
|
O(VADecPictureParameterBufferAV1, tile_rows);
|
|
O(VADecPictureParameterBufferAV1, width_in_sbs_minus_1);
|
|
O(VADecPictureParameterBufferAV1, height_in_sbs_minus_1);
|
|
O(VADecPictureParameterBufferAV1, tile_count_minus_1);
|
|
O(VADecPictureParameterBufferAV1, context_update_tile_id);
|
|
O(VADecPictureParameterBufferAV1, pic_info_fields);
|
|
O(VADecPictureParameterBufferAV1, superres_scale_denominator);
|
|
O(VADecPictureParameterBufferAV1, interp_filter);
|
|
O(VADecPictureParameterBufferAV1, filter_level);
|
|
O(VADecPictureParameterBufferAV1, filter_level_u);
|
|
O(VADecPictureParameterBufferAV1, filter_level_v);
|
|
O(VADecPictureParameterBufferAV1, loop_filter_info_fields);
|
|
O(VADecPictureParameterBufferAV1, ref_deltas);
|
|
O(VADecPictureParameterBufferAV1, mode_deltas);
|
|
O(VADecPictureParameterBufferAV1, base_qindex);
|
|
O(VADecPictureParameterBufferAV1, y_dc_delta_q);
|
|
O(VADecPictureParameterBufferAV1, u_dc_delta_q);
|
|
O(VADecPictureParameterBufferAV1, u_ac_delta_q);
|
|
O(VADecPictureParameterBufferAV1, v_dc_delta_q);
|
|
O(VADecPictureParameterBufferAV1, v_ac_delta_q);
|
|
O(VADecPictureParameterBufferAV1, qmatrix_fields);
|
|
O(VADecPictureParameterBufferAV1, mode_control_fields);
|
|
O(VADecPictureParameterBufferAV1, cdef_damping_minus_3);
|
|
O(VADecPictureParameterBufferAV1, cdef_bits);
|
|
O(VADecPictureParameterBufferAV1, cdef_y_strengths);
|
|
O(VADecPictureParameterBufferAV1, cdef_uv_strengths);
|
|
O(VADecPictureParameterBufferAV1, loop_restoration_fields);
|
|
O(VADecPictureParameterBufferAV1, wm);
|
|
O(VADecPictureParameterBufferAV1, va_reserved);
|
|
printf("count VADecPictureParameterBufferAV1 wm %zu\n",
|
|
sizeof(((VADecPictureParameterBufferAV1 *)0)->wm) /
|
|
sizeof(((VADecPictureParameterBufferAV1 *)0)->wm[0]));
|
|
printf("size union seq_info_fields %zu\n",
|
|
sizeof(((VADecPictureParameterBufferAV1 *)0)->seq_info_fields));
|
|
printf("size union pic_info_fields %zu\n",
|
|
sizeof(((VADecPictureParameterBufferAV1 *)0)->pic_info_fields));
|
|
printf("size union loop_filter_info_fields %zu\n",
|
|
sizeof(((VADecPictureParameterBufferAV1 *)0)->loop_filter_info_fields));
|
|
printf("size union qmatrix_fields %zu\n",
|
|
sizeof(((VADecPictureParameterBufferAV1 *)0)->qmatrix_fields));
|
|
printf("size union mode_control_fields %zu\n",
|
|
sizeof(((VADecPictureParameterBufferAV1 *)0)->mode_control_fields));
|
|
printf("size union loop_restoration_fields %zu\n",
|
|
sizeof(((VADecPictureParameterBufferAV1 *)0)->loop_restoration_fields));
|
|
|
|
S(VASliceParameterBufferAV1);
|
|
O(VASliceParameterBufferAV1, slice_data_size);
|
|
O(VASliceParameterBufferAV1, slice_data_offset);
|
|
O(VASliceParameterBufferAV1, slice_data_flag);
|
|
O(VASliceParameterBufferAV1, tile_row);
|
|
O(VASliceParameterBufferAV1, tile_column);
|
|
O(VASliceParameterBufferAV1, tg_start);
|
|
O(VASliceParameterBufferAV1, tg_end);
|
|
O(VASliceParameterBufferAV1, anchor_frame_idx);
|
|
O(VASliceParameterBufferAV1, tile_idx_in_tile_list);
|
|
O(VASliceParameterBufferAV1, va_reserved);
|
|
|
|
/*
|
|
* Bit-field allocation order for AV1's six unions — one field at a time, the
|
|
* same proof the H.264 block makes, repeated here because three of these
|
|
* unions are NARROWER than a word and a mistake there is invisible in a u32.
|
|
*/
|
|
{
|
|
VADecPictureParameterBufferAV1 a;
|
|
a.seq_info_fields.value = 0;
|
|
a.seq_info_fields.fields.still_picture = 1;
|
|
printf("bits av1 seq_info.still_picture=1 -> 0x%08x\n", a.seq_info_fields.value);
|
|
a.seq_info_fields.value = 0;
|
|
a.seq_info_fields.fields.film_grain_params_present = 1;
|
|
printf("bits av1 seq_info.film_grain_params_present=1 -> 0x%08x\n",
|
|
a.seq_info_fields.value);
|
|
a.seq_info_fields.value = 0;
|
|
a.seq_info_fields.fields.mono_chrome = 1;
|
|
printf("bits av1 seq_info.mono_chrome=1 -> 0x%08x\n", a.seq_info_fields.value);
|
|
|
|
a.pic_info_fields.value = 0;
|
|
a.pic_info_fields.bits.frame_type = 3;
|
|
printf("bits av1 pic_info.frame_type=3 -> 0x%08x\n", a.pic_info_fields.value);
|
|
a.pic_info_fields.value = 0;
|
|
a.pic_info_fields.bits.large_scale_tile = 1;
|
|
printf("bits av1 pic_info.large_scale_tile=1 -> 0x%08x\n", a.pic_info_fields.value);
|
|
a.pic_info_fields.value = 0;
|
|
a.pic_info_fields.bits.use_ref_frame_mvs = 1;
|
|
printf("bits av1 pic_info.use_ref_frame_mvs=1 -> 0x%08x\n", a.pic_info_fields.value);
|
|
|
|
a.loop_filter_info_fields.value = 0;
|
|
a.loop_filter_info_fields.bits.sharpness_level = 7;
|
|
printf("bits av1 loop_filter_info.sharpness_level=7 -> 0x%02x\n",
|
|
a.loop_filter_info_fields.value);
|
|
a.loop_filter_info_fields.value = 0;
|
|
a.loop_filter_info_fields.bits.mode_ref_delta_update = 1;
|
|
printf("bits av1 loop_filter_info.mode_ref_delta_update=1 -> 0x%02x\n",
|
|
a.loop_filter_info_fields.value);
|
|
|
|
a.qmatrix_fields.value = 0;
|
|
a.qmatrix_fields.bits.using_qmatrix = 1;
|
|
printf("bits av1 qmatrix.using_qmatrix=1 -> 0x%04x\n", a.qmatrix_fields.value);
|
|
a.qmatrix_fields.value = 0;
|
|
a.qmatrix_fields.bits.qm_v = 0xf;
|
|
printf("bits av1 qmatrix.qm_v=0xf -> 0x%04x\n", a.qmatrix_fields.value);
|
|
|
|
a.mode_control_fields.value = 0;
|
|
a.mode_control_fields.bits.delta_q_present_flag = 1;
|
|
printf("bits av1 mode_control.delta_q_present_flag=1 -> 0x%08x\n",
|
|
a.mode_control_fields.value);
|
|
a.mode_control_fields.value = 0;
|
|
a.mode_control_fields.bits.skip_mode_present = 1;
|
|
printf("bits av1 mode_control.skip_mode_present=1 -> 0x%08x\n",
|
|
a.mode_control_fields.value);
|
|
a.mode_control_fields.value = 0;
|
|
a.mode_control_fields.bits.tx_mode = 3;
|
|
printf("bits av1 mode_control.tx_mode=3 -> 0x%08x\n", a.mode_control_fields.value);
|
|
|
|
a.loop_restoration_fields.value = 0;
|
|
a.loop_restoration_fields.bits.yframe_restoration_type = 3;
|
|
printf("bits av1 loop_restoration.yframe_restoration_type=3 -> 0x%04x\n",
|
|
a.loop_restoration_fields.value);
|
|
a.loop_restoration_fields.value = 0;
|
|
a.loop_restoration_fields.bits.lr_uv_shift = 1;
|
|
printf("bits av1 loop_restoration.lr_uv_shift=1 -> 0x%04x\n",
|
|
a.loop_restoration_fields.value);
|
|
|
|
VASegmentationStructAV1 s;
|
|
s.segment_info_fields.value = 0;
|
|
s.segment_info_fields.bits.enabled = 1;
|
|
printf("bits av1 segment_info.enabled=1 -> 0x%08x\n", s.segment_info_fields.value);
|
|
s.segment_info_fields.value = 0;
|
|
s.segment_info_fields.bits.update_data = 1;
|
|
printf("bits av1 segment_info.update_data=1 -> 0x%08x\n", s.segment_info_fields.value);
|
|
|
|
VAFilmGrainStructAV1 g;
|
|
g.film_grain_info_fields.value = 0;
|
|
g.film_grain_info_fields.bits.apply_grain = 1;
|
|
printf("bits av1 film_grain.apply_grain=1 -> 0x%08x\n", g.film_grain_info_fields.value);
|
|
g.film_grain_info_fields.value = 0;
|
|
g.film_grain_info_fields.bits.clip_to_restricted_range = 1;
|
|
printf("bits av1 film_grain.clip_to_restricted_range=1 -> 0x%08x\n",
|
|
g.film_grain_info_fields.value);
|
|
g.film_grain_info_fields.value = 0;
|
|
g.film_grain_info_fields.bits.grain_scale_shift = 3;
|
|
printf("bits av1 film_grain.grain_scale_shift=3 -> 0x%08x\n",
|
|
g.film_grain_info_fields.value);
|
|
}
|
|
|
|
printf("enum VAProfileAV1Profile0 %d\n", VAProfileAV1Profile0);
|
|
printf("enum VAProfileAV1Profile1 %d\n", VAProfileAV1Profile1);
|
|
printf("enum VAAV1TransformationIdentity %d\n", VAAV1TransformationIdentity);
|
|
printf("enum VAAV1TransformationTranslation %d\n", VAAV1TransformationTranslation);
|
|
printf("enum VAAV1TransformationRotzoom %d\n", VAAV1TransformationRotzoom);
|
|
printf("enum VAAV1TransformationAffine %d\n", VAAV1TransformationAffine);
|
|
printf("enum VA_RT_FORMAT_YUV420_10 0x%08x\n", VA_RT_FORMAT_YUV420_10);
|
|
printf("enum VA_RT_FORMAT_YUV420 0x%08x\n", VA_RT_FORMAT_YUV420);
|
|
|
|
printf("VA_PADDING_LOW=%d VA_PADDING_MEDIUM=%d\n", VA_PADDING_LOW, VA_PADDING_MEDIUM);
|
|
|
|
/*
|
|
* The export descriptor. This one is not a buffer we FILL — it is a struct the
|
|
* driver WRITES, so a wrong layout is read as plausible garbage (an fd from the
|
|
* middle of a pitch, a plane count from a modifier's high word) rather than
|
|
* refused. It carries fixed-size arrays whose bounds the flattening walk trusts,
|
|
* which is exactly the shape that turned into the green-screen bug once already.
|
|
*/
|
|
S(VADRMPRIMESurfaceDescriptor);
|
|
O(VADRMPRIMESurfaceDescriptor, fourcc);
|
|
O(VADRMPRIMESurfaceDescriptor, width);
|
|
O(VADRMPRIMESurfaceDescriptor, height);
|
|
O(VADRMPRIMESurfaceDescriptor, num_objects);
|
|
O(VADRMPRIMESurfaceDescriptor, objects);
|
|
O(VADRMPRIMESurfaceDescriptor, num_layers);
|
|
O(VADRMPRIMESurfaceDescriptor, layers);
|
|
printf("count VADRMPRIMESurfaceDescriptor objects %zu\n",
|
|
sizeof(((VADRMPRIMESurfaceDescriptor *)0)->objects) /
|
|
sizeof(((VADRMPRIMESurfaceDescriptor *)0)->objects[0]));
|
|
printf("count VADRMPRIMESurfaceDescriptor layers %zu\n",
|
|
sizeof(((VADRMPRIMESurfaceDescriptor *)0)->layers) /
|
|
sizeof(((VADRMPRIMESurfaceDescriptor *)0)->layers[0]));
|
|
printf("count layer.object_index %zu\n",
|
|
sizeof(((VADRMPRIMESurfaceDescriptor *)0)->layers[0].object_index) /
|
|
sizeof(((VADRMPRIMESurfaceDescriptor *)0)->layers[0].object_index[0]));
|
|
|
|
/*
|
|
* The enumerators the runtime calls pass by value. Printed rather than
|
|
* transcribed because two of them are the exact pair this program has already
|
|
* been warned about: VASliceParameterBufferType and VASliceDataBufferType are
|
|
* 4 and 5, not the 3 and 4 that counting the enum from the top suggests.
|
|
*/
|
|
printf("enum VAEntrypointVLD %d\n", VAEntrypointVLD);
|
|
printf("enum VAConfigAttribRTFormat %d\n", VAConfigAttribRTFormat);
|
|
printf("enum VAPictureParameterBufferType %d\n", VAPictureParameterBufferType);
|
|
printf("enum VAIQMatrixBufferType %d\n", VAIQMatrixBufferType);
|
|
printf("enum VASliceParameterBufferType %d\n", VASliceParameterBufferType);
|
|
printf("enum VASliceDataBufferType %d\n", VASliceDataBufferType);
|
|
printf("enum VA_EXPORT_SURFACE_READ_ONLY 0x%04x\n", VA_EXPORT_SURFACE_READ_ONLY);
|
|
printf("enum VA_EXPORT_SURFACE_SEPARATE_LAYERS 0x%04x\n",
|
|
VA_EXPORT_SURFACE_SEPARATE_LAYERS);
|
|
printf("enum VA_SURFACE_ATTRIB_SETTABLE 0x%04x\n", VA_SURFACE_ATTRIB_SETTABLE);
|
|
printf("enum VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2 0x%08x\n",
|
|
VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2);
|
|
printf("enum VASurfaceAttribPixelFormat %d\n", VASurfaceAttribPixelFormat);
|
|
printf("enum VAGenericValueTypeInteger %d\n", VAGenericValueTypeInteger);
|
|
printf("enum VA_STATUS_SUCCESS %d\n", VA_STATUS_SUCCESS);
|
|
printf("enum VA_INVALID_ID 0x%08x\n", VA_INVALID_ID);
|
|
printf("enum VA_FOURCC_NV12 0x%08x\n", VA_FOURCC_NV12);
|
|
printf("enum VA_FOURCC_P010 0x%08x\n", VA_FOURCC_P010);
|
|
printf("enum VA_PROGRESSIVE 0x%04x\n", VA_PROGRESSIVE);
|
|
|
|
S(VASurfaceAttrib);
|
|
O(VASurfaceAttrib, type);
|
|
O(VASurfaceAttrib, flags);
|
|
O(VASurfaceAttrib, value);
|
|
S(VAGenericValue);
|
|
O(VAGenericValue, type);
|
|
O(VAGenericValue, value);
|
|
S(VAConfigAttrib);
|
|
O(VAConfigAttrib, type);
|
|
O(VAConfigAttrib, value);
|
|
return 0;
|
|
}
|