[vlc-commits] [Git][videolan/vlc][master] 3 commits: avcodec: vaapi: check AV1 capabilities

Steve Lhomme (@robUx4) gitlab at videolan.org
Wed Dec 18 13:09:26 UTC 2024



Steve Lhomme pushed to branch master at VideoLAN / VLC


Commits:
b7519c87 by Thomas Guillem at 2024-12-18T12:55:55+00:00
avcodec: vaapi: check AV1 capabilities

Since the avcodec hw module used for AV1 won't fallback to software, you
have to make sure vaapi can handle the AV1 profile.

- - - - -
46094cdc by Thomas Guillem at 2024-12-18T12:55:55+00:00
avcodec: let's the va module increase the picture count

- - - - -
9a22ccb7 by Thomas Guillem at 2024-12-18T12:55:55+00:00
avcodec: vaapi: increase picture count for AV1

Fixes the following deadlock:

Thread 11 (Thread 0x7f87e866b6c0 (LWP 2685607) "vlc-input"):
 #0  syscall () at ../sysdeps/unix/sysv/linux/x86_64/syscall.S:38
 #1  0x00007f87ea4e5e82 in sys_futex (addr=0x7f87e866a620, op=137, val=0, to=0x0, addr2=0x0, val3=-1) at ../../src/linux/thread.c:83
 #2  vlc_futex_wait (flags=0, to=0x0, addr=addr at entry=0x7f87e866a620, val=0) at ../../src/linux/thread.c:94
 #3  vlc_atomic_wait (addr=addr at entry=0x7f87e866a660, val=val at entry=0) at ../../src/linux/thread.c:110
 #4  0x00007f87ea4d5ff4 in vlc_cond_wait (cond=cond at entry=0x7f87d005f488, mutex=0x7f87d001ecc8) at ../../src/misc/threads.c:288
 #5  0x00007f87ea466ffb in vlc_fifo_WaitCond (fifo=<optimized out>, condvar=0x7f87d005f488) at ../../include/vlc_frame.h:696
 #6  vlc_input_decoder_Wait (p_owner=0x7f87d005efe0) at ../../src/input/decoder.c:2697
 #7  0x00007f87ea46d31a in EsOutDecodersStopBuffering (p_sys=p_sys at entry=0x55c57c97d640, b_forced=b_forced at entry=false) at ../../src/input/es_out.c:1000
 #8  0x00007f87ea47464a in EsOutVaControlLocked (p_sys=p_sys at entry=0x55c57c97d640, source=0x55c57c969cb0, source at entry=0x0, i_query=i_query at entry=8, args=args at entry=0x7f87e866a8f0) at ../../src/input/es_out.c:3381
 #9  0x00007f87ea474cb8 in EsOutControl (out=0x55c57c97d7d0, source=0x0, i_query=8, args=0x7f87e866a8f0) at ../../src/input/es_out.c:3976
 #10 0x00007f87ea475430 in es_out_in_vaControl (p_out=<optimized out>, in=<optimized out>, i_query=<optimized out>, args=0x7f87e866a8f0) at ../../src/input/es_out_timeshift.c:457
 #11 es_out_in_Control (p_out=<optimized out>, in=<optimized out>, i_query=<optimized out>) at ../../src/input/es_out_timeshift.c:468
 #12 0x00007f87ea4769ee in ControlLocked (p_out=0x7f87d0000c08, in=<optimized out>, i_query=<optimized out>, args=<optimized out>) at ../../src/input/es_out_timeshift.c:667
 #13 Control (p_tsout=0x7f87d0000c08, in=<optimized out>, i_query=<optimized out>, args=<optimized out>) at ../../src/input/es_out_timeshift.c:739
 #14 0x00007f87e4ecc1dc in es_out_vaControl (out=<optimized out>, i_query=8, args=0x7f87e866aa50) at ../../include/vlc_es_out.h:160
 #15 es_out_Control (out=<optimized out>, i_query=8, i_query=8) at ../../include/vlc_es_out.h:169
 #16 0x00007f87e4eccae4 in es_out_SetPCR (out=<optimized out>, pcr=1007501) at ../../include/vlc_es_out.h:187
 #17 mkv::UpdatePCR (p_demux=0x7f87d0028160) at ../../modules/demux/mkv/util.cpp:340
 #18 0x00007f87e4f01f1f in mkv::Demux (p_demux=0x7f87d0028160) at ../../modules/demux/mkv/mkv.cpp:880
 #19 0x00007f87ea47fc08 in MainLoopDemux (p_input=0x55c57c97aa30, pb_changed=<synthetic pointer>) at ../../src/input/input.c:481
 #20 MainLoop (p_input=p_input at entry=0x55c57c97aa30, b_interactive=b_interactive at entry=true) at ../../src/input/input.c:659
 #21 0x00007f87ea480815 in Run (data=0x55c57c97aa30) at ../../src/input/input.c:411
 #22 0x00007f87ea288112 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:447
 #23 0x00007f87ea3068f8 in __GI___clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78

