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
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
34
};
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
37
};
38
39
typedef
struct
AMRParseContext
{
40
ParseContext
pc
;
41
uint64_t
cumulated_size
;
42
uint64_t
block_count
;
43
int
current_channel
;
44
int
remaining
;
45
}
AMRParseContext
;
46
47
static
av_cold
int
amr_parse_init
(
AVCodecParserContext
*s1)
48
{
49
AMRParseContext
*
s
= s1->
priv_data
;
50
s
->remaining = -1;
51
return
0;
52
}
53
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)
58
{
59
AMRParseContext
*
s
= s1->
priv_data
;
60
ParseContext
*pc = &
s
->pc;
61
int
next =
END_NOT_FOUND
;
62
63
*poutbuf_size = 0;
64
*poutbuf =
NULL
;
65
66
if
(!avctx->
ch_layout
.
nb_channels
) {
67
av_channel_layout_uninit
(&avctx->
ch_layout
);
68
avctx->
ch_layout
= (
AVChannelLayout
)
AV_CHANNEL_LAYOUT_MONO
;
69
}
70
71
if
(s1->
flags
&
PARSER_FLAG_COMPLETE_FRAMES
) {
72
next = buf_size;
73
}
else
{
74
int
ch,
offset
= 0;
75
76
for
(ch =
s
->current_channel; ch < avctx->ch_layout.nb_channels; ch++) {
77
if
(
s
->remaining >= 0) {
78
next =
s
->remaining;
79
}
else
{
80
int
mode
= (buf[
offset
] >> 3) & 0x0F;
81
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
];
86
}
87
}
88
89
offset
+= next;
90
if
(
offset
>= buf_size) {
91
s
->remaining =
offset
- buf_size;
92
next =
END_NOT_FOUND
;
93
break
;
94
}
else
{
95
s
->remaining = -1;
96
}
97
}
98
99
s
->current_channel = ch % avctx->
ch_layout
.
nb_channels
;
100
if
(
s
->remaining < 0)
101
next =
offset
;
102
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;
108
}
109
}
110
111
if
(
ff_combine_frame
(pc, next, &buf, &buf_size) < 0) {
112
*poutbuf =
NULL
;
113
*poutbuf_size = 0;
114
return
buf_size;
115
}
116
}
117
118
s1->
duration
= avctx->
codec_id
==
AV_CODEC_ID_AMR_NB
? 160 : 320;
119
120
*poutbuf = buf;
121
*poutbuf_size = buf_size;
122
return
next;
123
}
124
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
,
131
};
AMRParseContext::cumulated_size
uint64_t cumulated_size
Definition:
amr_parser.c:41
AVCodecParserContext::duration
int duration
Duration of the current frame.
Definition:
avcodec.h:2862
ff_parse_close
void ff_parse_close(AVCodecParserContext *s)
Definition:
parser.c:290
amr_parse_init
static av_cold int amr_parse_init(AVCodecParserContext *s1)
Definition:
amr_parser.c:47
AV_CODEC_ID_AMR_NB
@ AV_CODEC_ID_AMR_NB
Definition:
codec_id.h:427
AVChannelLayout::nb_channels
int nb_channels
Number of channels in this layout.
Definition:
channel_layout.h:327
AV_CODEC_ID_AMR_WB
@ AV_CODEC_ID_AMR_WB
Definition:
codec_id.h:428
ParseContext
Definition:
parser.h:28
AVCodecContext::ch_layout
AVChannelLayout ch_layout
Audio channel layout.
Definition:
avcodec.h:1071
av_cold
#define av_cold
Definition:
attributes.h:90
intreadwrite.h
s
#define s(width, name)
Definition:
cbs_vp9.c:198
AMRParseContext
Definition:
amr_parser.c:39
AVCodecContext::codec_id
enum AVCodecID codec_id
Definition:
avcodec.h:461
NULL
#define NULL
Definition:
coverity.c:32
AMRParseContext::pc
ParseContext pc
Definition:
amr_parser.c:40
AVCodecContext::bit_rate
int64_t bit_rate
the average bitrate
Definition:
avcodec.h:501
AVCodecParserContext::flags
int flags
Definition:
avcodec.h:2781
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:54
AVCodecParser::codec_ids
int codec_ids[7]
Definition:
avcodec.h:2908
AVChannelLayout
An AVChannelLayout holds information about the channel layout of audio data.
Definition:
channel_layout.h:317
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:203
ff_amr_parser
const AVCodecParser ff_amr_parser
Definition:
amr_parser.c:125
PARSER_FLAG_COMPLETE_FRAMES
#define PARSER_FLAG_COMPLETE_FRAMES
Definition:
avcodec.h:2782
AMRParseContext::remaining
int remaining
Definition:
amr_parser.c:44
parser.h
AVCodecParserContext
Definition:
avcodec.h:2748
AVCodecContext
main external API structure.
Definition:
avcodec.h:451
amrwb_packed_size
static const uint8_t amrwb_packed_size[16]
Definition:
amr_parser.c:35
channel_layout.h
mode
mode
Definition:
ebur128.h:83
AMRParseContext::block_count
uint64_t block_count
Definition:
amr_parser.c:42
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:440
AMRParseContext::current_channel
int current_channel
Definition:
amr_parser.c:43
AV_CHANNEL_LAYOUT_MONO
#define AV_CHANNEL_LAYOUT_MONO
Definition:
channel_layout.h:392
END_NOT_FOUND
#define END_NOT_FOUND
Definition:
parser.h:40
AVCodecParser
Definition:
avcodec.h:2907
AVCodecParserContext::priv_data
void * priv_data
Definition:
avcodec.h:2749
amrnb_packed_size
static const uint8_t amrnb_packed_size[16]
Definition:
amr_parser.c:32
Generated on Wed Nov 20 2024 19:21:24 for FFmpeg by
1.8.17