aboutsummaryrefslogtreecommitdiffstats
path: root/libavcodec/amr_parser.c
diff options
context:
space:
mode:
authorPaul B Mahol <onemda@gmail.com>2021-09-30 14:18:22 +0200
committerPaul B Mahol <onemda@gmail.com>2021-10-03 11:42:15 +0200
commitf282c34c009e3653ec160c3880e64fc1a9300d0e (patch)
tree0c49a392a4477e8a7dcbd3fb0f5be7bf76162337 /libavcodec/amr_parser.c
parente26c4d252faff4f7b1bf3087f609b699f20b47d3 (diff)
downloadffmpeg-f282c34c009e3653ec160c3880e64fc1a9300d0e.tar.gz
avcodec/amr*dec: add multichannel support
Diffstat (limited to 'libavcodec/amr_parser.c')
-rw-r--r--libavcodec/amr_parser.c46
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,
};