1 /*
2 * GPAC - Multimedia Framework C SDK
3 *
4 * Authors: Jean Le Feuvre
5 * Copyright (c) Telecom ParisTech 2000-2020
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
27 #include <gpac/internal/odf_dev.h>
28 #include <gpac/token.h>
29 #include <gpac/constants.h>
30 /*for import flags*/
31 #include <gpac/media_tools.h>
32
33
34 /* to complete...*/
35
gf_odf_get_field_type(GF_Descriptor * desc,char * fieldName)36 u32 gf_odf_get_field_type(GF_Descriptor *desc, char *fieldName)
37 {
38 switch (desc->tag) {
39 case GF_ODF_IOD_TAG:
40 case GF_ODF_OD_TAG:
41 if (!stricmp(fieldName, "esDescr")) return GF_ODF_FT_OD_LIST;
42 else if (!stricmp(fieldName, "ociDescr")) return GF_ODF_FT_OD_LIST;
43 else if (!stricmp(fieldName, "ipmpDescrPtr")) return GF_ODF_FT_OD_LIST;
44 else if (!stricmp(fieldName, "ipmpDescr")) return GF_ODF_FT_OD_LIST;
45 else if (!stricmp(fieldName, "extDescr")) return GF_ODF_FT_OD_LIST;
46 else if (!stricmp(fieldName, "toolListDescr")) return GF_ODF_FT_OD;
47 return 0;
48 case GF_ODF_DCD_TAG:
49 if (!stricmp(fieldName, "decSpecificInfo")) return GF_ODF_FT_OD;
50 if (!stricmp(fieldName, "profileLevelIndicationIndexDescr")) return GF_ODF_FT_OD_LIST;
51 return 0;
52 case GF_ODF_ESD_TAG:
53 if (!stricmp(fieldName, "decConfigDescr")) return GF_ODF_FT_OD;
54 if (!stricmp(fieldName, "muxInfo")) return GF_ODF_FT_OD;
55 if (!stricmp(fieldName, "StreamSource")) return GF_ODF_FT_OD;
56 if (!stricmp(fieldName, "slConfigDescr")) return GF_ODF_FT_OD;
57 if (!stricmp(fieldName, "ipiPtr")) return GF_ODF_FT_OD;
58 if (!stricmp(fieldName, "qosDescr")) return GF_ODF_FT_OD;
59 if (!stricmp(fieldName, "regDescr")) return GF_ODF_FT_OD;
60 if (!stricmp(fieldName, "langDescr")) return GF_ODF_FT_OD;
61 if (!stricmp(fieldName, "ipIDS")) return GF_ODF_FT_OD_LIST;
62 if (!stricmp(fieldName, "ipmpDescrPtr")) return GF_ODF_FT_OD_LIST;
63 if (!stricmp(fieldName, "extDescr")) return GF_ODF_FT_OD_LIST;
64 return 0;
65 case GF_ODF_TEXT_CFG_TAG:
66 if (!stricmp(fieldName, "SampleDescriptions")) return GF_ODF_FT_OD_LIST;
67 return 0;
68 case GF_ODF_IPMP_TAG:
69 if (!stricmp(fieldName, "IPMPX_Data")) return GF_ODF_FT_IPMPX_LIST;
70 return 0;
71 case GF_ODF_IPMP_TL_TAG:
72 if (!stricmp(fieldName, "ipmpTool")) return GF_ODF_FT_OD_LIST;
73 return 0;
74 case GF_ODF_IPMP_TOOL_TAG:
75 if (!stricmp(fieldName, "toolParamDesc")) return GF_ODF_FT_IPMPX;
76 return 0;
77 case GF_ODF_BIFS_CFG_TAG:
78 if (!stricmp(fieldName, "elementaryMask")) return GF_ODF_FT_OD_LIST;
79 return 0;
80 }
81 return 0;
82 }
83
gf_odf_get_tag_by_name(char * descName)84 u32 gf_odf_get_tag_by_name(char *descName)
85 {
86 if (!stricmp(descName, "ObjectDescriptor")) return GF_ODF_OD_TAG;
87 if (!stricmp(descName, "InitialObjectDescriptor")) return GF_ODF_IOD_TAG;
88 if (!stricmp(descName, "ES_Descriptor")) return GF_ODF_ESD_TAG;
89 if (!stricmp(descName, "DecoderConfigDescriptor")) return GF_ODF_DCD_TAG;
90 if (!stricmp(descName, "DecoderSpecificInfo")) return GF_ODF_DSI_TAG;
91 if (!stricmp(descName, "DecoderSpecificInfoString")) return GF_ODF_DSI_TAG;
92 if (!stricmp(descName, "SLConfigDescriptor")) return GF_ODF_SLC_TAG;
93 if (!stricmp(descName, "SegmentDescriptor")) return GF_ODF_SEGMENT_TAG;
94 if (!stricmp(descName, "MuxInfo")) return GF_ODF_MUXINFO_TAG;
95 if (!stricmp(descName, "StreamSource")) return GF_ODF_MUXINFO_TAG;
96 if (!stricmp(descName, "BIFSConfig") || !stricmp(descName, "BIFSv2Config")) return GF_ODF_BIFS_CFG_TAG;
97 if (!stricmp(descName, "ElementaryMask")) return GF_ODF_ELEM_MASK_TAG;
98 if (!stricmp(descName, "TextConfig")) return GF_ODF_TEXT_CFG_TAG;
99 if (!stricmp(descName, "TextSampleDescriptor")) return GF_ODF_TX3G_TAG;
100 if (!stricmp(descName, "UIConfig")) return GF_ODF_UI_CFG_TAG;
101 if (!stricmp(descName, "ES_ID_Ref")) return GF_ODF_ESD_REF_TAG;
102 if (!stricmp(descName, "ES_ID_Inc")) return GF_ODF_ESD_INC_TAG;
103 if (!stricmp(descName, "AuxiliaryVideoData")) return GF_ODF_AUX_VIDEO_DATA;
104 if (!stricmp(descName, "DefaultDescriptor")) return GF_ODF_DSI_TAG;
105 if (!stricmp(descName, "LanguageDescriptor")) return GF_ODF_LANG_TAG;
106 if (!stricmp(descName, "GPACLanguage")) return GF_ODF_GPAC_LANG;
107
108 #ifndef GPAC_MINIMAL_ODF
109 if (!stricmp(descName, "MediaTimeDescriptor")) return GF_ODF_MEDIATIME_TAG;
110 if (!stricmp(descName, "ContentIdentification")) return GF_ODF_CI_TAG;
111 if (!stricmp(descName, "SuppContentIdentification")) return GF_ODF_SCI_TAG;
112 if (!stricmp(descName, "IPIPtr")) return GF_ODF_IPI_PTR_TAG;
113 if (!stricmp(descName, "IPMP_DescriptorPointer")) return GF_ODF_IPMP_PTR_TAG;
114 if (!stricmp(descName, "IPMP_Descriptor")) return GF_ODF_IPMP_TAG;
115 if (!stricmp(descName, "IPMP_ToolListDescriptor")) return GF_ODF_IPMP_TL_TAG;
116 if (!stricmp(descName, "IPMP_Tool")) return GF_ODF_IPMP_TOOL_TAG;
117 if (!stricmp(descName, "QoS")) return GF_ODF_QOS_TAG;
118 if (!stricmp(descName, "RegistrationDescriptor")) return GF_ODF_REG_TAG;
119 if (!stricmp(descName, "ExtensionPL")) return GF_ODF_EXT_PL_TAG;
120 if (!stricmp(descName, "PL_IndicationIndex")) return GF_ODF_PL_IDX_TAG;
121 if (!stricmp(descName, "ContentClassification")) return GF_ODF_CC_TAG;
122 if (!stricmp(descName, "KeyWordDescriptor")) return GF_ODF_KW_TAG;
123 if (!stricmp(descName, "RatingDescriptor")) return GF_ODF_RATING_TAG;
124 if (!stricmp(descName, "ShortTextualDescriptor")) return GF_ODF_SHORT_TEXT_TAG;
125 if (!stricmp(descName, "ExpandedTextualDescriptor")) return GF_ODF_TEXT_TAG;
126 if (!stricmp(descName, "ContentCreatorName")) return GF_ODF_CC_NAME_TAG;
127 if (!stricmp(descName, "ContentCreationDate")) return GF_ODF_CC_DATE_TAG;
128 if (!stricmp(descName, "OCI_CreatorName")) return GF_ODF_OCI_NAME_TAG;
129 if (!stricmp(descName, "OCI_CreationDate")) return GF_ODF_OCI_DATE_TAG;
130 if (!stricmp(descName, "SmpteCameraPosition")) return GF_ODF_SMPTE_TAG;
131 #endif /*GPAC_MINIMAL_ODF*/
132 return 0;
133 }
134
135 #include <gpac/internal/odf_parse_common.h>
136
OD_ParseBinData(u8 * val,u8 ** out_data,u32 * out_data_size)137 void OD_ParseBinData(u8 *val, u8 **out_data, u32 *out_data_size)
138 {
139 u32 i, c;
140 char s[3];
141 u32 len = (u32) strlen(val) / 3;
142 if (*out_data) gf_free(*out_data);
143 *out_data_size = len;
144 *out_data = gf_malloc(sizeof(char) * len);
145 s[2] = 0;
146 for (i=0; i<len; i++) {
147 s[0] = val[3*i+1];
148 s[1] = val[3*i+2];
149 sscanf(s, "%02X", &c);
150 (*out_data)[i] = (unsigned char) c;
151 }
152 }
153
gf_odf_set_field(GF_Descriptor * desc,char * fieldName,char * val)154 GF_Err gf_odf_set_field(GF_Descriptor *desc, char *fieldName, char *val)
155 {
156 #ifndef GPAC_MINIMAL_ODF
157 Bool OD_ParseUIConfig(u8 *val, u8 **out_data, u32 *out_data_size);
158 #endif
159 u32 ret = 0;
160 if (!fieldName || !val) return GF_BAD_PARAM;
161 if (!stricmp(val, "auto")) return GF_OK;
162 else if (!stricmp(val, "unspecified")) return GF_OK;
163
164 switch (desc->tag) {
165 case GF_ODF_IOD_TAG:
166 {
167 GF_InitialObjectDescriptor *iod = (GF_InitialObjectDescriptor *)desc;
168 if (!stricmp(fieldName, "objectDescriptorID") || !stricmp(fieldName, "binaryID")) ret += sscanf(val, "%hu", &iod->objectDescriptorID);
169 else if (!stricmp(fieldName, "URLString")) {
170 iod->URLString = gf_strdup(val);
171 ret = 1;
172 }
173 else if (!stricmp(fieldName, "includeInlineProfileLevelFlag")) {
174 GET_BOOL(iod->inlineProfileFlag)
175 if (!ret) {
176 iod->inlineProfileFlag = 0;
177 ret = 1;
178 }
179 }
180 else if (!stricmp(fieldName, "ODProfileLevelIndication")) {
181 GET_U8(iod->OD_profileAndLevel)
182 if (!ret) {
183 iod->OD_profileAndLevel = 0xFE;
184 ret = 1;
185 }
186 }
187 else if (!stricmp(fieldName, "sceneProfileLevelIndication")) {
188 GET_U8(iod->scene_profileAndLevel)
189 if (!ret) {
190 iod->scene_profileAndLevel = 0xFE;
191 ret = 1;
192 }
193 }
194 else if (!stricmp(fieldName, "audioProfileLevelIndication")) {
195 GET_U8(iod->audio_profileAndLevel)
196 if (!ret) {
197 iod->audio_profileAndLevel = 0xFE;
198 ret = 1;
199 }
200 }
201 else if (!stricmp(fieldName, "visualProfileLevelIndication")) {
202 GET_U8(iod->visual_profileAndLevel)
203 if (!ret) {
204 iod->visual_profileAndLevel = 0xFE;
205 ret = 1;
206 }
207 }
208 else if (!stricmp(fieldName, "graphicsProfileLevelIndication")) {
209 GET_U8(iod->graphics_profileAndLevel)
210 if (!ret) {
211 iod->graphics_profileAndLevel = 0xFE;
212 ret = 1;
213 }
214 }
215 }
216 break;
217 case GF_ODF_OD_TAG:
218 {
219 GF_ObjectDescriptor *od = (GF_ObjectDescriptor *) desc;
220 if (!stricmp(fieldName, "objectDescriptorID") || !stricmp(fieldName, "binaryID")) ret += sscanf(val, "%hu", &od->objectDescriptorID);
221 else if (!stricmp(fieldName, "URLString")) {
222 od->URLString = gf_strdup(val);
223 ret = 1;
224 }
225 }
226 break;
227 case GF_ODF_DCD_TAG:
228 {
229 GF_DecoderConfig *dcd = (GF_DecoderConfig *)desc;
230 if (!stricmp(fieldName, "objectTypeIndication")) {
231 GET_U8(dcd->objectTypeIndication)
232 /*XMT may use string*/
233 if (!ret) {
234 if (!stricmp(val, "MPEG4Systems1")) {
235 dcd->objectTypeIndication = GF_CODECID_OD_V1;
236 ret = 1;
237 }
238 else if (!stricmp(val, "MPEG4Systems2")) {
239 dcd->objectTypeIndication = GF_CODECID_BIFS_V2;
240 ret = 1;
241 }
242 else if (!stricmp(val, "MPEG4Visual")) {
243 dcd->objectTypeIndication = GF_CODECID_MPEG4_PART2;
244 ret = 1;
245 }
246 else if (!stricmp(val, "MPEG4Audio")) {
247 dcd->objectTypeIndication = GF_CODECID_AAC_MPEG4;
248 ret = 1;
249 }
250 else if (!stricmp(val, "MPEG2VisualSimple")) {
251 dcd->objectTypeIndication = GF_CODECID_MPEG2_SIMPLE;
252 ret = 1;
253 }
254 else if (!stricmp(val, "MPEG2VisualMain")) {
255 dcd->objectTypeIndication = GF_CODECID_MPEG2_MAIN;
256 ret = 1;
257 }
258 else if (!stricmp(val, "MPEG2VisualSNR")) {
259 dcd->objectTypeIndication = GF_CODECID_MPEG2_SNR;
260 ret = 1;
261 }
262 else if (!stricmp(val, "MPEG2VisualSpatial")) {
263 dcd->objectTypeIndication = GF_CODECID_MPEG2_SPATIAL;
264 ret = 1;
265 }
266 else if (!stricmp(val, "MPEG2VisualHigh")) {
267 dcd->objectTypeIndication = GF_CODECID_MPEG2_HIGH;
268 ret = 1;
269 }
270 else if (!stricmp(val, "MPEG2Visual422")) {
271 dcd->objectTypeIndication = GF_CODECID_MPEG2_422;
272 ret = 1;
273 }
274 else if (!stricmp(val, "MPEG2AudioMain")) {
275 dcd->objectTypeIndication = GF_CODECID_AAC_MPEG2_MP;
276 ret = 1;
277 }
278 else if (!stricmp(val, "MPEG2AudioLowComplexity")) {
279 dcd->objectTypeIndication = GF_CODECID_AAC_MPEG2_LCP;
280 ret = 1;
281 }
282 else if (!stricmp(val, "MPEG2AudioScaleableSamplingRate")) {
283 dcd->objectTypeIndication = GF_CODECID_AAC_MPEG2_SSRP;
284 ret = 1;
285 }
286 else if (!stricmp(val, "MPEG2AudioPart3")) {
287 dcd->objectTypeIndication = GF_CODECID_MPEG2_PART3;
288 ret = 1;
289 }
290 else if (!stricmp(val, "MPEG1Visual")) {
291 dcd->objectTypeIndication = GF_CODECID_MPEG1;
292 ret = 1;
293 }
294 else if (!stricmp(val, "MPEG1Audio")) {
295 dcd->objectTypeIndication = GF_CODECID_MPEG_AUDIO;
296 ret = 1;
297 }
298 else if (!stricmp(val, "JPEG")) {
299 dcd->objectTypeIndication = GF_CODECID_JPEG;
300 ret = 1;
301 }
302 else if (!stricmp(val, "PNG")) {
303 dcd->objectTypeIndication = GF_CODECID_PNG;
304 ret = 1;
305 }
306 }
307 }
308 else if (!stricmp(fieldName, "streamType")) {
309 GET_U8(dcd->streamType)
310 /*XMT may use string*/
311 if (!ret) {
312 dcd->streamType = gf_stream_type_by_name(val);
313 if (dcd->streamType != GF_STREAM_UNKNOWN)
314 ret = 1;
315 }
316 }
317 else if (!stricmp(fieldName, "upStream")) {
318 GET_BOOL(dcd->upstream)
319 }
320 else if (!stricmp(fieldName, "bufferSizeDB")) ret += sscanf(val, "%u", &dcd->bufferSizeDB);
321 else if (!stricmp(fieldName, "maxBitRate")) ret += sscanf(val, "%u", &dcd->maxBitrate);
322 else if (!stricmp(fieldName, "avgBitRate")) ret += sscanf(val, "%u", &dcd->avgBitrate);
323 }
324 break;
325 case GF_ODF_ESD_TAG:
326 {
327 GF_ESD *esd = (GF_ESD *)desc;
328 if (!stricmp(fieldName, "ES_ID") || !stricmp(fieldName, "binaryID")) {
329 ret += sscanf(val, "%hu", &esd->ESID);
330 }
331 else if (!stricmp(fieldName, "streamPriority")) GET_U8(esd->streamPriority)
332 else if (!stricmp(fieldName, "dependsOn_ES_ID") || !stricmp(fieldName, "dependsOnESID")) ret += sscanf(val, "%hu", &esd->dependsOnESID);
333 else if (!stricmp(fieldName, "OCR_ES_ID")) ret += sscanf(val, "%hu", &esd->OCRESID);
334 else if (!stricmp(fieldName, "URLstring")) {
335 esd->URLString = gf_strdup(val);
336 ret = 1;
337 }
338 /*ignore*/
339 else if (!stricmp(fieldName, "streamDependenceFlag")
340 || !stricmp(fieldName, "URL_Flag")
341 || !stricmp(fieldName, "OCRstreamFlag")
342 )
343 ret = 1;
344 }
345 break;
346 case GF_ODF_SLC_TAG:
347 {
348 GF_SLConfig *slc = (GF_SLConfig*)desc;
349 if (!stricmp(fieldName, "predefined")) GET_U8(slc->predefined)
350 else if (!stricmp(fieldName, "useAccessUnitStartFlag")) GET_BOOL(slc->useAccessUnitStartFlag)
351 else if (!stricmp(fieldName, "useAccessUnitEndFlag")) GET_BOOL(slc->useAccessUnitEndFlag)
352 else if (!stricmp(fieldName, "useRandomAccessPointFlag")) GET_BOOL(slc->useRandomAccessPointFlag)
353 else if (!stricmp(fieldName, "hasRandomAccessUnitsOnlyFlag") || !stricmp(fieldName, "useRandomAccessUnitsOnlyFlag")) GET_BOOL(slc->hasRandomAccessUnitsOnlyFlag)
354 else if (!stricmp(fieldName, "usePaddingFlag")) GET_BOOL(slc->usePaddingFlag)
355 else if (!stricmp(fieldName, "useTimeStampsFlag")) GET_BOOL(slc->useTimestampsFlag)
356 else if (!stricmp(fieldName, "useIdleFlag")) GET_BOOL(slc->useIdleFlag)
357 else if (!stricmp(fieldName, "timeStampResolution")) ret += sscanf(val, "%u", &slc->timestampResolution);
358 else if (!stricmp(fieldName, "OCRResolution")) ret += sscanf(val, "%u", &slc->OCRResolution);
359 else if (!stricmp(fieldName, "timeStampLength")) GET_U8(slc->timestampLength)
360 else if (!stricmp(fieldName, "OCRLength")) GET_U8(slc->OCRLength)
361 else if (!stricmp(fieldName, "AU_Length")) GET_U8(slc->AULength)
362 else if (!stricmp(fieldName, "instantBitrateLength")) GET_U8(slc->instantBitrateLength)
363 else if (!stricmp(fieldName, "degradationPriorityLength")) GET_U8(slc->degradationPriorityLength)
364 else if (!stricmp(fieldName, "AU_seqNumLength")) GET_U8(slc->AUSeqNumLength)
365 else if (!stricmp(fieldName, "packetSeqNumLength")) GET_U8(slc->packetSeqNumLength)
366 else if (!stricmp(fieldName, "timeScale")) ret += sscanf(val, "%u", &slc->timeScale);
367 else if (!stricmp(fieldName, "accessUnitDuration")) ret += sscanf(val, "%hu", &slc->AUDuration);
368 else if (!stricmp(fieldName, "compositionUnitDuration")) ret += sscanf(val, "%hu", &slc->CUDuration);
369 else if (!stricmp(fieldName, "startDecodingTimeStamp")) GET_U64(slc->startDTS)
370 else if (!stricmp(fieldName, "startCompositionTimeStamp")) GET_U64(slc->startCTS)
371 else if (!stricmp(fieldName, "durationFlag")) ret = 1;
372 }
373 break;
374 case GF_ODF_ELEM_MASK_TAG:
375 {
376 GF_ElementaryMask* em = (GF_ElementaryMask*)desc;
377 if (!stricmp(fieldName, "atNode")) {
378 GET_U32(em->node_id);
379 if (!ret || !em->node_id) em->node_name = gf_strdup(val);
380 ret = 1;
381 }
382 else if (!stricmp(fieldName, "numDynFields")) ret = 1;
383 }
384 break;
385 case GF_ODF_BIFS_CFG_TAG:
386 {
387 GF_BIFSConfig *bcd = (GF_BIFSConfig*)desc;
388 if (!stricmp(val, "auto")) return GF_OK;
389 if (!stricmp(fieldName, "nodeIDbits")) ret += sscanf(val, "%hu", &bcd->nodeIDbits);
390 else if (!stricmp(fieldName, "routeIDbits")) ret += sscanf(val, "%hu", &bcd->routeIDbits);
391 else if (!stricmp(fieldName, "protoIDbits")) ret += sscanf(val, "%hu", &bcd->protoIDbits);
392 else if (!stricmp(fieldName, "isCommandStream")) {
393 /*GET_BOOL(bcd->isCommandStream)*/ ret = 1;
394 }
395 else if (!stricmp(fieldName, "pixelMetric") || !stricmp(fieldName, "pixelMetrics")) GET_BOOL(bcd->pixelMetrics)
396 else if (!stricmp(fieldName, "pixelWidth")) ret += sscanf(val, "%hu", &bcd->pixelWidth);
397 else if (!stricmp(fieldName, "pixelHeight")) ret += sscanf(val, "%hu", &bcd->pixelHeight);
398 else if (!stricmp(fieldName, "use3DMeshCoding")) ret = 1;
399 else if (!stricmp(fieldName, "usePredictiveMFField")) ret = 1;
400 else if (!stricmp(fieldName, "randomAccess")) GET_BOOL(bcd->randomAccess)
401 else if (!stricmp(fieldName, "useNames")) GET_BOOL(bcd->useNames)
402 }
403 break;
404 case GF_ODF_MUXINFO_TAG:
405 {
406 GF_MuxInfo *mi = (GF_MuxInfo *)desc;
407 if (!stricmp(fieldName, "fileName") || !stricmp(fieldName, "url")) GET_STRING(mi->file_name)
408 else if (!stricmp(fieldName, "streamFormat")) GET_STRING(mi->streamFormat)
409 else if (!stricmp(fieldName, "GroupID")) ret += sscanf(val, "%u", &mi->GroupID);
410 else if (!stricmp(fieldName, "startTime")) ret += sscanf(val, "%d", &mi->startTime);
411 else if (!stricmp(fieldName, "duration")) ret += sscanf(val, "%u", &mi->duration);
412 else if (!stricmp(fieldName, "carouselPeriod")) {
413 ret += sscanf(val, "%u", &mi->carousel_period_plus_one);
414 mi->carousel_period_plus_one += 1;
415 }
416 else if (!stricmp(fieldName, "aggregateOnESID")) ret += sscanf(val, "%hu", &mi->aggregate_on_esid);
417
418 #ifndef GPAC_DISABLE_MEDIA_IMPORT
419 else if (!stricmp(fieldName, "compactSize"))
420 {
421 ret = 1;
422 if (!stricmp(val, "true") || !stricmp(val, "1")) mi->import_flags |= GF_IMPORT_USE_COMPACT_SIZE;
423 }
424 else if (!stricmp(fieldName, "useDataReference")) {
425 ret = 1;
426 if (!stricmp(val, "true") || !stricmp(val, "1")) mi->import_flags |= GF_IMPORT_USE_DATAREF;
427 }
428 else if (!stricmp(fieldName, "noFrameDrop")) {
429 ret = 1;
430 if (!stricmp(val, "true") || !stricmp(val, "1")) mi->import_flags |= GF_IMPORT_NO_FRAME_DROP;
431 }
432 else if (!stricmp(fieldName, "SBR_Type")) {
433 ret = 1;
434 if (!stricmp(val, "implicit") || !stricmp(val, "1")) mi->import_flags |= GF_IMPORT_SBR_IMPLICIT;
435 else if (!stricmp(val, "explicit") || !stricmp(val, "2")) mi->import_flags |= GF_IMPORT_SBR_EXPLICIT;
436 }
437 #endif /*GPAC_DISABLE_MEDIA_IMPORT*/
438 else if (!stricmp(fieldName, "textNode")) GET_STRING(mi->textNode)
439 else if (!stricmp(fieldName, "fontNode")) GET_STRING(mi->fontNode)
440 else if (!stricmp(fieldName, "frameRate")) {
441 ret = 1;
442 mi->frame_rate = atof(val);
443 }
444 }
445 break;
446 case GF_ODF_DSI_TAG:
447 {
448 GF_DefaultDescriptor *dsi = (GF_DefaultDescriptor*)desc;
449 if (!stricmp(fieldName, "info")) {
450 /*only parse true hexa strings*/
451 if (val[0] == '%') {
452 OD_ParseBinData(val, &dsi->data, &dsi->dataLength);
453 ret = 1;
454 } else if (!strnicmp(val, "file:", 5)) {
455 gf_file_load_data(val+5, (u8 **) &dsi->data, &dsi->dataLength);
456 ret = 1;
457 } else if (!strlen(val)) ret = 1;
458 }
459 if (!stricmp(fieldName, "src")) {
460 u32 len = (u32) strlen("data:application/octet-string,");
461 if (strnicmp(val, "data:application/octet-string,", len)) break;
462 val += len;
463 /*only parse true hexa strings*/
464 if (val[0] == '%') {
465 OD_ParseBinData(val, &dsi->data, &dsi->dataLength);
466 ret = 1;
467 } else if (!strnicmp(val, "file:", 5)) {
468 gf_file_load_data(val+5, (u8 **) &dsi->data, &dsi->dataLength);
469 ret = 1;
470 }
471 }
472 }
473 break;
474 case GF_ODF_SEGMENT_TAG:
475 {
476 GF_Segment *sd = (GF_Segment*)desc;
477 if (!stricmp(fieldName, "start") || !stricmp(fieldName, "startTime")) GET_DOUBLE(sd->startTime)
478 else if (!stricmp(fieldName, "duration")) GET_DOUBLE(sd->Duration)
479 else if (!stricmp(fieldName, "name") || !stricmp(fieldName, "segmentName")) GET_STRING(sd->SegmentName)
480 }
481 break;
482 case GF_ODF_UI_CFG_TAG:
483 {
484 GF_UIConfig *uic = (GF_UIConfig*)desc;
485 if (!stricmp(fieldName, "deviceName")) GET_STRING(uic->deviceName)
486 else if (!stricmp(fieldName, "termChar")) GET_U8(uic->termChar)
487 else if (!stricmp(fieldName, "delChar")) GET_U8(uic->delChar)
488 else if (!stricmp(fieldName, "uiData")) {
489 /*only parse true hexa strings*/
490 if (val[0] == '%') {
491 OD_ParseBinData(val, &uic->ui_data, &uic->ui_data_length);
492 ret = 1;
493 } else if (!strnicmp(val, "file:", 5)) {
494 gf_file_load_data(val+5, (u8 **) &uic->ui_data, &uic->ui_data_length);
495 ret = 1;
496 } else {
497 #ifndef GPAC_MINIMAL_ODF
498 ret = OD_ParseUIConfig(val, &uic->ui_data, &uic->ui_data_length);
499 #else
500 ret= GF_FALSE;
501 #endif
502 }
503 }
504 }
505 break;
506 case GF_ODF_ESD_INC_TAG:
507 {
508 GF_ES_ID_Inc *inc = (GF_ES_ID_Inc *)desc;
509 if (!stricmp(fieldName, "trackID")) ret += sscanf(val, "%u", &inc->trackID);
510 }
511 break;
512 case GF_ODF_ESD_REF_TAG:
513 {
514 GF_ES_ID_Ref *inc = (GF_ES_ID_Ref *)desc;
515 if (!stricmp(fieldName, "trackID")) ret += sscanf(val, "%hu", &inc->trackRef);
516 }
517 break;
518 case GF_ODF_TEXT_CFG_TAG:
519 {
520 GF_TextConfig *txt = (GF_TextConfig*)desc;
521 if (!stricmp(fieldName, "3GPPBaseFormat")) GET_U8(txt->Base3GPPFormat)
522 else if (!stricmp(fieldName, "MPEGExtendedFormat")) GET_U8(txt->MPEGExtendedFormat)
523 else if (!stricmp(fieldName, "profileLevel")) GET_U8(txt->profileLevel)
524 else if (!stricmp(fieldName, "durationClock") || !stricmp(fieldName, "timescale") ) GET_U32(txt->timescale)
525 else if (!stricmp(fieldName, "layer")) GET_U32(txt->layer)
526 else if (!stricmp(fieldName, "text_width")) GET_U32(txt->text_width)
527 else if (!stricmp(fieldName, "text_height")) GET_U32(txt->text_height)
528 else if (!stricmp(fieldName, "video_width")) {
529 GET_U32(txt->video_width)
530 txt->has_vid_info = GF_TRUE;
531 }
532 else if (!stricmp(fieldName, "video_height")) {
533 GET_U32(txt->video_height)
534 txt->has_vid_info = GF_TRUE;
535 }
536 else if (!stricmp(fieldName, "horizontal_offset")) {
537 GET_S16(txt->horiz_offset)
538 txt->has_vid_info = GF_TRUE;
539 }
540 else if (!stricmp(fieldName, "vertical_offset")) {
541 GET_S32(txt->vert_offset)
542 txt->has_vid_info = GF_TRUE;
543 }
544 }
545 break;
546 case GF_ODF_TX3G_TAG:
547 {
548 GF_TextSampleDescriptor *sd = (GF_TextSampleDescriptor*)desc;
549 if (!stricmp(fieldName, "displayFlags")) GET_U32(sd->displayFlags)
550 else if (!stricmp(fieldName, "horiz_justif")) GET_S32(sd->horiz_justif)
551 else if (!stricmp(fieldName, "vert_justif")) GET_S32(sd->vert_justif)
552 else if (!stricmp(fieldName, "back_color")) GET_S32(sd->back_color)
553 else if (!stricmp(fieldName, "top")) GET_S32(sd->default_pos.top)
554 else if (!stricmp(fieldName, "bottom")) GET_S32(sd->default_pos.bottom)
555 else if (!stricmp(fieldName, "left")) GET_S32(sd->default_pos.left)
556 else if (!stricmp(fieldName, "right")) GET_S32(sd->default_pos.right)
557 else if (!stricmp(fieldName, "style_font_ID")) GET_S32(sd->default_style.fontID)
558 else if (!stricmp(fieldName, "style_font_size")) GET_S32(sd->default_style.font_size)
559 else if (!stricmp(fieldName, "style_text_color")) GET_U32(sd->default_style.text_color)
560 else if (!stricmp(fieldName, "style_flags")) {
561 char szStyles[1024];
562 strcpy(szStyles, val);
563 strlwr(szStyles);
564 if (strstr(szStyles, "bold")) sd->default_style.style_flags |= GF_TXT_STYLE_BOLD;
565 if (strstr(szStyles, "italic")) sd->default_style.style_flags |= GF_TXT_STYLE_ITALIC;
566 if (strstr(szStyles, "underlined")) sd->default_style.style_flags |= GF_TXT_STYLE_UNDERLINED;
567 ret = 1;
568 }
569 else if (!stricmp(fieldName, "fontID") || !stricmp(fieldName, "fontName")) {
570 /*check if we need a new entry*/
571 if (!sd->font_count) {
572 sd->fonts = (GF_FontRecord*)gf_malloc(sizeof(GF_FontRecord));
573 sd->font_count = 1;
574 sd->fonts[0].fontID = 0;
575 sd->fonts[0].fontName = NULL;
576 } else {
577 Bool realloc_fonts = GF_FALSE;
578 if (!stricmp(fieldName, "fontID") && sd->fonts[sd->font_count-1].fontID) realloc_fonts = GF_TRUE;
579 else if (!stricmp(fieldName, "fontName") && sd->fonts[sd->font_count-1].fontName) realloc_fonts = GF_TRUE;
580 if (realloc_fonts) {
581 sd->font_count += 1;
582 sd->fonts = (GF_FontRecord*)gf_realloc(sd->fonts, sizeof(GF_FontRecord)*sd->font_count);
583 sd->fonts[sd->font_count-1].fontID = 0;
584 sd->fonts[sd->font_count-1].fontName = NULL;
585 }
586 }
587 if (!stricmp(fieldName, "fontID")) GET_U32(sd->fonts[sd->font_count-1].fontID)
588 if (!stricmp(fieldName, "fontName")) GET_STRING(sd->fonts[sd->font_count-1].fontName)
589 }
590 }
591 break;
592 case GF_ODF_IPMP_TAG:
593 {
594 GF_IPMP_Descriptor *ipmp = (GF_IPMP_Descriptor*)desc;
595 if (!stricmp(fieldName, "IPMP_DescriptorID")) GET_U8(ipmp->IPMP_DescriptorID)
596 else if (!stricmp(fieldName, "IPMPS_Type")) GET_U16(ipmp->IPMPS_Type)
597 else if (!stricmp(fieldName, "IPMP_DescriptorIDEx")) GET_U16(ipmp->IPMP_DescriptorIDEx)
598 else if (!stricmp(fieldName, "IPMP_ToolID")) {
599 ret = 1;
600 gf_bin128_parse(val, ipmp->IPMP_ToolID);
601 }
602 else if (!stricmp(fieldName, "controlPointCode")) GET_U8(ipmp->control_point)
603 else if (!stricmp(fieldName, "sequenceCode")) GET_U8(ipmp->cp_sequence_code)
604 }
605 break;
606 case GF_ODF_IPMP_PTR_TAG:
607 {
608 GF_IPMPPtr *ipmpd = (GF_IPMPPtr*)desc;
609 if (!stricmp(fieldName, "IPMP_DescriptorID")) GET_U8(ipmpd->IPMP_DescriptorID)
610 else if (!stricmp(fieldName, "IPMP_DescriptorIDEx")) ret += sscanf(val, "%hu", &ipmpd->IPMP_DescriptorIDEx);
611 else if (!stricmp(fieldName, "IPMP_ES_ID")) ret += sscanf(val, "%hu", &ipmpd->IPMP_ES_ID);
612 }
613 break;
614 case GF_ODF_LANG_TAG:
615 case GF_ODF_GPAC_LANG:
616 {
617 GF_Language *ld = (GF_Language *)desc;
618 if (!stricmp(fieldName, "languageCode")) {
619 u32 li, l = (u32) strlen(val);
620 ld->langCode = 0;
621 for (li = 0; li < l; li++) {
622 /* Warning: sensitive to big endian, little endian */
623 ld->langCode |= (val[li] << (l-li-1)*8);
624 }
625 ret++;
626 }
627 }
628 break;
629 case GF_ODF_AUX_VIDEO_DATA:
630 {
631 GF_AuxVideoDescriptor *avd = (GF_AuxVideoDescriptor *)desc;
632 if (!stricmp(fieldName, "aux_video_type")) GET_U8(avd->aux_video_type)
633 else if (!stricmp(fieldName, "position_offset_h")) GET_U8(avd->position_offset_h)
634 else if (!stricmp(fieldName, "position_offset_v")) GET_U8(avd->position_offset_v)
635 else if (!stricmp(fieldName, "knear")) GET_U8(avd->knear)
636 else if (!stricmp(fieldName, "kfar")) GET_U8(avd->kfar)
637 else if (!stricmp(fieldName, "parallax_zero")) GET_U16(avd->parallax_zero)
638 else if (!stricmp(fieldName, "parallax_scale")) GET_U16(avd->parallax_scale)
639 else if (!stricmp(fieldName, "dref")) GET_U16(avd->dref)
640 else if (!stricmp(fieldName, "wref")) GET_U16(avd->wref)
641 }
642 break;
643 case GF_ODF_IPMP_TOOL_TAG:
644 {
645 GF_IPMP_Tool *it = (GF_IPMP_Tool*)desc;
646 if (!stricmp(fieldName, "IPMP_ToolID")) {
647 ret = 1;
648 gf_bin128_parse(val, it->IPMP_ToolID);
649 }
650 else if (!stricmp(fieldName, "ToolURL")) GET_STRING(it->tool_url)
651 }
652 break;
653 }
654
655 return ret ? GF_OK : GF_BAD_PARAM;
656 }
657
658 #ifndef GPAC_MINIMAL_ODF
OD_ParseUIConfig(u8 * val,u8 ** out_data,u32 * out_data_size)659 Bool OD_ParseUIConfig(u8 *val, u8 **out_data, u32 *out_data_size)
660 {
661 GF_BitStream *bs;
662 if (!strnicmp(val, "HTK:", 4)) {
663 char szItem[100];
664 s64 pos, bs_start, bs_cur;
665 Bool has_word;
666 u32 nb_phonems, nbWords = 0;
667 bs_start = 0;
668 nb_phonems = 0;
669 bs = gf_bs_new(NULL, 0, GF_BITSTREAM_WRITE);
670 /*we'll write the nb of words later on*/
671 gf_bs_write_int(bs, 0, 8);
672 has_word = GF_FALSE;
673 /*parse all words*/
674 val += 4;
675 while (1) {
676 pos = gf_token_get(val, 0, " ;", szItem, 100);
677 if (pos>0) val += pos;
678 if (!has_word) {
679 has_word = GF_TRUE;
680 nbWords++;
681 nb_phonems = 0;
682 bs_start = gf_bs_get_position(bs);
683 /*nb phonems*/
684 gf_bs_write_int(bs, 0, 8);
685 gf_bs_write_data(bs, szItem, (u32) strlen(szItem));
686 gf_bs_write_int(bs, 0, 8);
687 continue;
688 }
689 if (pos>0) {
690
691 nb_phonems ++;
692 /*would be nicer with a phone book & use indexes*/
693 if (!stricmp(szItem, "vcl")) {
694 gf_bs_write_data(bs, "vc", 2);
695 } else {
696 gf_bs_write_data(bs, szItem, 2);
697 }
698
699 while (val[0] && (val[0]==' ')) val += 1;
700 }
701
702 if ((pos<0) || !val[0] || val[0]==';') {
703 if (has_word) {
704 has_word = GF_FALSE;
705 bs_cur = gf_bs_get_position(bs);
706 gf_bs_seek(bs, bs_start);
707 gf_bs_write_int(bs, nb_phonems, 8);
708 gf_bs_seek(bs, bs_cur);
709 }
710 if ((pos<0) || !val[0]) break;
711 val += 1;
712 while (val[0] && (val[0]==' ')) val += 1;
713 }
714 }
715 if (nbWords) {
716 bs_cur = gf_bs_get_position(bs);
717 gf_bs_seek(bs, 0);
718 gf_bs_write_int(bs, nbWords, 8);
719 gf_bs_seek(bs, bs_cur);
720 gf_bs_get_content(bs, out_data, out_data_size);
721 }
722 gf_bs_del(bs);
723 return GF_TRUE;
724 }
725 return GF_FALSE;
726 }
727 #endif
728