Thread 4 (Thread 0x7f87d42bd6c0 (LWP 2685615) "vlc-vout"):
 #0  syscall () at ../sysdeps/unix/sysv/linux/x86_64/syscall.S:38
 #1  0x00007f87ea4e5ed6 in sys_futex (addr=0x7f87d42bcd30, op=137, val=0, to=<optimized out>, addr2=0x0, val3=-1) at ../../src/linux/thread.c:83
 #2  vlc_futex_wait (addr=0x7f87d42bcd30, flags=0, val=0, to=<optimized out>) at ../../src/linux/thread.c:94
 #3  vlc_atomic_timedwait (addr=addr at entry=0x7f87d42bcd30, val=val at entry=0, deadline=deadline at entry=160719871360) at ../../src/linux/thread.c:117
 #4  0x00007f87ea4d60dc in vlc_cond_timedwait (cond=cond at entry=0x7f87d0067d90, mutex=mutex at entry=0x7f87d0067d80, deadline=deadline at entry=160719871360) at ../../src/misc/threads.c:302
 #5  0x00007f87ea4a569f in vout_control_Wait (ctrl=ctrl at entry=0x7f87d0067d80, deadline=deadline at entry=160719871360) at ../../src/video_output/control.c:113
 #6  0x00007f87ea4aaf5a in Thread (object=0x7f87d0067c30) at ../../src/video_output/video_output.c:1897
 #7  0x00007f87ea288112 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:447
 #8  0x00007f87ea3068f8 in __GI___clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78

