firefox-fourier patch 3: probe v4l2_request via codec name first
build and publish packages / distcc-avahi-aarch64 (push) Successful in 33s
build and publish packages / lmcp-any (push) Successful in 7s
build and publish packages / lmcp-debian (push) Successful in 6s
build and publish packages / claude-his-any (push) Successful in 8s
build and publish packages / claude-his-debian (push) Has been cancelled
build and publish packages / ffmpeg-v4l2-request-aarch64 (push) Has been cancelled
build and publish packages / distcc-avahi-aarch64 (push) Successful in 33s
build and publish packages / lmcp-any (push) Successful in 7s
build and publish packages / lmcp-debian (push) Successful in 6s
build and publish packages / claude-his-any (push) Successful in 8s
build and publish packages / claude-his-debian (push) Has been cancelled
build and publish packages / ffmpeg-v4l2-request-aarch64 (push) Has been cancelled
Diagnostic on fresnel (RK3399 / Mali-T860 / mainline) showed
InitV4L2RequestDecoder running at runtime but failing the
hw_configs sanity check:
FFMPEG: Initialising V4L2 stateless (request API) FFmpeg decoder
FFMPEG: codec h264 has no DRM hwaccel —
libavcodec built without --enable-v4l2-request?
FFMPEG: Initialising V4L2-DRM FFmpeg decoder ← falls through to stateful
FFMPEG: V4L2 codec h264_v4l2m2m : V4L2 mem2mem H.264 decoder wrapper
FFMPEG: Couldn't initialise V4L2 decoder ← stateful also fails
…despite the system libavcodec.so being built with
--enable-v4l2-request and exposing h264_v4l2request, vp8_v4l2request,
etc. as named AVCodec entries.
Root cause: libavcodec exposes v4l2_request through one of two
mechanisms depending on the build:
(a) Named AVCodec entry (legacy, distro-portable): looked up via
avcodec_find_decoder_by_name("h264_v4l2request"). ALARM,
Debian, most distros use this.
(b) hw_configs entry on the generic codec (modern, upstream): the
generic codec's AVCodecHWConfig array advertises
AV_HWDEVICE_TYPE_DRM. Setting hw_device_ctx binds the hwaccel.
Patch 3 originally only probed (b). On builds that ship (a) — the
common case — the check failed even though v4l2_request was fully
functional.
Fix: probe (a) first via the codec-name lookup table, fall back to
(b) walking hw_configs. Both shapes work; the decoder is opened with
whichever AVCodec the probe selected. The DRM hwdevice ctx
attachment is unchanged (both mechanisms need it for surface
allocation).
Patch description and the in-code comment block updated to document
the dual mechanism. Behaviour on stateful-only boards (Pi4 / vendor
MPP) preserved: neither named codec nor hw_configs DRM is registered,
the function bails out, the existing InitV4L2Decoder runs as before.
This commit is contained in:
@@ -15,12 +15,16 @@ fails to open, Firefox falls all the way through to software.
|
||||
|
||||
This patch adds a sibling init path, `InitV4L2RequestDecoder`, that:
|
||||
|
||||
* uses the **generic** codec (e.g. plain `h264`, returned by
|
||||
`avcodec_find_decoder(AV_CODEC_ID_H264)`) rather than the stateful
|
||||
wrapper;
|
||||
* sanity-checks the codec's `hw_configs` for an `AV_HWDEVICE_TYPE_DRM`
|
||||
entry — that's how libavcodec surfaces the v4l2_request hwaccel
|
||||
upstream (no dedicated `_V4L2REQUEST` device type exists);
|
||||
* looks up the codec via two complementary mechanisms libavcodec
|
||||
uses for v4l2_request:
|
||||
- **named codec** (`h264_v4l2request`, `vp8_v4l2request`, etc.):
|
||||
the legacy AVCodec-per-hwaccel registration, used by ALARM /
|
||||
Debian / most distros that build with --enable-v4l2-request;
|
||||
- **generic codec + AV_HWDEVICE_TYPE_DRM** in `hw_configs`:
|
||||
the modern hwaccel registration, used by some upstream-only
|
||||
builds.
|
||||
Probes named-codec first (explicit, portable) and falls back to
|
||||
walking the generic codec's hw_configs.
|
||||
* creates an `AV_HWDEVICE_TYPE_DRM` hwdevice context bound to
|
||||
`/dev/dri/renderD128` via the new `av_hwdevice_ctx_create` wrapper
|
||||
(patch 2/4) and attaches it to the codec context;
|
||||
@@ -104,30 +108,55 @@ diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp b/dom/media/platf
|
||||
+
|
||||
+ StaticMutexAutoLock mon(sMutex);
|
||||
+
|
||||
+ // Use the GENERIC codec (not the _v4l2m2m wrapper). libavcodec picks
|
||||
+ // the v4l2_request hwaccel internally by walking the codec's
|
||||
+ // hw_configs once an AV_HWDEVICE_TYPE_DRM ctx is attached.
|
||||
+ AVCodec* codec = mLib->avcodec_find_decoder(mCodecID);
|
||||
+ if (!codec) {
|
||||
+ FFMPEG_LOG(" generic codec for ID %d not found", mCodecID);
|
||||
+ // libavcodec exposes V4L2 stateless decoders through one of two
|
||||
+ // mechanisms depending on the build:
|
||||
+ // (a) Named AVCodec entry (h264_v4l2request, vp8_v4l2request,
|
||||
+ // etc.) — the legacy mechanism. Each hwaccel is a standalone
|
||||
+ // AVCodec, looked up by name. ALARM, Debian, and most distros
|
||||
+ // building with --enable-v4l2-request expose this.
|
||||
+ // (b) Modern hwaccel registration: the generic codec advertises
|
||||
+ // AV_HWDEVICE_TYPE_DRM in its hw_configs array, and setting
|
||||
+ // hw_device_ctx on the codec context binds v4l2_request
|
||||
+ // internally. Some upstream-only builds expose this.
|
||||
+ // Probe (a) first — it's the explicit, distro-portable lookup.
|
||||
+ // Fall back to (b) when the named entry isn't registered.
|
||||
+ const char* requestName = nullptr;
|
||||
+ switch (mCodecID) {
|
||||
+ case AV_CODEC_ID_H264: requestName = "h264_v4l2request"; break;
|
||||
+ case AV_CODEC_ID_HEVC: requestName = "hevc_v4l2request"; break;
|
||||
+ case AV_CODEC_ID_VP8: requestName = "vp8_v4l2request"; break;
|
||||
+ case AV_CODEC_ID_VP9: requestName = "vp9_v4l2request"; break;
|
||||
+ case AV_CODEC_ID_AV1: requestName = "av1_v4l2request"; break;
|
||||
+ case AV_CODEC_ID_MPEG2VIDEO: requestName = "mpeg2_v4l2request"; break;
|
||||
+ default:
|
||||
+ FFMPEG_LOG(" no v4l2_request mapping for codec ID %d", mCodecID);
|
||||
+ return NS_ERROR_NOT_AVAILABLE;
|
||||
+ }
|
||||
+
|
||||
+ // Sanity-check: refuse when libavcodec was built without the
|
||||
+ // v4l2_request hwaccel (no DRM hwaccel registered against this
|
||||
+ // codec). Distro packagers occasionally drop --enable-v4l2-request.
|
||||
+ bool hasDrmHwaccel = false;
|
||||
+ AVCodec* codec = mLib->avcodec_find_decoder_by_name(requestName);
|
||||
+ if (codec) {
|
||||
+ FFMPEG_LOG(" using named v4l2_request codec %s", requestName);
|
||||
+ } else {
|
||||
+ // Fallback path (b): generic codec + DRM hwaccel.
|
||||
+ AVCodec* generic = mLib->avcodec_find_decoder(mCodecID);
|
||||
+ if (generic) {
|
||||
+ for (int i = 0;; i++) {
|
||||
+ const AVCodecHWConfig* cfg = mLib->avcodec_get_hw_config(codec, i);
|
||||
+ const AVCodecHWConfig* cfg = mLib->avcodec_get_hw_config(generic, i);
|
||||
+ if (!cfg) break;
|
||||
+ if (cfg->device_type == AV_HWDEVICE_TYPE_DRM) {
|
||||
+ hasDrmHwaccel = true;
|
||||
+ codec = generic;
|
||||
+ FFMPEG_LOG(" using generic codec %s with DRM hwaccel", codec->name);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ if (!hasDrmHwaccel) {
|
||||
+ FFMPEG_LOG(" codec %s has no DRM hwaccel — libavcodec built "
|
||||
+ "without --enable-v4l2-request?", codec->name);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (!codec) {
|
||||
+ FFMPEG_LOG(" no v4l2_request path for codec ID %d — neither named "
|
||||
+ "codec %s nor generic codec with DRM hwaccel available "
|
||||
+ "(libavcodec built without --enable-v4l2-request?)",
|
||||
+ mCodecID, requestName);
|
||||
+ return NS_ERROR_NOT_AVAILABLE;
|
||||
+ }
|
||||
+ FFMPEG_LOG(" V4L2 stateless: codec %s : %s", codec->name, codec->long_name);
|
||||
|
||||
Reference in New Issue
Block a user