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