[vlc-devel] [PATCH v3 2/2] dav1d: parse the extra data to get the output chroma

Steve Lhomme robux4 at ycbcr.xyz
Thu Sep 10 14:44:01 CEST 2020


The only difference with v2 is the use of AV1_OBUGetType() to check the 
private data is a sequence header OBU.

On 2020-09-10 14:40, Steve Lhomme wrote:
> If there are some extra data, the chroma should be constant and we can estimate
> it so that we create the decoder output with the proper chroma on open.
> ---
>   modules/codec/Makefile.am |  3 ++-
>   modules/codec/dav1d.c     | 53 +++++++++++++++++++++++++++++++++++----
>   2 files changed, 50 insertions(+), 6 deletions(-)
> 
> diff --git a/modules/codec/Makefile.am b/modules/codec/Makefile.am
> index 0aede611336..acb5071f569 100644
> --- a/modules/codec/Makefile.am
> +++ b/modules/codec/Makefile.am
> @@ -552,7 +552,8 @@ libtwolame_plugin_la_LIBADD = $(TWOLAME_LIBS) $(LIBM)
>   EXTRA_LTLIBRARIES += libtwolame_plugin.la
>   codec_LTLIBRARIES += $(LTLIBtwolame)
>   
> -libdav1d_plugin_la_SOURCES = codec/dav1d.c
> +libdav1d_plugin_la_SOURCES = codec/dav1d.c \
> +	packetizer/av1_obu.c packetizer/av1_obu.h
>   libdav1d_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) $(DAV1D_CFLAGS)
>   libdav1d_plugin_la_CFLAGS = $(AM_CFLAGS)
>   libdav1d_plugin_la_LDFLAGS = $(AM_LDFLAGS) -rpath '$(codecdir)'
> diff --git a/modules/codec/dav1d.c b/modules/codec/dav1d.c
> index 92f6f441464..a56e0207066 100644
> --- a/modules/codec/dav1d.c
> +++ b/modules/codec/dav1d.c
> @@ -38,6 +38,7 @@
>   #include <dav1d/dav1d.h>
>   
>   #include "../packetizer/iso_color_tables.h"
> +#include "../packetizer/av1_obu.h"
>   #include "cc.h"
>   
>   /****************************************************************************
> @@ -391,6 +392,37 @@ static int OpenDecoder(vlc_object_t *p_this)
>       p_sys->s.allocator.alloc_picture_callback = NewPicture;
>       p_sys->s.allocator.release_picture_callback = FreePicture;
>   
> +    av1_OBU_sequence_header_t *sequence_hdr = NULL;
> +    if (dec->fmt_in.i_extra > 4)
> +    {
> +        // in ISOBMFF/WebM/Matroska the first 4 bytes are from the AV1CodecConfigurationBox
> +        // and then one or more OBU
> +        uint8_t *obu_start = ((uint8_t*) dec->fmt_in.p_extra) + 4;
> +        if (AV1_OBUGetType(obu_start) == AV1_OBU_SEQUENCE_HEADER)
> +            sequence_hdr = AV1_OBU_parse_sequence_header(obu_start,
> +                                                         dec->fmt_in.i_extra - 4);
> +    }
> +
> +    if (!sequence_hdr)
> +    {
> +        dec->fmt_out.i_codec = VLC_CODEC_I420;
> +        dec->fmt_out.video.i_width = dec->fmt_in.video.i_width;
> +        dec->fmt_out.video.i_height = dec->fmt_in.video.i_height;
> +    }
> +    else
> +    {
> +        // use the sequence header to get a better chroma to start with
> +        dec->fmt_out.i_codec = AV1_get_chroma(sequence_hdr);
> +
> +        AV1_get_frame_max_dimensions(sequence_hdr, &dec->fmt_out.video.i_width, &dec->fmt_out.video.i_height);
> +
> +        if (dec->fmt_out.video.transfer == TRANSFER_FUNC_UNDEF)
> +            AV1_get_colorimetry(sequence_hdr, &dec->fmt_out.video.primaries, &dec->fmt_out.video.transfer,
> +                                &dec->fmt_out.video.space, &dec->fmt_out.video.color_range);
> +    }
> +    dec->fmt_out.video.i_visible_width  = dec->fmt_out.video.i_width;
> +    dec->fmt_out.video.i_visible_height = dec->fmt_out.video.i_height;
> +
>       if (dav1d_open(&p_sys->c, &p_sys->s) < 0)
>       {
>           msg_Err(p_this, "Could not open the Dav1d decoder");
> @@ -400,13 +432,10 @@ static int OpenDecoder(vlc_object_t *p_this)
>       msg_Dbg(p_this, "Using dav1d version %s with %d/%d frame/tile threads",
>               dav1d_version(), p_sys->s.n_frame_threads, p_sys->s.n_tile_threads);
>   
> -    dec->pf_decode = Decode;
> -    dec->pf_flush = FlushDecoder;
>       dec->i_extra_picture_buffers = (p_sys->s.n_frame_threads - 1);
> +    dec->fmt_out.video.i_width  = (dec->fmt_out.video.i_width + 0x7F) & ~0x7F;
> +    dec->fmt_out.video.i_height = (dec->fmt_out.video.i_height + 0x7F) & ~0x7F;
>   
> -    dec->fmt_out.video.i_width = dec->fmt_in.video.i_width;
> -    dec->fmt_out.video.i_height = dec->fmt_in.video.i_height;
> -    dec->fmt_out.i_codec = VLC_CODEC_I420;
>       dec->p_sys = p_sys;
>   
>       if (dec->fmt_in.video.i_sar_num > 0 && dec->fmt_in.video.i_sar_den > 0) {
> @@ -420,6 +449,20 @@ static int OpenDecoder(vlc_object_t *p_this)
>       dec->fmt_out.video.mastering   = dec->fmt_in.video.mastering;
>       dec->fmt_out.video.lighting    = dec->fmt_in.video.lighting;
>   
> +    if (sequence_hdr != NULL)
> +    {
> +        // we have the proper chroma, make sure we can use it
> +        AV1_release_sequence_header(sequence_hdr);
> +
> +        if (decoder_UpdateVideoFormat(dec) != 0)
> +        {
> +            CloseDecoder(VLC_OBJECT(dec));
> +            return VLC_EGENERIC;
> +        }
> +    }
> +    dec->pf_decode = Decode;
> +    dec->pf_flush = FlushDecoder;
> +
>       cc_Init(&p_sys->cc);
>   
>       return VLC_SUCCESS;
> -- 
> 2.26.2
> 
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel
> 


More information about the vlc-devel mailing list