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