Skip to content

bcm2835-codec: H.264 video playback fails for 1080p #6837

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
sly547 opened this issue May 6, 2025 · 2 comments
Open

bcm2835-codec: H.264 video playback fails for 1080p #6837

sly547 opened this issue May 6, 2025 · 2 comments

Comments

@sly547
Copy link

sly547 commented May 6, 2025

Describe the bug

I am trying to use the v4l2-mem2mem device to play AVC-encoded videos with hardware decoding on a Pi 3B or Zero 2W:

mpv --hwdec=v4l2m2m-copy video.mp4
# or
ffmpeg -codec:v h264_v4l2m2m -i video.mp4 -vcodec rawvideo -acodec copy -f matroska - | mpv -

Note: I was told in mpv's IRC channel that mpv also uses ffmpeg's libavcodec for the v4l2m2m decoder.

It works for some videos, but for others, playback never starts and the decoder seems to be stuck.

It seems to be related to the bitrate: I tried one video, downloaded from youtube in 720p and 1080p variants (see "Steps to reproduce"), and only the 1080p variant fails.

Steps to reproduce the behaviour

yt-dlp -f "ba[acodec^=mp4a]+bv[height=1080][vcodec^=avc1]" https://www.youtube.com/watch?v=K7dcSr04G8s
mpv --hwdec=v4l2m2m-copy Vinyl\ Cat\ \[K7dcSr04G8s].mp4

When switching to the 720p variant of the same video it works:

yt-dlp -f "ba[acodec^=mp4a]+bv[height=720][vcodec^=avc1]" https://www.youtube.com/watch?v=K7dcSr04G8s

Device (s)

Raspberry Pi 3 Mod. B, Raspberry Pi Zero 2 W

System

$ doas vcgencmd version
Dec  7 2024 13:02:17 
Copyright (c) 2012 Broadcom
version 3858f977ab6d689a226ad24d26749266762b7160 (clean) (release) (start)
$ uname -a
Linux myhostname 6.12.13-0-rpi #1-Alpine SMP PREEMPT Thu Feb 13 22:15:47 UTC 2025 aarch64 Linux

raspinfo.log

Logs

I am attaching logs from mpv -v --hwdec=v4l2m2m-copy and from strace -y mpv --hwdec=v4l2m2m-copy (only the last couple of thousand lines).
mpv_v4l2m2m-copy_console.log
mpv_v4l2m2m-copy_strace.log
It always ends on this line until I press Ctrl+C and killall -9 mpv:

[..]
ppoll([{fd=17, events=POLLIN|POLLPRI|POLLOUT|POLLRDNORM|POLLWRNORM}], 1, NULL, NULL, 8

fd 17 refers to /dev/video10.

I took the strace logs last week; right now it ends like this (I noticed an extra munmap()):

futex(0x7fa4cc4404, FUTEX_WAKE_PRIVATE, 1) = 1
futex(0x7fa5099f14, FUTEX_WAKE_PRIVATE, 1) = 1
clock_gettime(CLOCK_MONOTONIC_RAW, {tv_sec=79284, tv_nsec=624683192}) = 0
clock_gettime(CLOCK_MONOTONIC_RAW, {tv_sec=79284, tv_nsec=625218297}) = 0
ppoll([{fd=17, events=POLLIN|POLLPRI|POLLOUT|POLLRDNORM|POLLWRNORM}], 1, {tv_sec=0, tv_nsec=0}, NULL, 8) = 1 ([{fd=17, revents=POLLOUT|POLLWRNORM}], left {tv_sec=0, tv_nsec=0})
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f9ee6c000
ppoll([{fd=17, events=POLLOUT|POLLWRNORM}], 1, {tv_sec=0, tv_nsec=0}, NULL, 8) = 1 ([{fd=17, revents=POLLOUT|POLLWRNORM}], left {tv_sec=0, tv_nsec=0})
ioctl(17, VIDIOC_DQBUF, {type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, index=0, memory=V4L2_MEMORY_MMAP, m.offset=0xe63b6118, length=1, bytesused=0, flags=V4L2_BUF_FLAG_MAPPED|V4L2_BUF_FLAG_KEYFRAME|V4L2_BUF_FLAG_TIMESTAMP_COPY|V4L2_BUF_FLAG_TSTAMP_SRC_EOF, timestamp={tv_sec=3, tv_usec=366667}, ...}) = 0
ppoll([{fd=17, events=POLLOUT|POLLWRNORM}], 1, {tv_sec=0, tv_nsec=0}, NULL, 8) = 0 (Timeout)
ioctl(17, VIDIOC_QBUF, {type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, index=0, memory=V4L2_MEMORY_MMAP, m.offset=0xa4391368, length=1, bytesused=0, flags=V4L2_BUF_FLAG_MAPPED|V4L2_BUF_FLAG_QUEUED|V4L2_BUF_FLAG_KEYFRAME|V4L2_BUF_FLAG_TIMESTAMP_COPY|V4L2_BUF_FLAG_TSTAMP_SRC_EOF, ...}) = 0
munmap(0x7f9ee6c000, 4096)              = 0
ppoll([{fd=17, events=POLLIN|POLLPRI|POLLOUT|POLLRDNORM|POLLWRNORM}], 1, NULL, NULL, 8

Additional context

The same RPi 3B with Arch Linux ARM has Kodi and ffmpeg with downstream patches for what I picked up as "the requests API". Here the same videos play flawlessly, but for my application I want to use Alpine without downstream patches.

@6by9
Copy link
Contributor

6by9 commented May 6, 2025

Tested, and there is no issue on Raspberry Pi OS (at least with no windowing system hence rendering direct to DRM/KMS via mpv)

The request API is only relevant for the V4L2 stateless decoder API.
H264 decode on Pi0-4 uses the V4L2 stateful decoder API

Mainline FFmpeg does the wrong thing with stateful decode in some situations, hence the decode stalls. That's not something that would get fixed in the kernel.
(Gut feel is that you need jc-kynesim/rpi-ffmpeg@7f8ee20, but I get lost around FFmpeg patches).

@sly547
Copy link
Author

sly547 commented May 6, 2025

Thank you for testing and providing some insight!

I see that the ffmpeg shipped by Raspberry Pi OS is also patched and I think it also contains the patch that you linked. (I looked into this archive and found /debian/patches/): https://archive.raspberrypi.org/debian/pool/main/f/ffmpeg/ffmpeg_5.1.6-0+deb12u1+rpt3.debian.tar.xz

So I tried applying jc-kynesim/rpi-ffmpeg@b149dc9 (same patch you linked to, but based on ffmpeg-6.1) to the APKBUILD in Alpine's aports. With two small fixes, it got built successfully.

It is now able to play the video in question, even though it drops frames, looks slow and goes out of sync with the audio.
(Here is a log from mpv, not too interesting: mpv_v4l2m2m-copy_with_patched_ffmpeg.log)

But it seems to give some credibility to the position that the kernel driver shouldn't be blamed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants