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