2 * Copyright (c) 2011 Justin Ruggles
4 * This file is part of Libav.
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.
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.
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
25 * Reads header to extradata and splits packets into individual blocks.
28 #include "libavutil/intreadwrite.h"
32 typedef struct ADXParseContext {
39 #define MIN_HEADER_SIZE 24
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)
46 ADXParseContext *s = s1->priv_data;
47 ParseContext *pc = &s->pc;
48 int next = END_NOT_FOUND;
50 if (!avctx->extradata_size) {
53 ff_combine_frame(pc, END_NOT_FOUND, &buf, &buf_size);
55 if (!s->header_size && pc->index >= MIN_HEADER_SIZE) {
56 if (ret = avpriv_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;
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;
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;
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;
86 if (buf_size + pc->index >= s->block_size)
87 next = s->block_size - pc->index;
89 if (ff_combine_frame(pc, next, &buf, &buf_size) < 0 || !buf_size) {
95 *poutbuf_size = buf_size;
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,