diff options
author | Mark Thompson <sw@jkqxz.net> | 2016-10-27 20:02:29 +0100 |
---|---|---|
committer | Mark Thompson <sw@jkqxz.net> | 2016-11-14 19:38:19 +0000 |
commit | 182cf170a544bce069c8690c90b49381150a1f10 (patch) | |
tree | ce5c1e01628d7f78cbb993f2ee02f39d2481a1f4 | |
parent | b6582b29277e00e5d49f400e58beefa5a21d83b8 (diff) | |
download | ffmpeg-182cf170a544bce069c8690c90b49381150a1f10.tar.gz |
vp8: Return stream format information from parser
-rw-r--r-- | libavcodec/vp8_parser.c | 49 |
1 files changed, 44 insertions, 5 deletions
diff --git a/libavcodec/vp8_parser.c b/libavcodec/vp8_parser.c index 8f6459ccec..fad652dbea 100644 --- a/libavcodec/vp8_parser.c +++ b/libavcodec/vp8_parser.c @@ -1,6 +1,4 @@ /* - * Copyright (C) 2008 Michael Niedermayer - * * This file is part of Libav. * * Libav is free software; you can redistribute it and/or @@ -18,15 +16,56 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "parser.h" +#include "libavutil/intreadwrite.h" + +#include "avcodec.h" static int parse(AVCodecParserContext *s, AVCodecContext *avctx, const uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size) { - s->pict_type = (buf[0] & 0x01) ? AV_PICTURE_TYPE_P - : AV_PICTURE_TYPE_I; + unsigned int frame_type; + unsigned int profile; + + if (buf_size < 3) + return AVERROR_INVALIDDATA; + + frame_type = buf[0] & 1; + profile = (buf[0] >> 1) & 7; + if (profile > 3) { + av_log(avctx, AV_LOG_ERROR, "Invalid profile %u.\n", profile); + return AVERROR_INVALIDDATA; + } + + avctx->profile = profile; + s->key_frame = frame_type == 0; + s->pict_type = frame_type ? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I; + s->format = AV_PIX_FMT_YUV420P; + s->field_order = AV_FIELD_PROGRESSIVE; + s->picture_structure = AV_PICTURE_STRUCTURE_FRAME; + + if (frame_type == 0) { + unsigned int sync_code; + unsigned int width, height; + + if (buf_size < 10) + return AVERROR_INVALIDDATA; + + sync_code = AV_RL24(buf + 3); + if (sync_code != 0x2a019d) { + av_log(avctx, AV_LOG_ERROR, "Invalid sync code %06x.\n", sync_code); + return AVERROR_INVALIDDATA; + } + + width = AV_RL16(buf + 6) & 0x3fff; + height = AV_RL16(buf + 8) & 0x3fff; + + s->width = width; + s->height = height; + s->coded_width = FFALIGN(width, 16); + s->coded_height = FFALIGN(height, 16); + } *poutbuf = buf; *poutbuf_size = buf_size; |