Hi.
I've created a minimal custom compiled version of libavcodec based on the patched ffmpeg version available via `apt source libavcodec-dev`. The download includes a rather large patch in `debian/patches/ffmpeg-5.1.3-rpi_22.patch`. Is there a repository somewhere tracking these changes?
I believe I've found an issue when decoding H264 videos on a Pi4. The V4L2m2mContext is using locking. When starting to decode a stream, from what I understand the decoder calls `do_source change` once the dimensions of the decoded video is detected. Unfortunately this results in a call to ff_mutex_lock(&ctx->lock) prior to `ff_mutex_init(&ctx->lock)`. See this traceback:
The `do_source_change` (#8 in the traceback above) moves into the else part of `if (!reinit)`...
and releases the previous `ctx` using `ff_v4l2_context_release`. A few lines later `ff_v4l2_context_set_status` is called (#7). There the now released ctx is locked using `ff_mutex_lock` on a lock with a now undefined state:
The lock itself is then reinitialized in `stuff_all_buffers` (#6) via `ff_v4l2_context_init`:
Due to the wrong order (the lock being locked prior to being initialized), the later unlock fails with `pthread_mutex_unlock failed with error: Operation not permitted`.
I'm not sure why I don't see this behaviour in the packaged version.
I've created a minimal custom compiled version of libavcodec based on the patched ffmpeg version available via `apt source libavcodec-dev`. The download includes a rather large patch in `debian/patches/ffmpeg-5.1.3-rpi_22.patch`. Is there a repository somewhere tracking these changes?
I believe I've found an issue when decoding H264 videos on a Pi4. The V4L2m2mContext is using locking. When starting to decode a stream, from what I understand the decoder calls `do_source change` once the dimensions of the decoded video is detected. Unfortunately this results in a call to ff_mutex_lock(&ctx->lock) prior to `ff_mutex_init(&ctx->lock)`. See this traceback:
Code:
#5 ff_v4l2_context_init (ctx=0xf7fc3100, ctx@entry=0xa5d98) at libavcodec/v4l2_context.c:1301#6 0xf7d8e3e0 in stuff_all_buffers (ctx=0xa5d98, avctx=0x9a590) at libavcodec/v4l2_context.c:902#7 ff_v4l2_context_set_status (ctx=0xa5d98, ctx@entry=0xffffff14, cmd=1074026002) at libavcodec/v4l2_context.c:935#8 0xf7d8e8f8 in do_source_change (s=0xffffef0c) at libavcodec/v4l2_context.c:402#9 get_event (m=0xffffef0c, m@entry=0xa4d90) at libavcodec/v4l2_context.c:567#10 0xf7d8f034 in get_qbuf (timeout=<optimized out>, ppavbuf=0xfffeef70, ctx=<optimized out>) at libavcodec/v4l2_context.c:664#11 ff_v4l2_context_dequeue_frame (ctx=ctx@entry=0xa5d98, frame=0x225a0, frame@entry=0x70, timeout=60000, timeout@entry=5) at libavcodec/v4l2_context.c:1036#12 0xf7d91bb8 in v4l2_receive_frame (avctx=<optimized out>, frame=0x70) at libavcodec/v4l2_m2m_dec.c:664#13 0xf7babc44 in decode_receive_frame_internal (avctx=avctx@entry=0x9a590, frame=0x225a0) at libavcodec/decode.c:532#14 0xf7bac9ac in avcodec_send_packet (avctx=0x9a590, avpkt=0xfffef2f8) at libavcodec/decode.c:604
Code:
static int do_source_change(V4L2m2mContext * const s) { ... if (!reinit) { ... } else { ... ff_v4l2_context_release(&s->capture); ... } ret = ff_v4l2_context_set_status(&s->capture, VIDIOC_STREAMON);
Code:
int ff_v4l2_context_set_status(V4L2Context* ctx, uint32_t cmd) { ... ff_mutex_lock(&ctx->lock); // <- this lock has been destroyed in ff_v4l2_context_release if (cmd == VIDIOC_STREAMON && !V4L2_TYPE_IS_OUTPUT(ctx->type)) stuff_all_buffers(avctx, ctx);
Code:
static int stuff_all_buffers(AVCodecContext * avctx, V4L2Context* ctx) { ... if (!ctx->bufrefs) { rv = ff_v4l2_context_init(ctx); // this reinitialized the ctx->lock again
I'm not sure why I don't see this behaviour in the packaged version.
Statistics: Posted by dividuum — Sun Jan 21, 2024 12:58 pm — Replies 3 — Views 136