Files
libva-v4l2-request-fourier/src/surface.h
T
claude-noether 7f84bbb50f fresnel-fourier iter3 Phase 6 commit C: picture.c VP8 dispatch + 4
buffer-type cases + new VAProbabilityBufferType outer case + per-
frame reset + surface.h params.vp8 union extension

Five sites in picture.c + one site in surface.h wire up the VP8
codec dispatcher introduced by commit B:

  1. Include #include "vp8.h" in the codec headers block.

  2. codec_set_controls: NEW case VAProfileVP8Version0_3 calling
     vp8_set_controls(driver_data, context, surface_object).
     Same shape as MPEG-2 + HEVC dispatch.

  3. codec_store_buffer VAPictureParameterBufferType: NEW VP8 case
     memcpy'ing into surface_object->params.vp8.picture
     (sizeof VAPictureParameterBufferVP8).

  4. codec_store_buffer VASliceParameterBufferType: NEW VP8 case
     memcpy'ing into surface_object->params.vp8.slice (single,
     no slices[] array — VP8 is frame-mode, no multi-slice).

  5. codec_store_buffer VAIQMatrixBufferType: NEW VP8 case
     memcpy'ing into surface_object->params.vp8.iqmatrix +
     setting iqmatrix_set true.

  6. codec_store_buffer NEW outer case VAProbabilityBufferType
     (Phase 5 C3: NOT VAProbabilityDataBufferType — that's the
     STRUCT name; the buffer-type enum constant is
     VAProbabilityBufferType = 13 per va.h:2058). Inner switch
     dispatches by profile, with VP8 case memcpy'ing into
     surface_object->params.vp8.probability + setting
     probability_set true.

  7. RequestBeginPicture: NEW per-frame reset for the two VP8
     flags — params.vp8.iqmatrix_set = false +
     params.vp8.probability_set = false. Mirrors the existing
     iter1 (h264.matrix_set) + iter2 (h265.num_slices) per-frame
     resets.

surface.h extension:

  8. params union: NEW vp8 struct after h265 — holds the 4 VAAPI
     buffer-type structs (VAPictureParameterBufferVP8,
     VASliceParameterBufferVP8, VAIQMatrixBufferVP8 + iqmatrix_set,
     VAProbabilityDataBufferVP8 + probability_set).

The NEW vp8 union member adds ~5300 bytes (sizeof
VAProbabilityDataBufferVP8 dominated by dct_coeff_probs[4][8][3]
[11] = 1056 + bookkeeping). The h265 member with slices[64] array
remains the largest (~17 KB), so the union size doesn't grow.

After this commit: backend builds clean, links cleanly. mpv-vaapi
VP8 decode should engage end-to-end on hantro env binding. Phase
1 criteria 1 + 2 + 3 expected satisfied; criterion 4 (HW=SW byte-
identical) and criterion 5 (3-codec regression) verified at Phase
6 smoke + Phase 7.

Refs:
  ../fresnel-fourier/phase4_iter3_plan.md (Commit C site list)
  ../fresnel-fourier/phase2_iter3_situation.md (B6, B7, B8, B9
                                                 bug enumeration)
  ../fresnel-fourier/phase5_iter3_review.md (C3 VAProbabilityBuffer
                                              Type rename
                                              empirically verified)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 22:52:24 +00:00

195 lines
7.3 KiB
C

/*
* Copyright (C) 2007 Intel Corporation
* Copyright (C) 2016 Florent Revest <florent.revest@free-electrons.com>
* Copyright (C) 2018 Paul Kocialkowski <paul.kocialkowski@bootlin.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
* IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef _SURFACE_H_
#define _SURFACE_H_
#include <linux/videodev2.h>
#include <va/va_backend.h>
#include "object_heap.h"
#include "cap_pool.h"
#include "h265.h"
struct request_data;
#define SURFACE(data, id) \
((struct object_surface *)object_heap_lookup(&(data)->surface_heap, id))
#define SURFACE_ID_OFFSET 0x04000000
struct object_surface {
struct object_base base;
VASurfaceStatus status;
int width;
int height;
unsigned int source_index;
void *source_data;
unsigned int source_size;
/*
* Iter2 Fix 3: destination_* fields below are now per-decode-cycle.
* They are populated from current_slot in RequestBeginPicture and
* remain valid through SyncSurface, ExportSurfaceHandle, and
* DeriveImage/copy_surface_to_image (vaapi-copy path). Subsequent
* BeginPicture for this surface releases the prior slot and
* acquires a new one.
*
* destination_planes_count, destination_sizes, destination_offsets,
* destination_bytesperlines are FORMAT-uniform across all CAPTURE
* buffers, so they're set once at CreateSurfaces2 time and stay.
*
* destination_index, destination_map[], destination_map_lengths,
* destination_map_offsets, destination_data[] are SLOT-specific
* and re-populated each BeginPicture from current_slot.
*
* destination_buffers_count is also format-uniform (V4L2 planes
* per buffer = 1 for single-plane MPLANE NV12).
*/
struct cap_pool_slot *current_slot; /* iter2 Fix 3 */
unsigned int destination_index;
void *destination_map[VIDEO_MAX_PLANES];
unsigned int destination_map_lengths[VIDEO_MAX_PLANES];
unsigned int destination_map_offsets[VIDEO_MAX_PLANES];
void *destination_data[VIDEO_MAX_PLANES];
unsigned int destination_sizes[VIDEO_MAX_PLANES];
unsigned int destination_offsets[VIDEO_MAX_PLANES];
unsigned int destination_bytesperlines[VIDEO_MAX_PLANES];
unsigned int destination_planes_count;
unsigned int destination_buffers_count;
unsigned int slices_size;
unsigned int slices_count;
struct timeval timestamp;
union {
struct {
VAPictureParameterBufferMPEG2 picture;
VASliceParameterBufferMPEG2 slice;
VAIQMatrixBufferMPEG2 iqmatrix;
bool iqmatrix_set;
} mpeg2;
struct {
VAIQMatrixBufferH264 matrix;
bool matrix_set;
VAPictureParameterBufferH264 picture;
VASliceParameterBufferH264 slice;
} h264;
struct {
VAPictureParameterBufferHEVC picture;
VASliceParameterBufferHEVC slice;
VASliceParameterBufferHEVC slices[HEVC_MAX_SLICES_PER_FRAME];
unsigned int num_slices;
VAIQMatrixBufferHEVC iqmatrix;
bool iqmatrix_set;
} h265;
struct {
VAPictureParameterBufferVP8 picture;
VASliceParameterBufferVP8 slice;
VAIQMatrixBufferVP8 iqmatrix;
bool iqmatrix_set;
VAProbabilityDataBufferVP8 probability;
bool probability_set;
} vp8;
} params;
int request_fd;
};
VAStatus RequestCreateSurfaces2(VADriverContextP context, unsigned int format,
unsigned int width, unsigned int height,
VASurfaceID *surfaces_ids,
unsigned int surfaces_count,
VASurfaceAttrib *attributes,
unsigned int attributes_count);
VAStatus RequestCreateSurfaces(VADriverContextP context, int width, int height,
int format, int surfaces_count,
VASurfaceID *surfaces_ids);
VAStatus RequestDestroySurfaces(VADriverContextP context,
VASurfaceID *surfaces_ids, int surfaces_count);
VAStatus RequestSyncSurface(VADriverContextP context, VASurfaceID surface_id);
VAStatus RequestQuerySurfaceAttributes(VADriverContextP context,
VAConfigID config,
VASurfaceAttrib *attributes,
unsigned int *attributes_count);
VAStatus RequestQuerySurfaceStatus(VADriverContextP context,
VASurfaceID surface_id,
VASurfaceStatus *status);
VAStatus RequestPutSurface(VADriverContextP context, VASurfaceID surface_id,
void *draw, short src_x, short src_y,
unsigned short src_width, unsigned short src_height,
short dst_x, short dst_y, unsigned short dst_width,
unsigned short dst_height, VARectangle *cliprects,
unsigned int cliprects_count, unsigned int flags);
VAStatus RequestLockSurface(VADriverContextP context, VASurfaceID surface_id,
unsigned int *fourcc, unsigned int *luma_stride,
unsigned int *chroma_u_stride,
unsigned int *chroma_v_stride,
unsigned int *luma_offset,
unsigned int *chroma_u_offset,
unsigned int *chroma_v_offset,
unsigned int *buffer_name, void **buffer);
VAStatus RequestUnlockSurface(VADriverContextP context, VASurfaceID surface_id);
VAStatus RequestExportSurfaceHandle(VADriverContextP context,
VASurfaceID surface_id, uint32_t mem_type,
uint32_t flags, void *descriptor);
/*
* Iteration 2 Fix 1: invalidate the LAST_OUTPUT_WIDTH/HEIGHT cache used
* by RequestCreateSurfaces2 to skip redundant v4l2_set_format calls.
*
* Must be called when the kernel's CAPTURE format state is no longer
* guaranteed to match what we last set on OUTPUT — at minimum, on
* RequestDestroyContext after REQBUFS(0). Without this, Firefox
* playing a multi-video page (mozilla.org with 864-wide intro
* videos at varying resolutions) corrupts the next session's CAPTURE
* format query: the cache says "already 1920x1088" while the kernel
* has reset to defaults, our subsequent G_FMT returns 48x48, and the
* exported descriptor encodes wrong pitch/offset.
*
* Iter5 Track E: cache lives per-driver_data (request_data.last_output_*),
* resolving the Sonnet review 7.3 / 9.6 multi-context race.
*/
void surface_reset_format_cache(struct request_data *driver_data);
/*
* Iter2 Fix 3: bind / unbind a CAPTURE-pool slot to an object_surface.
* Called from picture.c::RequestBeginPicture (acquire+bind) and
* surface.c::RequestDestroySurfaces (unbind). Mirrors slot's V4L2 index
* and mmap pointers into surface_object->destination_* so existing
* QBUF/DQBUF/EXPBUF code paths see no behavioral change.
*/
void surface_bind_slot(struct object_surface *surface_object,
struct cap_pool_slot *slot);
void surface_unbind_slot(struct request_data *driver_data,
struct object_surface *surface_object);
#endif