vorbis_parser: use a dedicated AVClass for logging

Currently, the API takes an external AVCodecContext, which is used only
for extradata and logging. This change will allow to it to work without
an AVCodecContext in the following commits.
This commit is contained in:
Anton Khirnov 2014-10-29 14:18:06 +01:00
parent a490391157
commit 874792641e
2 changed files with 29 additions and 21 deletions

View File

@ -25,34 +25,42 @@
* Determines the duration for each packet. * Determines the duration for each packet.
*/ */
#include "libavutil/log.h"
#include "get_bits.h" #include "get_bits.h"
#include "parser.h" #include "parser.h"
#include "xiph.h" #include "xiph.h"
#include "vorbis_parser.h" #include "vorbis_parser.h"
static int parse_id_header(AVCodecContext *avctx, VorbisParseContext *s, static const AVClass vorbis_parser_class = {
.class_name = "Vorbis parser",
.item_name = av_default_item_name,
.version = LIBAVUTIL_VERSION_INT,
};
static int parse_id_header(VorbisParseContext *s,
const uint8_t *buf, int buf_size) const uint8_t *buf, int buf_size)
{ {
/* Id header should be 30 bytes */ /* Id header should be 30 bytes */
if (buf_size < 30) { if (buf_size < 30) {
av_log(avctx, AV_LOG_ERROR, "Id header is too short\n"); av_log(s, AV_LOG_ERROR, "Id header is too short\n");
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
/* make sure this is the Id header */ /* make sure this is the Id header */
if (buf[0] != 1) { if (buf[0] != 1) {
av_log(avctx, AV_LOG_ERROR, "Wrong packet type in Id header\n"); av_log(s, AV_LOG_ERROR, "Wrong packet type in Id header\n");
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
/* check for header signature */ /* check for header signature */
if (memcmp(&buf[1], "vorbis", 6)) { if (memcmp(&buf[1], "vorbis", 6)) {
av_log(avctx, AV_LOG_ERROR, "Invalid packet signature in Id header\n"); av_log(s, AV_LOG_ERROR, "Invalid packet signature in Id header\n");
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
if (!(buf[29] & 0x1)) { if (!(buf[29] & 0x1)) {
av_log(avctx, AV_LOG_ERROR, "Invalid framing bit in Id header\n"); av_log(s, AV_LOG_ERROR, "Invalid framing bit in Id header\n");
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
@ -62,7 +70,7 @@ static int parse_id_header(AVCodecContext *avctx, VorbisParseContext *s,
return 0; return 0;
} }
static int parse_setup_header(AVCodecContext *avctx, VorbisParseContext *s, static int parse_setup_header(VorbisParseContext *s,
const uint8_t *buf, int buf_size) const uint8_t *buf, int buf_size)
{ {
GetBitContext gb, gb0; GetBitContext gb, gb0;
@ -72,25 +80,25 @@ static int parse_setup_header(AVCodecContext *avctx, VorbisParseContext *s,
/* avoid overread */ /* avoid overread */
if (buf_size < 7) { if (buf_size < 7) {
av_log(avctx, AV_LOG_ERROR, "Setup header is too short\n"); av_log(s, AV_LOG_ERROR, "Setup header is too short\n");
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
/* make sure this is the Setup header */ /* make sure this is the Setup header */
if (buf[0] != 5) { if (buf[0] != 5) {
av_log(avctx, AV_LOG_ERROR, "Wrong packet type in Setup header\n"); av_log(s, AV_LOG_ERROR, "Wrong packet type in Setup header\n");
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
/* check for header signature */ /* check for header signature */
if (memcmp(&buf[1], "vorbis", 6)) { if (memcmp(&buf[1], "vorbis", 6)) {
av_log(avctx, AV_LOG_ERROR, "Invalid packet signature in Setup header\n"); av_log(s, AV_LOG_ERROR, "Invalid packet signature in Setup header\n");
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
/* reverse bytes so we can easily read backwards with get_bits() */ /* reverse bytes so we can easily read backwards with get_bits() */
if (!(rev_buf = av_malloc(buf_size))) { if (!(rev_buf = av_malloc(buf_size))) {
av_log(avctx, AV_LOG_ERROR, "Out of memory\n"); av_log(s, AV_LOG_ERROR, "Out of memory\n");
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
} }
for (i = 0; i < buf_size; i++) for (i = 0; i < buf_size; i++)
@ -105,7 +113,7 @@ static int parse_setup_header(AVCodecContext *avctx, VorbisParseContext *s,
} }
} }
if (!got_framing_bit) { if (!got_framing_bit) {
av_log(avctx, AV_LOG_ERROR, "Invalid Setup header\n"); av_log(s, AV_LOG_ERROR, "Invalid Setup header\n");
ret = AVERROR_INVALIDDATA; ret = AVERROR_INVALIDDATA;
goto bad_header; goto bad_header;
} }
@ -132,7 +140,7 @@ static int parse_setup_header(AVCodecContext *avctx, VorbisParseContext *s,
} }
} }
if (!got_mode_header) { if (!got_mode_header) {
av_log(avctx, AV_LOG_ERROR, "Invalid Setup header\n"); av_log(s, AV_LOG_ERROR, "Invalid Setup header\n");
ret = AVERROR_INVALIDDATA; ret = AVERROR_INVALIDDATA;
goto bad_header; goto bad_header;
} }
@ -141,7 +149,7 @@ static int parse_setup_header(AVCodecContext *avctx, VorbisParseContext *s,
* we may need to approach this the long way and parse the whole Setup * we may need to approach this the long way and parse the whole Setup
* header, but I hope very much that it never comes to that. */ * header, but I hope very much that it never comes to that. */
if (last_mode_count > 2) { if (last_mode_count > 2) {
avpriv_request_sample(avctx, avpriv_request_sample(s,
"%d modes (either a false positive or a " "%d modes (either a false positive or a "
"sample from an unknown encoder)", "sample from an unknown encoder)",
last_mode_count); last_mode_count);
@ -149,7 +157,7 @@ static int parse_setup_header(AVCodecContext *avctx, VorbisParseContext *s,
/* We're limiting the mode count to 63 so that we know that the previous /* We're limiting the mode count to 63 so that we know that the previous
* block flag will be in the first packet byte. */ * block flag will be in the first packet byte. */
if (last_mode_count > 63) { if (last_mode_count > 63) {
av_log(avctx, AV_LOG_ERROR, "Unsupported mode count: %d\n", av_log(s, AV_LOG_ERROR, "Unsupported mode count: %d\n",
last_mode_count); last_mode_count);
ret = AVERROR_INVALIDDATA; ret = AVERROR_INVALIDDATA;
goto bad_header; goto bad_header;
@ -179,20 +187,20 @@ int avpriv_vorbis_parse_extradata(AVCodecContext *avctx, VorbisParseContext *s)
int header_len[3]; int header_len[3];
int ret; int ret;
s->avctx = avctx; s->class = &vorbis_parser_class;
s->extradata_parsed = 1; s->extradata_parsed = 1;
if ((ret = avpriv_split_xiph_headers(avctx->extradata, if ((ret = avpriv_split_xiph_headers(avctx->extradata,
avctx->extradata_size, 30, avctx->extradata_size, 30,
header_start, header_len)) < 0) { header_start, header_len)) < 0) {
av_log(avctx, AV_LOG_ERROR, "Extradata corrupt.\n"); av_log(s, AV_LOG_ERROR, "Extradata corrupt.\n");
return ret; return ret;
} }
if ((ret = parse_id_header(avctx, s, header_start[0], header_len[0])) < 0) if ((ret = parse_id_header(s, header_start[0], header_len[0])) < 0)
return ret; return ret;
if ((ret = parse_setup_header(avctx, s, header_start[2], header_len[2])) < 0) if ((ret = parse_setup_header(s, header_start[2], header_len[2])) < 0)
return ret; return ret;
s->valid_extradata = 1; s->valid_extradata = 1;
@ -211,7 +219,7 @@ int avpriv_vorbis_parse_frame(VorbisParseContext *s, const uint8_t *buf,
int previous_blocksize = s->previous_blocksize; int previous_blocksize = s->previous_blocksize;
if (buf[0] & 1) { if (buf[0] & 1) {
av_log(s->avctx, AV_LOG_ERROR, "Invalid packet\n"); av_log(s, AV_LOG_ERROR, "Invalid packet\n");
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
if (s->mode_count == 1) if (s->mode_count == 1)
@ -219,7 +227,7 @@ int avpriv_vorbis_parse_frame(VorbisParseContext *s, const uint8_t *buf,
else else
mode = (buf[0] & s->mode_mask) >> 1; mode = (buf[0] & s->mode_mask) >> 1;
if (mode >= s->mode_count) { if (mode >= s->mode_count) {
av_log(s->avctx, AV_LOG_ERROR, "Invalid mode in packet\n"); av_log(s, AV_LOG_ERROR, "Invalid mode in packet\n");
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
if (mode) { if (mode) {

View File

@ -31,7 +31,7 @@
#include "avcodec.h" #include "avcodec.h"
typedef struct VorbisParseContext { typedef struct VorbisParseContext {
AVCodecContext *avctx; ///< codec context const AVClass *class;
int extradata_parsed; ///< we have attempted to parse extradata int extradata_parsed; ///< we have attempted to parse extradata
int valid_extradata; ///< extradata is valid, so we can calculate duration int valid_extradata; ///< extradata is valid, so we can calculate duration
int blocksize[2]; ///< short and long window sizes int blocksize[2]; ///< short and long window sizes