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 #ifndef GPAC_MINIMAL_ODF
29
30 /************************************************************
31 QoSQualifiers Functions
32 ************************************************************/
33
34 GF_EXPORT
gf_odf_qos_new(u8 tag)35 GF_QoS_Default *gf_odf_qos_new(u8 tag)
36 {
37
38 GF_QoS_Default *NewQoS(u8 tag);
39
40 GF_QoS_Default *qos;
41
42 qos = NewQoS(tag);
43 return qos;
44 }
45
46 GF_EXPORT
gf_odf_qos_del(GF_QoS_Default ** qos)47 GF_Err gf_odf_qos_del(GF_QoS_Default **qos)
48 {
49 if (*qos) gf_odf_delete_qos_qual(*qos);
50 *qos = NULL;
51 return GF_OK;
52 }
53
54
55 //same function, but for QoS, as a Qualifier IS NOT a descriptor
56 GF_EXPORT
gf_odf_qos_add_qualif(GF_QoS_Descriptor * desc,GF_QoS_Default * qualif)57 GF_Err gf_odf_qos_add_qualif(GF_QoS_Descriptor *desc, GF_QoS_Default *qualif)
58 {
59 u32 i;
60 GF_QoS_Default *def;
61
62 if (desc->tag != GF_ODF_QOS_TAG) return GF_BAD_PARAM;
63 if (desc->predefined) return GF_ODF_FORBIDDEN_DESCRIPTOR;
64
65 i = 0;
66 while ((def = (GF_QoS_Default *)gf_list_enum(desc->QoS_Qualifiers, &i))) {
67 //if same Qualifier, not allowed...
68 if (def->tag == qualif->tag) return GF_ODF_FORBIDDEN_DESCRIPTOR;
69 }
70 return gf_list_add(desc->QoS_Qualifiers, qualif);
71 }
72
gf_odf_delete_qos_qual(GF_QoS_Default * qos)73 void gf_odf_delete_qos_qual(GF_QoS_Default *qos)
74 {
75 switch (qos->tag) {
76 case QoSMaxDelayTag:
77 case QoSPrefMaxDelayTag:
78 case QoSLossProbTag:
79 case QoSMaxGapLossTag:
80 case QoSMaxAUSizeTag:
81 case QoSAvgAUSizeTag:
82 case QoSMaxAURateTag:
83 gf_free(qos);
84 return;
85
86 default:
87 if (((GF_QoS_Private *)qos)->DataLength)
88 gf_free(((GF_QoS_Private *)qos)->Data);
89 gf_free((GF_QoS_Private *)qos);
90 return;
91 }
92 }
93
94
gf_odf_size_qos_qual(GF_QoS_Default * qos)95 GF_Err gf_odf_size_qos_qual(GF_QoS_Default *qos)
96 {
97 if (!qos) return GF_BAD_PARAM;
98 qos->size = 0;
99
100 switch (qos->tag) {
101 case QoSMaxDelayTag:
102 case QoSPrefMaxDelayTag:
103 case QoSLossProbTag:
104 case QoSMaxGapLossTag:
105 case QoSMaxAUSizeTag:
106 case QoSAvgAUSizeTag:
107 case QoSMaxAURateTag:
108 qos->size += 4;
109 return GF_OK;
110
111 case 0x00:
112 case 0xFF:
113 return GF_ODF_FORBIDDEN_DESCRIPTOR;
114
115 default:
116 qos->size += ((GF_QoS_Private *)qos)->DataLength;
117 }
118 return GF_OK;
119 }
120
gf_odf_write_qos_qual(GF_BitStream * bs,GF_QoS_Default * qos)121 GF_Err gf_odf_write_qos_qual(GF_BitStream *bs, GF_QoS_Default *qos)
122 {
123 GF_Err e;
124 if (!bs || !qos) return GF_BAD_PARAM;
125
126 e = gf_odf_size_qos_qual(qos);
127 if (e) return e;
128 e = gf_odf_write_base_descriptor(bs, qos->tag, qos->size);
129 if (e) return e;
130
131 switch (qos->tag) {
132 case QoSMaxDelayTag:
133 gf_bs_write_int(bs, ((GF_QoS_MaxDelay *)qos)->MaxDelay, 32);
134 break;
135
136 case QoSPrefMaxDelayTag:
137 gf_bs_write_int(bs, ((GF_QoS_PrefMaxDelay *)qos)->PrefMaxDelay, 32);
138 break;
139
140 case QoSLossProbTag:
141 //FLOAT (double on 4 bytes)
142 gf_bs_write_float(bs, ((GF_QoS_LossProb *)qos)->LossProb);
143 break;
144
145 case QoSMaxGapLossTag:
146 gf_bs_write_int(bs, ((GF_QoS_MaxGapLoss *)qos)->MaxGapLoss, 32);
147 break;
148
149 case QoSMaxAUSizeTag:
150 gf_bs_write_int(bs, ((GF_QoS_MaxAUSize *)qos)->MaxAUSize, 32);
151 break;
152
153 case QoSAvgAUSizeTag:
154 gf_bs_write_int(bs, ((GF_QoS_AvgAUSize *)qos)->AvgAUSize, 32);
155 break;
156
157 case QoSMaxAURateTag:
158 gf_bs_write_int(bs, ((GF_QoS_MaxAURate *)qos)->MaxAURate, 32);
159 break;
160
161 case 0x00:
162 case 0xFF:
163 return GF_ODF_FORBIDDEN_DESCRIPTOR;
164
165 default:
166 //we defined the private qos...
167 gf_bs_write_data(bs, ((GF_QoS_Private *)qos)->Data, ((GF_QoS_Private *)qos)->DataLength);
168 break;
169 }
170 return GF_OK;
171 }
172
173
174
gf_odf_parse_qos(GF_BitStream * bs,GF_QoS_Default ** qos_qual,u32 * qual_size)175 GF_Err gf_odf_parse_qos(GF_BitStream *bs, GF_QoS_Default **qos_qual, u32 *qual_size)
176 {
177 u32 tag, qos_size, val, bytesParsed, sizeHeader;
178 GF_QoS_Default *newQoS;
179
180 //tag
181 tag = gf_bs_read_int(bs, 8);
182 bytesParsed = 1;
183 //size of instance
184 qos_size = 0;
185 sizeHeader = 0;
186 do {
187 val = gf_bs_read_int(bs, 8);
188 sizeHeader++;
189 qos_size <<= 7;
190 qos_size |= val & 0x7F;
191 } while (val & 0x80);
192 bytesParsed += sizeHeader;
193
194 //Payload
195 switch (tag) {
196 case QoSMaxDelayTag:
197 newQoS = (GF_QoS_Default *)gf_malloc(sizeof(GF_QoS_MaxDelay));
198 ((GF_QoS_MaxDelay *)newQoS)->MaxDelay = gf_bs_read_int(bs, 32);
199 bytesParsed += 4;
200 break;
201
202 case QoSPrefMaxDelayTag:
203 newQoS = (GF_QoS_Default *)gf_malloc(sizeof(GF_QoS_PrefMaxDelay));
204 ((GF_QoS_PrefMaxDelay *)newQoS)->PrefMaxDelay = gf_bs_read_int(bs, 32);
205 bytesParsed += 4;
206 break;
207
208 case QoSLossProbTag:
209 newQoS = (GF_QoS_Default *)gf_malloc(sizeof(GF_QoS_LossProb));
210 ((GF_QoS_LossProb *)newQoS)->LossProb = gf_bs_read_float(bs);
211 bytesParsed += 4;
212 break;
213
214 case QoSMaxGapLossTag:
215 newQoS = (GF_QoS_Default *)gf_malloc(sizeof(GF_QoS_MaxGapLoss));
216 ((GF_QoS_MaxGapLoss *)newQoS)->MaxGapLoss = gf_bs_read_int(bs, 32);
217 bytesParsed += 4;
218 break;
219
220 case QoSMaxAUSizeTag:
221 newQoS = (GF_QoS_Default *)gf_malloc(sizeof(GF_QoS_MaxAUSize));
222 ((GF_QoS_MaxAUSize *)newQoS)->MaxAUSize = gf_bs_read_int(bs, 32);
223 bytesParsed += 4;
224 break;
225
226 case QoSAvgAUSizeTag:
227 newQoS = (GF_QoS_Default *)gf_malloc(sizeof(GF_QoS_AvgAUSize));
228 ((GF_QoS_AvgAUSize *)newQoS)->AvgAUSize = gf_bs_read_int(bs, 32);
229 bytesParsed += 4;
230 break;
231
232 case QoSMaxAURateTag:
233 newQoS = (GF_QoS_Default *)gf_malloc(sizeof(GF_QoS_MaxAURate));
234 ((GF_QoS_MaxAURate *)newQoS)->MaxAURate = gf_bs_read_int(bs, 32);
235 bytesParsed += 4;
236 break;
237
238 case 0x00:
239 case 0xFF:
240 return GF_ODF_FORBIDDEN_DESCRIPTOR;
241
242 default:
243 //we defined the private qos...
244 newQoS = (GF_QoS_Default *)gf_malloc(sizeof(GF_QoS_Private));
245 ((GF_QoS_Private *)newQoS)->DataLength = qos_size;
246 gf_bs_read_data(bs, ((GF_QoS_Private *)newQoS)->Data, ((GF_QoS_Private *)newQoS)->DataLength);
247 bytesParsed += ((GF_QoS_Private *)newQoS)->DataLength;
248 break;
249 }
250 newQoS->size = qos_size;
251 newQoS->tag = tag;
252 if (bytesParsed != 1 + qos_size + sizeHeader) {
253 gf_odf_delete_qos_qual(newQoS);
254 return GF_ODF_INVALID_DESCRIPTOR;
255 }
256 *qos_qual = newQoS;
257 *qual_size = bytesParsed;
258 return GF_OK;
259 }
260
261
NewQoS(u8 tag)262 GF_QoS_Default *NewQoS(u8 tag)
263 {
264 GF_QoS_Default *newQoS;
265
266 switch (tag) {
267 case QoSMaxDelayTag:
268 newQoS = (GF_QoS_Default *)gf_malloc(sizeof(GF_QoS_MaxDelay));
269 ((GF_QoS_MaxDelay *)newQoS)->MaxDelay = 0;
270 ((GF_QoS_MaxDelay *)newQoS)->size = 4;
271 break;
272
273 case QoSPrefMaxDelayTag:
274 newQoS = (GF_QoS_Default *)gf_malloc(sizeof(GF_QoS_PrefMaxDelay));
275 ((GF_QoS_PrefMaxDelay *)newQoS)->PrefMaxDelay = 0;
276 ((GF_QoS_PrefMaxDelay *)newQoS)->size = 4;
277 break;
278
279 case QoSLossProbTag:
280 newQoS = (GF_QoS_Default *)gf_malloc(sizeof(GF_QoS_LossProb));
281 ((GF_QoS_LossProb *)newQoS)->LossProb = 0;
282 ((GF_QoS_LossProb *)newQoS)->size = 4;
283 break;
284
285 case QoSMaxGapLossTag:
286 newQoS = (GF_QoS_Default *)gf_malloc(sizeof(GF_QoS_MaxGapLoss));
287 ((GF_QoS_MaxGapLoss *)newQoS)->MaxGapLoss = 0;
288 ((GF_QoS_MaxGapLoss *)newQoS)->size = 4;
289 break;
290
291 case QoSMaxAUSizeTag:
292 newQoS = (GF_QoS_Default *)gf_malloc(sizeof(GF_QoS_MaxAUSize));
293 ((GF_QoS_MaxAUSize *)newQoS)->MaxAUSize = 0;
294 ((GF_QoS_MaxAUSize *)newQoS)->size = 0;
295 break;
296
297 case QoSAvgAUSizeTag:
298 newQoS = (GF_QoS_Default *)gf_malloc(sizeof(GF_QoS_AvgAUSize));
299 ((GF_QoS_AvgAUSize *)newQoS)->AvgAUSize = 0;
300 ((GF_QoS_AvgAUSize *)newQoS)->size = 4;
301 break;
302
303 case QoSMaxAURateTag:
304 newQoS = (GF_QoS_Default *)gf_malloc(sizeof(GF_QoS_MaxAURate));
305 ((GF_QoS_MaxAURate *)newQoS)->MaxAURate = 0;
306 ((GF_QoS_MaxAURate *)newQoS)->size = 4;
307 break;
308
309 case 0x00:
310 case 0xFF:
311 return NULL;
312
313 default:
314 //we defined the private qos...
315 newQoS = (GF_QoS_Default *)gf_malloc(sizeof(GF_QoS_Private));
316 ((GF_QoS_Private *)newQoS)->DataLength = 0;
317 ((GF_QoS_Private *)newQoS)->Data = NULL;
318 break;
319 }
320 newQoS->tag = tag;
321 return newQoS;
322 }
323
324 //
325 // Constructor
326 //
gf_odf_new_qos()327 GF_Descriptor *gf_odf_new_qos()
328 {
329 GF_QoS_Descriptor *newDesc = (GF_QoS_Descriptor *)gf_malloc(sizeof(GF_QoS_Descriptor));
330 if (!newDesc) return NULL;
331 newDesc->QoS_Qualifiers = gf_list_new();
332 newDesc->predefined = 0;
333 newDesc->tag = GF_ODF_QOS_TAG;
334 return (GF_Descriptor *)newDesc;
335 }
336
337 //
338 // Desctructor
339 //
gf_odf_del_qos(GF_QoS_Descriptor * qos)340 GF_Err gf_odf_del_qos(GF_QoS_Descriptor *qos)
341 {
342 if (!qos) return GF_BAD_PARAM;
343
344 while (gf_list_count(qos->QoS_Qualifiers)) {
345 GF_QoS_Default *tmp = (GF_QoS_Default*)gf_list_get(qos->QoS_Qualifiers, 0);
346 gf_odf_delete_qos_qual(tmp);
347 gf_list_rem(qos->QoS_Qualifiers, 0);
348 }
349 gf_list_del(qos->QoS_Qualifiers);
350 return GF_OK;
351 }
352
353
354 //
355 // Reader
356 //
gf_odf_read_qos(GF_BitStream * bs,GF_QoS_Descriptor * qos,u32 DescSize)357 GF_Err gf_odf_read_qos(GF_BitStream *bs, GF_QoS_Descriptor *qos, u32 DescSize)
358 {
359 GF_Err e;
360 GF_QoS_Default *tmp;
361 u32 tmp_size, nbBytes = 0;
362 if (!qos) return GF_BAD_PARAM;
363
364 qos->predefined = gf_bs_read_int(bs, 8);
365 nbBytes += 1;
366
367 if (qos->predefined) {
368 if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
369 return GF_OK;
370 }
371
372 while (nbBytes < DescSize) {
373 tmp = NULL;
374 e = gf_odf_parse_qos(bs, &tmp, &tmp_size);
375 if (e) return e;
376 if (!tmp) return GF_ODF_INVALID_DESCRIPTOR;
377 e = gf_list_add(qos->QoS_Qualifiers, tmp);
378 if (e) return e;
379 nbBytes += tmp_size;
380 }
381 if (nbBytes != DescSize) return GF_ODF_INVALID_DESCRIPTOR;
382 return GF_OK;
383 }
384
385
386
387
388 //
389 // Size
390 //
gf_odf_size_qos(GF_QoS_Descriptor * qos,u32 * outSize)391 GF_Err gf_odf_size_qos(GF_QoS_Descriptor *qos, u32 *outSize)
392 {
393 GF_Err e;
394 u32 i;
395 GF_QoS_Default *tmp;
396
397 if (!qos) return GF_BAD_PARAM;
398
399 *outSize = 1;
400
401 i = 0;
402 while ((tmp = (GF_QoS_Default *)gf_list_enum(qos->QoS_Qualifiers, &i))) {
403 e = gf_odf_size_qos_qual(tmp);
404 if (e) return e;
405 *outSize += tmp->size + gf_odf_size_field_size(tmp->size);
406 }
407 return GF_OK;
408 }
409
410 //
411 // Writer
412 //
gf_odf_write_qos(GF_BitStream * bs,GF_QoS_Descriptor * qos)413 GF_Err gf_odf_write_qos(GF_BitStream *bs, GF_QoS_Descriptor *qos)
414 {
415 GF_Err e;
416 u32 size, i;
417 GF_QoS_Default *tmp;
418 if (!qos) return GF_BAD_PARAM;
419
420 e = gf_odf_size_descriptor((GF_Descriptor *)qos, &size);
421 if (e) return e;
422 e = gf_odf_write_base_descriptor(bs, qos->tag, size);
423 if (e) return e;
424
425 gf_bs_write_int(bs, qos->predefined, 8);
426
427 if (!qos->predefined) {
428 i = 0;
429 while ((tmp = (GF_QoS_Default *)gf_list_enum(qos->QoS_Qualifiers, &i))) {
430 e = gf_odf_write_qos_qual(bs, tmp);
431 if (e) return e;
432 }
433 }
434 return GF_OK;
435 }
436
437
438 #endif /*GPAC_MINIMAL_ODF*/
439
440