Thread 3 (Thread 0x7f87d41bc6c0 (LWP 2685616) "vlc-dec-video"):
 #0  syscall () at ../sysdeps/unix/sysv/linux/x86_64/syscall.S:38
 #1  0x00007f87ea4e5e82 in sys_futex (addr=0x7f87d41bb1b0, op=137, val=0, to=0x0, addr2=0x0, val3=-1) at ../../src/linux/thread.c:83
 #2  vlc_futex_wait (flags=0, to=0x0, addr=addr at entry=0x7f87d41bb1b0, val=0) at ../../src/linux/thread.c:94
 #3  vlc_atomic_wait (addr=addr at entry=0x7f87d41bb1f0, val=val at entry=0) at ../../src/linux/thread.c:110
 #4  0x00007f87ea4d5ff4 in vlc_cond_wait (cond=cond at entry=0x7f87d0272390, mutex=mutex at entry=0x7f87d0272380) at ../../src/misc/threads.c:288
 #5  0x00007f87ea4d293b in picture_pool_Wait (pool=0x7f87d0272380) at ../../src/misc/picture_pool.c:182
 #6  0x00007f87ea46339c in ModuleThread_NewVideoBuffer (p_dec=<optimized out>) at ../../src/input/decoder.c:866
 #7  0x00007f87ddad1c24 in lavc_va_GetFrame (ctx=0x7f87d0063d00, frame=0x7f87a0005940, flags=1) at ../../modules/codec/avcodec/video.c:1788
 #8  lavc_GetFrame (ctx=0x7f87d0063d00, frame=0x7f87a0005940, flags=<optimized out>) at ../../modules/codec/avcodec/video.c:1943
 #9  0x00007f87ddbb1342 in ff_get_buffer (avctx=0x7f87d0063d00, frame=0x7f87a0005940, flags=1) at src/libavcodec/decode.c:1745
 #10 0x00007f87dde3b375 in thread_get_buffer_internal (avctx=0x7f87d0063d00, f=0x7f87a0005940, flags=1) at src/libavcodec/pthread_frame.c:1032
 #11 ff_thread_get_buffer (avctx=0x7f87d0063d00, f=0x7f87a0005940, flags=1) at src/libavcodec/pthread_frame.c:1051
 #12 0x00007f87ddf72c0b in vaapi_av1_start_frame (avctx=0x7f87d0063d00, buffer=<optimized out>, size=<optimized out>) at src/libavcodec/vaapi_av1.c:136
 #13 0x00007f87ddb099d2 in av1_receive_frame_internal (avctx=<optimized out>, frame=<optimized out>) at src/libavcodec/av1dec.c:1375
 #14 av1_receive_frame (avctx=<optimized out>, frame=<optimized out>) at src/libavcodec/av1dec.c:1528
 #15 0x00007f87ddbaf236 in ff_decode_receive_frame_internal (avctx=0x7f87d0063d00, frame=0x7f87d0065c40) at src/libavcodec/decode.c:634
 #16 0x00007f87ddbaf855 in decode_receive_frame_internal (avctx=avctx at entry=0x7f87d0063d00, frame=0x7f87d0065c40) at src/libavcodec/decode.c:666
 #17 0x00007f87ddbafafc in avcodec_send_packet (avctx=0x7f87d0063d00, avpkt=0x7f87a0000e00) at src/libavcodec/decode.c:753
 #18 0x00007f87ddacf2ee in DecodeBlock (p_dec=<optimized out>, pp_block=<optimized out>) at ../../modules/codec/avcodec/video.c:1427
 #19 DecodeVideo (p_dec=<optimized out>, p_block=<optimized out>) at ../../modules/codec/avcodec/video.c:1677
 #20 0x00007f87ea4655b0 in DecoderThread_DecodeBlock (p_owner=0x7f87d005efe0, frame=0x7f87d0edaf50) at ../../src/input/decoder.c:1629
 #21 0x00007f87ea465c0b in DecoderThread_ProcessInput (p_owner=p_owner at entry=0x7f87d005efe0, frame=<optimized out>) at ../../src/input/decoder.c:1755
 #22 0x00007f87ea465e89 in DecoderThread (p_data=0x7f87d005efe0) at ../../src/input/decoder.c:1869
 #23 0x00007f87ea288112 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:447
 #24 0x00007f87ea3068f8 in __GI___clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78

- - - - -


3 changed files:

- modules/codec/avcodec/va.h
- modules/codec/avcodec/vaapi.c
- modules/codec/avcodec/video.c


Changes:

=====================================
modules/codec/avcodec/va.h
=====================================
@@ -73,6 +73,13 @@ struct vlc_va_cfg
      * False, by default, set to true if the module is using this API
      */
     bool use_hwframes;
+
+    /**
+     * Request more pictures
+     *
+     * 0 by default, set if from the module
+     */
+    unsigned extra_pictures;
 };
 
 struct vlc_va_operations {


=====================================
modules/codec/avcodec/vaapi.c
=====================================
@@ -169,6 +169,83 @@ static const struct vlc_video_context_operations vaapi_ctx_ops =
     .destroy = vaapi_ctx_destroy,
 };
 
