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 "
avio_internal.h
"
23
#include "
rtpdec_formats.h
"
24
#include "
internal.h
"
25
#include "
libavutil/avstring.h
"
26
#include "
libavcodec/get_bits.h
"
27
28
struct
PayloadContext
{
29
AVIOContext
*
dyn_buf
;
30
uint8_t
*
buf
;
31
int
pos
,
len
;
32
uint32_t
timestamp
;
33
};
34
35
static
void
latm_close_context
(
PayloadContext
*
data
)
36
{
37
ffio_free_dyn_buf
(&data->
dyn_buf
);
38
av_freep
(&data->
buf
);
39
}
40
41
static
int
latm_parse_packet
(
AVFormatContext
*ctx,
PayloadContext
*
data
,
42
AVStream
*st,
AVPacket
*
pkt
, uint32_t *timestamp,
43
const
uint8_t
*
buf
,
int
len
, uint16_t seq,
44
int
flags
)
45
{
46
int
ret
, cur_len;
47
48
if
(buf) {
49
if
(!data->
dyn_buf
|| data->
timestamp
!= *timestamp) {
50
av_freep
(&data->
buf
);
51
ffio_free_dyn_buf
(&data->
dyn_buf
);
52
53
data->
timestamp
= *timestamp;
54
if
((ret =
avio_open_dyn_buf
(&data->
dyn_buf
)) < 0)
55
return
ret
;
56
}
57
avio_write
(data->
dyn_buf
, buf, len);
58
59
if
(!(flags &
RTP_FLAG_MARKER
))
60
return
AVERROR
(EAGAIN);
61
av_freep
(&data->
buf
);
62
data->
len
=
avio_close_dyn_buf
(data->
dyn_buf
, &data->
buf
);
63
data->
dyn_buf
=
NULL
;
64
data->
pos
= 0;
65
}
66
67
if
(!data->
buf
) {
68
av_log
(ctx,
AV_LOG_ERROR
,
"No data available yet\n"
);
69
return
AVERROR
(EIO);
70
}
71
72
cur_len = 0;
73
while
(data->
pos
< data->
len
) {
74
uint8_t
val
= data->
buf
[data->
pos
++];
75
cur_len +=
val
;
76
if
(val != 0xff)
77
break
;
78
}
79
if
(data->
pos
+ cur_len > data->
len
) {
80
av_log
(ctx,
AV_LOG_ERROR
,
"Malformed LATM packet\n"
);
81
return
AVERROR
(EIO);
82
}
83
84
if
((ret =
av_new_packet
(pkt, cur_len)) < 0)
85
return
ret
;
86
memcpy(pkt->
data
, data->
buf
+ data->
pos
, cur_len);
87
data->
pos
+= cur_len;
88
pkt->
stream_index
= st->
index
;
89
return
data->
pos
< data->
len
;
90
}
91
92
static
int
parse_fmtp_config
(
AVStream
*st,
const
char
*
value
)
93
{
94
int
len
=
ff_hex_to_data
(
NULL
, value), i,
ret
= 0;
95
GetBitContext
gb;
96
uint8_t
*
config
;
97
int
audio_mux_version, same_time_framing, num_programs, num_layers;
98
99
/* Pad this buffer, too, to avoid out of bounds reads with get_bits below */
100
config =
av_mallocz
(len +
FF_INPUT_BUFFER_PADDING_SIZE
);
101
if
(!config)
102
return
AVERROR
(ENOMEM);
103
ff_hex_to_data
(config, value);
104
init_get_bits
(&gb, config, len*8);
105
audio_mux_version =
get_bits
(&gb, 1);
106
same_time_framing =
get_bits
(&gb, 1);
107
skip_bits
(&gb, 6);
/* num_sub_frames */
108
num_programs =
get_bits
(&gb, 4);
109
num_layers =
get_bits
(&gb, 3);
110
if
(audio_mux_version != 0 || same_time_framing != 1 || num_programs != 0 ||
111
num_layers != 0) {
112
av_log
(
NULL
,
AV_LOG_WARNING
,
"Unsupported LATM config (%d,%d,%d,%d)\n"
,
113
audio_mux_version, same_time_framing,
114
num_programs, num_layers);
115
ret =
AVERROR_PATCHWELCOME
;
116
goto
end
;
117
}
118
av_freep
(&st->
codec
->
extradata
);
119
if
(
ff_alloc_extradata
(st->
codec
, (
get_bits_left
(&gb) + 7)/8)) {
120
ret =
AVERROR
(ENOMEM);
121
goto
end
;
122
}
123
for
(i = 0; i < st->
codec
->
extradata_size
; i++)
124
st->
codec
->
extradata
[i] =
get_bits
(&gb, 8);
125
126
end
:
127
av_free
(config);
128
return
ret
;
129
}
130
131
static
int
parse_fmtp
(
AVFormatContext
*
s
,
132
AVStream
*stream,
PayloadContext
*
data
,
133
const
char
*attr,
const
char
*
value
)
134
{
135
int
res;
136
137
if
(!strcmp(attr,
"config"
)) {
138
res =
parse_fmtp_config
(stream, value);
139
if
(res < 0)
140
return
res;
141
}
else
if
(!strcmp(attr,
"cpresent"
)) {
142
int
cpresent = atoi(value);
143
if
(cpresent != 0)
144
avpriv_request_sample
(s,
145
"RTP MP4A-LATM with in-band configuration"
);
146
}
147
148
return
0;
149
}
150
151
static
int
latm_parse_sdp_line
(
AVFormatContext
*
s
,
int
st_index,
152
PayloadContext
*
data
,
const
char
*
line
)
153
{
154
const
char
*p;
155
156
if
(st_index < 0)
157
return
0;
158
159
if
(
av_strstart
(line,
"fmtp:"
, &p))
160
return
ff_parse_fmtp
(s, s->
streams
[st_index], data, p,
parse_fmtp
);
161
162
return
0;
163
}
164
165
RTPDynamicProtocolHandler
ff_mp4a_latm_dynamic_handler
= {
166
.
enc_name
=
"MP4A-LATM"
,
167
.codec_type =
AVMEDIA_TYPE_AUDIO
,
168
.codec_id =
AV_CODEC_ID_AAC
,
169
.priv_data_size =
sizeof
(
PayloadContext
),
170
.parse_sdp_a_line =
latm_parse_sdp_line
,
171
.close =
latm_close_context
,
172
.
parse_packet
=
latm_parse_packet
,
173
};
Generated on Sun Mar 8 2015 02:35:12 for FFmpeg by
1.8.2