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