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"
31 #include "parser_internal.h"
33 static const uint8_t amrnb_packed_size
[16] = {
34 13, 14, 16, 18, 20, 21, 27, 32, 6, 1, 1, 1, 1, 1, 1, 1
36 static const uint8_t amrwb_packed_size
[16] = {
37 18, 24, 33, 37, 41, 47, 51, 59, 61, 6, 1, 1, 1, 1, 1, 1
40 typedef struct AMRParseContext
{
42 uint64_t cumulated_size
;
48 static av_cold
int amr_parse_init(AVCodecParserContext
*s1
)
50 AMRParseContext
*s
= s1
->priv_data
;
55 static int amr_parse(AVCodecParserContext
*s1
,
56 AVCodecContext
*avctx
,
57 const uint8_t **poutbuf
, int *poutbuf_size
,
58 const uint8_t *buf
, int buf_size
)
60 AMRParseContext
*s
= s1
->priv_data
;
61 ParseContext
*pc
= &s
->pc
;
62 int next
= END_NOT_FOUND
;
67 if (!avctx
->ch_layout
.nb_channels
) {
68 av_channel_layout_uninit(&avctx
->ch_layout
);
69 avctx
->ch_layout
= (AVChannelLayout
)AV_CHANNEL_LAYOUT_MONO
;
72 if (s1
->flags
& PARSER_FLAG_COMPLETE_FRAMES
) {
77 for (ch
= s
->current_channel
; ch
< avctx
->ch_layout
.nb_channels
; ch
++) {
78 if (s
->remaining
>= 0) {
81 int mode
= (buf
[offset
] >> 3) & 0x0F;
83 if (avctx
->codec_id
== AV_CODEC_ID_AMR_NB
) {
84 next
= amrnb_packed_size
[mode
];
85 } else if (avctx
->codec_id
== AV_CODEC_ID_AMR_WB
) {
86 next
= amrwb_packed_size
[mode
];
91 if (offset
>= buf_size
) {
92 s
->remaining
= offset
- buf_size
;
100 s
->current_channel
= ch
% avctx
->ch_layout
.nb_channels
;
101 if (s
->remaining
< 0)
104 if (next
!= END_NOT_FOUND
) {
105 if (s
->cumulated_size
< UINT64_MAX
- next
) {
106 s
->cumulated_size
+= next
;
107 /* Both AMR formats have 50 frames per second */
108 avctx
->bit_rate
= s
->cumulated_size
/ ++s
->block_count
* 8 * 50;
112 if (ff_combine_frame(pc
, next
, &buf
, &buf_size
) < 0) {
119 s1
->duration
= avctx
->codec_id
== AV_CODEC_ID_AMR_NB
? 160 : 320;
122 *poutbuf_size
= buf_size
;
126 const FFCodecParser ff_amr_parser
= {
127 PARSER_CODEC_LIST(AV_CODEC_ID_AMR_NB
, AV_CODEC_ID_AMR_WB
),
128 .priv_data_size
= sizeof(AMRParseContext
),
129 .init
= amr_parse_init
,
131 .close
= ff_parse_close
,