[vlc-commits] [Git][videolan/vlc][3.0.x] 3 commits: avcodec: va: pass the software AVPixFmtDescriptor for AV1 special decoder

Jean-Baptiste Kempf (@jbk) gitlab at videolan.org
Sun Jul 16 09:32:01 UTC 2023



Jean-Baptiste Kempf pushed to branch 3.0.x at VideoLAN / VLC


Commits:
ed9fc431 by Steve Lhomme at 2023-07-13T11:10:43+02:00
avcodec: va: pass the software AVPixFmtDescriptor for AV1 special decoder

This is what is passed in the normal decoding case.

This fixes an issue where 10-bit sources don't play properly as we can't
tell from the Profile 0 is we're decoding in 8-bit or 10-bit.

(cherry picked from commit 1aa624e28db64fbd53888789ff91520ef8997983)
Signed-off-by: Steve Lhomme <robux4 at ycbcr.xyz>

- - - - -
632652bc by Steve Lhomme at 2023-07-13T11:10:53+02:00
avcodec: va: move the AV1 profile extraction in a function

(cherry picked from commit 5892a9106aa2760b0bdf9d4a4c785dca9bfe21b8) (edited)

edited:
- in 4.0 p_dec->fmt_in is a (const) pointer
- there's no VLC_ENOTSUP in 3.0
Signed-off-by: Steve Lhomme <robux4 at ycbcr.xyz>

- - - - -
dfdc90c3 by Steve Lhomme at 2023-07-13T11:11:11+02:00
avcodec: va: set the software source for special AV1 decoder

So far we did not need it. We should always have the format matching
the one we detected by the decoder. If we don't that means the packetizer
failed to reset the decoder.

(cherry picked from commit c901da645b3a00766831750fe882b8a52360ef88)
Signed-off-by: Steve Lhomme <robux4 at ycbcr.xyz>

- - - - -


1 changed file:

- modules/codec/avcodec/video.c


Changes:

=====================================
modules/codec/avcodec/video.c
=====================================
@@ -699,40 +699,23 @@ static const enum PixelFormat hwfmts[] =
     AV_PIX_FMT_NONE,
 };
 