+static int CheckCodecConfig(vlc_va_t *va, AVCodecContext *ctx, VADisplay va_dpy,
+                            const AVPixFmtDescriptor *sw_desc)
+{
+    assert(ctx->codec_id == AV_CODEC_ID_AV1);
+
+    if (sw_desc->nb_components < 2)
+        return VLC_EGENERIC;
+
+    int va_rt_format, vc_fourcc;
+    switch (sw_desc->comp[0].depth)
+    {
+        case 8:
+            va_rt_format = VA_RT_FORMAT_YUV420;
+            vc_fourcc = VA_FOURCC_NV12;
+            break;
+        case 10:
+            va_rt_format = VA_RT_FORMAT_YUV420_10BPP;
+            vc_fourcc = VA_FOURCC_P010;
+            break;
+        default:
+            return VLC_EGENERIC;
+    }
+
+    VAProfile profile;
+    switch (ctx->profile)
+    {
+        case FF_PROFILE_AV1_MAIN:
+            profile = VAProfileAV1Profile0;
+            break;
+        case FF_PROFILE_AV1_HIGH:
+            profile = VAProfileAV1Profile1;
+            break;
+        default:
+            return VLC_EGENERIC;
+    }
+
+    VAConfigID config_id = VA_INVALID_ID;
+    VASurfaceID render_target = VA_INVALID_ID;
+    VAContextID context_id = VA_INVALID_ID;
+
+    config_id = vlc_vaapi_CreateConfigChecked(VLC_OBJECT(va), va_dpy, profile,
+                                              VAEntrypointVLD, 0);
+    if (config_id == VA_INVALID_ID)
+        goto error;
+
+    VASurfaceAttrib fourcc_attribs[1] = {
+        {
+            .type = VASurfaceAttribPixelFormat,
+            .flags = VA_SURFACE_ATTRIB_SETTABLE,
+            .value.type    = VAGenericValueTypeInteger,
+            .value.value.i = vc_fourcc,
+        }
+    };
+
+    VA_CALL(VLC_OBJECT(va), vaCreateSurfaces, va_dpy, va_rt_format,
+            ctx->coded_width, ctx->coded_height, &render_target, 1,
+            fourcc_attribs, 1);
+
+    context_id = vlc_vaapi_CreateContext(VLC_OBJECT(va), va_dpy, config_id,
+                                         ctx->coded_width, ctx->coded_height,
+                                         VA_PROGRESSIVE, &render_target, 1);
+
+error:
+    if (render_target != VA_INVALID_ID)
+        VA_CALL(VLC_OBJECT(va), vaDestroySurfaces, va_dpy, &render_target, 1);
+
+    if (config_id != VA_INVALID_ID)
+        vlc_vaapi_DestroyConfig(VLC_OBJECT(va), va_dpy, config_id);
+
+    if (context_id != VA_INVALID_ID)
+    {
+        vlc_vaapi_DestroyContext(VLC_OBJECT(va), va_dpy, context_id);
+        return VLC_SUCCESS;
+    }
+    return VLC_EGENERIC;
+}
+
 static int Create(vlc_va_t *va, struct vlc_va_cfg *cfg)
 {
     AVCodecContext *ctx = cfg->avctx;
@@ -182,6 +259,24 @@ static int Create(vlc_va_t *va, struct vlc_va_cfg *cfg)
 
     VADisplay va_dpy = dec_device->opaque;
 
+    switch (ctx->codec_id)
+    {
+        case AV_CODEC_ID_AV1:
+        {
+            /* Tested with ffmpeg @2d077f9, and few AV1 samples, 10 extra
+             * pictures are needed to avoid deadlocks (cf. commit description)
+             * when playing and seeking. */
+            cfg->extra_pictures = 10;
+
+            int ret = CheckCodecConfig(va, ctx, va_dpy, cfg->desc);
+            if (ret != VLC_SUCCESS)
+                return ret;
+            break;
+        }
+        default:
+            break;
+    }
+
     AVBufferRef *hwdev_ref = av_hwdevice_ctx_alloc(AV_HWDEVICE_TYPE_VAAPI);
     if (hwdev_ref == NULL)
         return VLC_EGENERIC;


=====================================
modules/codec/avcodec/video.c
=====================================
@@ -767,6 +767,7 @@ static int ffmpeg_OpenVa(decoder_t *p_dec, AVCodecContext *p_context,
         .video_fmt_out = &p_dec->fmt_out.video,
         .vctx_out = NULL,
         .use_hwframes = false,
+        .extra_pictures = 0,
     };
     vlc_va_t *va = vlc_va_New(VLC_OBJECT(p_dec), &cfg);
 
@@ -775,6 +776,7 @@ static int ffmpeg_OpenVa(decoder_t *p_dec, AVCodecContext *p_context,
     assert(p_dec->fmt_out.video.i_chroma != 0);
     assert(cfg.vctx_out != NULL);
     p_dec->fmt_out.i_codec = p_dec->fmt_out.video.i_chroma;
+    p_dec->i_extra_picture_buffers += cfg.extra_pictures;
 
     if (decoder_UpdateVideoOutput(p_dec, cfg.vctx_out))
     {



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/f7cc4f770613f6f30a7a4348f452466ff53b46ba...9a22ccb72f83c144a678dad9b92b8750d7a46f0d

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/f7cc4f770613f6f30a7a4348f452466ff53b46ba...9a22ccb72f83c144a678dad9b92b8750d7a46f0d
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list