[FFmpeg-devel] [PATCH] avcodec/vp9_parser: export profile and pixel format
Chris Cunningham
chcunningham at chromium.org
Wed Oct 24 21:12:58 EEST 2018
On Wed, Oct 3, 2018 at 10:49 AM James Almer <jamrial at gmail.com> wrote:
> Signed-off-by: James Almer <jamrial at gmail.com>
> ---
> libavcodec/vp9_parser.c | 82 ++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 80 insertions(+), 2 deletions(-)
>
> diff --git a/libavcodec/vp9_parser.c b/libavcodec/vp9_parser.c
> index 9531f34a32..d4110f20bf 100644
> --- a/libavcodec/vp9_parser.c
> +++ b/libavcodec/vp9_parser.c
> @@ -23,36 +23,114 @@
>
> #include "libavutil/intreadwrite.h"
> #include "libavcodec/get_bits.h"
> +#include "libavcodec/internal.h"
> #include "parser.h"
>
> +#define VP9_SYNCCODE 0x498342
> +
> +static int read_colorspace_details(AVCodecParserContext *ctx,
> AVCodecContext *avctx,
> + GetBitContext *gb)
> +{
> + static const enum AVColorSpace colorspaces[8] = {
> + AVCOL_SPC_UNSPECIFIED, AVCOL_SPC_BT470BG, AVCOL_SPC_BT709,
> AVCOL_SPC_SMPTE170M,
> + AVCOL_SPC_SMPTE240M, AVCOL_SPC_BT2020_NCL, AVCOL_SPC_RESERVED,
> AVCOL_SPC_RGB,
> + };
> + int colorspace, bits = avctx->profile <= 1 ? 0 : 1 + get_bits1(gb);
> // 0:8, 1:10, 2:12
> +
> + colorspace = colorspaces[get_bits(gb, 3)];
> + if (colorspace == AVCOL_SPC_RGB) { // RGB = profile 1
> + static const enum AVPixelFormat pix_fmt_rgb[3] = {
> + AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRP12
> + };
> + if (avctx->profile & 1) {
> + if (get_bits1(gb)) // reserved bit
> + return AVERROR_INVALIDDATA;
> + } else
> + return AVERROR_INVALIDDATA;
> + ctx->format = pix_fmt_rgb[bits];
> + } else {
> + static const enum AVPixelFormat pix_fmt_for_ss[3][2 /* v */][2 /*
> h */] = {
> + { { AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV422P },
> + { AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV420P } },
> + { { AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUV422P10 },
> + { AV_PIX_FMT_YUV440P10, AV_PIX_FMT_YUV420P10 } },
> + { { AV_PIX_FMT_YUV444P12, AV_PIX_FMT_YUV422P12 },
> + { AV_PIX_FMT_YUV440P12, AV_PIX_FMT_YUV420P12 } }
> + };
> + if (avctx->profile & 1) {
> + int ss_h, ss_v, format;
> +
> + ss_h = get_bits1(gb);
> + ss_v = get_bits1(gb);
> + format = pix_fmt_for_ss[bits][ss_v][ss_h];
> + if (format == AV_PIX_FMT_YUV420P)
> + // YUV 4:2:0 not supported in profiles 1 and 3
> + return AVERROR_INVALIDDATA;
> + else if (get_bits1(gb)) // color details reserved bit
> + return AVERROR_INVALIDDATA;
> + ctx->format = format;
> + } else {
> + ctx->format = pix_fmt_for_ss[bits][1][1];
> + }
> + }
> +
> + return 0;
> +}
> +
> static int parse(AVCodecParserContext *ctx,
> AVCodecContext *avctx,
> const uint8_t **out_data, int *out_size,
> const uint8_t *data, int size)
> {
> GetBitContext gb;
> - int res, profile, keyframe;
> + int res, profile, keyframe, invisible, errorres;
>
> *out_data = data;
> *out_size = size;
>
> - if ((res = init_get_bits8(&gb, data, size)) < 0)
> + if (!size || (res = init_get_bits8(&gb, data, size)) < 0)
> return size; // parsers can't return errors
> get_bits(&gb, 2); // frame marker
> profile = get_bits1(&gb);
> profile |= get_bits1(&gb) << 1;
> if (profile == 3) profile += get_bits1(&gb);
> + if (profile > 3)
> + return size;
>
> + avctx->profile = profile;
> if (get_bits1(&gb)) {
> keyframe = 0;
> + skip_bits(&gb, 3);
> } else {
> keyframe = !get_bits1(&gb);
> }
>
> + invisible = !get_bits1(&gb);
> + errorres = get_bits1(&gb);
> +
> if (!keyframe) {
> + int intraonly = invisible ? get_bits1(&gb) : 0;
> + if (!errorres)
> + skip_bits(&gb, 2);
> + if (intraonly) {
> + if (get_bits_long(&gb, 24) != VP9_SYNCCODE) // synccode
> + return size;
> + if (profile >= 1) {
> + if ((read_colorspace_details(ctx, avctx, &gb)) < 0)
> + return size;
> + } else {
> + ctx->format = AV_PIX_FMT_YUV420P;
> + }
> + }
> +
> ctx->pict_type = AV_PICTURE_TYPE_P;
> ctx->key_frame = 0;
> } else {
> + if (get_bits_long(&gb, 24) != VP9_SYNCCODE) // synccode
> + return size;
> + if (read_colorspace_details(ctx, avctx, &gb) < 0)
> + return size;
> +
> ctx->pict_type = AV_PICTURE_TYPE_I;
> ctx->key_frame = 1;
> }
> --
> 2.19.0
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Friendly ping for review.
More information about the ffmpeg-devel
mailing list