2 * Copyright (c) 2021 Paul B Mahol
4 * This file is part of FFmpeg.
6 * FFmpeg 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 * FFmpeg 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 FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 * Splits packets into individual blocks.
28 #include "libavutil/channel_layout.h"
29 #include "libavutil/intreadwrite.h"
32 static const uint8_t amrnb_packed_size
[16] = {
33 13, 14, 16, 18, 20, 21, 27, 32, 6, 1, 1, 1, 1, 1, 1, 1
35 static const uint8_t amrwb_packed_size
[16] = {
36 18, 24, 33, 37, 41, 47, 51, 59, 61, 6, 1, 1, 1, 1, 1, 1
39 typedef struct AMRParseContext
{
41 uint64_t cumulated_size
;
47 static av_cold
int amr_parse_init(AVCodecParserContext
*s1
)
49 AMRParseContext
*s
= s1
->priv_data
;
54 static int amr_parse(AVCodecParserContext
*s1
,
55 AVCodecContext
*avctx
,
56 const uint8_t **poutbuf
, int *poutbuf_size
,
57 const uint8_t *buf
, int buf_size
)
59 AMRParseContext
*s
= s1
->priv_data
;
60 ParseContext
*pc
= &s
->pc
;
61 int next
= END_NOT_FOUND
;
66 if (!avctx
->ch_layout
.nb_channels
) {
67 av_channel_layout_uninit(&avctx
->ch_layout
);
68 avctx
->ch_layout
= (AVChannelLayout
)AV_CHANNEL_LAYOUT_MONO
;
71 if (s1
->flags
& PARSER_FLAG_COMPLETE_FRAMES
) {
76 for (ch
= s
->current_channel
; ch
< avctx
->ch_layout
.nb_channels
; ch
++) {
77 if (s
->remaining
>= 0) {
80 int mode
= (buf
[offset
] >> 3) & 0x0F;
82 if (avctx
->codec_id
== AV_CODEC_ID_AMR_NB
) {
83 next
= amrnb_packed_size
[mode
];
84 } else if (avctx
->codec_id
== AV_CODEC_ID_AMR_WB
) {
85 next
= amrwb_packed_size
[mode
];
90 if (offset
>= buf_size
) {
91 s
->remaining
= offset
- buf_size
;
99 s
->current_channel
= ch
% avctx
->ch_layout
.nb_channels
;
100 if (s
->remaining
< 0)
103 if (next
!= END_NOT_FOUND
) {
104 if (s
->cumulated_size
< UINT64_MAX
- next
) {
105 s
->cumulated_size
+= next
;
106 /* Both AMR formats have 50 frames per second */
107 avctx
->bit_rate
= s
->cumulated_size
/ ++s
->block_count
* 8 * 50;
111 if (ff_combine_frame(pc
, next
, &buf
, &buf_size
) < 0) {
118 s1
->duration
= avctx
->codec_id
== AV_CODEC_ID_AMR_NB
? 160 : 320;
121 *poutbuf_size
= buf_size
;
125 const AVCodecParser ff_amr_parser
= {
126 .codec_ids
= { AV_CODEC_ID_AMR_NB
, AV_CODEC_ID_AMR_WB
},
127 .priv_data_size
= sizeof(AMRParseContext
),
128 .parser_init
= amr_parse_init
,
129 .parser_parse
= amr_parse
,
130 .parser_close
= ff_parse_close
,