FFmpeg
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
Examples
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
libavformat
rtpdec_latm.c
Go to the documentation of this file.
1
/*
2
* RTP Depacketization of MP4A-LATM, RFC 3016
3
* Copyright (c) 2010 Martin Storsjo
4
*
5
* This file is part of FFmpeg.
6
*
7
* FFmpeg is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU Lesser General Public
9
* License as published by the Free Software Foundation; either
10
* version 2.1 of the License, or (at your option) any later version.
11
*
12
* FFmpeg is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Lesser General Public License for more details.
16
*
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with FFmpeg; if not, write to the Free Software
19
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
*/
21
22
#include "
rtpdec_formats.h
"
23
#include "
internal.h
"
24
#include "
libavutil/avstring.h
"
25
#include "
libavcodec/get_bits.h
"
26
27
struct
PayloadContext
{
28
AVIOContext
*
dyn_buf
;
29
uint8_t
*
buf
;
30
int
pos
,
len
;
31
uint32_t
timestamp
;
32
};
33
34
static
PayloadContext
*
latm_new_context
(
void
)
35
{
36
return
av_mallocz
(
sizeof
(
PayloadContext
));
37
}
38
39
static
void
latm_free_context
(
PayloadContext
*
data
)
40
{
41
if
(!data)
42
return
;
43
if
(data->
dyn_buf
) {
44
uint8_t
*p;
45
avio_close_dyn_buf
(data->
dyn_buf
, &p);
46
av_free
(p);
47
}
48
av_free
(data->
buf
);
49
av_free
(data);
50
}
51
52
static
int
latm_parse_packet
(
AVFormatContext
*ctx,
PayloadContext
*
data
,
53
AVStream
*st,
AVPacket
*
pkt
, uint32_t *timestamp,
54
const
uint8_t
*
buf
,
int
len
, uint16_t seq,
55
int
flags
)
56
{
57
int
ret
, cur_len;
58
59
if
(buf) {
60
if
(!data->
dyn_buf
|| data->
timestamp
!= *timestamp) {
61
av_freep
(&data->
buf
);
62
if
(data->
dyn_buf
)
63
avio_close_dyn_buf
(data->
dyn_buf
, &data->
buf
);
64
data->
dyn_buf
= NULL;
65
av_freep
(&data->
buf
);
66
67
data->
timestamp
= *timestamp;
68
if
((ret =
avio_open_dyn_buf
(&data->
dyn_buf
)) < 0)
69
return
ret
;
70
}
71
avio_write
(data->
dyn_buf
, buf, len);
72
73
if
(!(flags &
RTP_FLAG_MARKER
))
74
return
AVERROR
(EAGAIN);
75
av_free
(data->
buf
);
76
data->
len
=
avio_close_dyn_buf
(data->
dyn_buf
, &data->
buf
);
77
data->
dyn_buf
= NULL;
78
data->
pos
= 0;
79
}
80
81
if
(!data->
buf
) {
82
av_log
(ctx,
AV_LOG_ERROR
,
"No data available yet\n"
);
83
return
AVERROR
(EIO);
84
}
85
86
cur_len = 0;
87
while
(data->
pos
< data->
len
) {
88
uint8_t
val
= data->
buf
[data->
pos
++];
89
cur_len +=
val
;
90
if
(val != 0xff)
91
break
;
92
}
93
if
(data->
pos
+ cur_len > data->
len
) {
94
av_log
(ctx,
AV_LOG_ERROR
,
"Malformed LATM packet\n"
);
95
return
AVERROR
(EIO);
96
}
97
98
if
((ret =
av_new_packet
(pkt, cur_len)) < 0)
99
return
ret
;
100
memcpy(pkt->
data
, data->
buf
+ data->
pos
, cur_len);
101
data->
pos
+= cur_len;
102
pkt->
stream_index
= st->
index
;
103
return
data->
pos
< data->
len
;
104
}
105
106
static
int
parse_fmtp_config
(
AVStream
*st,
char
*
value
)
107
{
108
int
len
=
ff_hex_to_data
(NULL, value), i,
ret
= 0;
109
GetBitContext
gb;
110
uint8_t
*
config
;
111
int
audio_mux_version, same_time_framing, num_programs, num_layers;
112
113
/* Pad this buffer, too, to avoid out of bounds reads with get_bits below */
114
config =
av_mallocz
(len +
FF_INPUT_BUFFER_PADDING_SIZE
);
115
if
(!config)
116
return
AVERROR
(ENOMEM);
117
ff_hex_to_data
(config, value);
118
init_get_bits
(&gb, config, len*8);
119
audio_mux_version =
get_bits
(&gb, 1);
120
same_time_framing =
get_bits
(&gb, 1);
121
skip_bits
(&gb, 6);
/* num_sub_frames */
122
num_programs =
get_bits
(&gb, 4);
123
num_layers =
get_bits
(&gb, 3);
124
if
(audio_mux_version != 0 || same_time_framing != 1 || num_programs != 0 ||
125
num_layers != 0) {
126
av_log
(NULL,
AV_LOG_WARNING
,
"Unsupported LATM config (%d,%d,%d,%d)\n"
,
127
audio_mux_version, same_time_framing,
128
num_programs, num_layers);
129
ret =
AVERROR_PATCHWELCOME
;
130
goto
end
;
131
}
132
av_freep
(&st->
codec
->
extradata
);
133
st->
codec
->
extradata_size
= (
get_bits_left
(&gb) + 7)/8;
134
st->
codec
->
extradata
=
av_mallocz
(st->
codec
->
extradata_size
+
135
FF_INPUT_BUFFER_PADDING_SIZE
);
136
if
(!st->
codec
->
extradata
) {
137
ret =
AVERROR
(ENOMEM);
138
goto
end
;
139
}
140
for
(i = 0; i < st->
codec
->
extradata_size
; i++)
141
st->
codec
->
extradata
[i] =
get_bits
(&gb, 8);
142
143
end
:
144
av_free
(config);
145
return
ret
;
146
}
147
148
static
int
parse_fmtp
(
AVStream
*stream,
PayloadContext
*
data
,
149
char
*attr,
char
*
value
)
150
{
151
int
res
;
152
153
if
(!strcmp(attr,
"config"
)) {
154
res =
parse_fmtp_config
(stream, value);
155
if
(res < 0)
156
return
res
;
157
}
else
if
(!strcmp(attr,
"cpresent"
)) {
158
int
cpresent = atoi(value);
159
if
(cpresent != 0)
160
avpriv_request_sample
(NULL,
161
"RTP MP4A-LATM with in-band configuration"
);
162
}
163
164
return
0;
165
}
166
167
static
int
latm_parse_sdp_line
(
AVFormatContext
*
s
,
int
st_index,
168
PayloadContext
*
data
,
const
char
*
line
)
169
{
170
const
char
*p;
171
172
if
(st_index < 0)
173
return
0;
174
175
if
(
av_strstart
(line,
"fmtp:"
, &p))
176
return
ff_parse_fmtp
(s->
streams
[st_index], data, p,
parse_fmtp
);
177
178
return
0;
179
}
180
181
RTPDynamicProtocolHandler
ff_mp4a_latm_dynamic_handler
= {
182
.
enc_name
=
"MP4A-LATM"
,
183
.codec_type =
AVMEDIA_TYPE_AUDIO
,
184
.codec_id =
AV_CODEC_ID_AAC
,
185
.parse_sdp_a_line =
latm_parse_sdp_line
,
186
.alloc =
latm_new_context
,
187
.free =
latm_free_context
,
188
.parse_packet =
latm_parse_packet
189
};
Generated on Wed Jul 10 2013 23:48:14 for FFmpeg by
1.8.2