This simplifies the decoder so it doesn't have to process an in-packet header or handle arbitrary-sized packets. It also fixes decoding of files with large headers.
Unified · Split
| @@ -595,6 +595,7 @@ OBJS-$(CONFIG_AAC_PARSER) += aac_parser.o aac_ac3_parser.o \ · 594 unmodified lines | |||
| 595 | aacadtsdec.o mpeg4audio.o | 595 | aacadtsdec.o mpeg4audio.o |
| 596 | OBJS-$(CONFIG_AC3_PARSER) += ac3_parser.o ac3tab.o \ | 596 | OBJS-$(CONFIG_AC3_PARSER) += ac3_parser.o ac3tab.o \ |
| 597 | aac_ac3_parser.o | 597 | aac_ac3_parser.o |
| 598 | OBJS-$(CONFIG_ADX_PARSER) += adx_parser.o adx.o | ||
| 598 | OBJS-$(CONFIG_CAVSVIDEO_PARSER) += cavs_parser.o | 599 | OBJS-$(CONFIG_CAVSVIDEO_PARSER) += cavs_parser.o |
| 599 | OBJS-$(CONFIG_DCA_PARSER) += dca_parser.o | 600 | OBJS-$(CONFIG_DCA_PARSER) += dca_parser.o |
| 600 | OBJS-$(CONFIG_DIRAC_PARSER) += dirac_parser.o | 601 | OBJS-$(CONFIG_DIRAC_PARSER) += dirac_parser.o |
| @@ -43,8 +43,7 @@ typedef struct { · 42 unmodified lines | |||
| 43 | int channels; | 43 | int channels; |
| 44 | ADXChannelState prev[2]; | 44 | ADXChannelState prev[2]; |
| 45 | int header_parsed; | 45 | int header_parsed; |
| 46 | unsigned char dec_temp[18*2]; | 46 | int eof; |
| 47 | int in_temp; | ||
| 48 | int cutoff; | 47 | int cutoff; |
| 49 | int coeff[2]; | 48 | int coeff[2]; |
| 50 | } ADXContext; | 49 | } ADXContext; |
| @@ -0,0 +1,104 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2011 Justin Ruggles | ||
| 3 | * | ||
| 4 | * This file is part of Libav. | ||
| 5 | * | ||
| 6 | * Libav is free software; you can redistribute it and/or | ||
| 7 | * modify it under the terms of the GNU Lesser General Public | ||
| 8 | * License as published by the Free Software Foundation; either | ||
| 9 | * version 2.1 of the License, or (at your option) any later version. | ||
| 10 | * | ||
| 11 | * Libav is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 14 | * Lesser General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU Lesser General Public | ||
| 17 | * License along with Libav; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 19 | */ | ||
| 20 | |||
| 21 | /** | ||
| 22 | * @file | ||
| 23 | * ADX audio parser | ||
| 24 | * | ||
| 25 | * Reads header to extradata and splits packets into individual blocks. | ||
| 26 | */ | ||
| 27 | |||
| 28 | #include "libavutil/intreadwrite.h" | ||
| 29 | #include "parser.h" | ||
| 30 | #include "adx.h" | ||
| 31 | |||
| 32 | typedef struct ADXParseContext { | ||
| 33 | ParseContext pc; | ||
| 34 | int header_size; | ||
| 35 | int block_size; | ||
| 36 | int buf_pos; | ||
| 37 | } ADXParseContext; | ||
| 38 | |||
| 39 | #define MIN_HEADER_SIZE 24 | ||
| 40 | |||
| 41 | static int adx_parse(AVCodecParserContext *s1, | ||
| 42 | AVCodecContext *avctx, | ||
| 43 | const uint8_t **poutbuf, int *poutbuf_size, | ||
| 44 | const uint8_t *buf, int buf_size) | ||
| 45 | { | ||
| 46 | ADXParseContext *s = s1->priv_data; | ||
| 47 | ParseContext *pc = &s->pc; | ||
| 48 | int next = END_NOT_FOUND; | ||
| 49 | |||
| 50 | if (!avctx->extradata_size) { | ||
| 51 | int ret; | ||
| 52 | |||
| 53 | ff_combine_frame(pc, END_NOT_FOUND, &buf, &buf_size); | ||
| 54 | |||
| 55 | if (!s->header_size && pc->index >= MIN_HEADER_SIZE) { | ||
| 56 | if (ret = ff_adx_decode_header(avctx, pc->buffer, pc->index, | ||
| 57 | &s->header_size, NULL)) | ||
| 58 | return AVERROR_INVALIDDATA; | ||
| 59 | s->block_size = BLOCK_SIZE * avctx->channels; | ||
| 60 | } | ||
| 61 | if (s->header_size && s->header_size <= pc->index) { | ||
| 62 | avctx->extradata = av_mallocz(s->header_size + FF_INPUT_BUFFER_PADDING_SIZE); | ||
| 63 | if (!avctx->extradata) | ||
| 64 | return AVERROR(ENOMEM); | ||
| 65 | avctx->extradata_size = s->header_size; | ||
| 66 | memcpy(avctx->extradata, pc->buffer, s->header_size); | ||
| 67 | memmove(pc->buffer, pc->buffer + s->header_size, s->header_size); | ||
| 68 | pc->index -= s->header_size; | ||
| 69 | } | ||
| 70 | *poutbuf = NULL; | ||
| 71 | *poutbuf_size = 0; | ||
| 72 | return buf_size; | ||
| 73 | } | ||
| 74 | |||
| 75 | if (pc->index - s->buf_pos >= s->block_size) { | ||
| 76 | *poutbuf = &pc->buffer[s->buf_pos]; | ||
| 77 | *poutbuf_size = s->block_size; | ||
| 78 | s->buf_pos += s->block_size; | ||
| 79 | return 0; | ||
| 80 | } | ||
| 81 | if (pc->index && s->buf_pos) { | ||
| 82 | memmove(pc->buffer, &pc->buffer[s->buf_pos], pc->index - s->buf_pos); | ||
| 83 | pc->index -= s->buf_pos; | ||
| 84 | s->buf_pos = 0; | ||
| 85 | } | ||
| 86 | if (buf_size + pc->index >= s->block_size) | ||
| 87 | next = s->block_size - pc->index; | ||
| 88 | |||
| 89 | if (ff_combine_frame(pc, next, &buf, &buf_size) < 0 || !buf_size) { | ||
| 90 | *poutbuf = NULL; | ||
| 91 | *poutbuf_size = 0; | ||
| 92 | return buf_size; | ||
| 93 | } | ||
| 94 | *poutbuf = buf; | ||
| 95 | *poutbuf_size = buf_size; | ||
| 96 | return next; | ||
| 97 | } | ||
| 98 | |||
| 99 | AVCodecParser ff_adx_parser = { | ||
| 100 | .codec_ids = { CODEC_ID_ADPCM_ADX }, | ||
| 101 | .priv_data_size = sizeof(ADXParseContext), | ||
| 102 | .parser_parse = adx_parse, | ||
| 103 | .parser_close = ff_parse_close, | ||
| 104 | }; | ||
| @@ -35,6 +35,19 @@ · 34 unmodified lines | |||
| 35 | 35 | ||
| 36 | static av_cold int adx_decode_init(AVCodecContext *avctx) | 36 | static av_cold int adx_decode_init(AVCodecContext *avctx) |
| 37 | { | 37 | { |
| 38 | ADXContext *c = avctx->priv_data; | ||
| 39 | int ret, header_size; | ||
| 40 | |||
| 41 | if (avctx->extradata_size < 24) | ||
| 42 | return AVERROR_INVALIDDATA; | ||
| 43 | |||
| 44 | if ((ret = ff_adx_decode_header(avctx, avctx->extradata, avctx->extradata_size, | ||
| 45 | &header_size, c->coeff)) < 0) { | ||
| 46 | av_log(avctx, AV_LOG_ERROR, "error parsing ADX header\n"); | ||
| 47 | return AVERROR_INVALIDDATA; | ||
| 48 | } | ||
| 49 | c->channels = avctx->channels; | ||
| 50 | |||
| 38 | avctx->sample_fmt = AV_SAMPLE_FMT_S16; | 51 | avctx->sample_fmt = AV_SAMPLE_FMT_S16; |
| 39 | return 0; | 52 | return 0; |
| 40 | } | 53 | } |
| @@ -46,7 +59,7 @@ static av_cold int adx_decode_init(AVCodecContext *avctx) · 5 unmodified lines | |||
| 46 | * 2nd-order LPC filter applied to it to form the output signal for a single | 59 | * 2nd-order LPC filter applied to it to form the output signal for a single |
| 47 | * channel. | 60 | * channel. |
| 48 | */ | 61 | */ |
| 49 | static void adx_decode(ADXContext *c, int16_t *out, const uint8_t *in, int ch) | 62 | static int adx_decode(ADXContext *c, int16_t *out, const uint8_t *in, int ch) |
| 50 | { | 63 | { |
| 51 | ADXChannelState *prev = &c->prev[ch]; | 64 | ADXChannelState *prev = &c->prev[ch]; |
| 52 | GetBitContext gb; | 65 | GetBitContext gb; |
| @@ -54,6 +67,10 @@ static void adx_decode(ADXContext *c, int16_t *out, const uint8_t *in, int ch) · 1 unmodified line | |||
| 54 | int i; | 67 | int i; |
| 55 | int s0, s1, s2, d; | 68 | int s0, s1, s2, d; |
| 56 | 69 | ||
| 70 | /* check if this is an EOF packet */ | ||
| 71 | if (scale & 0x8000) | ||
| 72 | return -1; | ||
| 73 | |||
| 57 | init_get_bits(&gb, in + 2, (BLOCK_SIZE - 2) * 8); | 74 | init_get_bits(&gb, in + 2, (BLOCK_SIZE - 2) * 8); |
| 58 | s1 = prev->s1; | 75 | s1 = prev->s1; |
| 59 | s2 = prev->s2; | 76 | s2 = prev->s2; |
| @@ -67,84 +84,55 @@ static void adx_decode(ADXContext *c, int16_t *out, const uint8_t *in, int ch) · 7 unmodified lines | |||
| 67 | } | 84 | } |
| 68 | prev->s1 = s1; | 85 | prev->s1 = s1; |
| 69 | prev->s2 = s2; | 86 | prev->s2 = s2; |
| 70 | } | ||
| 71 | |||
| 72 | static int adx_decode_header(AVCodecContext *avctx, const uint8_t *buf, | ||
| 73 | int bufsize) | ||
| 74 | { | ||
| 75 | ADXContext *c = avctx->priv_data; | ||
| 76 | int ret, header_size; | ||
| 77 | 87 | ||
| 78 | if ((ret = ff_adx_decode_header(avctx, buf, bufsize, &header_size, | 88 | return 0; |
| 79 | c->coeff)) < 0) | ||
| 80 | return ret; | ||
| 81 | |||
| 82 | c->channels = avctx->channels; | ||
| 83 | return header_size; | ||
| 84 | } | 89 | } |
| 85 | 90 | ||
| 86 | static int adx_decode_frame(AVCodecContext *avctx, void *data, int *data_size, | 91 | static int adx_decode_frame(AVCodecContext *avctx, void *data, int *data_size, |
| 87 | AVPacket *avpkt) | 92 | AVPacket *avpkt) |
| 88 | { | 93 | { |
| 89 | const uint8_t *buf0 = avpkt->data; | ||
| 90 | int buf_size = avpkt->size; | 94 | int buf_size = avpkt->size; |
| 91 | ADXContext *c = avctx->priv_data; | 95 | ADXContext *c = avctx->priv_data; |
| 92 | int16_t *samples = data; | 96 | int16_t *samples = data; |
| 93 | const uint8_t *buf = buf0; | 97 | const uint8_t *buf = avpkt->data; |
| 94 | int rest = buf_size; | 98 | int num_blocks, ch; |
| 95 | int num_blocks; | 99 | |
| 96 | 100 | if (c->eof) { | |
| 97 | if (!c->header_parsed) { | 101 | *data_size = 0; |
| 98 | int hdrsize = adx_decode_header(avctx, buf, rest); | 102 | return buf_size; |
| 99 | if (hdrsize < 0) { | ||
| 100 | av_log(avctx, AV_LOG_ERROR, "invalid stream header\n"); | ||
| 101 | return hdrsize; | ||
| 102 | } | ||
| 103 | c->header_parsed = 1; | ||
| 104 | buf += hdrsize; | ||
| 105 | rest -= hdrsize; | ||
| 106 | } | 103 | } |
| 107 | 104 | ||
| 108 | /* 18 bytes of data are expanded into 32*2 bytes of audio, | 105 | /* 18 bytes of data are expanded into 32*2 bytes of audio, |
| 109 | so guard against buffer overflows */ | 106 | so guard against buffer overflows */ |
| 110 | num_blocks = (rest + c->in_temp) / (BLOCK_SIZE * c->channels); | 107 | num_blocks = buf_size / (BLOCK_SIZE * c->channels); |
| 111 | if (num_blocks > *data_size / (BLOCK_SAMPLES * c->channels)) { | 108 | if (num_blocks > *data_size / (BLOCK_SAMPLES * c->channels)) { |
| 112 | rest = (*data_size / (BLOCK_SAMPLES * c->channels)) * BLOCK_SIZE; | 109 | buf_size = (*data_size / (BLOCK_SAMPLES * c->channels)) * BLOCK_SIZE; |
| 113 | num_blocks = (rest + c->in_temp) / (BLOCK_SIZE * c->channels); | 110 | num_blocks = buf_size / (BLOCK_SIZE * c->channels); |
| 114 | } | 111 | } |
| 115 | if (!num_blocks) { | 112 | if (!buf_size || buf_size % (BLOCK_SIZE * avctx->channels)) { |
| 116 | av_log(avctx, AV_LOG_ERROR, "packet is too small\n"); | 113 | if (buf_size >= 4 && (AV_RB16(buf) & 0x8000)) { |
| 114 | c->eof = 1; | ||
| 115 | *data_size = 0; | ||
| 116 | return avpkt->size; | ||
| 117 | } | ||
| 117 | return AVERROR_INVALIDDATA; | 118 | return AVERROR_INVALIDDATA; |
| 118 | } | 119 | } |
| 119 | 120 | ||
| 120 | if (c->in_temp) { | ||
| 121 | int copysize = BLOCK_SIZE * avctx->channels - c->in_temp; | ||
| 122 | memcpy(c->dec_temp + c->in_temp, buf, copysize); | ||
| 123 | rest -= copysize; | ||
| 124 | buf += copysize; | ||
| 125 | adx_decode(c, samples, c->dec_temp, 0); | ||
| 126 | if (avctx->channels == 2) | ||
| 127 | adx_decode(c, samples + 1, c->dec_temp + BLOCK_SIZE, 1); | ||
| 128 | samples += BLOCK_SAMPLES * c->channels; | ||
| 129 | num_blocks--; | ||
| 130 | } | ||
| 131 | |||
| 132 | while (num_blocks--) { | 121 | while (num_blocks--) { |
| 133 | adx_decode(c, samples, buf, 0); | 122 | for (ch = 0; ch < c->channels; ch++) { |
| 134 | if (c->channels == 2) | 123 | if (adx_decode(c, samples + ch, buf, ch)) { |
| 135 | adx_decode(c, samples + 1, buf + BLOCK_SIZE, 1); | 124 | c->eof = 1; |
| 136 | rest -= BLOCK_SIZE * c->channels; | 125 | buf = avpkt->data + avpkt->size; |
| 137 | buf += BLOCK_SIZE * c->channels; | 126 | break; |
| 127 | } | ||
| 128 | buf_size -= BLOCK_SIZE; | ||
| 129 | buf += BLOCK_SIZE; | ||
| 130 | } | ||
| 138 | samples += BLOCK_SAMPLES * c->channels; | 131 | samples += BLOCK_SAMPLES * c->channels; |
| 139 | } | 132 | } |
| 140 | 133 | ||
| 141 | c->in_temp = rest; | ||
| 142 | if (rest) { | ||
| 143 | memcpy(c->dec_temp, buf, rest); | ||
| 144 | buf += rest; | ||
| 145 | } | ||
| 146 | *data_size = (uint8_t*)samples - (uint8_t*)data; | 134 | *data_size = (uint8_t*)samples - (uint8_t*)data; |
| 147 | return buf - buf0; | 135 | return buf - avpkt->data; |
| 148 | } | 136 | } |
| 149 | 137 | ||
| 150 | AVCodec ff_adpcm_adx_decoder = { | 138 | AVCodec ff_adpcm_adx_decoder = { |
| @@ -388,6 +388,7 @@ void avcodec_register_all(void) · 387 unmodified lines | |||
| 388 | REGISTER_PARSER (AAC, aac); | 388 | REGISTER_PARSER (AAC, aac); |
| 389 | REGISTER_PARSER (AAC_LATM, aac_latm); | 389 | REGISTER_PARSER (AAC_LATM, aac_latm); |
| 390 | REGISTER_PARSER (AC3, ac3); | 390 | REGISTER_PARSER (AC3, ac3); |
| 391 | REGISTER_PARSER (ADX, adx); | ||
| 391 | REGISTER_PARSER (CAVSVIDEO, cavsvideo); | 392 | REGISTER_PARSER (CAVSVIDEO, cavsvideo); |
| 392 | REGISTER_PARSER (DCA, dca); | 393 | REGISTER_PARSER (DCA, dca); |
| 393 | REGISTER_PARSER (DIRAC, dirac); | 394 | REGISTER_PARSER (DIRAC, dirac); |
| @@ -21,8 +21,8 @@ · 20 unmodified lines | |||
| 21 | #define AVCODEC_VERSION_H | 21 | #define AVCODEC_VERSION_H |
| 22 | 22 | ||
| 23 | #define LIBAVCODEC_VERSION_MAJOR 53 | 23 | #define LIBAVCODEC_VERSION_MAJOR 53 |
| 24 | #define LIBAVCODEC_VERSION_MINOR 22 | 24 | #define LIBAVCODEC_VERSION_MINOR 23 |
| 25 | #define LIBAVCODEC_VERSION_MICRO 1 | 25 | #define LIBAVCODEC_VERSION_MICRO 0 |
| 26 | 26 | ||
| 27 | #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ | 27 | #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ |
| 28 | LIBAVCODEC_VERSION_MINOR, \ | 28 | LIBAVCODEC_VERSION_MINOR, \ |
| @@ -172,6 +172,7 @@ static int film_read_header(AVFormatContext *s, · 171 unmodified lines | |||
| 172 | if (film->audio_type == CODEC_ID_ADPCM_ADX) { | 172 | if (film->audio_type == CODEC_ID_ADPCM_ADX) { |
| 173 | st->codec->bits_per_coded_sample = 18 * 8 / 32; | 173 | st->codec->bits_per_coded_sample = 18 * 8 / 32; |
| 174 | st->codec->block_align = st->codec->channels * 18; | 174 | st->codec->block_align = st->codec->channels * 18; |
| 175 | st->need_parsing = AVSTREAM_PARSE_FULL; | ||
| 175 | } else { | 176 | } else { |
| 176 | st->codec->bits_per_coded_sample = film->audio_bits; | 177 | st->codec->bits_per_coded_sample = film->audio_bits; |
| 177 | st->codec->block_align = st->codec->channels * | 178 | st->codec->block_align = st->codec->channels * |