On 10/24/2018 3:12 PM, Chris Cunningham wrote: > 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.
Dropping this as it's not correct. It's not taking into account show_existing_frame frames (And reading bits way past the header bits), or superframes, where it may be parsing an invisible frame. Pushed only the part setting profile. _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel