diff options
Diffstat (limited to 'libavcodec')
-rw-r--r-- | libavcodec/vp9_parser.c | 127 |
1 files changed, 10 insertions, 117 deletions
diff --git a/libavcodec/vp9_parser.c b/libavcodec/vp9_parser.c index 9900e7ab1f..9531f34a32 100644 --- a/libavcodec/vp9_parser.c +++ b/libavcodec/vp9_parser.c @@ -25,21 +25,19 @@ #include "libavcodec/get_bits.h" #include "parser.h" -typedef struct VP9ParseContext { - int n_frames; // 1-8 - int size[8]; - int marker_size; - int64_t pts; -} VP9ParseContext; - -static int parse_frame(AVCodecParserContext *ctx, const uint8_t *buf, int size) +static int parse(AVCodecParserContext *ctx, + AVCodecContext *avctx, + const uint8_t **out_data, int *out_size, + const uint8_t *data, int size) { - VP9ParseContext *s = ctx->priv_data; GetBitContext gb; - int res, profile, keyframe, invisible; + int res, profile, keyframe; - if ((res = init_get_bits8(&gb, buf, size)) < 0) - return res; + *out_data = data; + *out_size = size; + + if ((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; @@ -47,10 +45,8 @@ static int parse_frame(AVCodecParserContext *ctx, const uint8_t *buf, int size) if (get_bits1(&gb)) { keyframe = 0; - invisible = 0; } else { keyframe = !get_bits1(&gb); - invisible = !get_bits1(&gb); } if (!keyframe) { @@ -61,113 +57,10 @@ static int parse_frame(AVCodecParserContext *ctx, const uint8_t *buf, int size) ctx->key_frame = 1; } - if (!invisible) { - if (ctx->pts == AV_NOPTS_VALUE) - ctx->pts = s->pts; - s->pts = AV_NOPTS_VALUE; - } else if (ctx->pts != AV_NOPTS_VALUE) { - s->pts = ctx->pts; - ctx->pts = AV_NOPTS_VALUE; - } - - return 0; -} - -static int parse(AVCodecParserContext *ctx, - AVCodecContext *avctx, - const uint8_t **out_data, int *out_size, - const uint8_t *data, int size) -{ - VP9ParseContext *s = ctx->priv_data; - int full_size = size; - int marker; - - if (size <= 0) { - *out_size = 0; - *out_data = data; - - return 0; - } - - if (s->n_frames > 0) { - int i; - int size_sum = 0; - - for (i = 0; i < s->n_frames ;i++) - size_sum += s->size[i]; - size_sum += s->marker_size; - - if (size_sum != size) { - av_log(avctx, AV_LOG_ERROR, "Inconsistent input frame sizes %d %d\n", - size_sum, size); - s->n_frames = 0; - } - } - - if (s->n_frames > 0) { - *out_data = data; - *out_size = s->size[--s->n_frames]; - parse_frame(ctx, *out_data, *out_size); - - return s->n_frames > 0 ? *out_size : size /* i.e. include idx tail */; - } - - marker = data[size - 1]; - if ((marker & 0xe0) == 0xc0) { - int nbytes = 1 + ((marker >> 3) & 0x3); - int n_frames = 1 + (marker & 0x7), idx_sz = 2 + n_frames * nbytes; - - if (size >= idx_sz && data[size - idx_sz] == marker) { - const uint8_t *idx = data + size + 1 - idx_sz; - int first = 1; - - switch (nbytes) { -#define case_n(a, rd) \ - case a: \ - while (n_frames--) { \ - unsigned sz = rd; \ - idx += a; \ - if (sz == 0 || sz > size) { \ - s->n_frames = 0; \ - *out_size = size; \ - *out_data = data; \ - av_log(avctx, AV_LOG_ERROR, \ - "Invalid superframe packet size: %u frame size: %d\n", \ - sz, size); \ - return full_size; \ - } \ - if (first) { \ - first = 0; \ - *out_data = data; \ - *out_size = sz; \ - s->n_frames = n_frames; \ - } else { \ - s->size[n_frames] = sz; \ - } \ - data += sz; \ - size -= sz; \ - } \ - s->marker_size = size; \ - parse_frame(ctx, *out_data, *out_size); \ - return s->n_frames > 0 ? *out_size : full_size - - case_n(1, *idx); - case_n(2, AV_RL16(idx)); - case_n(3, AV_RL24(idx)); - case_n(4, AV_RL32(idx)); - } - } - } - - *out_data = data; - *out_size = size; - parse_frame(ctx, data, size); - return size; } AVCodecParser ff_vp9_parser = { .codec_ids = { AV_CODEC_ID_VP9 }, - .priv_data_size = sizeof(VP9ParseContext), .parser_parse = parse, }; |