7f84bbb50f
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>
195 lines
7.3 KiB
C
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
|