-int InitVideoHwDec( vlc_object_t *obj )
+static int ExtractAV1Profile(AVCodecContext *p_context, const es_format_t *fmt_in, decoder_sys_t *p_sys)
 {
-    decoder_t *p_dec = container_of(obj, decoder_t, obj);
-
-    if (p_dec->fmt_in.i_codec != VLC_CODEC_AV1)
-        return VLC_EGENERIC;
-
-    decoder_sys_t *p_sys = calloc(1, sizeof(*p_sys));
-    if( unlikely(p_sys == NULL) )
-        return VLC_ENOMEM;
-
-    const AVCodec *p_codec;
-    AVCodecContext *p_context = ffmpeg_AllocContext( p_dec, &p_codec );
-    if( unlikely(p_context == NULL) )
-    {
-        free(p_sys);
-        return VLC_ENOMEM;
-    }
-
     av1_OBU_sequence_header_t *sequence_hdr = NULL;
     unsigned w, h;
 
-    if (p_dec->fmt_in.i_extra > 4)
+    if (fmt_in->i_extra > 4)
     {
         // in ISOBMFF/WebM/Matroska the first 4 bytes are from the AV1CodecConfigurationBox
         // and then one or more OBU
-        const uint8_t *obu_start = ((const uint8_t*) p_dec->fmt_in.p_extra) + 4;
-        int obu_size = p_dec->fmt_in.i_extra - 4;
+        const uint8_t *obu_start = ((const uint8_t*) fmt_in->p_extra) + 4;
+        int obu_size = fmt_in->i_extra - 4;
         if (AV1_OBUIsValid(obu_start, obu_size) && AV1_OBUGetType(obu_start) == AV1_OBU_SEQUENCE_HEADER)
             sequence_hdr = AV1_OBU_parse_sequence_header(obu_start, obu_size);
     }
 
     if (sequence_hdr == NULL)
-        goto failed;
+        return VLC_EGENERIC;
 
     // fill the AVCodecContext with the values from the sequence header
     // so we can create the expected VA right away:
@@ -742,14 +725,14 @@ int InitVideoHwDec( vlc_object_t *obj )
     if (chroma == 0)
     {
         AV1_release_sequence_header(sequence_hdr);
-        goto failed;
+        return VLC_EGENERIC;
     }
     p_context->sw_pix_fmt = FindFfmpegChroma(chroma);
 
     if (p_context->sw_pix_fmt == AV_PIX_FMT_NONE)
     {
         AV1_release_sequence_header(sequence_hdr);
-        goto failed;
+        return VLC_EGENERIC;
     }
 
     AV1_get_frame_max_dimensions(sequence_hdr, &w, &h);
@@ -757,7 +740,7 @@ int InitVideoHwDec( vlc_object_t *obj )
     p_context->coded_width  = p_context->width  = w;
     p_context->coded_height = p_context->height = h;
 
-    if (!p_dec->fmt_in.video.i_frame_rate || !p_dec->fmt_in.video.i_frame_rate_base)
+    if (!fmt_in->video.i_frame_rate || !fmt_in->video.i_frame_rate_base)
     {
         unsigned num, den;
         if (AV1_get_frame_rate(sequence_hdr, &num, &den))
@@ -772,6 +755,31 @@ int InitVideoHwDec( vlc_object_t *obj )
 
     AV1_release_sequence_header(sequence_hdr);
 
+    return VLC_SUCCESS;
+}
+
+int InitVideoHwDec( vlc_object_t *obj )
+{
+    decoder_t *p_dec = container_of(obj, decoder_t, obj);
+
+    if (p_dec->fmt_in.i_codec != VLC_CODEC_AV1)
+        return VLC_EGENERIC;
+
+    decoder_sys_t *p_sys = calloc(1, sizeof(*p_sys));
+    if( unlikely(p_sys == NULL) )
+        return VLC_ENOMEM;
+
+    const AVCodec *p_codec;
+    AVCodecContext *p_context = ffmpeg_AllocContext( p_dec, &p_codec );
+    if( unlikely(p_context == NULL) )
+    {
+        free(p_sys);
+        return VLC_ENOMEM;
+    }
+
+    if (ExtractAV1Profile(p_context, &p_dec->fmt_in, p_sys) != VLC_SUCCESS)
+        goto failed;
+
     p_dec->p_sys = p_sys;
     p_sys->p_context = p_context;
     p_sys->p_codec = p_codec;
@@ -782,15 +790,11 @@ int InitVideoHwDec( vlc_object_t *obj )
     if (res != VLC_SUCCESS)
         goto not_usable;
 
+    const AVPixFmtDescriptor *src_desc = av_pix_fmt_desc_get(p_context->sw_pix_fmt);
+
     for( size_t i = 0; hwfmts[i] != AV_PIX_FMT_NONE; i++ )
     {
-        enum AVPixelFormat hwfmt = hwfmts[i];
-
-        const AVPixFmtDescriptor *dsc = av_pix_fmt_desc_get(hwfmt);
-        if (dsc == NULL)
-            continue;
-
-        if (ffmpeg_OpenVa(p_dec, p_context, hwfmt, p_context->sw_pix_fmt, dsc, NULL) == VLC_SUCCESS)
+        if (ffmpeg_OpenVa(p_dec, p_context, hwfmts[i], p_context->sw_pix_fmt, src_desc, NULL) == VLC_SUCCESS)
             // we have a matching hardware decoder
             return VLC_SUCCESS;
     }
@@ -1753,8 +1757,18 @@ static enum PixelFormat ffmpeg_GetFormat( AVCodecContext *p_context,
 
     /* Use the default fmt in priority of any sw fmt if the default fmt is a hw
      * one */
-    if (defaultfmt != AV_PIX_FMT_NONE && !p_sys->b_hardware_only)
+    if (defaultfmt != AV_PIX_FMT_NONE)
+    {
+        if (p_sys->b_hardware_only)
+        {
+            if (defaultfmt != p_context->sw_pix_fmt)
+            {
+                // the source format changed and we didn't detect it
+                vlc_assert_unreachable();
+            }
+        }
         swfmt = defaultfmt;
+    }
 
     if (p_sys->pix_fmt == AV_PIX_FMT_NONE)
         goto no_reuse;



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/1f686d34505e6ed50fe45a59f9aa4b06d7f0dc7f...dfdc90c30a50a7e4fbdddeac2c06d51ade7ab385

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/1f686d34505e6ed50fe45a59f9aa4b06d7f0dc7f...dfdc90c30a50a7e4fbdddeac2c06d51ade7ab385
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