diff --git a/arch/firefox-fourier/patches/0003-ffmpegvideo-v4l2-request-route.patch b/arch/firefox-fourier/patches/0003-ffmpegvideo-v4l2-request-route.patch index 8447be1b4..97ead5f1a 100644 --- a/arch/firefox-fourier/patches/0003-ffmpegvideo-v4l2-request-route.patch +++ b/arch/firefox-fourier/patches/0003-ffmpegvideo-v4l2-request-route.patch @@ -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); -+ return NS_ERROR_NOT_AVAILABLE; ++ // 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; -+ for (int i = 0;; i++) { -+ const AVCodecHWConfig* cfg = mLib->avcodec_get_hw_config(codec, i); -+ if (!cfg) break; -+ if (cfg->device_type == AV_HWDEVICE_TYPE_DRM) { -+ hasDrmHwaccel = true; -+ break; ++ 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(generic, i); ++ if (!cfg) break; ++ if (cfg->device_type == AV_HWDEVICE_TYPE_DRM) { ++ 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);