1 /*
2 * Common code for the RTP depacketization of MPEG-4 formats.
3 * Copyright (c) 2010 Fabrice Bellard
4 * Romain Degez
5 *
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23 /**
24 * @file
25 * @brief MPEG-4 / RTP Code
26 * @author Fabrice Bellard
27 * @author Romain Degez
28 */
29
35
36 #define MAX_AAC_HBR_FRAME_SIZE 8191
37
38 /** Structure listing useful vars to parse RTP packet payload */
47
48 /** mpeg 4 AU headers */
63
67 };
68
73
74 /** Range for integer values */
80
81 /* All known fmtp parameters and the corresponding RTPAttrTypeEnum */
82 #define ATTR_NAME_TYPE_INT 0
83 #define ATTR_NAME_TYPE_STR 1
87 {0, 32} }, // SizeLength number of bits used to encode AU-size integer value
90 {0, 32} }, // IndexLength number of bits used to encode AU-Index integer value
93 {0, 32} }, // IndexDeltaLength number of bits to encode AU-Index-delta integer value
96 {INT32_MIN, INT32_MAX} }, // It differs depending on StreamType
99 {0x00, 0x3F} }, // Values from ISO/IEC 14496-1, 'StreamType Values' table
102 {0} },
103 {
NULL, -1, -1, {0} },
104 };
105
107 {
110 }
111
113 {
114 /* decode the hexa encoded parameter */
116
120 return 0;
121 }
122
124 {
125 int au_headers_length, au_header_size,
i;
128
131
132 /* decode the first 2 bytes where the AUHeader sections are stored
133 length in bits */
134 au_headers_length =
AV_RB16(buf);
135
137 return -1;
138
139 data->au_headers_length_bytes = (au_headers_length + 7) / 8;
140
141 /* skip AU headers length section (2 bytes) */
142 buf += 2;
144
145 if (len < data->au_headers_length_bytes)
147
151
152 /* XXX: Wrong if optional additional sections are present (cts, dts etc...) */
153 au_header_size =
data->sizelength +
data->indexlength;
154 if (au_header_size <= 0 || (au_headers_length % au_header_size != 0))
155 return -1;
156
157 data->nb_au_headers = au_headers_length / au_header_size;
158 if (!
data->au_headers ||
data->au_headers_allocated <
data->nb_au_headers) {
161 if (!
data->au_headers)
163 data->au_headers_allocated =
data->nb_au_headers;
164 }
165
166 for (
i = 0;
i <
data->nb_au_headers; ++
i) {
169 }
170
171 return 0;
172 }
173
174
175 /* Follows RFC 3640 */
178 const uint8_t *buf,
int len, uint16_t seq,
180 {
182
183
184 if (!buf) {
185 if (
data->cur_au_index >
data->nb_au_headers) {
188 }
189 if (
data->buf_size -
data->buf_pos <
data->au_headers[
data->cur_au_index].size) {
192 }
196 }
198 data->buf_pos +=
data->au_headers[
data->cur_au_index].size;
200 data->cur_au_index++;
201
202 if (
data->cur_au_index ==
data->nb_au_headers) {
204 return 0;
205 }
206
207 return 1;
208 }
209
212 return -1;
213 }
214
215 buf +=
data->au_headers_length_bytes + 2;
216 len -=
data->au_headers_length_bytes + 2;
217 if (
data->nb_au_headers == 1 && len < data->au_headers[0].size) {
218 /* Packet is fragmented */
219
220 if (!
data->buf_pos) {
224 }
225
226 data->buf_size =
data->au_headers[0].size;
227 data->timestamp = *timestamp;
228 }
229
230 if (
data->timestamp != *timestamp ||
231 data->au_headers[0].size !=
data->buf_size ||
237 }
238
241
244
245 if (
data->buf_pos !=
data->buf_size) {
249 }
250
256 }
258
260
261 return 0;
262 }
263
264 if (len < data->au_headers[0].
size) {
267 }
271 }
273 len -=
data->au_headers[0].size;
274 buf +=
data->au_headers[0].size;
276
277 if (
len > 0 &&
data->nb_au_headers > 1) {
279 memcpy(
data->buf, buf,
data->buf_size);
280 data->cur_au_index = 1;
282 return 1;
283 }
284
285 return 0;
286 }
287
290 const char *attr,
const char *
value)
291 {
294
295 if (!strcmp(attr, "config")) {
297
298 if (res < 0)
299 return res;
300 }
301
303 /* Looking for a known attribute */
307 char *end_ptr =
NULL;
308 long long int val = strtoll(
value, &end_ptr, 10);
309 if (end_ptr ==
value || end_ptr[0] !=
'0円') {
311 "The %s field value is not a valid number: %s\n",
314 }
318 "fmtp field %s should be in range [%d,%d] (provided value: %lld)",
321 }
322
323 *(
int *)((
char *)
data+
329 *(
char **)((
char *)
data+
331 }
332 }
333 }
334 }
335 return 0;
336 }
337
340 {
341 const char *p;
342
343 if (st_index < 0)
344 return 0;
345
348
349 return 0;
350 }
351
359 };
360
369 };