On Wed, Oct 3, 2018 at 10:49 AM James Almer <jamr...@gmail.com> wrote:
> Signed-off-by: James Almer <jamr...@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@ffmpeg.org > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel Friendly ping for review. _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel