📄 fileimport.c
字号:
gf_isom_modify_alternate_brand(mp4, GF_ISOM_BRAND_ISOM, 1);err_exit: if (statsman) gf_sm_stats_del(statsman); gf_sm_del(ctx); gf_sg_del(sg); return e;}/* MPEG-4 chunk encoding*/static u32 GetNbBits(u32 MaxVal){ u32 k=0; while ((s32) MaxVal > ((1<<k)-1) ) k+=1; return k;}GF_Err EncodeBIFSChunk(GF_SceneManager *ctx, char *bifsOutputFile, GF_Err (*AUCallback)(GF_ISOSample *)){ GF_Err e; char *data; u32 data_len; GF_BifsEncoder *bifsenc; GF_InitialObjectDescriptor *iod; u32 i, j, count; GF_StreamContext *sc; GF_ESD *esd; Bool is_in_iod, delete_desc, encode_names, delete_bcfg; GF_BIFSConfig *bcfg; GF_AUContext *au; char szRad[GF_MAX_PATH], *ext; char szName[1024]; FILE *f; strcpy(szRad, bifsOutputFile); ext = strrchr(szRad, '.'); if (ext) ext[0] = 0; /* step3: encoding all AUs in ctx->streams starting at AU index 1 (0 is SceneReplace from previous context) */ bifsenc = gf_bifs_encoder_new(ctx->scene_graph); e = GF_OK; iod = (GF_InitialObjectDescriptor *) ctx->root_od; /*if no iod check we only have one bifs*/ if (!iod) { count = 0; for (i=0; i<gf_list_count(ctx->streams); i++) { sc = gf_list_get(ctx->streams, i); if (sc->streamType == GF_STREAM_OD) count++; } if (!iod && count>1) return GF_NOT_SUPPORTED; } count = gf_list_count(ctx->streams); for (i=0; i<gf_list_count(ctx->streams); i++) { u32 nbb; GF_StreamContext *sc = gf_list_get(ctx->streams, i); esd = NULL; if (sc->streamType != GF_STREAM_SCENE) continue; delete_desc = 0; esd = NULL; is_in_iod = 1; if (iod) { is_in_iod = 0; for (j=0; j<gf_list_count(iod->ESDescriptors); j++) { esd = gf_list_get(iod->ESDescriptors, j); if (esd->decoderConfig && esd->decoderConfig->streamType == GF_STREAM_SCENE) { if (!sc->ESID) sc->ESID = esd->ESID; if (sc->ESID == esd->ESID) { is_in_iod = 1; break; } } /*special BIFS direct import from NHNT*/ else if (gf_list_count(iod->ESDescriptors)==1) { sc->ESID = esd->ESID; is_in_iod = 1; break; } esd = NULL; } } if (!esd) { delete_desc = 1; esd = gf_odf_desc_esd_new(2); gf_odf_desc_del((GF_Descriptor *) esd->decoderConfig->decoderSpecificInfo); esd->decoderConfig->decoderSpecificInfo = NULL; esd->ESID = sc->ESID; esd->decoderConfig->streamType = GF_STREAM_SCENE; } /*should NOT happen (means inputctx is not properly setup)*/ if (!esd->decoderConfig->decoderSpecificInfo) { bcfg = (GF_BIFSConfig*)gf_odf_desc_new(GF_ODF_BIFS_CFG_TAG); delete_bcfg = 1; } /*regular retrieve from ctx*/ else if (esd->decoderConfig->decoderSpecificInfo->tag == GF_ODF_BIFS_CFG_TAG) { bcfg = (GF_BIFSConfig *)esd->decoderConfig->decoderSpecificInfo; delete_bcfg = 0; } /*should not happen either (unless loading from MP4 in which case BIFSc is not decoded)*/ else { bcfg = gf_odf_get_bifs_config(esd->decoderConfig->decoderSpecificInfo, esd->decoderConfig->objectTypeIndication); delete_bcfg = 1; } /*NO CHANGE TO BIFSC otherwise the generated update will not match the input context*/ nbb = GetNbBits(ctx->max_node_id); if (bcfg->nodeIDbits<nbb) fprintf(stdout, "Warning: BIFSConfig.NodeIDBits TOO SMALL\n"); nbb = GetNbBits(ctx->max_route_id); if (bcfg->routeIDbits<nbb) fprintf(stdout, "Warning: BIFSConfig.RouteIDBits TOO SMALL\n"); nbb = GetNbBits(ctx->max_proto_id); if (bcfg->protoIDbits<nbb) fprintf(stdout, "Warning: BIFSConfig.ProtoIDBits TOO SMALL\n"); /*this is the real pb, not stored in cfg or file level, set at EACH replaceScene*/ encode_names = 0; /* The BIFS Config that is passed here should be the BIFSConfig from the IOD */ gf_bifs_encoder_new_stream(bifsenc, sc->ESID, bcfg, encode_names, 0); if (delete_bcfg) gf_odf_desc_del((GF_Descriptor *)bcfg); /*setup MP4 track*/ if (!esd->slConfig) esd->slConfig = (GF_SLConfig *) gf_odf_desc_new(GF_ODF_SLC_TAG); if (sc->timeScale) esd->slConfig->timestampResolution = sc->timeScale; if (!esd->slConfig->timestampResolution) esd->slConfig->timestampResolution = 1000; esd->ESID = sc->ESID; gf_bifs_encoder_get_config(bifsenc, sc->ESID, &data, &data_len); if (esd->decoderConfig->decoderSpecificInfo) gf_odf_desc_del((GF_Descriptor *) esd->decoderConfig->decoderSpecificInfo); esd->decoderConfig->decoderSpecificInfo = (GF_DefaultDescriptor *) gf_odf_desc_new(GF_ODF_DSI_TAG); esd->decoderConfig->decoderSpecificInfo->data = data; esd->decoderConfig->decoderSpecificInfo->dataLength = data_len; esd->decoderConfig->objectTypeIndication = gf_bifs_encoder_get_version(bifsenc, sc->ESID); for (j=1; j<gf_list_count(sc->AUs); j++) { char *data; u32 data_len; au = gf_list_get(sc->AUs, j); e = gf_bifs_encode_au(bifsenc, sc->ESID, au->commands, &data, &data_len); if (data) { sprintf(szName, "%s%02d.bifs", szRad, j); f = fopen(szName, "wb"); fwrite(data, data_len, 1, f); fclose(f); free(data); } } } gf_bifs_encoder_del(bifsenc); return e;}/** * @chunkFile BT chunk to be encoded * @bifs output file name for the BIFS data * @inputContext initial BT upon which the chunk is based (shall not be NULL) * @outputContext: file name to dump the context after applying the new chunk to the input context can be NULL, without .bt * @logFile: can be NULL */GF_Err EncodeFileChunk(char *chunkFile, char *bifs, char *inputContext, char *outputContext, const char *tmpdir) { GF_Err e; GF_SceneGraph *sg; GF_SceneManager *ctx; GF_SceneLoader load; /*Step 1: create context and load input*/ sg = gf_sg_new(); ctx = gf_sm_new(sg); memset(&load, 0, sizeof(GF_SceneLoader)); load.fileName = inputContext; load.ctx = ctx; /*since we're encoding we must get MPEG4 nodes only*/ load.flags = GF_SM_LOAD_MPEG4_STRICT; e = gf_sm_load_init(&load); if (!e) e = gf_sm_load_run(&load); gf_sm_load_done(&load); if (e) { fprintf(stdout, "Cannot load context %s - %s\n", inputContext, gf_error_to_string(e)); goto exit; } /* Step 2: make sure we have only ONE RAP for each stream*/ e = gf_sm_make_random_access(ctx); if (e) goto exit; /*Step 3: loading the chunk into the context*/ memset(&load, 0, sizeof(GF_SceneLoader)); load.fileName = chunkFile; load.ctx = ctx; load.flags = GF_SM_LOAD_MPEG4_STRICT | GF_SM_LOAD_CONTEXT_READY; e = gf_sm_load_init(&load); if (!e) e = gf_sm_load_run(&load); gf_sm_load_done(&load); if (e) { fprintf(stdout, "Cannot load chunk context %s - %s\n", chunkFile, gf_error_to_string(e)); goto exit; } fprintf(stdout, "Context and chunks loaded\n"); /* Assumes that the first AU contains only one command a SceneReplace and that is not part of the current chunk */ /* Last argument is a callback to pass the encoded AUs: not needed here Saving is not handled correctly */ e = EncodeBIFSChunk(ctx, bifs, NULL); if (e) goto exit; if (outputContext) { u32 d_mode, do_enc; char szF[GF_MAX_PATH], *ext; /*make random access for storage*/ e = gf_sm_make_random_access(ctx); if (e) goto exit; /*check if we dump to BT, XMT or encode to MP4*/ strcpy(szF, outputContext); ext = strrchr(szF, '.'); d_mode = GF_SM_DUMP_BT; do_enc = 0; if (ext) { if (!stricmp(ext, ".xmt") || !stricmp(ext, ".xmta")) d_mode = GF_SM_DUMP_XMTA; else if (!stricmp(ext, ".mp4")) do_enc = 1; ext[0] = 0; } if (do_enc) { GF_ISOFile *mp4; strcat(szF, ".mp4"); mp4 = gf_isom_open(szF, GF_ISOM_WRITE_EDIT, tmpdir); e = gf_sm_encode_to_file(ctx, mp4, NULL); if (e) gf_isom_delete(mp4); else gf_isom_close(mp4); } else e = gf_sm_dump(ctx, szF, d_mode); }exit: if (ctx) { sg = ctx->scene_graph; gf_sm_del(ctx); gf_sg_del(sg); } return e;}#include <gpac/xml.h>void sax_node_start(void *sax_cbck, const char *node_name, const char *name_space, const GF_XMLAttribute *attributes, u32 nb_attributes){ char szCheck[100]; GF_List *imports = sax_cbck; GF_XMLAttribute *att; u32 i=0; /*do not process hyperlinks*/ if (!strcmp(node_name, "a") || !strcmp(node_name, "Anchor")) return; for (i=0; i<nb_attributes;i++) { att = (GF_XMLAttribute *) &attributes[i]; if (stricmp(att->name, "xlink:href") && stricmp(att->name, "url")) continue; if (att->value[0]=='#') continue; if (!strnicmp(att->value, "od:", 3)) continue; sprintf(szCheck, "%d", atoi(att->value)); if (!strcmp(szCheck, att->value)) continue; gf_list_add(imports, strdup(att->value) ); }}GF_ISOFile *package_file(char *file_name, char *fcc, const char *tmpdir){ GF_ISOFile *file = NULL; GF_Err e; GF_SAXParser *sax; GF_List *imports; Bool ascii; char *isom_src = NULL; u32 i, count, mtype; char *type; type = gf_xml_get_root_type(file_name, &e); if (!type) { fprintf(stdout, "Cannot process XML file %s: %s\n", file_name, gf_error_to_string(e) ); return NULL; } imports = gf_list_new(); sax = gf_xml_sax_new(sax_node_start, NULL, NULL, imports); e = gf_xml_sax_parse_file(sax, file_name, NULL); ascii = !gf_xml_sax_binary_file(sax); gf_xml_sax_del(sax); if (e<0) goto exit; e = GF_OK; if (fcc) { mtype = GF_4CC(fcc[0],fcc[1],fcc[2],fcc[3]); } else { mtype = 0; if (!stricmp(type, "svg")) mtype = ascii ? GF_4CC('s','v','g',' ') : GF_4CC('s','v','g','z'); else if (!stricmp(type, "smil")) mtype = ascii ? GF_4CC('s','m','i','l') : GF_4CC('s','m','l','z'); else if (!stricmp(type, "x3d")) mtype = ascii ? GF_4CC('x','3','d',' ') : GF_4CC('x','3','d','z') ; else if (!stricmp(type, "xmt-a")) mtype = ascii ? GF_4CC('x','m','t','a') : GF_4CC('x','m','t','z'); } if (!mtype) { fprintf(stdout, "Missing 4CC code for meta name - please use ABCD:fileName\n"); e = GF_BAD_PARAM; goto exit; } count = gf_list_count(imports); for (i=0; i<count; i++) { char *item = gf_list_get(imports, i); FILE *test = fopen(item, "rb"); if (!test) { gf_list_rem(imports, i); i--; count--; free(item); continue; } fclose(test); if (gf_isom_probe_file(item)) { if (isom_src) { fprintf(stdout, "Cannot package several IsoMedia files together\n"); e = GF_NOT_SUPPORTED; goto exit; } gf_list_rem(imports, i); i--; count--; isom_src = item; continue; } } if (isom_src) { file = gf_isom_open(isom_src, GF_ISOM_OPEN_EDIT, tmpdir); } else { file = gf_isom_open("package", GF_ISOM_WRITE_EDIT, tmpdir); } e = gf_isom_set_meta_type(file, 1, 0, mtype); if (e) goto exit; /*add self ref*/ if (isom_src) { e = gf_isom_add_meta_item(file, 1, 0, 1, NULL, isom_src, NULL, NULL, NULL, NULL); if (e) goto exit; } e = gf_isom_set_meta_xml(file, 1, 0, file_name, !ascii); if (e) goto exit; count = gf_list_count(imports); for (i=0; i<count; i++) { char *ext, *mime, *encoding; char *item = gf_list_get(imports, i); mime = encoding = NULL; ext = strrchr(item, '.'); if (!stricmp(ext, ".gz")) ext = strrchr(ext-1, '.'); if (!stricmp(ext, ".jpg") || !stricmp(ext, ".jpeg")) mime = "image/jpeg"; else if (!stricmp(ext, ".png")) mime = "image/png"; else if (!stricmp(ext, ".svg")) mime = "image/svg+xml"; else if (!stricmp(ext, ".x3d")) mime = "model/x3d+xml"; else if (!stricmp(ext, ".xmt")) mime = "application/x-xmt"; else if (!stricmp(ext, ".svgz") || !stricmp(ext, ".svg.gz")) { mime = "image/svg+xml"; encoding = "binary-gzip"; } else if (!stricmp(ext, ".x3dz") || !stricmp(ext, ".x3d.gz")) { mime = "model/x3d+xml"; encoding = "binary-gzip"; } else if (!stricmp(ext, ".xmtz") || !stricmp(ext, ".xmt.gz")) { mime = "application/x-xmt"; encoding = "binary-gzip"; } e = gf_isom_add_meta_item(file, 1, 0, 0, item, item, mime, NULL, NULL, NULL); if (e) goto exit; }exit: while (gf_list_count(imports)) { char *item = gf_list_last(imports); gf_list_rem_last(imports); free(item); } gf_list_del(imports); if (isom_src) free(isom_src); if (type) free(type); if (e) { if (file) gf_isom_delete(file); return NULL; } return file;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -