diff options
author | Paul B Mahol <onemda@gmail.com> | 2021-09-30 14:18:22 +0200 |
---|---|---|
committer | Paul B Mahol <onemda@gmail.com> | 2021-10-03 11:42:15 +0200 |
commit | f282c34c009e3653ec160c3880e64fc1a9300d0e (patch) | |
tree | 0c49a392a4477e8a7dcbd3fb0f5be7bf76162337 /libavcodec/amr_parser.c | |
parent | e26c4d252faff4f7b1bf3087f609b699f20b47d3 (diff) | |
download | ffmpeg-f282c34c009e3653ec160c3880e64fc1a9300d0e.tar.gz |
avcodec/amr*dec: add multichannel support
Diffstat (limited to 'libavcodec/amr_parser.c')
-rw-r--r-- | libavcodec/amr_parser.c | 46 |
1 files changed, 34 insertions, 12 deletions
diff --git a/libavcodec/amr_parser.c b/libavcodec/amr_parser.c index 2659cb40d7..79258d4d0c 100644 --- a/libavcodec/amr_parser.c +++ b/libavcodec/amr_parser.c @@ -39,9 +39,17 @@ typedef struct AMRParseContext { ParseContext pc; uint64_t cumulated_size; uint64_t block_count; + int current_channel; int remaining; } AMRParseContext; +static av_cold int amr_parse_init(AVCodecParserContext *s1) +{ + AMRParseContext *s = s1->priv_data; + s->remaining = -1; + return 0; +} + static int amr_parse(AVCodecParserContext *s1, AVCodecContext *avctx, const uint8_t **poutbuf, int *poutbuf_size, @@ -57,21 +65,34 @@ static int amr_parse(AVCodecParserContext *s1, if (s1->flags & PARSER_FLAG_COMPLETE_FRAMES) { next = buf_size; } else { - if (s->remaining) { - next = s->remaining; - } else { - int mode = (buf[0] >> 3) & 0x0F; - - if (avctx->codec_id == AV_CODEC_ID_AMR_NB) { - next = amrnb_packed_size[mode]; - } else if (avctx->codec_id == AV_CODEC_ID_AMR_WB) { - next = amrwb_packed_size[mode]; + int ch, offset = 0; + + for (ch = s->current_channel; ch < avctx->channels; ch++) { + if (s->remaining >= 0) { + next = s->remaining; + } else { + int mode = (buf[offset] >> 3) & 0x0F; + + if (avctx->codec_id == AV_CODEC_ID_AMR_NB) { + next = amrnb_packed_size[mode]; + } else if (avctx->codec_id == AV_CODEC_ID_AMR_WB) { + next = amrwb_packed_size[mode]; + } + } + + offset += next; + if (offset >= buf_size) { + s->remaining = offset - buf_size; + next = END_NOT_FOUND; + break; + } else { + s->remaining = -1; } } - s->remaining = next - FFMIN(buf_size, next); - if (s->remaining) - next = END_NOT_FOUND; + s->current_channel = ch % avctx->channels; + if (s->remaining < 0) + next = offset; if (next != END_NOT_FOUND) { if (s->cumulated_size < UINT64_MAX - next) { @@ -98,6 +119,7 @@ static int amr_parse(AVCodecParserContext *s1, const AVCodecParser ff_amr_parser = { .codec_ids = { AV_CODEC_ID_AMR_NB, AV_CODEC_ID_AMR_WB }, .priv_data_size = sizeof(AMRParseContext), + .parser_init = amr_parse_init, .parser_parse = amr_parse, .parser_close = ff_parse_close, }; |