Line data Source code
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 / Scene Management 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 :
28 : #include <gpac/constants.h>
29 : #include <gpac/utf.h>
30 : #include <gpac/xml.h>
31 : #include <gpac/internal/media_dev.h>
32 : #include <gpac/scene_manager.h>
33 :
34 : enum
35 : {
36 : GF_TEXT_IMPORT_NONE = 0,
37 : GF_TEXT_IMPORT_SRT,
38 : GF_TEXT_IMPORT_SUB,
39 : GF_TEXT_IMPORT_TTXT,
40 : GF_TEXT_IMPORT_TEXML,
41 : };
42 :
43 : #define REM_TRAIL_MARKS(__str, __sep) while (1) { \
44 : u32 _len = (u32) strlen(__str); \
45 : if (!_len) break; \
46 : _len--; \
47 : if (strchr(__sep, __str[_len])) __str[_len] = 0; \
48 : else break; \
49 : } \
50 :
51 :
52 2 : static GF_Err gf_text_guess_format(char *filename, u32 *fmt)
53 : {
54 : char szLine[2048], szTest[10];
55 : u32 val;
56 2 : FILE *test = gf_fopen(filename, "rt");
57 2 : if (!test) return GF_URL_ERROR;
58 :
59 2 : while (gf_fgets(szLine, 2048, test) != NULL) {
60 4 : REM_TRAIL_MARKS(szLine, "\r\n\t ")
61 :
62 2 : if (strlen(szLine)) break;
63 : }
64 2 : *fmt = GF_TEXT_IMPORT_NONE;
65 2 : if ((szLine[0]=='{') && strstr(szLine, "}{")) *fmt = GF_TEXT_IMPORT_SUB;
66 1 : else if (sscanf(szLine, "%u", &val)==1) {
67 1 : sprintf(szTest, "%u", val);
68 1 : if (!strcmp(szTest, szLine)) *fmt = GF_TEXT_IMPORT_SRT;
69 : }
70 0 : else if (!strnicmp(szLine, "<?xml ", 6)) {
71 0 : char *ext = gf_file_ext_start(filename);
72 0 : if (!strnicmp(ext, ".ttxt", 5)) *fmt = GF_TEXT_IMPORT_TTXT;
73 0 : ext = strstr(szLine, "?>");
74 0 : if (ext) ext += 2;
75 0 : if (ext && !ext[0]) {
76 0 : if (!gf_fgets(szLine, 2048, test))
77 0 : szLine[0] = '\0';
78 : }
79 0 : if (strstr(szLine, "x-quicktime-tx3g")) *fmt = GF_TEXT_IMPORT_TEXML;
80 : }
81 2 : gf_fclose(test);
82 2 : return GF_OK;
83 : }
84 :
85 : #ifndef GPAC_DISABLE_VRML
86 :
87 1 : static GF_Err gf_text_import_srt_bifs(GF_SceneManager *ctx, GF_ESD *src, GF_MuxInfo *mux)
88 : {
89 : GF_Err e;
90 : GF_Node *text, *font;
91 : GF_StreamContext *srt;
92 : FILE *srt_in;
93 : GF_FieldInfo string, style;
94 : u32 sh, sm, ss, sms, eh, em, es, ems, start, end;
95 : GF_AUContext *au;
96 : GF_Command *com;
97 : SFString *sfstr;
98 : GF_CommandField *inf;
99 : Bool italic, underlined, bold;
100 : u32 state, curLine, line, i, len;
101 : char szLine[2048], szText[2048], *ptr;
102 : GF_StreamContext *sc = NULL;
103 :
104 1 : if (!ctx->scene_graph) {
105 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[srt->bifs] base scene not assigned\n"));
106 : return GF_BAD_PARAM;
107 : }
108 1 : i=0;
109 2 : while ((sc = (GF_StreamContext*)gf_list_enum(ctx->streams, &i))) {
110 1 : if (sc->streamType==GF_STREAM_SCENE) break;
111 : sc = NULL;
112 : }
113 :
114 1 : if (!sc) {
115 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[srt->bifs] cannot locate base scene\n"));
116 : return GF_BAD_PARAM;
117 : }
118 1 : if (!mux->textNode) {
119 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[srt->bifs] Target text node unspecified\n"));
120 : return GF_BAD_PARAM;
121 : }
122 1 : text = gf_sg_find_node_by_name(ctx->scene_graph, mux->textNode);
123 1 : if (!text) {
124 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[srt->bifs] cannot find target text node %s\n", mux->textNode));
125 : return GF_BAD_PARAM;
126 : }
127 1 : if (gf_node_get_field_by_name(text, "string", &string) != GF_OK) {
128 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[srt->bifs] Target text node %s doesn't look like text\n", mux->textNode));
129 : return GF_BAD_PARAM;
130 : }
131 :
132 : font = NULL;
133 1 : if (mux->fontNode) {
134 1 : font = gf_sg_find_node_by_name(ctx->scene_graph, mux->fontNode);
135 1 : if (!font) {
136 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[srt->bifs] cannot find target font node %s\n", mux->fontNode));
137 : return GF_BAD_PARAM;
138 : }
139 1 : if (gf_node_get_field_by_name(font, "style", &style) != GF_OK) {
140 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[srt->bifs] Target font node %s doesn't look like font\n", mux->fontNode));
141 : return GF_BAD_PARAM;
142 : }
143 : }
144 :
145 1 : srt_in = gf_fopen(mux->file_name, "rt");
146 1 : if (!srt_in) {
147 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[srt->bifs] cannot open input file %s\n", mux->file_name));
148 : return GF_URL_ERROR;
149 : }
150 :
151 1 : srt = gf_sm_stream_new(ctx, src->ESID, GF_STREAM_SCENE, GF_CODECID_BIFS);
152 1 : if (!srt) return GF_OUT_OF_MEM;
153 :
154 1 : if (!src->slConfig) src->slConfig = (GF_SLConfig *) gf_odf_desc_new(GF_ODF_SLC_TAG);
155 1 : src->slConfig->timestampResolution = 1000;
156 1 : if (!src->decoderConfig) src->decoderConfig = (GF_DecoderConfig *) gf_odf_desc_new(GF_ODF_DCD_TAG);
157 1 : src->decoderConfig->streamType = GF_STREAM_SCENE;
158 1 : src->decoderConfig->objectTypeIndication = GF_CODECID_BIFS;
159 :
160 : e = GF_OK;
161 : state = end = 0;
162 : curLine = 0;
163 : au = NULL;
164 : com = NULL;
165 : italic = underlined = bold = 0;
166 : inf = NULL;
167 :
168 : while (1) {
169 24 : char *sOK = gf_fgets(szLine, 2048, srt_in);
170 :
171 24 : if (sOK) REM_TRAIL_MARKS(szLine, "\r\n\t ")
172 :
173 24 : if (!sOK || !strlen(szLine)) {
174 : state = 0;
175 7 : if (au) {
176 : /*if italic or underscore do it*/
177 5 : if (font && (italic || underlined || bold)) {
178 3 : com = gf_sg_command_new(ctx->scene_graph, GF_SG_FIELD_REPLACE);
179 3 : com->node = font;
180 3 : gf_node_register(font, NULL);
181 3 : inf = gf_sg_command_field_new(com);
182 3 : inf->fieldIndex = style.fieldIndex;
183 3 : inf->fieldType = style.fieldType;
184 3 : inf->field_ptr = gf_sg_vrml_field_pointer_new(style.fieldType);
185 3 : sfstr = (SFString *)inf->field_ptr;
186 3 : if (bold && italic && underlined) sfstr->buffer = gf_strdup("BOLDITALIC UNDERLINED");
187 3 : else if (italic && underlined) sfstr->buffer = gf_strdup("ITALIC UNDERLINED");
188 3 : else if (bold && underlined) sfstr->buffer = gf_strdup("BOLD UNDERLINED");
189 3 : else if (underlined) sfstr->buffer = gf_strdup("UNDERLINED");
190 3 : else if (bold && italic) sfstr->buffer = gf_strdup("BOLDITALIC");
191 2 : else if (bold) sfstr->buffer = gf_strdup("BOLD");
192 1 : else sfstr->buffer = gf_strdup("ITALIC");
193 3 : gf_list_add(au->commands, com);
194 : }
195 :
196 5 : au = gf_sm_stream_au_new(srt, end, 0, 1);
197 5 : com = gf_sg_command_new(ctx->scene_graph, GF_SG_FIELD_REPLACE);
198 5 : com->node = text;
199 5 : gf_node_register(text, NULL);
200 5 : inf = gf_sg_command_field_new(com);
201 5 : inf->fieldIndex = string.fieldIndex;
202 5 : inf->fieldType = string.fieldType;
203 5 : inf->field_ptr = gf_sg_vrml_field_pointer_new(string.fieldType);
204 5 : gf_list_add(au->commands, com);
205 : /*reset font styles so that all AUs are true random access*/
206 5 : if (font) {
207 5 : com = gf_sg_command_new(ctx->scene_graph, GF_SG_FIELD_REPLACE);
208 5 : com->node = font;
209 5 : gf_node_register(font, NULL);
210 5 : inf = gf_sg_command_field_new(com);
211 5 : inf->fieldIndex = style.fieldIndex;
212 5 : inf->fieldType = style.fieldType;
213 5 : inf->field_ptr = gf_sg_vrml_field_pointer_new(style.fieldType);
214 5 : gf_list_add(au->commands, com);
215 : }
216 : au = NULL;
217 : }
218 : inf = NULL;
219 7 : if (!sOK) break;
220 6 : continue;
221 : }
222 :
223 17 : switch (state) {
224 5 : case 0:
225 5 : if (sscanf(szLine, "%u", &line) != 1) {
226 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[srt->bifs] bad frame format (src: %s)\n", szLine));
227 : e = GF_CORRUPTED_DATA;
228 : goto exit;
229 : }
230 5 : if (line != curLine + 1) {
231 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[srt->bifs] bad frame: previous %d - current %d (src: %s)\n", curLine, line, szLine));
232 : e = GF_CORRUPTED_DATA;
233 : goto exit;
234 : }
235 : curLine = line;
236 : state = 1;
237 : break;
238 5 : case 1:
239 5 : if (sscanf(szLine, "%u:%u:%u,%u --> %u:%u:%u,%u", &sh, &sm, &ss, &sms, &eh, &em, &es, &ems) != 8) {
240 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[srt->bifs] bad frame %u (src: %s)\n", curLine, szLine));
241 : e = GF_CORRUPTED_DATA;
242 : goto exit;
243 : }
244 5 : start = (3600*sh + 60*sm + ss)*1000 + sms;
245 5 : if (start<end) {
246 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_PARSER, ("[srt->bifs] corrupted frame starts before end of previous one (SRT Frame %d) - adjusting time stamps\n", curLine));
247 : start = end;
248 : }
249 5 : end = (3600*eh + 60*em + es)*1000 + ems;
250 : /*make stream start at 0 by inserting a fake AU*/
251 5 : if ((curLine==1) && start>0) {
252 1 : au = gf_sm_stream_au_new(srt, 0, 0, 1);
253 1 : com = gf_sg_command_new(ctx->scene_graph, GF_SG_FIELD_REPLACE);
254 1 : com->node = text;
255 1 : gf_node_register(text, NULL);
256 1 : inf = gf_sg_command_field_new(com);
257 1 : inf->fieldIndex = string.fieldIndex;
258 1 : inf->fieldType = string.fieldType;
259 1 : inf->field_ptr = gf_sg_vrml_field_pointer_new(string.fieldType);
260 1 : gf_list_add(au->commands, com);
261 : }
262 :
263 5 : au = gf_sm_stream_au_new(srt, start, 0, 1);
264 : com = NULL;
265 : state = 2;
266 : italic = underlined = bold = 0;
267 5 : break;
268 :
269 : default:
270 : ptr = szLine;
271 : /*FIXME - other styles posssibles ??*/
272 : while (1) {
273 11 : if (!strnicmp(ptr, "<i>", 3)) {
274 : italic = 1;
275 2 : ptr += 3;
276 : }
277 9 : else if (!strnicmp(ptr, "<u>", 3)) {
278 : underlined = 1;
279 0 : ptr += 3;
280 : }
281 9 : else if (!strnicmp(ptr, "<b>", 3)) {
282 : bold = 1;
283 2 : ptr += 3;
284 : }
285 : else
286 : break;
287 : }
288 : /*if style remove end markers*/
289 11 : while ((strlen(ptr)>4) && (ptr[strlen(ptr) - 4] == '<') && (ptr[strlen(ptr) - 1] == '>')) {
290 4 : ptr[strlen(ptr) - 4] = 0;
291 : }
292 :
293 7 : if (!com) {
294 5 : com = gf_sg_command_new(ctx->scene_graph, GF_SG_FIELD_REPLACE);
295 5 : com->node = text;
296 5 : gf_node_register(text, NULL);
297 5 : inf = gf_sg_command_field_new(com);
298 5 : inf->fieldIndex = string.fieldIndex;
299 5 : inf->fieldType = string.fieldType;
300 5 : inf->field_ptr = gf_sg_vrml_field_pointer_new(string.fieldType);
301 5 : gf_list_add(au->commands, com);
302 : }
303 : assert(inf);
304 7 : gf_sg_vrml_mf_append(inf->field_ptr, GF_SG_VRML_MFSTRING, (void **) &sfstr);
305 : len = 0;
306 142 : for (i=0; i<strlen(ptr); i++) {
307 : /*FIXME - UTF16 support !!*/
308 135 : if (ptr[i] & 0x80) {
309 : /*non UTF8 (likely some win-CP)*/
310 4 : if ((ptr[i+1] & 0xc0) != 0x80) {
311 4 : szText[len] = 0xc0 | ( (ptr[i] >> 6) & 0x3 );
312 4 : len++;
313 4 : ptr[i] &= 0xbf;
314 : }
315 : /*we only handle UTF8 chars on 2 bytes (eg first byte is 0b110xxxxx)*/
316 0 : else if ((ptr[i] & 0xe0) == 0xc0) {
317 0 : szText[len] = ptr[i];
318 0 : len++;
319 0 : i++;
320 : }
321 : }
322 135 : szText[len] = ptr[i];
323 135 : len++;
324 : }
325 7 : szText[len] = 0;
326 7 : sfstr->buffer = gf_strdup(szText);
327 7 : break;
328 : }
329 : }
330 :
331 1 : exit:
332 1 : gf_fclose(srt_in);
333 1 : return e;
334 : }
335 : #endif /*GPAC_DISABLE_VRML*/
336 :
337 :
338 : #ifndef GPAC_DISABLE_VRML
339 :
340 1 : static GF_Err gf_text_import_sub_bifs(GF_SceneManager *ctx, GF_ESD *src, GF_MuxInfo *mux)
341 : {
342 : GF_Err e;
343 : GF_Node *text, *font;
344 : GF_StreamContext *srt;
345 : FILE *sub_in;
346 : GF_FieldInfo string, style;
347 : u32 start, end, line, i, j, k, len;
348 : GF_AUContext *au;
349 : GF_Command *com;
350 : SFString *sfstr;
351 : GF_CommandField *inf;
352 : Bool first_samp;
353 : char szLine[2048], szTime[30], szText[2048];
354 : GF_StreamContext *sc = NULL;
355 :
356 1 : if (!ctx->scene_graph) {
357 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[sub->bifs] base scene not assigned\n"));
358 : return GF_BAD_PARAM;
359 : }
360 1 : i=0;
361 2 : while ((sc = (GF_StreamContext*)gf_list_enum(ctx->streams, &i))) {
362 1 : if (sc->streamType==GF_STREAM_SCENE) break;
363 : sc = NULL;
364 : }
365 :
366 1 : if (!sc) {
367 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[sub->bifs] cannot locate base scene\n"));
368 : return GF_BAD_PARAM;
369 : }
370 1 : if (!mux->textNode) {
371 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[sub->bifs] target text node unspecified\n"));
372 : return GF_BAD_PARAM;
373 : }
374 1 : text = gf_sg_find_node_by_name(ctx->scene_graph, mux->textNode);
375 1 : if (!text) {
376 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[sub->bifs] cannot find target text node %s\n", mux->textNode));
377 : return GF_BAD_PARAM;
378 : }
379 1 : if (gf_node_get_field_by_name(text, "string", &string) != GF_OK) {
380 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[sub->bifs] target text node %s doesn't look like text\n", mux->textNode));
381 : return GF_BAD_PARAM;
382 : }
383 :
384 : font = NULL;
385 1 : if (mux->fontNode) {
386 1 : font = gf_sg_find_node_by_name(ctx->scene_graph, mux->fontNode);
387 1 : if (!font) {
388 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[sub->bifs] cannot find target font node %s\n", mux->fontNode));
389 : return GF_BAD_PARAM;
390 : }
391 1 : if (gf_node_get_field_by_name(font, "style", &style) != GF_OK) {
392 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[sub->bifs] target font node %s doesn't look like font\n", mux->fontNode));
393 : return GF_BAD_PARAM;
394 : }
395 : }
396 :
397 1 : sub_in = gf_fopen(mux->file_name, "rt");
398 1 : if (!sub_in) {
399 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[sub->bifs] cannot open input file %s\n", mux->file_name));
400 : return GF_URL_ERROR;
401 : }
402 :
403 1 : srt = gf_sm_stream_new(ctx, src->ESID, GF_STREAM_SCENE, GF_CODECID_BIFS);
404 1 : if (!srt) return GF_OUT_OF_MEM;
405 :
406 1 : if (!src->slConfig) src->slConfig = (GF_SLConfig *) gf_odf_desc_new(GF_ODF_SLC_TAG);
407 1 : src->slConfig->timestampResolution = 1000;
408 1 : if (!src->decoderConfig) src->decoderConfig = (GF_DecoderConfig *) gf_odf_desc_new(GF_ODF_DCD_TAG);
409 1 : src->decoderConfig->streamType = GF_STREAM_SCENE;
410 1 : src->decoderConfig->objectTypeIndication = GF_CODECID_BIFS;
411 :
412 : e = GF_OK;
413 : end = 0;
414 : au = NULL;
415 : com = NULL;
416 : inf = NULL;
417 :
418 : line = 0;
419 : first_samp = 1;
420 : while (1) {
421 6 : char *sOK = gf_fgets(szLine, 2048, sub_in);
422 6 : if (!sOK) break;
423 10 : REM_TRAIL_MARKS(szLine, "\r\n\t ")
424 :
425 5 : line++;
426 : len = (u32) strlen(szLine);
427 5 : if (!len) continue;
428 :
429 3 : i=0;
430 3 : if (szLine[i] != '{') {
431 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[sub->bifs] Bad frame (line %d): expecting \"{\" got \"%c\"\n", line, szLine[i]));
432 : e = GF_NON_COMPLIANT_BITSTREAM;
433 : break;
434 : }
435 10 : while (szLine[i+1] && szLine[i+1]!='}') {
436 7 : szTime[i] = szLine[i+1];
437 7 : i++;
438 : }
439 3 : szTime[i] = 0;
440 3 : start = atoi(szTime);
441 3 : if (start<end) {
442 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_PARSER, ("[sub->bifs] corrupted SUB frame (line %d) - starts (at %d ms) before end of previous one (%d ms) - adjusting time stamps\n", line, start, end));
443 : start = end;
444 : }
445 3 : j=i+2;
446 3 : i=0;
447 3 : if (szLine[i+j] != '{') {
448 0 : GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[sub->bifs] Bad frame - expecting \"{\" got \"%c\"\n", szLine[i]));
449 : e = GF_NON_COMPLIANT_BITSTREAM;
450 : break;
451 : }
452 11 : while (szLine[i+1+j] && szLine[i+1+j]!='}') {
453 8 : szTime[i] = szLine[i+1+j];
454 8 : i++;
455 : }
456 3 : szTime[i] = 0;
457 3 : end = atoi(szTime);
458 3 : j+=i+2;
459 :
460 3 : if (start>end) {
461 0 : GF_LOG(GF_LOG_WARNING, GF_LOG_PARSER, ("[sub->bifs] corrupted frame (line %d) - ends (at %d ms) before start of current frame (%d ms) - skipping\n", line, end, start));
462 0 : continue;
463 : }
464 :
465 3 : if (start && first_samp) {
466 3 : au = gf_sm_stream_au_new(srt, 0, 0, 1);
467 3 : com = gf_sg_command_new(ctx->scene_graph, GF_SG_FIELD_REPLACE);
468 3 : com->node = text;
469 3 : gf_node_register(text, NULL);
470 3 : inf = gf_sg_command_field_new(com);
471 3 : inf->fieldIndex = string.fieldIndex;
472 3 : inf->fieldType = string.fieldType;
473 3 : inf->field_ptr = gf_sg_vrml_field_pointer_new(string.fieldType);
474 3 : gf_list_add(au->commands, com);
475 : }
476 :
477 : k=0;
478 70 : for (i=j; i<len; i++) {
479 67 : if (szLine[i]=='|') {
480 1 : szText[k] = '\n';
481 : } else {
482 66 : if (szLine[i] & 0x80) {
483 : /*non UTF8 (likely some win-CP)*/
484 4 : if ( (szLine[i+1] & 0xc0) != 0x80) {
485 4 : szText[k] = 0xc0 | ( (szLine[i] >> 6) & 0x3 );
486 4 : k++;
487 4 : szLine[i] &= 0xbf;
488 : }
489 : /*we only handle UTF8 chars on 2 bytes (eg first byte is 0b110xxxxx)*/
490 0 : else if ( (szLine[i] & 0xe0) == 0xc0) {
491 0 : szText[k] = szLine[i];
492 0 : i++;
493 0 : k++;
494 : }
495 : }
496 66 : szText[k] = szLine[i];
497 : }
498 67 : k++;
499 : }
500 3 : szText[i-j] = 0;
501 :
502 3 : if (au) {
503 3 : com = gf_sg_command_new(ctx->scene_graph, GF_SG_FIELD_REPLACE);
504 3 : com->node = text;
505 3 : gf_node_register(text, NULL);
506 3 : inf = gf_sg_command_field_new(com);
507 3 : inf->fieldIndex = string.fieldIndex;
508 3 : inf->fieldType = string.fieldType;
509 3 : inf->field_ptr = gf_sg_vrml_field_pointer_new(string.fieldType);
510 3 : gf_list_add(au->commands, com);
511 :
512 3 : gf_sg_vrml_mf_append(inf->field_ptr, GF_SG_VRML_MFSTRING, (void **) &sfstr);
513 3 : sfstr->buffer = gf_strdup(szText);
514 : }
515 : }
516 1 : gf_fclose(sub_in);
517 1 : return e;
518 : }
519 : #endif
520 :
521 :
522 : GF_EXPORT
523 2 : GF_Err gf_sm_import_bifs_subtitle(GF_SceneManager *ctx, GF_ESD *src, GF_MuxInfo *mux)
524 : {
525 : #ifndef GPAC_DISABLE_VRML
526 : GF_Err e;
527 : u32 fmt;
528 2 : e = gf_text_guess_format(mux->file_name, &fmt);
529 2 : if (e) return e;
530 2 : if (!fmt || (fmt>=3)) return GF_NOT_SUPPORTED;
531 :
532 2 : if (fmt==1) return gf_text_import_srt_bifs(ctx, src, mux);
533 1 : else return gf_text_import_sub_bifs(ctx, src, mux);
534 : #else
535 : return GF_NOT_SUPPORTED;
536 : #endif
537 : }
538 :
|