FFmpeg
libavcodec
amr_parser.c
Go to the documentation of this file.
1
/*
2
* Copyright (c) 2021 Paul B Mahol
3
*
4
* This file is part of FFmpeg.
5
*
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.
10
*
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.
15
*
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
19
*/
20
21
/**
22
* @file
23
* AMR audio parser
24
*
25
* Splits packets into individual blocks.
26
*/
27
28
#include "
libavutil/channel_layout.h
"
29
#include "
libavutil/intreadwrite.h
"
30
#include "
parser.h
"
31
#include "
parser_internal.h
"
32
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
35
};
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
38
};
39
40
typedef
struct
AMRParseContext
{
41
ParseContext
pc
;
42
uint64_t
cumulated_size
;
43
uint64_t
block_count
;
44
int
current_channel
;
45
int
remaining
;
46
}
AMRParseContext
;
47
48
static
av_cold
int
amr_parse_init
(
AVCodecParserContext
*s1)
49
{
50
AMRParseContext
*
s
= s1->
priv_data
;
51
s
->remaining = -1;
52
return
0;
53
}
54
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)
59
{
60
AMRParseContext
*
s
= s1->
priv_data
;
61
ParseContext
*pc = &
s
->pc;
62
int
next =
END_NOT_FOUND
;
63
64
*poutbuf_size = 0;
65
*poutbuf =
NULL
;
66
67
if
(!avctx->
ch_layout
.
nb_channels
) {
68
av_channel_layout_uninit
(&avctx->
ch_layout
);
69
avctx->
ch_layout
= (
AVChannelLayout
)
AV_CHANNEL_LAYOUT_MONO
;
70
}
71
72
if
(s1->
flags
&
PARSER_FLAG_COMPLETE_FRAMES
) {
73
next = buf_size;
74
}
else
{
75
int
ch,
offset
= 0;
76
77
for
(ch =
s
->current_channel; ch < avctx->ch_layout.nb_channels; ch++) {
78
if
(
s
->remaining >= 0) {
79
next =
s
->remaining;
80
}
else
{
81
int
mode
= (buf[
offset
] >> 3) & 0x0F;
82
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
];
87
}
88
}
89
90
offset
+= next;
91
if
(
offset
>= buf_size) {
92
s
->remaining =
offset
- buf_size;
93
next =
END_NOT_FOUND
;
94
break
;
95
}
else
{
96
s
->remaining = -1;
97
}
98
}
99
100
s
->current_channel = ch % avctx->
ch_layout
.
nb_channels
;
101
if
(
s
->remaining < 0)
102
next =
offset
;
103
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;
109
}
110
}
111
112
if
(
ff_combine_frame
(pc, next, &buf, &buf_size) < 0) {
113
*poutbuf =
NULL
;
114
*poutbuf_size = 0;
115
return
buf_size;
116
}
117
}
118
119
s1->
duration
= avctx->
codec_id
==
AV_CODEC_ID_AMR_NB
? 160 : 320;
120
121
*poutbuf = buf;
122
*poutbuf_size = buf_size;
123
return
next;
124
}
125
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
,
130
.
parse
=
amr_parse
,
131
.
close
=
ff_parse_close
,
132
};
AMRParseContext::cumulated_size
uint64_t cumulated_size
Definition:
amr_parser.c:42
ff_parse_close
av_cold void ff_parse_close(AVCodecParserContext *s)
Definition:
parser.c:298
AVCodecParserContext::duration
int duration
Duration of the current frame.
Definition:
avcodec.h:2689
parser_internal.h
mode
Definition:
swscale.c:56
amr_parse_init
static av_cold int amr_parse_init(AVCodecParserContext *s1)
Definition:
amr_parser.c:48
AV_CODEC_ID_AMR_NB
@ AV_CODEC_ID_AMR_NB
Definition:
codec_id.h:440
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition:
channel_layout.h:329
AV_CODEC_ID_AMR_WB
@ AV_CODEC_ID_AMR_WB
Definition:
codec_id.h:441
close
static av_cold void close(AVCodecParserContext *s)
Definition:
apv_parser.c:136
ParseContext
Definition:
parser.h:28
AVCodecContext::ch_layout
AVChannelLayout ch_layout
Audio channel layout.
Definition:
avcodec.h:1039
av_cold
#define av_cold
Definition:
attributes.h:106
intreadwrite.h
s
#define s(width, name)
Definition:
cbs_vp9.c:198
AMRParseContext
Definition:
amr_parser.c:40
AVCodecContext::codec_id
enum AVCodecID codec_id
Definition:
avcodec.h:441
NULL
#define NULL
Definition:
coverity.c:32
AMRParseContext::pc
ParseContext pc
Definition:
amr_parser.c:41
AVCodecContext::bit_rate
int64_t bit_rate
the average bitrate
Definition:
avcodec.h:481
ff_amr_parser
const FFCodecParser ff_amr_parser
Definition:
amr_parser.c:126
AVCodecParserContext::flags
int flags
Definition:
avcodec.h:2608
parse
static int parse(AVCodecParserContext *s, AVCodecContext *avctx, const uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size)
Definition:
apv_parser.c:46
amr_parse
static int amr_parse(AVCodecParserContext *s1, AVCodecContext *avctx, const uint8_t **poutbuf, int *poutbuf_size, const uint8_t *buf, int buf_size)
Definition:
amr_parser.c:55
init
int(* init)(AVBSFContext *ctx)
Definition:
dts2pts.c:368
AVChannelLayout
An AVChannelLayout holds information about the channel layout of audio data.
Definition:
channel_layout.h:319
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition:
writing_filters.txt:86
ff_combine_frame
int ff_combine_frame(ParseContext *pc, int next, const uint8_t **buf, int *buf_size)
Combine the (truncated) bitstream to a complete frame.
Definition:
parser.c:211
FFCodecParser
Definition:
parser_internal.h:29
PARSER_FLAG_COMPLETE_FRAMES
#define PARSER_FLAG_COMPLETE_FRAMES
Definition:
avcodec.h:2609
AMRParseContext::remaining
int remaining
Definition:
amr_parser.c:45
parser.h
PARSER_CODEC_LIST
#define PARSER_CODEC_LIST(...)
Definition:
parser_internal.h:76
AVCodecParserContext
Definition:
avcodec.h:2575
AVCodecContext
main external API structure.
Definition:
avcodec.h:431
amrwb_packed_size
static const uint8_t amrwb_packed_size[16]
Definition:
amr_parser.c:36
channel_layout.h
mode
mode
Definition:
ebur128.h:83
AMRParseContext::block_count
uint64_t block_count
Definition:
amr_parser.c:43
av_channel_layout_uninit
void av_channel_layout_uninit(AVChannelLayout *channel_layout)
Free any allocated data in the channel layout and reset the channel count to 0.
Definition:
channel_layout.c:442
AMRParseContext::current_channel
int current_channel
Definition:
amr_parser.c:44
AV_CHANNEL_LAYOUT_MONO
#define AV_CHANNEL_LAYOUT_MONO
Definition:
channel_layout.h:394
END_NOT_FOUND
#define END_NOT_FOUND
Definition:
parser.h:40
AVCodecParserContext::priv_data
void * priv_data
Definition:
avcodec.h:2576
amrnb_packed_size
static const uint8_t amrnb_packed_size[16]
Definition:
amr_parser.c:33
Generated on Mon Nov 3 2025 19:21:43 for FFmpeg by
1.8.17