📄 text_to_bifs.c
字号:
default: ptr = szLine; /*FIXME - other styles posssibles ??*/ while (1) { if (!strnicmp(ptr, "<i>", 3)) { italic = 1; ptr += 3; } else if (!strnicmp(ptr, "<u>", 3)) { underlined = 1; ptr += 3; } else if (!strnicmp(ptr, "<b>", 3)) { bold = 1; ptr += 3; } else break; } /*if style remove end markers*/ while ((strlen(ptr)>4) && (ptr[strlen(ptr) - 4] == '<') && (ptr[strlen(ptr) - 1] == '>')) { ptr[strlen(ptr) - 4] = 0; } if (!com) { com = gf_sg_command_new(ctx->scene_graph, GF_SG_FIELD_REPLACE); com->node = text; gf_node_register(text, NULL); inf = gf_sg_command_field_new(com); inf->fieldIndex = string.fieldIndex; inf->fieldType = string.fieldType; inf->field_ptr = gf_sg_vrml_field_pointer_new(string.fieldType); gf_list_add(au->commands, com); } assert(inf); gf_sg_vrml_mf_append(inf->field_ptr, GF_SG_VRML_MFSTRING, (void **) &sfstr); len = 0; for (i=0; i<strlen(ptr); i++) { /*FIXME - UTF16 support !!*/ if (ptr[i] & 0x80) { /*non UTF8 (likely some win-CP)*/ if ((ptr[i+1] & 0xc0) != 0x80) { szText[len] = 0xc0 | ( (ptr[i] >> 6) & 0x3 ); len++; ptr[i] &= 0xbf; } /*we only handle UTF8 chars on 2 bytes (eg first byte is 0b110xxxxx)*/ else if ((ptr[i] & 0xe0) == 0xc0) { szText[len] = ptr[i]; len++; i++; } } szText[len] = ptr[i]; len++; } szText[len] = 0; sfstr->buffer = strdup(szText); break; } }exit: if (e) gf_sm_stream_del(ctx, srt); fclose(srt_in); return e;}static GF_Err gf_text_import_sub_bifs(GF_SceneManager *ctx, GF_ESD *src, GF_MuxInfo *mux){ GF_Err e; GF_Node *text, *font; GF_StreamContext *srt; FILE *sub_in; GF_FieldInfo string, style; u32 start, end, line, i, j, k, len; GF_AUContext *au; GF_Command *com; SFString *sfstr; GF_CommandField *inf; Bool first_samp; Double fps; char szLine[2048], szTime[30], szText[2048]; GF_StreamContext *sc = NULL; if (!ctx->scene_graph) { GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[sub->bifs] base scene not assigned\n")); return GF_BAD_PARAM; } i=0; while ((sc = (GF_StreamContext*)gf_list_enum(ctx->streams, &i))) { if (sc->streamType==GF_STREAM_SCENE) break; sc = NULL; } if (!sc) { GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[sub->bifs] cannot locate base scene\n")); return GF_BAD_PARAM; } if (!mux->textNode) { GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[sub->bifs] target text node unspecified\n")); return GF_BAD_PARAM; } text = gf_sg_find_node_by_name(ctx->scene_graph, mux->textNode); if (!text) { GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[sub->bifs] cannot find target text node %s\n", mux->textNode)); return GF_BAD_PARAM; } if (gf_node_get_field_by_name(text, "string", &string) != GF_OK) { GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[sub->bifs] target text node %s doesn't look like text\n", mux->textNode)); return GF_BAD_PARAM; } font = NULL; if (mux->fontNode) { font = gf_sg_find_node_by_name(ctx->scene_graph, mux->fontNode); if (!font) { GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[sub->bifs] cannot find target font node %s\n", mux->fontNode)); return GF_BAD_PARAM; } if (gf_node_get_field_by_name(font, "style", &style) != GF_OK) { GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[sub->bifs] target font node %s doesn't look like font\n", mux->fontNode)); return GF_BAD_PARAM; } } sub_in = fopen(mux->file_name, "rt"); if (!sub_in) { GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[sub->bifs] cannot open input file %s\n", mux->file_name)); return GF_URL_ERROR; } srt = gf_sm_stream_new(ctx, src->ESID, GF_STREAM_SCENE, 1); if (!srt) return GF_OUT_OF_MEM; if (!src->slConfig) src->slConfig = (GF_SLConfig *) gf_odf_desc_new(GF_ODF_SLC_TAG); src->slConfig->timestampResolution = 1000; if (!src->decoderConfig) src->decoderConfig = (GF_DecoderConfig *) gf_odf_desc_new(GF_ODF_DCD_TAG); src->decoderConfig->streamType = GF_STREAM_SCENE; src->decoderConfig->objectTypeIndication = 1; e = GF_OK; start = end = 0; au = NULL; com = NULL; inf = NULL; fps = 25.0; if (mux->frame_rate) fps = mux->frame_rate; line = 0; first_samp = 1; while (1) { char *sOK = fgets(szLine, 2048, sub_in); if (!sOK) break; REM_TRAIL_MARKS(szLine, "\r\n\t ") line++; len = strlen(szLine); if (!len) continue; i=0; if (szLine[i] != '{') { GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[sub->bifs] Bad frame (line %d): expecting \"{\" got \"%c\"\n", line, szLine[i])); e = GF_NON_COMPLIANT_BITSTREAM; break; } while (szLine[i+1] && szLine[i+1]!='}') { szTime[i] = szLine[i+1]; i++; } szTime[i] = 0; start = atoi(szTime); if (start<end) { 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)); start = end; } j=i+2; i=0; if (szLine[i+j] != '{') { GF_LOG(GF_LOG_ERROR, GF_LOG_PARSER, ("[sub->bifs] Bad frame - expecting \"{\" got \"%c\"\n", szLine[i])); e = GF_NON_COMPLIANT_BITSTREAM; break; } while (szLine[i+1+j] && szLine[i+1+j]!='}') { szTime[i] = szLine[i+1+j]; i++; } szTime[i] = 0; end = atoi(szTime); j+=i+2; if (start>end) { 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)); continue; } if (start && first_samp) { au = gf_sm_stream_au_new(srt, 0, 0, 1); com = gf_sg_command_new(ctx->scene_graph, GF_SG_FIELD_REPLACE); com->node = text; gf_node_register(text, NULL); inf = gf_sg_command_field_new(com); inf->fieldIndex = string.fieldIndex; inf->fieldType = string.fieldType; inf->field_ptr = gf_sg_vrml_field_pointer_new(string.fieldType); gf_list_add(au->commands, com); } k=0; for (i=j; i<len; i++) { if (szLine[i]=='|') { szText[k] = '\n'; } else { if (szLine[i] & 0x80) { /*non UTF8 (likely some win-CP)*/ if ( (szLine[i+1] & 0xc0) != 0x80) { szText[k] = 0xc0 | ( (szLine[i] >> 6) & 0x3 ); k++; szLine[i] &= 0xbf; } /*we only handle UTF8 chars on 2 bytes (eg first byte is 0b110xxxxx)*/ else if ( (szLine[i] & 0xe0) == 0xc0) { szText[k] = szLine[i]; i++; k++; } } szText[k] = szLine[i]; } k++; } szText[i-j] = 0; com = gf_sg_command_new(ctx->scene_graph, GF_SG_FIELD_REPLACE); com->node = text; gf_node_register(text, NULL); inf = gf_sg_command_field_new(com); inf->fieldIndex = string.fieldIndex; inf->fieldType = string.fieldType; inf->field_ptr = gf_sg_vrml_field_pointer_new(string.fieldType); gf_list_add(au->commands, com); gf_sg_vrml_mf_append(inf->field_ptr, GF_SG_VRML_MFSTRING, (void **) &sfstr); sfstr->buffer = strdup(szText); } if (e) gf_sm_stream_del(ctx, srt); fclose(sub_in); return e;}GF_EXPORTGF_Err gf_sm_import_bifs_subtitle(GF_SceneManager *ctx, GF_ESD *src, GF_MuxInfo *mux){ GF_Err e; u32 fmt; e = gf_text_guess_format(mux->file_name, &fmt); if (e) return e; if (!fmt || (fmt>=3)) return GF_NOT_SUPPORTED; if (fmt==1) return gf_text_import_srt_bifs(ctx, src, mux); else return gf_text_import_sub_bifs(ctx, src, mux);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -