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 	/*handle all unknown predefined as predef-null*/
103 	default:
104 		sl->useAccessUnitStartFlag = 0;
105 		sl->useAccessUnitEndFlag = 0;
106 		sl->useRandomAccessPointFlag = 0;
107 		sl->hasRandomAccessUnitsOnlyFlag = 0;
108 		sl->usePaddingFlag = 0;
109 		sl->useTimestampsFlag = 1;
110 		sl->useIdleFlag = 0;
111 		sl->AULength = 0;
112 		sl->degradationPriorityLength = 0;
113 		sl->AUSeqNumLength = 0;
114 		sl->packetSeqNumLength = 0;
115 
116 		sl->timestampResolution = 1000;
117 		sl->timestampLength = 32;
118 		break;
119 	}
120 
121 	return GF_OK;
122 }
123 
124 
125 //this function gets the real amount of bytes needed to store the timeStamp
GetTSbytesLen(GF_SLConfig * sl)126 static u32 GetTSbytesLen(GF_SLConfig *sl)
127 {
128 	u32 TSlen, TSbytes;
129 	if (! sl) return 0;
130 
131 	TSlen = sl->timestampLength * 2;
132 	TSbytes = TSlen / 8;
133 	TSlen = TSlen % 8;
134 	if (TSlen) TSbytes += 1;
135 	return TSbytes;
136 }
137 
138 //
139 //		Reader
140 //
gf_odf_read_slc(GF_BitStream * bs,GF_SLConfig * sl,u32 DescSize)141 GF_Err gf_odf_read_slc(GF_BitStream *bs, GF_SLConfig *sl, u32 DescSize)
142 {
143 	GF_Err e;
144 	u32 nbBytes = 0;
145 
146 	if (!sl) return GF_BAD_PARAM;
147 
148 	//APPLE fix
149 	if (!DescSize) {
150 		sl->predefined = SLPredef_MP4;
151 		return gf_odf_slc_set_pref(sl);
152 	}
153 
154 	sl->predefined = gf_bs_read_int(bs, 8);
155 	nbBytes += 1;
156 
157 	/*MPEG4 IP fix*/
158 	if (!sl->predefined && nbBytes==DescSize) {
159 		sl->predefined = SLPredef_Null;
160 		gf_odf_slc_set_pref(sl);
161 		return GF_OK;
162 	}
163 
164 	if (sl->predefined) {
165 		//predefined configuration
166 		e = gf_odf_slc_set_pref(sl);
167 		if (e) return e;
168 	} else {
169 		sl->useAccessUnitStartFlag = gf_bs_read_int(bs, 1);
170 		sl->useAccessUnitEndFlag = gf_bs_read_int(bs, 1);
171 		sl->useRandomAccessPointFlag = gf_bs_read_int(bs, 1);
172 		sl->hasRandomAccessUnitsOnlyFlag = gf_bs_read_int(bs, 1);
173 		sl->usePaddingFlag = gf_bs_read_int(bs, 1);
174 		sl->useTimestampsFlag = gf_bs_read_int(bs, 1);
175 		sl->useIdleFlag = gf_bs_read_int(bs, 1);
176 		sl->durationFlag = gf_bs_read_int(bs, 1);
177 		sl->timestampResolution = gf_bs_read_int(bs, 32);
178 		sl->OCRResolution = gf_bs_read_int(bs, 32);
179 
180 		sl->timestampLength = gf_bs_read_int(bs, 8);
181 		if (sl->timestampLength > 64) return GF_ODF_INVALID_DESCRIPTOR;
182 
183 		sl->OCRLength = gf_bs_read_int(bs, 8);
184 		if (sl->OCRLength > 64) return GF_ODF_INVALID_DESCRIPTOR;
185 
186 		sl->AULength = gf_bs_read_int(bs, 8);
187 		if (sl->AULength > 32) return GF_ODF_INVALID_DESCRIPTOR;
188 
189 		sl->instantBitrateLength = gf_bs_read_int(bs, 8);
190 		sl->degradationPriorityLength = gf_bs_read_int(bs, 4);
191 		sl->AUSeqNumLength = gf_bs_read_int(bs, 5);
192 		if (sl->AUSeqNumLength > 16) return GF_ODF_INVALID_DESCRIPTOR;
193 		sl->packetSeqNumLength = gf_bs_read_int(bs, 5);
194 		if (sl->packetSeqNumLength > 16) return GF_ODF_INVALID_DESCRIPTOR;
195 
196 		/*reserved = */gf_bs_read_int(bs, 2);
197 		nbBytes += 15;
198 	}
199 
200 	if (sl->durationFlag) {
201 		sl->timeScale = gf_bs_read_int(bs, 32);
202 		sl->AUDuration = gf_bs_read_int(bs, 16);
203 		sl->CUDuration = gf_bs_read_int(bs, 16);
204 		nbBytes += 8;
205 	}
206 	if (! sl->useTimestampsFlag) {
207 		sl->startDTS = gf_bs_read_long_int(bs, sl->timestampLength);
208 		sl->startCTS = gf_bs_read_long_int(bs, sl->timestampLength);
209 		nbBytes += GetTSbytesLen(sl);
210 	}
211 
212 	if (DescSize != nbBytes) return GF_ODF_INVALID_DESCRIPTOR;
213 	return GF_OK;
214 }
215 
216 
217 //
218 //	Size
219 //
gf_odf_size_slc(GF_SLConfig * sl,u32 * outSize)220 GF_Err gf_odf_size_slc(GF_SLConfig *sl, u32 *outSize)
221 {
222 	if (! sl) return GF_BAD_PARAM;
223 
224 	*outSize = 1;
225 	if (! sl->predefined)	*outSize += 15;
226 	if (sl->durationFlag)	*outSize += 8;
227 	if (! sl->useTimestampsFlag) *outSize += GetTSbytesLen(sl);
228 	return GF_OK;
229 }
230 
231 //
232 //	Writer
233 //
gf_odf_write_slc(GF_BitStream * bs,GF_SLConfig * sl)234 GF_Err gf_odf_write_slc(GF_BitStream *bs, GF_SLConfig *sl)
235 {
236 	GF_Err e;
237 	u32 size;
238 	if (! sl) return GF_BAD_PARAM;
239 
240 	e = gf_odf_size_descriptor((GF_Descriptor *)sl, &size);
241 	if (e) return e;
242 	e = gf_odf_write_base_descriptor(bs, sl->tag, size);
243 	if (e) return e;
244 
245 	gf_bs_write_int(bs, sl->predefined, 8);
246 	if (! sl->predefined) {
247 		gf_bs_write_int(bs, sl->useAccessUnitStartFlag, 1);
248 		gf_bs_write_int(bs, sl->useAccessUnitEndFlag, 1);
249 		gf_bs_write_int(bs, sl->useRandomAccessPointFlag, 1);
250 		gf_bs_write_int(bs, sl->hasRandomAccessUnitsOnlyFlag, 1);
251 		gf_bs_write_int(bs, sl->usePaddingFlag, 1);
252 		gf_bs_write_int(bs, sl->useTimestampsFlag, 1);
253 		gf_bs_write_int(bs, sl->useIdleFlag, 1);
254 		gf_bs_write_int(bs, sl->durationFlag, 1);
255 		gf_bs_write_int(bs, sl->timestampResolution, 32);
256 		gf_bs_write_int(bs, sl->OCRResolution, 32);
257 		gf_bs_write_int(bs, sl->timestampLength, 8);
258 		gf_bs_write_int(bs, sl->OCRLength, 8);
259 		gf_bs_write_int(bs, sl->AULength, 8);
260 		gf_bs_write_int(bs, sl->instantBitrateLength, 8);
261 		gf_bs_write_int(bs, sl->degradationPriorityLength, 4);
262 		gf_bs_write_int(bs, sl->AUSeqNumLength, 5);
263 		gf_bs_write_int(bs, sl->packetSeqNumLength, 5);
264 		gf_bs_write_int(bs, 3, 2);	//reserved: 0b11 == 3
265 	}
266 	if (sl->durationFlag) {
267 		gf_bs_write_int(bs, sl->timeScale, 32);
268 		gf_bs_write_int(bs, sl->AUDuration, 16);
269 		gf_bs_write_int(bs, sl->CUDuration, 16);
270 	}
271 	if (! sl->useTimestampsFlag) {
272 		gf_bs_write_long_int(bs, sl->startDTS, sl->timestampLength);
273 		gf_bs_write_long_int(bs, sl->startCTS, sl->timestampLength);
274 	}
275 
276 	return GF_OK;
277 }
278 
279 
280 /*allocates and writes the SL-PDU (Header + PDU) given the SLConfig and the GF_SLHeader
281 for this PDU. AUs must be split in PDUs by another process if needed (packetizer).*/
282 GF_EXPORT
gf_sl_packetize(GF_SLConfig * slConfig,GF_SLHeader * Header,u8 * PDU,u32 size,u8 ** outPacket,u32 * OutSize)283 void gf_sl_packetize(GF_SLConfig* slConfig,
284                      GF_SLHeader *Header,
285                      u8 *PDU,
286                      u32 size,
287                      u8 **outPacket,
288                      u32 *OutSize)
289 {
290 	GF_BitStream *bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
291 	*OutSize = 0;
292 	if (!bs) return;
293 
294 	if (slConfig->useAccessUnitStartFlag) gf_bs_write_int(bs, Header->accessUnitStartFlag, 1);
295 	if (slConfig->useAccessUnitEndFlag) gf_bs_write_int(bs, Header->accessUnitEndFlag, 1);
296 	if (slConfig->OCRLength > 0) gf_bs_write_int(bs, Header->OCRflag, 1);
297 	if (slConfig->useIdleFlag) gf_bs_write_int(bs, Header->idleFlag, 1);
298 	if (slConfig->usePaddingFlag) {
299 		gf_bs_write_int(bs, Header->paddingFlag, 1);
300 		if (Header->paddingFlag) gf_bs_write_int(bs, Header->paddingBits, 3);
301 	}
302 	if (! Header->idleFlag && (! Header->paddingFlag || Header->paddingBits != 0)) {
303 		if (slConfig->packetSeqNumLength > 0) gf_bs_write_int(bs, Header->packetSequenceNumber, slConfig->packetSeqNumLength);
304 		if (slConfig->degradationPriorityLength > 0) {
305 			gf_bs_write_int(bs, Header->degradationPriorityFlag, 1);
306 			if (Header->degradationPriorityFlag) gf_bs_write_int(bs, Header->degradationPriority, slConfig->degradationPriorityLength);
307 		}
308 		if (Header->OCRflag) gf_bs_write_long_int(bs, Header->objectClockReference, slConfig->OCRLength);
309 		if (Header->accessUnitStartFlag) {
310 			if (slConfig->useRandomAccessPointFlag) gf_bs_write_int(bs, Header->randomAccessPointFlag, 1);
311 			if (slConfig->AUSeqNumLength > 0) gf_bs_write_int(bs, Header->AU_sequenceNumber, slConfig->AUSeqNumLength);
312 			if (slConfig->useTimestampsFlag) {
313 				gf_bs_write_int(bs, Header->decodingTimeStampFlag, 1);
314 				gf_bs_write_int(bs, Header->compositionTimeStampFlag, 1);
315 			}
316 			if (slConfig->instantBitrateLength > 0) gf_bs_write_int(bs, Header->instantBitrateFlag, 1);
317 			if (Header->decodingTimeStampFlag) gf_bs_write_long_int(bs, Header->decodingTimeStamp, slConfig->timestampLength);
318 			if (Header->compositionTimeStampFlag) gf_bs_write_long_int(bs, Header->compositionTimeStamp, slConfig->timestampLength);
319 			if (slConfig->AULength > 0) gf_bs_write_int(bs, Header->accessUnitLength, slConfig->AULength);
320 			if (Header->instantBitrateFlag) gf_bs_write_int(bs, Header->instantBitrate, slConfig->instantBitrateLength);
321 		}
322 	}
323 	/*done with the Header, Alin*/
324 	gf_bs_align(bs);
325 
326 	/*write the PDU - already byte aligned with stuffing (paddingBits in SL Header)*/
327 	if (PDU && size)
328 		gf_bs_write_data(bs, PDU, size);
329 
330 	gf_bs_align(bs);
331 	gf_bs_get_content(bs, outPacket, OutSize);
332 	gf_bs_del(bs);
333 }
334 
335 /*allocates and writes the SL-PDU (Header + PDU) given the SLConfig and the GF_SLHeader
336 for this PDU. AUs must be split in PDUs by another process if needed (packetizer).*/
337 GF_EXPORT
gf_sl_get_header_size(GF_SLConfig * slConfig,GF_SLHeader * Header)338 u32 gf_sl_get_header_size(GF_SLConfig* slConfig, GF_SLHeader *Header)
339 {
340 	u32 nb_bits = 0;
341 
342 	if (slConfig->useAccessUnitStartFlag) nb_bits++;
343 	if (slConfig->useAccessUnitEndFlag) nb_bits++;
344 	if (slConfig->OCRLength > 0) nb_bits++;
345 	if (slConfig->useIdleFlag) nb_bits++;
346 	if (slConfig->usePaddingFlag) {
347 		nb_bits++;
348 		if (Header->paddingFlag) nb_bits+=3;
349 	}
350 	if (!Header->idleFlag && (! Header->paddingFlag || Header->paddingBits != 0)) {
351 		if (slConfig->packetSeqNumLength > 0) nb_bits += slConfig->packetSeqNumLength;
352 		if (slConfig->degradationPriorityLength > 0) {
353 			nb_bits++;
354 			if (Header->degradationPriorityFlag) nb_bits += slConfig->degradationPriorityLength;
355 		}
356 		if (Header->OCRflag) nb_bits += slConfig->OCRLength;
357 		if (Header->accessUnitStartFlag) {
358 			if (slConfig->useRandomAccessPointFlag) nb_bits++;
359 			if (slConfig->AUSeqNumLength > 0) nb_bits += slConfig->AUSeqNumLength;
360 			if (slConfig->useTimestampsFlag) {
361 				nb_bits++;
362 				nb_bits++;
363 			}
364 			if (slConfig->instantBitrateLength > 0) nb_bits++;
365 			if (Header->decodingTimeStampFlag) nb_bits += slConfig->timestampLength;
366 			if (Header->compositionTimeStampFlag) nb_bits += slConfig->timestampLength;
367 			if (slConfig->AULength > 0) nb_bits += slConfig->AULength;
368 			if (Header->instantBitrateFlag) nb_bits += slConfig->instantBitrateLength;
369 		}
370 	}
371 	while (nb_bits%8) nb_bits++;
372 	return nb_bits/8;
373 }
374 
375 
376 GF_EXPORT
gf_sl_depacketize(GF_SLConfig * slConfig,GF_SLHeader * Header,const u8 * PDU,u32 PDULength,u32 * HeaderLen)377 void gf_sl_depacketize (GF_SLConfig *slConfig, GF_SLHeader *Header, const u8 *PDU, u32 PDULength, u32 *HeaderLen)
378 {
379 	GF_BitStream *bs;
380 	*HeaderLen = 0;
381 	if (!Header) return;
382 	//reset the input header
383 	memset(Header, 0, sizeof(GF_SLHeader));
384 
385 	bs = gf_bs_new(PDU, PDULength, GF_BITSTREAM_READ);
386 	if (!bs) return;
387 
388 	if (slConfig->useAccessUnitStartFlag) Header->accessUnitStartFlag = gf_bs_read_int(bs, 1);
389 	if (slConfig->useAccessUnitEndFlag) Header->accessUnitEndFlag = gf_bs_read_int(bs, 1);
390 	if ( !slConfig->useAccessUnitStartFlag && !slConfig->useAccessUnitEndFlag) {
391 		Header->accessUnitStartFlag = 1;
392 		Header->accessUnitEndFlag = 1;
393 	}
394 	if (slConfig->OCRLength > 0) Header->OCRflag = gf_bs_read_int(bs, 1);
395 	if (slConfig->useIdleFlag) Header->idleFlag = gf_bs_read_int(bs, 1);
396 	if (slConfig->usePaddingFlag) {
397 		Header->paddingFlag = gf_bs_read_int(bs, 1);
398 		if (Header->paddingFlag) Header->paddingBits = gf_bs_read_int(bs, 3);
399 	}
400 	if (!Header->paddingFlag || (Header->paddingBits != 0)) {
401 
402 		if (slConfig->packetSeqNumLength > 0) Header->packetSequenceNumber = gf_bs_read_int(bs, slConfig->packetSeqNumLength);
403 		if (slConfig->degradationPriorityLength > 0) {
404 			Header->degradationPriorityFlag = gf_bs_read_int(bs, 1);
405 			if (Header->degradationPriorityFlag) Header->degradationPriority = gf_bs_read_int(bs, slConfig->degradationPriorityLength);
406 		}
407 		if (Header->OCRflag) Header->objectClockReference = gf_bs_read_long_int(bs, slConfig->OCRLength);
408 		if (Header->accessUnitStartFlag) {
409 			if (slConfig->useRandomAccessPointFlag) Header->randomAccessPointFlag = gf_bs_read_int(bs, 1);
410 			if (slConfig->AUSeqNumLength > 0) Header->AU_sequenceNumber = gf_bs_read_int(bs, slConfig->AUSeqNumLength);
411 			if (slConfig->useTimestampsFlag) {
412 				Header->decodingTimeStampFlag = gf_bs_read_int(bs, 1);
413 				Header->compositionTimeStampFlag = gf_bs_read_int(bs, 1);
414 			}
415 			if (slConfig->instantBitrateLength > 0) Header->instantBitrateFlag = gf_bs_read_int(bs, 1);
416 			if (Header->decodingTimeStampFlag) Header->decodingTimeStamp = gf_bs_read_long_int(bs, slConfig->timestampLength);
417 			if (Header->compositionTimeStampFlag) Header->compositionTimeStamp = gf_bs_read_long_int(bs, slConfig->timestampLength);
418 			if (slConfig->AULength > 0) Header->accessUnitLength = gf_bs_read_int(bs, slConfig->AULength);
419 			if (Header->instantBitrateFlag) Header->instantBitrate = gf_bs_read_int(bs, slConfig->instantBitrateLength);
420 		}
421 	}
422 	gf_bs_align(bs);
423 	*HeaderLen = (u32) gf_bs_get_position(bs);
424 	gf_bs_del(bs);
425 }
426