📄 fileimport.c
字号:
char *name; u64 chap_time; gf_isom_get_chapter(mp4, 0, i+1, &chap_time, (const char **) &name); max_dts = (Double) (s64) chap_time; max_dts /= 1000; if (max_dts<cur_file_time) continue; if (max_dts>cur_file_time+file_split_dur) break; max_dts-=cur_file_time; chap_time = (u64) (max_dts*1000); gf_isom_add_chapter(dest, 0, chap_time, name); /*add prev*/ if (do_add && i) { gf_isom_get_chapter(mp4, 0, i, &chap_time, (const char **) &name); gf_isom_add_chapter(dest, 0, 0, name); do_add = 0; } } cur_file_time += file_split_dur; if (conv_type==1) gf_media_make_isma(dest, 1, 0, 0); else if (conv_type==2) gf_media_make_3gpp(dest); if (InterleavingTime) { gf_isom_make_interleave(dest, InterleavingTime); } else { gf_isom_set_storage_mode(dest, GF_ISOM_STORE_STREAMABLE); } gf_isom_clone_pl_indications(mp4, dest); e = gf_isom_close(dest); dest = NULL; if (e) fprintf(stdout, "Error storing file %s\n", gf_error_to_string(e)); if (is_last || chunk_extraction) break; cur_file++; } gf_set_progress("Splitting", nb_samp, nb_samp);err_exit: if (dest) gf_isom_delete(dest); free(tks); return e;}GF_Err cat_multiple_files(GF_ISOFile *dest, char *fileName, u32 import_flags, Double force_fps, u32 frames_per_sample, char *tmp_dir);GF_Err cat_isomedia_file(GF_ISOFile *dest, char *fileName, u32 import_flags, Double force_fps, u32 frames_per_sample, char *tmp_dir){ u32 i, j, count, nb_tracks, nb_samp, nb_done; GF_ISOFile *orig; GF_Err e; Float ts_scale; Double dest_orig_dur; u32 dst_tk, tk_id, mtype; u64 insert_dts, skip_until_dts; GF_ISOSample *samp; if (strchr(fileName, '*')) return cat_multiple_files(dest, fileName, import_flags, force_fps, frames_per_sample, tmp_dir); e = GF_OK; if (!gf_isom_probe_file(fileName)) { orig = gf_isom_open("temp", GF_ISOM_WRITE_EDIT, tmp_dir); e = import_file(orig, fileName, import_flags, force_fps, frames_per_sample); if (e) return e; } else { orig = gf_isom_open(fileName, GF_ISOM_OPEN_READ, NULL); } nb_samp = 0; nb_tracks = gf_isom_get_track_count(orig); for (i=0; i<nb_tracks; i++) { u32 mtype = gf_isom_get_media_type(orig, i+1); switch (mtype) { case GF_ISOM_MEDIA_HINT: case GF_ISOM_MEDIA_OD: case GF_ISOM_MEDIA_FLASH: fprintf(stdout, "WARNING: Track ID %d (type %s) not handled by concatenation - removing from destination\n", gf_isom_get_track_id(orig, i+1), gf_4cc_to_str(mtype)); continue; case GF_ISOM_MEDIA_AUDIO: case GF_ISOM_MEDIA_TEXT: case GF_ISOM_MEDIA_VISUAL: case GF_ISOM_MEDIA_SCENE: case GF_ISOM_MEDIA_OCR: case GF_ISOM_MEDIA_OCI: case GF_ISOM_MEDIA_IPMP: case GF_ISOM_MEDIA_MPEGJ: case GF_ISOM_MEDIA_MPEG7: default: /*only cat self-contained files*/ if (gf_isom_is_self_contained(orig, i+1, 1)) { nb_samp+= gf_isom_get_sample_count(orig, i+1); break; } break; } } if (!nb_samp) { fprintf(stdout, "No suitable media tracks to cat in %s - skipping\n", fileName); goto err_exit; } dest_orig_dur = (Double) (s64) gf_isom_get_duration(dest); dest_orig_dur /= gf_isom_get_timescale(dest); fprintf(stdout, "Appending file %s\n", fileName); nb_done = 0; for (i=0; i<nb_tracks; i++) { u64 last_DTS; Bool use_ts_dur = 1; mtype = gf_isom_get_media_type(orig, i+1); switch (mtype) { case GF_ISOM_MEDIA_HINT: case GF_ISOM_MEDIA_OD: case GF_ISOM_MEDIA_FLASH: continue; case GF_ISOM_MEDIA_TEXT: case GF_ISOM_MEDIA_SCENE: use_ts_dur = 0; case GF_ISOM_MEDIA_AUDIO: case GF_ISOM_MEDIA_VISUAL: case GF_ISOM_MEDIA_OCR: case GF_ISOM_MEDIA_OCI: case GF_ISOM_MEDIA_IPMP: case GF_ISOM_MEDIA_MPEGJ: case GF_ISOM_MEDIA_MPEG7: default: if (!gf_isom_is_self_contained(orig, i+1, 1)) continue; break; } dst_tk = 0; tk_id = gf_isom_get_track_id(orig, i+1); dst_tk = gf_isom_get_track_by_id(dest, tk_id); if (dst_tk) { if (!gf_isom_is_same_sample_description(orig, i+1, dest, dst_tk)) dst_tk = 0; else if (mtype==GF_ISOM_MEDIA_VISUAL) { u32 w, h, ow, oh; gf_isom_get_visual_info(orig, i+1, 1, &ow, &oh); gf_isom_get_visual_info(dest, dst_tk, 1, &w, &h); if ((ow!=w) || (oh!=h)) dst_tk = 0; } } if (!dst_tk) { for (j=0; j<gf_isom_get_track_count(dest); j++) { if (mtype != gf_isom_get_media_type(dest, j+1)) continue; if (gf_isom_is_same_sample_description(orig, i+1, dest, j+1)) { if (mtype==GF_ISOM_MEDIA_VISUAL) { u32 w, h, ow, oh; gf_isom_get_visual_info(orig, i+1, 1, &ow, &oh); gf_isom_get_visual_info(dest, j+1, 1, &w, &h); if ((ow==w) && (oh==h)) { dst_tk = j+1; break; } } else { dst_tk = j+1; break; } } } } /*looks like a new file*/ if (!dst_tk) { fprintf(stdout, "No suitable destination track found - creating new one (type %s)\n", gf_4cc_to_str(mtype)); e = gf_isom_clone_track(orig, i+1, dest, 1, &dst_tk); if (e) goto err_exit; gf_isom_clone_pl_indications(orig, dest); /*remove any edit stuff that could have been copied over*/ gf_isom_remove_edit_segments(dest, dst_tk); } count = gf_isom_get_sample_count(dest, dst_tk); if (use_ts_dur && (count>1)) { insert_dts = 2*gf_isom_get_sample_dts(dest, dst_tk, count) - gf_isom_get_sample_dts(dest, dst_tk, count-1); } else { insert_dts = gf_isom_get_media_duration(dest, dst_tk); if (!count) insert_dts = 0; } ts_scale = (Float) gf_isom_get_media_timescale(dest, dst_tk); ts_scale /= gf_isom_get_media_timescale(orig, i+1); skip_until_dts = 0; if (gf_isom_get_edit_segment_count(orig, i+1)) { u64 editTime, segmentDuration, mediaTime; u8 editMode; gf_isom_get_edit_segment(orig, i+1, 1, &editTime, &segmentDuration, &mediaTime, &editMode); if (editMode == GF_ISOM_EDIT_EMPTY) { Double offset = (Double) (s64)segmentDuration * gf_isom_get_media_timescale(orig, i+1); offset /= gf_isom_get_timescale(orig); insert_dts += (u64) (offset*ts_scale); } else if (editMode == GF_ISOM_EDIT_NORMAL) { skip_until_dts = mediaTime; } } last_DTS = 0; count = gf_isom_get_sample_count(orig, i+1); for (j=0; j<count; j++) { u32 di; samp = gf_isom_get_sample(orig, i+1, j+1, &di); if (skip_until_dts) { if (skip_until_dts > samp->DTS) { gf_isom_sample_del(&samp); continue; } samp->DTS -= skip_until_dts; } last_DTS = samp->DTS; samp->DTS = (u64) (ts_scale * (s64)samp->DTS) + insert_dts; samp->CTS_Offset = (u32) (samp->CTS_Offset * ts_scale); if (gf_isom_is_self_contained(orig, i+1, di)) { e = gf_isom_add_sample(dest, dst_tk, di, samp); } else { u64 offset; GF_ISOSample *s = gf_isom_get_sample_info(orig, i+1, j+1, &di, &offset); e = gf_isom_add_sample_reference(dest, dst_tk, di, samp, offset); gf_isom_sample_del(&s); } gf_isom_sample_del(&samp); if (e) goto err_exit; gf_set_progress("Appending", nb_done, nb_samp); nb_done++; } /*scene description and text: compute last sample duration based on original media duration*/ if (!use_ts_dur) { insert_dts = gf_isom_get_media_duration(orig, i+1) - last_DTS; gf_isom_set_last_sample_duration(dest, dst_tk, (u32) insert_dts); } } gf_set_progress("Appending", nb_samp, nb_samp); /*check chapters*/ for (i=0; i<gf_isom_get_chapter_count(orig, 0); i++) { char *name; Double c_time; u64 chap_time; gf_isom_get_chapter(orig, 0, i+1, &chap_time, (const char **) &name); c_time = (Double) (s64) chap_time; c_time /= 1000; c_time += dest_orig_dur; /*check last file chapter*/ if (!i && gf_isom_get_chapter_count(dest, 0)) { const char *last_name; u64 last_chap_time; gf_isom_get_chapter(dest, 0, gf_isom_get_chapter_count(dest, 0), &last_chap_time, &last_name); /*last and first chapters are the same, don't duplicate*/ if (last_name && name && !stricmp(last_name, name)) continue; } chap_time = (u64) (c_time*1000); gf_isom_add_chapter(dest, 0, chap_time, name); }err_exit: gf_isom_delete(orig); return e;}typedef struct{ char szPath[GF_MAX_PATH]; char szRad1[1024], szRad2[1024], szOpt[200]; GF_ISOFile *dest; u32 import_flags; Double force_fps; u32 frames_per_sample; char *tmp_dir;} CATEnum;Bool cat_enumerate(void *cbk, char *szName, char *szPath){ GF_Err e; u32 len_rad1; char szFileName[GF_MAX_PATH]; CATEnum *cat_enum = (CATEnum *)cbk; len_rad1 = strlen(cat_enum->szRad1); if (strnicmp(szName, cat_enum->szRad1, len_rad1)) return 0; if (strlen(cat_enum->szRad2) && !strstr(szName + len_rad1, cat_enum->szRad2) ) return 0; strcpy(szFileName, szName); strcat(szFileName, cat_enum->szOpt); e = cat_isomedia_file(cat_enum->dest, szFileName, cat_enum->import_flags, cat_enum->force_fps, cat_enum->frames_per_sample, cat_enum->tmp_dir); if (e) return 1; return 0;}GF_Err cat_multiple_files(GF_ISOFile *dest, char *fileName, u32 import_flags, Double force_fps, u32 frames_per_sample, char *tmp_dir){ CATEnum cat_enum; char *sep; cat_enum.dest = dest; cat_enum.import_flags = import_flags; cat_enum.force_fps = force_fps; cat_enum.frames_per_sample = frames_per_sample; cat_enum.tmp_dir = tmp_dir; strcpy(cat_enum.szPath, fileName); sep = strrchr(cat_enum.szPath, GF_PATH_SEPARATOR); if (!sep) sep = strrchr(cat_enum.szPath, '/'); if (!sep) { strcpy(cat_enum.szPath, "."); strcpy(cat_enum.szRad1, fileName); } else { strcpy(cat_enum.szRad1, sep+1); sep[0] = 0; } sep = strchr(cat_enum.szRad1, '*'); strcpy(cat_enum.szRad2, sep+1); sep[0] = 0; sep = strchr(cat_enum.szRad2, '%'); if (!sep) sep = strchr(cat_enum.szRad2, '#'); if (!sep) sep = strchr(cat_enum.szRad2, ':'); strcpy(cat_enum.szOpt, ""); if (sep) { strcpy(cat_enum.szOpt, sep); sep[0] = 0; } return gf_enum_directory(cat_enum.szPath, 0, cat_enumerate, &cat_enum, NULL);}/* MPEG-4 encoding*/GF_Err EncodeFile(char *in, GF_ISOFile *mp4, GF_SMEncodeOptions *opts, FILE *logs) { GF_Err e; GF_SceneLoader load; GF_SceneManager *ctx; GF_SceneGraph *sg; GF_StatManager *statsman = NULL; sg = gf_sg_new(); ctx = gf_sm_new(sg); memset(&load, 0, sizeof(GF_SceneLoader)); load.fileName = in; load.ctx = ctx; load.swf_import_flags = swf_flags; load.swf_flatten_limit = swf_flatten_angle; /*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<0) { gf_sm_load_done(&load); fprintf(stdout, "Cannot load context - %s\n", gf_error_to_string(e)); goto err_exit; } e = gf_sm_load_run(&load); gf_sm_load_done(&load); if (opts->auto_qant) { fprintf(stdout, "Analysing Scene for Automatic Quantization\n"); statsman = gf_sm_stats_new(); e = gf_sm_stats_for_scene(statsman, ctx); if (!e) { GF_SceneStatistics *stats = gf_sm_stats_get(statsman); if (opts->resolution > (s32)stats->frac_res_2d) { fprintf(stdout, " Given resolution %d is (unnecessarily) too high, using %d instead.\n", opts->resolution, stats->frac_res_2d); opts->resolution = stats->frac_res_2d; } else if (stats->int_res_2d + opts->resolution <= 0) { fprintf(stdout, " Given resolution %d is too low, using %d instead.\n", opts->resolution, stats->int_res_2d - 1); opts->resolution = 1 - stats->int_res_2d; } opts->coord_bits = stats->int_res_2d + opts->resolution; fprintf(stdout, " Coordinates & Lengths encoded using "); if (opts->resolution < 0) fprintf(stdout, "only the %d most significant bits (of %d).\n", opts->coord_bits, stats->int_res_2d); else fprintf(stdout, "a %d.%d representation\n", stats->int_res_2d, opts->resolution); fprintf(stdout, " Matrix Scale & Skew Coefficients "); if (opts->coord_bits < stats->scale_int_res_2d) { opts->scale_bits = stats->scale_int_res_2d - opts->coord_bits; fprintf(stdout, "encoded using a %d.8 representation\n", stats->scale_int_res_2d); } else { opts->scale_bits = 0; fprintf(stdout, "not encoded.\n"); } } } if (e) { fprintf(stdout, "Error loading file %s\n", gf_error_to_string(e)); goto err_exit; } else { u32 prev_level = gf_log_get_level(); u32 prev_tools = gf_log_get_tools(); gf_log_cbk prev_logs = NULL; if (logs) { gf_log_set_tools(GF_LOG_CODING); gf_log_set_level(GF_LOG_DEBUG); prev_logs = gf_log_set_callback(logs, scene_coding_log); } e = gf_sm_encode_to_file(ctx, mp4, opts); if (logs) { gf_log_set_tools(prev_tools); gf_log_set_level(prev_level); gf_log_set_callback(NULL, prev_logs); } } gf_isom_set_brand_info(mp4, GF_ISOM_BRAND_MP42, 1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -