[FFmpeg-devel] [PATCH 1/2] avformat/dashenc: Set VP9 codec string with profile, level and bitdepth

James Almer jamrial at gmail.com
Wed Apr 18 16:42:48 EEST 2018


On 4/18/2018 9:03 AM, Karthick J wrote:
> From: Karthick Jeyapal <kjeyapal at akamai.com>
> 
> Otherwise some versions of chrome browser returns "codec not supported" error
> ---
>  libavformat/dashenc.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 78 insertions(+), 1 deletion(-)
> 
> diff --git a/libavformat/dashenc.c b/libavformat/dashenc.c
> index 9e72636..5443e31 100644
> --- a/libavformat/dashenc.c
> +++ b/libavformat/dashenc.c
> @@ -170,6 +170,79 @@ static void dashenc_io_close(AVFormatContext *s, AVIOContext **pb, char *filenam
>      }
>  }
>  
> +static void set_vp9_codec_str(AVCodecParameters *par, char *str, int size) {
> +    int profile, level, bitdepth;
> +    int picture_size = par->width * par->height;
> +    switch (par->format) {
> +    case AV_PIX_FMT_YUV420P:
> +    case AV_PIX_FMT_YUVA420P:
> +        bitdepth = 8;
> +        profile = 0;
> +        break;
> +    case AV_PIX_FMT_YUV422P:
> +    case AV_PIX_FMT_YUV440P:
> +    case AV_PIX_FMT_GBRP:
> +    case AV_PIX_FMT_YUV444P:
> +        bitdepth = 8;
> +        profile = 1;
> +        break;
> +    case AV_PIX_FMT_YUV420P10:
> +        bitdepth = 10;
> +        profile = 2;
> +        break;
> +    case AV_PIX_FMT_YUV420P12:
> +        bitdepth = 12;
> +        profile = 2;
> +        break;
> +    case AV_PIX_FMT_YUV422P10:
> +    case AV_PIX_FMT_YUV440P10:
> +    case AV_PIX_FMT_GBRP10:
> +    case AV_PIX_FMT_YUV444P10:
> +        bitdepth = 10;
> +        profile = 3;
> +        break;
> +    case AV_PIX_FMT_YUV422P12:
> +    case AV_PIX_FMT_YUV440P12:
> +    case AV_PIX_FMT_GBRP12:
> +    case AV_PIX_FMT_YUV444P12:
> +        bitdepth = 12;
> +        profile = 3;
> +        break;
> +    default:
> +        goto error;
> +    }

This is too big and unwieldy, you're not looking at par->profile first
(which is more than likely set to the correct value already), also
you're in any case not using the FF_PROFILE constants either.

And you should reuse as much code from vpcc.c as possible here. It will
be needed in other muxers like Matroska soon enough either way.
I'll send a patch in a moment to make that file usable for cases like
this one.

> +    // Finding VP9 level accurately in a ffmpeg muxer is almost impossible.
> +    // Hence we will set approximate levels based on the width and height.

You should check for par->level first, to see if it's not
FF_LEVEL_UNKNOWN (chances are it is, though).
Also, this should be implemented to vpcc.c, so it can be reused there to
write the vpcc atom for mp4 output (it's currently writing 0 when level
is unknown, which is probably wrong).

> +    if (picture_size <= 0) {
> +        goto error;
> +    } else if (picture_size <= 36864) {
> +        level = 0x10;
> +    } else if (picture_size <= 73728) {
> +        level = 0x11;
> +    } else if (picture_size <= 122880) {
> +        level = 0x20;
> +    } else if (picture_size <= 245760) {
> +        level = 0x21;
> +    } else if (picture_size <= 552960) {
> +        level = 0x30;
> +    } else if (picture_size <= 983040) {
> +        level = 0x31;
> +    } else if (picture_size <= 2228224) {
> +        level = 0x40;
> +    } else if (picture_size <= 8912896) {
> +        level = 0x50;
> +    } else if (picture_size <= 35651584) {
> +        level = 0x60;
> +    } else {
> +        goto error;
> +    }
> +    av_strlcatf(str, size, "vp09.%02x.%02x.%02x", profile, level, bitdepth);
> +    return;
> +error:
> +    // Default to just vp9 in case of error while finding out profile or level
> +    av_strlcpy(str, "vp9", size);
> +    return;
> +}
>  static void set_codec_str(AVFormatContext *s, AVCodecParameters *par,
>                            char *str, int size)
>  {
> @@ -180,7 +253,11 @@ static void set_codec_str(AVFormatContext *s, AVCodecParameters *par,
>      // common Webm codecs are not part of RFC 6381
>      for (i = 0; codecs[i].id; i++)
>          if (codecs[i].id == par->codec_id) {
> -            av_strlcpy(str, codecs[i].str, size);
> +            if (codecs[i].id == AV_CODEC_ID_VP9) {
> +                set_vp9_codec_str(par, str, size);
> +            } else {
> +                av_strlcpy(str, codecs[i].str, size);
> +            }
>              return;
>          }
>  
> 



More information about the ffmpeg-devel mailing list