Update with current state: library builds clean, vainfo enumerates
profiles, vaCreateContext succeeds on Brave (with STREAMON deferred as
WIP unblocker), next failure is frame pool initialization in
vaCreateSurfaces2. Documents the 12-step diff stack vs bootlin upstream
and what still needs to happen to actually decode a frame.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Chromium's vaapi_video_decoder may call vaCreateContext with surfaces=NULL,
surfaces_count=0 and then create surfaces afterwards via vaCreateSurfaces2.
In that order driver_data->video_format is still NULL when CreateContext
runs and our early `video_format == NULL` guard returns OPERATION_FAILED.
Confirmed via temporary request_log() — Brave hits exactly that path on
ohm.
Move the probe out of RequestCreateSurfaces into a new
video_format_probe() helper in video.c, and call it eagerly from
RequestInit. RequestCreateSurfaces still re-probes if init came up NULL,
which preserves the original lazy behaviour for any caller that needs it.
Also small clean-up of surface.c since the probe block moved out: drop
the now-dead `bool found` local.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sandboxed processes (Chromium GPU process etc.) redirect stderr, so
request_log() output never reaches our test harness. Add a lazy-open
append to /tmp/libva-fourier.log so we can capture diagnostic logging
regardless of process sandboxing.
Will revert before final.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Added request_log() calls at every failure path inside RequestCreateContext
to identify exactly which guard fires when Brave's vaCreateContext fails on
ohm. Will revert these before final.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The whole body of tiled_yuv.S is wrapped in #ifndef __aarch64__ — the
ARMv7 NEON Thumb code doesn't assemble on aarch64. On 64-bit ARM the
.S object is therefore empty and tiled_to_planar comes out as an
undefined symbol in the .so, which dlopen rejects at vainfo time:
libva error: dlopen ... failed: undefined symbol: tiled_to_planar
Runtime-wise, tiled_to_planar is only called when
video_format_is_linear() returns false, which only happens for the
sunxi-cedrus DRM_FORMAT_MOD_ALLWINNER_TILED NV12 entry — never on
hantro/rkvdec. So the right fix is a no-op stub on aarch64 just to
satisfy the linker.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
decode->num_slices was the last field on v4l2_ctrl_h264_decode_params
that didn't survive the upstream cleanup. The kernel now infers the
slice count from how many slice_params controls were queued via the
request API for the given OUTPUT buffer; no explicit count is needed.
This was the only remaining build error; library should now compile clean
against current linux-api-headers.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The H.264 stateless control structs and CIDs were upstreamed and
reshaped during the journey from libva-v4l2-request's bundled headers
to the kernel's <linux/v4l2-controls.h>. Three breaking changes need
matching code-side updates:
1. struct v4l2_ctrl_h264_slice_params lost its .size field. The full
slice byte length is now communicated via the OUTPUT buffer's
m.planes[0].bytesused at QBUF time, which v4l2_queue_buffer already
sets. Drop the assignment.
2. struct v4l2_h264_reference replaces the bare integer DPB index in
ref_pic_list0[] / ref_pic_list1[]. The new struct is { __u8 fields,
__u8 index } where `fields` is V4L2_H264_TOP_FIELD_REF (0x1) /
BOTTOM_FIELD_REF (0x2) / FRAME_REF (0x3). Hantro G1 only does
frame-based H.264, so use V4L2_H264_FRAME_REF unconditionally.
3. The pred_weight_table block moved out of slice_params into its own
V4L2_CID_STATELESS_H264_PRED_WEIGHTS control with struct
v4l2_ctrl_h264_pred_weights. Add it as a separate v4l2_set_control()
call alongside SPS/PPS/SLICE_PARAMS/DECODE_PARAMS/SCALING_MATRIX, and
thread the pred_weights pointer through h264_va_slice_to_v4l2().
Also: switch the v4l2_set_control() CID arguments from V4L2_CID_MPEG_VIDEO_H264_*
to V4L2_CID_STATELESS_H264_* directly. h264-ctrls.h still defines the
old names as aliases so external callers keep working, but using the
canonical names internally matches what the kernel actually expects and
avoids confusion when reading h264.c side-by-side with the kernel
source.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
H.264 stateless controls were upstreamed to the kernel some time after
this library went dormant. The struct names match exactly (the kernel
adopted v4l2_ctrl_h264_{sps,pps,scaling_matrix,pred_weights,slice_params,
decode_params} and v4l2_h264_{weight_factors,dpb_entry,reference}
verbatim) so the duplicated copies in include/h264-ctrls.h trigger
redefinition errors as soon as any source file pulls in
<linux/videodev2.h> (which transitively pulls in <linux/v4l2-controls.h>).
Same fix as hevc-ctrls.h in commit 4ccbfe9: replace the bundled struct
definitions with a passthrough to <linux/v4l2-controls.h>. The CID
prefix changed during upstreaming from V4L2_CID_MPEG_VIDEO_H264_* to
V4L2_CID_STATELESS_H264_*; provide compatibility aliases so h264.c keeps
compiling. V4L2_PIX_FMT_H264_SLICE is already in <linux/videodev2.h>
(same fourcc value, same name we renamed to in commit c1f5108) so no
need to redefine.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This is what was actually broken — and it's much smaller than the STUDY
guessed.
The library is in fact multiplanar-aware throughout the v4l2.c helpers
(v4l2_setup_format, v4l2_get_format, v4l2_query_buffer, v4l2_queue_buffer,
v4l2_dequeue_buffer all branch on v4l2_type_is_mplane). The whole
"context.c / picture.c are single-plane" hypothesis from STUDY.md was wrong —
they derive output_type and capture_type from
video_format->v4l2_mplane and pass them through.
The bug is upstream of all that: driver_data->video_format is set in
RequestCreateSurfaces only, and the probe there only tries
V4L2_BUF_TYPE_VIDEO_CAPTURE (single-plane). On hantro the single-plane
ENUM_FMT returns nothing, video_format stays NULL, and every subsequent
operation hits the `if (video_format == NULL) return OPERATION_FAILED`
guard at the top of context.c / buffer.c / image.c. That's exactly what
Brave's vaCreateContext failure was — not a downstream multiplanar fault,
just the format-detection short-circuit firing.
Three small changes:
- src/video.c: add an NV12 multi-plane entry next to the existing
single-plane NV12 / Sunxi entries. Same pixelformat fourcc (S264 vs NV12
has nothing to do with mplane), distinguished by the v4l2_mplane bit.
- src/video.h + src/video.c: video_format_find() takes a `bool mplane`
parameter and matches both fields. Without this the single-plane and
multi-plane NV12 entries collide on pixelformat.
- src/surface.c: the probe block now tries V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
as a fallback after the single-plane probes return nothing. On a
single-plane decoder the mplane probe is a no-op; on hantro it picks
the new mplane NV12 entry, video_format gets set, and the rest of the
library — already mplane-aware — does the right thing for OUTPUT
S_FMT, REQBUFS, EXPBUF, QBUF, DQBUF.
Also: src/context.c: the H264 case still referenced V4L2_PIX_FMT_H264_SLICE_RAW
that we renamed in commit c1f5108. Caught now.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bootlin's original probe assumed single-plane decoders (the sunxi-cedrus
target the library was originally written for). Rockchip's hantro VPU
on RK3566/RK3588 reports V4L2_CAP_VIDEO_M2M_MPLANE only — the single-
plane VIDIOC_ENUM_FMT path returns nothing, so vainfo prints an empty
"Supported profile and entrypoints" list and downstream apps fall back
to software.
Add an OUTPUT_MPLANE fallback to all three format probes (MPEG-2, H.264,
HEVC). On a single-plane decoder the second probe is a no-op; on a
multi-plane decoder it's what makes the profile list non-empty.
This is the *probe* fix only — it gets vainfo to enumerate profiles and
gets Brave's GPU process to attempt vaCreateContext. The rest of the
multiplanar port (S_FMT / REQBUFS / EXPBUF / QBUF in context.c, picture.c,
v4l2.c) is the next phase; vaCreateContext currently fails because
those paths are still single-plane only.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three changes that together make the build compile cleanly against a
current linux-api-headers (>= 5.x post-HEVC-UAPI-rename):
- src/meson.build: comment h265.c + h265.h out of sources/headers.
- include/hevc-ctrls.h: replace bundled HEVC structs with a single
#include <linux/v4l2-controls.h>. The bundled definitions were
identical to what later landed in mainline as V4L2_CID_STATELESS_HEVC_*
(renamed) and v4l2_ctrl_hevc_* (kept the field names but moved into
the kernel public header). Keeping a duplicate copy now triggers
redefinition errors. The header is kept as a passthrough rather than
deleted so any downstream patch that says #include <hevc-ctrls.h>
still compiles.
- src/picture.c: drop the four HEVC case blocks. Three of them were in
switches that already had `default: break`, so removing them is
functionally a no-op. The fourth was the only external reference to
h265_set_controls — removing it lets the library link cleanly with
h265.c excluded.
Why this is OK rather than the more ambitious "fix HEVC properly":
RK3566 has no HW HEVC at all (the only decoder block is the Hantro G1
which speaks H.264 / MPEG-2 / VP8). HEVC can come back as a separate
effort once we're on RK3588 silicon AND the library is updated to the
renamed kernel CIDs. For Fourier's first port milestone (H.264 multi-
plane on RK3566 hantro) HEVC is dead weight.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
GCC's -Wimplicit-function-declaration is fatal in current toolchains
(GCC 14+) but was a warning when this code was written. h264.c uses
request_log() in two places without including utils.h; the build was
quietly relying on an implicit declaration that recent compilers reject.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Kernel mainline renamed V4L2_PIX_FMT_H264_SLICE_RAW → V4L2_PIX_FMT_H264_SLICE
some time after this library went dormant (the 'S264' fourcc value is
unchanged; only the C identifier moved). The two definitions have the same
value so this is purely cosmetic at runtime, but keeping the name aligned
with linux/videodev2.h matches downstream patches (e.g. bootlin PR #38)
and avoids confusion when reading kernel + library side-by-side.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Distritubions may install libraries under architecture-specific
sub-directories, to support multiple architectures on the same
system. In addition, the user may not wish to install the library
with the default prefix.
Use the libdir variable when setting the install path. This
allows both specifying different sub-directories, and a different
prefix.
The system normally has kernel headers shipped with the distribution.
These typically lag behind actual kernel releases. Thus they would not
have the latest API additions, such as the V4L2 request API this driver
uses.
However, it is also bad practice to just install new kernel headers into
the system wide default location, as there may be some differences
between it and what the C library was built against.
Add an option to specify a path to a set of up-to-date kernel headers.
This would allow the user to build this project in a safe but working
environment.
Signed-off-by: Chen-Yu Tsai <wens@csie.org>
We where first copying the image structure and then setting the pitches
and offets, so this information was lost. This fixes vaDerivedImage and
vaGetImage implementation.
Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
This enables raw playback within GStreamer. This is useful for testing
even if slower then DMABuf. This is a partial implementation since we
don't implement partial copy of the surface.
Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
The vaCreateSurface2 may be called multiple times, setting the format
again would lead to EBUSY being returned as you cannot change the
format if you have buffers allocated.
Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Reference frames are now identified using their timestamp:
set the timestamp when queuing the output buffer and use it to identify
the frame later on.
Signed-off-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
Drop the per-codec options while at it, since we'll soon include a copy
of the associated headers.
Signed-off-by: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
Commit 7ff2543e64 ("Add support for the single-planar V4L2 API")
missed the VIDIOC_QBUF bytesused parameter. The kernel will
warn loudly if bytesused is not properly defined for an OUTPUT buffer.
Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
Apparently, pixelformats are expected to be settable although
the reason is not exactly clear to me.
However, intel vaapi driver sets all its pixelformats as
settable, and gstreamer-vaapi expects that as well.
Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
H.264 and H.265 support is still not supported upstream,
so it makes sense to autodetect each codec and only
enable those that are supported.
Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
Albin did not had an account on Kickstarter initially, so he was
registered as GuestXYZ. Upon his request, add his real name.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
As promised by Bootlin's Kickstarter campaign, all contributors above
16 EUR would get their name in the CREDITS file. This commit
implements the promised CREDITS file.
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>