1 /*
2 * GPAC - Multimedia Framework C SDK
3 *
4 * Authors: Jean Le Feuvre
5 * Copyright (c) Telecom ParisTech 2000-2012
6 * All rights reserved
7 *
8 * This file is part of GPAC / MPEG-4 ObjectDescriptor sub-project
9 *
10 * GPAC is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation; either version 2, or (at your option)
13 * any later version.
14 *
15 * GPAC is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; see the file COPYING. If not, write to
22 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 */
25
26 #include <gpac/internal/odf_dev.h>
27
28
29 //
30 // Constructor
31 //
gf_odf_new_slc(u8 predef)32 GF_Descriptor *gf_odf_new_slc(u8 predef)
33 {
34 GF_SLConfig *newDesc = (GF_SLConfig *)gf_malloc(sizeof(GF_SLConfig));
35 if (!newDesc) return NULL;
36 memset(newDesc, 0, sizeof(GF_SLConfig));
37 newDesc->tag = GF_ODF_SLC_TAG;
38 newDesc->predefined = predef;
39 if (predef) gf_odf_slc_set_pref(newDesc);
40 newDesc->useTimestampsFlag = 1;
41
42 return (GF_Descriptor *)newDesc;
43 }
44
45 //
46 // Destructor
47 //
gf_odf_del_slc(GF_SLConfig * sl)48 GF_Err gf_odf_del_slc(GF_SLConfig *sl)
49 {
50 if (!sl) return GF_BAD_PARAM;
51 gf_free(sl);
52 return GF_OK;
53 }
54
55 //
56 // Set the SL to the ISO predefined value
57 //
58 GF_EXPORT
gf_odf_slc_set_pref(GF_SLConfig * sl)59 GF_Err gf_odf_slc_set_pref(GF_SLConfig *sl)
60 {
61 if (!sl) return GF_BAD_PARAM;
62
63 switch (sl->predefined) {
64
65 case SLPredef_MP4:
66 sl->useAccessUnitStartFlag = 0;
67 sl->useAccessUnitEndFlag = 0;
68 //each packet is an AU, and we need RAP signaling
69 sl->useRandomAccessPointFlag = 1;
70 sl->hasRandomAccessUnitsOnlyFlag = 0;
71 sl->usePaddingFlag = 0;
72 //in MP4 file, we use TimeStamps
73 sl->useTimestampsFlag = 1;
74 sl->useIdleFlag = 0;
75 sl->durationFlag = 0;
76 sl->timestampLength = 0;
77 sl->OCRLength = 0;
78 sl->AULength = 0;
79 sl->instantBitrateLength = 0;
80 sl->degradationPriorityLength = 0;
81 sl->AUSeqNumLength = 0;
82 sl->packetSeqNumLength = 0;
83 break;
84
85 case SLPredef_Null:
86 sl->useAccessUnitStartFlag = 0;
87 sl->useAccessUnitEndFlag = 0;
88 sl->useRandomAccessPointFlag = 0;
89 sl->hasRandomAccessUnitsOnlyFlag = 0;
90 sl->usePaddingFlag = 0;
91 sl->useTimestampsFlag = 0;
92 sl->useIdleFlag = 0;
93 sl->AULength = 0;
94 sl->degradationPriorityLength = 0;
95 sl->AUSeqNumLength = 0;
96 sl->packetSeqNumLength = 0;
97
98 //for MPEG4 IP
99 sl->timestampResolution = 1000;
100 sl->timestampLength = 32;
101 break;
102 case SLPredef_SkipSL:
103 sl->predefined = SLPredef_SkipSL;
104 break;
105 /*handle all unknown predefined as predef-null*/
106 default:
107 sl->useAccessUnitStartFlag = 0;
108 sl->useAccessUnitEndFlag = 0;
109 sl->useRandomAccessPointFlag = 0;
110 sl->hasRandomAccessUnitsOnlyFlag = 0;
111 sl->usePaddingFlag = 0;
112 sl->useTimestampsFlag = 1;
113 sl->useIdleFlag = 0;
114 sl->AULength = 0;
115 sl->degradationPriorityLength = 0;
116 sl->AUSeqNumLength = 0;
117 sl->packetSeqNumLength = 0;
118
119 sl->timestampResolution = 1000;
120 sl->timestampLength = 32;
121 break;
122 }
123
124 return GF_OK;
125 }
126
SLIsPredefined(GF_SLConfig * sl)127 u32 SLIsPredefined(GF_SLConfig *sl)
128 {
129 if (!sl) return 0;
130 if (sl->predefined) return sl->predefined;
131
132 if (!sl->useAccessUnitStartFlag
133 && !sl->useAccessUnitEndFlag
134 && !sl->usePaddingFlag
135 && sl->useTimestampsFlag
136 && !sl->useIdleFlag
137 && !sl->durationFlag
138 && !sl->timestampLength
139 && !sl->OCRLength
140 && !sl->AULength
141 && !sl->instantBitrateLength
142 && !sl->degradationPriorityLength
143 && !sl->AUSeqNumLength
144 && !sl->packetSeqNumLength)
145 return SLPredef_MP4;
146
147 return 0;
148 }
149
150 //this function gets the real amount of bytes needed to store the timeStamp
GetTSbytesLen(GF_SLConfig * sl)151 static u32 GetTSbytesLen(GF_SLConfig *sl)
152 {
153 u32 TSlen, TSbytes;
154 if (!sl) return 0;
155
156 TSlen = sl->timestampLength * 2;
157 TSbytes = TSlen / 8;
158 TSlen = TSlen % 8;
159 if (TSlen) TSbytes += 1;
160 return TSbytes;
161 }
162
163 //
164 // Reader
165 //
gf_odf_read_slc(GF_BitStream * bs,GF_SLConfig * sl,u32 DescSize)166 GF_Err gf_odf_read_slc(GF_BitStream *bs, GF_SLConfig *sl, u32 DescSize)
167 {
168 GF_Err e;
169 u32 nbBytes = 0;
170
171 if (!sl) return GF_BAD_PARAM;
172
173 //APPLE fix
174 if (!DescSize) {
175 sl->predefined = SLPredef_MP4;
176 return gf_odf_slc_set_pref(sl);
177 }
178
179 sl->predefined = gf_bs_read_int(bs, 8);
180 nbBytes += 1;
181
182 /*MPEG4 IP fix*/
183 if (!sl->predefined && nbBytes == DescSize) {
184 sl->predefined = SLPredef_Null;
185 gf_odf_slc_set_pref(sl);
186 return GF_OK;
187 }
188
189 if (sl->predefined) {
190 //predefined configuration
191 e = gf_odf_slc_set_pref(sl);
192 if (e) return e;
193 }
194 else {
195 sl->useAccessUnitStartFlag = gf_bs_read_int(bs, 1);
196 sl->useAccessUnitEndFlag = gf_bs_read_int(bs, 1);
197 sl->useRandomAccessPointFlag = gf_bs_read_int(bs, 1);
198 sl->hasRandomAccessUnitsOnlyFlag = gf_bs_read_int(bs, 1);
199 sl->usePaddingFlag = gf_bs_read_int(bs, 1);
200 sl->useTimestampsFlag = gf_bs_read_int(bs, 1);
201 sl->useIdleFlag = gf_bs_read_int(bs, 1);
202 sl->durationFlag = gf_bs_read_int(bs, 1);
203 sl->timestampResolution = gf_bs_read_int(bs, 32);
204 sl->OCRResolution = gf_bs_read_int(bs, 32);
205
206 sl->timestampLength = gf_bs_read_int(bs, 8);
207 if (sl->timestampLength > 64) return GF_ODF_INVALID_DESCRIPTOR;
208
209 sl->OCRLength = gf_bs_read_int(bs, 8);
210 if (sl->OCRLength > 64) return GF_ODF_INVALID_DESCRIPTOR;
211
212 sl->AULength = gf_bs_read_int(bs, 8);
213 if (sl->AULength > 32) return GF_ODF_INVALID_DESCRIPTOR;
214
215 sl->instantBitrateLength = gf_bs_read_int(bs, 8);
216 sl->degradationPriorityLength = gf_bs_read_int(bs, 4);
217 sl->AUSeqNumLength = gf_bs_read_int(bs, 5);
218 if (sl->AUSeqNumLength > 16) return GF_ODF_INVALID_DESCRIPTOR;
219 sl->packetSeqNumLength = gf_bs_read_int(bs, 5);
220 if (sl->packetSeqNumLength > 16) return GF_ODF_INVALID_DESCRIPTOR;
221
222 /*reserved = */gf_bs_read_int(bs, 2);
223 nbBytes += 15;
224 }
225
226 if (sl->durationFlag) {
227 sl->timeScale = gf_bs_read_int(bs, 32);
228 sl->AUDuration = gf_bs_read_int(bs, 16);
229 sl->CUDuration = gf_bs_read_int(bs, 16);
230 nbBytes += 8;
231 }
232 if (!sl->useTimestampsFlag) {
233 sl->startDTS = gf_bs_read_long_int(bs, sl->timestampLength);
234 sl->startCTS = gf_bs_read_long_int(bs, sl->timestampLength);
235 nbBytes += GetTSbytesLen(sl);
236 }
237
238 if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR;
239 return GF_OK;
240 }
241
242
243 //
244 // Size
245 //
gf_odf_size_slc(GF_SLConfig * sl,u32 * outSize)246 GF_Err gf_odf_size_slc(GF_SLConfig *sl, u32 *outSize)
247 {
248 if (!sl) return GF_BAD_PARAM;
249
250 *outSize = 1;
251 if (!sl->predefined) *outSize += 15;
252 if (sl->durationFlag) *outSize += 8;
253 if (!sl->useTimestampsFlag) *outSize += GetTSbytesLen(sl);
254 return GF_OK;
255 }
256
257 //
258 // Writer
259 //
gf_odf_write_slc(GF_BitStream * bs,GF_SLConfig * sl)260 GF_Err gf_odf_write_slc(GF_BitStream *bs, GF_SLConfig *sl)
261 {
262 GF_Err e;
263 u32 size;
264 if (!sl) return GF_BAD_PARAM;
265
266 e = gf_odf_size_descriptor((GF_Descriptor *)sl, &size);
267 if (e) return e;
268 e = gf_odf_write_base_descriptor(bs, sl->tag, size);
269 if (e) return e;
270
271 gf_bs_write_int(bs, sl->predefined, 8);
272 if (!sl->predefined) {
273 gf_bs_write_int(bs, sl->useAccessUnitStartFlag, 1);
274 gf_bs_write_int(bs, sl->useAccessUnitEndFlag, 1);
275 gf_bs_write_int(bs, sl->useRandomAccessPointFlag, 1);
276 gf_bs_write_int(bs, sl->hasRandomAccessUnitsOnlyFlag, 1);
277 gf_bs_write_int(bs, sl->usePaddingFlag, 1);
278 gf_bs_write_int(bs, sl->useTimestampsFlag, 1);
279 gf_bs_write_int(bs, sl->useIdleFlag, 1);
280 gf_bs_write_int(bs, sl->durationFlag, 1);
281 gf_bs_write_int(bs, sl->timestampResolution, 32);
282 gf_bs_write_int(bs, sl->OCRResolution, 32);
283 gf_bs_write_int(bs, sl->timestampLength, 8);
284 gf_bs_write_int(bs, sl->OCRLength, 8);
285 gf_bs_write_int(bs, sl->AULength, 8);
286 gf_bs_write_int(bs, sl->instantBitrateLength, 8);
287 gf_bs_write_int(bs, sl->degradationPriorityLength, 4);
288 gf_bs_write_int(bs, sl->AUSeqNumLength, 5);
289 gf_bs_write_int(bs, sl->packetSeqNumLength, 5);
290 gf_bs_write_int(bs, 3, 2); //reserved: 0b11 == 3
291 }
292 if (sl->durationFlag) {
293 gf_bs_write_int(bs, sl->timeScale, 32);
294 gf_bs_write_int(bs, sl->AUDuration, 16);
295 gf_bs_write_int(bs, sl->CUDuration, 16);
296 }
297 if (!sl->useTimestampsFlag) {
298 gf_bs_write_long_int(bs, sl->startDTS, sl->timestampLength);
299 gf_bs_write_long_int(bs, sl->startCTS, sl->timestampLength);
300 }
301
302 return GF_OK;
303 }
304
305
306 /*allocates and writes the SL-PDU (Header + PDU) given the SLConfig and the GF_SLHeader
307 for this PDU. AUs must be split in PDUs by another process if needed (packetizer).*/
308 GF_EXPORT
gf_sl_packetize(GF_SLConfig * slConfig,GF_SLHeader * Header,char * PDU,u32 size,char ** outPacket,u32 * OutSize)309 void gf_sl_packetize(GF_SLConfig* slConfig,
310 GF_SLHeader *Header,
311 char *PDU,
312 u32 size,
313 char **outPacket,
314 u32 *OutSize)
315 {
316 GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
317 *OutSize = 0;
318 if (!bs) return;
319
320 if (slConfig->useAccessUnitStartFlag) gf_bs_write_int(bs, Header->accessUnitStartFlag, 1);
321 if (slConfig->useAccessUnitEndFlag) gf_bs_write_int(bs, Header->accessUnitEndFlag, 1);
322 if (slConfig->OCRLength > 0) gf_bs_write_int(bs, Header->OCRflag, 1);
323 if (slConfig->useIdleFlag) gf_bs_write_int(bs, Header->idleFlag, 1);
324 if (slConfig->usePaddingFlag) {
325 gf_bs_write_int(bs, Header->paddingFlag, 1);
326 if (Header->paddingFlag) gf_bs_write_int(bs, Header->paddingBits, 3);
327 }
328 if (!Header->idleFlag && (!Header->paddingFlag || Header->paddingBits != 0)) {
329 if (slConfig->packetSeqNumLength > 0) gf_bs_write_int(bs, Header->packetSequenceNumber, slConfig->packetSeqNumLength);
330 if (slConfig->degradationPriorityLength > 0) {
331 gf_bs_write_int(bs, Header->degradationPriorityFlag, 1);
332 if (Header->degradationPriorityFlag) gf_bs_write_int(bs, Header->degradationPriority, slConfig->degradationPriorityLength);
333 }
334 if (Header->OCRflag) gf_bs_write_long_int(bs, Header->objectClockReference, slConfig->OCRLength);
335 if (Header->accessUnitStartFlag) {
336 if (slConfig->useRandomAccessPointFlag) gf_bs_write_int(bs, Header->randomAccessPointFlag, 1);
337 if (slConfig->AUSeqNumLength > 0) gf_bs_write_int(bs, Header->AU_sequenceNumber, slConfig->AUSeqNumLength);
338 if (slConfig->useTimestampsFlag) {
339 gf_bs_write_int(bs, Header->decodingTimeStampFlag, 1);
340 gf_bs_write_int(bs, Header->compositionTimeStampFlag, 1);
341 }
342 if (slConfig->instantBitrateLength > 0) gf_bs_write_int(bs, Header->instantBitrateFlag, 1);
343 if (Header->decodingTimeStampFlag) gf_bs_write_long_int(bs, Header->decodingTimeStamp, slConfig->timestampLength);
344 if (Header->compositionTimeStampFlag) gf_bs_write_long_int(bs, Header->compositionTimeStamp, slConfig->timestampLength);
345 if (slConfig->AULength > 0) gf_bs_write_int(bs, Header->accessUnitLength, slConfig->AULength);
346 if (Header->instantBitrateFlag) gf_bs_write_int(bs, Header->instantBitrate, slConfig->instantBitrateLength);
347 }
348 }
349 /*done with the Header, Alin*/
350 gf_bs_align(bs);
351
352 /*write the PDU - already byte aligned with stuffing (paddingBits in SL Header)*/
353 if (PDU && size)
354 gf_bs_write_data(bs, PDU, size);
355
356 gf_bs_align(bs);
357 gf_bs_get_content(bs, outPacket, OutSize);
358 gf_bs_del(bs);
359 }
360
361 /*allocates and writes the SL-PDU (Header + PDU) given the SLConfig and the GF_SLHeader
362 for this PDU. AUs must be split in PDUs by another process if needed (packetizer).*/
363 GF_EXPORT
gf_sl_get_header_size(GF_SLConfig * slConfig,GF_SLHeader * Header)364 u32 gf_sl_get_header_size(GF_SLConfig* slConfig, GF_SLHeader *Header)
365 {
366 u32 nb_bits = 0;
367
368 if (slConfig->useAccessUnitStartFlag) nb_bits++;
369 if (slConfig->useAccessUnitEndFlag) nb_bits++;
370 if (slConfig->OCRLength > 0) nb_bits++;
371 if (slConfig->useIdleFlag) nb_bits++;
372 if (slConfig->usePaddingFlag) {
373 nb_bits++;
374 if (Header->paddingFlag) nb_bits += 3;
375 }
376 if (!Header->idleFlag && (!Header->paddingFlag || Header->paddingBits != 0)) {
377 if (slConfig->packetSeqNumLength > 0) nb_bits += slConfig->packetSeqNumLength;
378 if (slConfig->degradationPriorityLength > 0) {
379 nb_bits++;
380 if (Header->degradationPriorityFlag) nb_bits += slConfig->degradationPriorityLength;
381 }
382 if (Header->OCRflag) nb_bits += slConfig->OCRLength;
383 if (Header->accessUnitStartFlag) {
384 if (slConfig->useRandomAccessPointFlag) nb_bits++;
385 if (slConfig->AUSeqNumLength > 0) nb_bits += slConfig->AUSeqNumLength;
386 if (slConfig->useTimestampsFlag) {
387 nb_bits++;
388 nb_bits++;
389 }
390 if (slConfig->instantBitrateLength > 0) nb_bits++;
391 if (Header->decodingTimeStampFlag) nb_bits += slConfig->timestampLength;
392 if (Header->compositionTimeStampFlag) nb_bits += slConfig->timestampLength;
393 if (slConfig->AULength > 0) nb_bits += slConfig->AULength;
394 if (Header->instantBitrateFlag) nb_bits += slConfig->instantBitrateLength;
395 }
396 }
397 while (nb_bits % 8) nb_bits++;
398 return nb_bits / 8;
399 }
400
401
402 GF_EXPORT
gf_sl_depacketize(GF_SLConfig * slConfig,GF_SLHeader * Header,const char * PDU,u32 PDULength,u32 * HeaderLen)403 void gf_sl_depacketize(GF_SLConfig *slConfig, GF_SLHeader *Header, const char *PDU, u32 PDULength, u32 *HeaderLen)
404 {
405 GF_BitStream *bs;
406 *HeaderLen = 0;
407 if (!Header) return;
408 //reset the input header
409 memset(Header, 0, sizeof(GF_SLHeader));
410
411 bs = gf_bs_new(PDU, PDULength, GF_BITSTREAM_READ);
412 if (!bs) return;
413
414 if (slConfig->useAccessUnitStartFlag) Header->accessUnitStartFlag = gf_bs_read_int(bs, 1);
415 if (slConfig->useAccessUnitEndFlag) Header->accessUnitEndFlag = gf_bs_read_int(bs, 1);
416 if (!slConfig->useAccessUnitStartFlag && !slConfig->useAccessUnitEndFlag) {
417 Header->accessUnitStartFlag = 1;
418 Header->accessUnitEndFlag = 1;
419 }
420 if (slConfig->OCRLength > 0) Header->OCRflag = gf_bs_read_int(bs, 1);
421 if (slConfig->useIdleFlag) Header->idleFlag = gf_bs_read_int(bs, 1);
422 if (slConfig->usePaddingFlag) {
423 Header->paddingFlag = gf_bs_read_int(bs, 1);
424 if (Header->paddingFlag) Header->paddingBits = gf_bs_read_int(bs, 3);
425 }
426 if (!Header->paddingFlag || (Header->paddingBits != 0)) {
427
428 if (slConfig->packetSeqNumLength > 0) Header->packetSequenceNumber = gf_bs_read_int(bs, slConfig->packetSeqNumLength);
429 if (slConfig->degradationPriorityLength > 0) {
430 Header->degradationPriorityFlag = gf_bs_read_int(bs, 1);
431 if (Header->degradationPriorityFlag) Header->degradationPriority = gf_bs_read_int(bs, slConfig->degradationPriorityLength);
432 }
433 if (Header->OCRflag) Header->objectClockReference = gf_bs_read_long_int(bs, slConfig->OCRLength);
434 if (Header->accessUnitStartFlag) {
435 if (slConfig->useRandomAccessPointFlag) Header->randomAccessPointFlag = gf_bs_read_int(bs, 1);
436 if (slConfig->AUSeqNumLength > 0) Header->AU_sequenceNumber = gf_bs_read_int(bs, slConfig->AUSeqNumLength);
437 if (slConfig->useTimestampsFlag) {
438 Header->decodingTimeStampFlag = gf_bs_read_int(bs, 1);
439 Header->compositionTimeStampFlag = gf_bs_read_int(bs, 1);
440 }
441 if (slConfig->instantBitrateLength > 0) Header->instantBitrateFlag = gf_bs_read_int(bs, 1);
442 if (Header->decodingTimeStampFlag) Header->decodingTimeStamp = gf_bs_read_long_int(bs, slConfig->timestampLength);
443 if (Header->compositionTimeStampFlag) Header->compositionTimeStamp = gf_bs_read_long_int(bs, slConfig->timestampLength);
444 if (slConfig->AULength > 0) Header->accessUnitLength = gf_bs_read_int(bs, slConfig->AULength);
445 if (Header->instantBitrateFlag) Header->instantBitrate = gf_bs_read_int(bs, slConfig->instantBitrateLength);
446 }
447 }
448 gf_bs_align(bs);
449 *HeaderLen = (u32)gf_bs_get_position(bs);
450 gf_bs_del(bs);
451 }
452