in applications/mp4box/main.c [1735:4717]
int mp4boxMain(int argc, char **argv)
{
char outfile[5000];
GF_Err e;
#ifndef GPAC_DISABLE_SCENE_ENCODER
GF_SMEncodeOptions opts;
#endif
SDPLine *sdp_lines = NULL;
Double interleaving_time, split_duration, split_start, import_fps, dash_duration, dash_subduration;
MetaAction *metas = NULL;
TrackAction *tracks = NULL;
TSELAction *tsel_acts = NULL;
u64 movie_time, initial_tfdt;
s32 subsegs_per_sidx;
u32 *brand_add = NULL;
u32 *brand_rem = NULL;
GF_DashSwitchingMode bitstream_switching_mode = GF_DASH_BSMODE_DEFAULT;
u32 i, stat_level, hint_flags, info_track_id, import_flags, nb_add, nb_cat, crypt, agg_samples, nb_sdp_ex, max_ptime, raw_sample_num, split_size, nb_meta_act, nb_track_act, rtp_rate, major_brand, nb_alt_brand_add, nb_alt_brand_rem, old_interleave, car_dur, minor_version, conv_type, nb_tsel_acts, program_number, dump_nal, time_shift_depth, initial_moof_sn, dump_std, import_subtitle;
GF_DashDynamicMode dash_mode=GF_DASH_STATIC;
#ifndef GPAC_DISABLE_SCENE_DUMP
GF_SceneDumpFormat dump_mode;
#endif
Double mpd_live_duration = 0;
Bool HintIt, needSave, FullInter, Frag, HintInter, dump_rtp, regular_iod, remove_sys_tracks, remove_hint, force_new, remove_root_od;
Bool print_sdp, print_info, open_edit, dump_isom, dump_cr, force_ocr, encode, do_log, do_flat, dump_srt, dump_ttxt, dump_timestamps, do_saf, dump_m2ts, dump_cart, do_hash, verbose, force_cat, align_cat, pack_wgt, single_group, dash_live, no_fragments_defaults, single_traf_per_moof;
char *inName, *outName, *arg, *mediaSource, *tmpdir, *input_ctx, *output_ctx, *drm_file, *avi2raw, *cprt, *chap_file, *pes_dump, *itunes_tags, *pack_file, *raw_cat, *seg_name, *dash_ctx_file;
u32 track_dump_type;
u32 trackID;
Double min_buffer = 1.5;
s32 ast_offset_ms = 0;
u32 dump_chap = 0;
u32 dump_udta_type = 0;
u32 dump_udta_track = 0;
char **mpd_base_urls = NULL;
u32 nb_mpd_base_urls=0;
u32 dash_scale = 1000;
Bool insert_utc = GF_FALSE;
#ifndef GPAC_DISABLE_MPD
Bool do_mpd = 0;
#endif
#ifndef GPAC_DISABLE_SCENE_ENCODER
Bool chunk_mode=0;
#endif
#ifndef GPAC_DISABLE_ISOM_HINTING
Bool HintCopy=0;
u32 MTUSize = 1450;
#endif
GF_ISOFile *file;
Bool frag_real_time = 0;
Double mpd_update_time = 0;
Bool stream_rtp=0;
Bool force_co64 = GF_FALSE;
Bool live_scene=0;
Bool enable_mem_tracker = 0;
Bool dump_iod=0;
Bool pssh_in_moof=0;
Bool samplegroups_in_traf=0;
Bool daisy_chain_sidx=0;
Bool single_segment=0;
Bool single_file=0;
Bool segment_timeline=0;
u32 segment_marker = 0;
GF_DashProfile dash_profile = GF_DASH_PROFILE_UNKNOWN;
const char *dash_profile_extension = NULL;
Bool use_url_template=0;
Bool seg_at_rap=0;
Bool frag_at_rap=0;
Bool adjust_split_end = 0;
Bool memory_frags = 1;
Bool keep_utc = 0;
Bool do_bin_nhml = 0;
u32 timescale = 0;
const char *do_wget = NULL;
GF_DashSegmenterInput *dash_inputs = NULL;
u32 nb_dash_inputs = 0;
char *gf_logs = NULL;
char *seg_ext = NULL;
const char *dash_title = NULL;
const char *dash_source = NULL;
const char *dash_more_info = NULL;
#if !defined(GPAC_DISABLE_STREAMING)
const char *grab_m2ts = NULL;
const char *grab_ifce = NULL;
#endif
FILE *logfile = NULL;
nb_tsel_acts = nb_add = nb_cat = nb_track_act = nb_sdp_ex = max_ptime = raw_sample_num = nb_meta_act = rtp_rate = major_brand = nb_alt_brand_add = nb_alt_brand_rem = car_dur = minor_version = 0;
e = GF_OK;
split_duration = 0.0;
split_start = -1.0;
interleaving_time = 0.0;
dash_duration = dash_subduration = 0.0;
import_fps = 0;
import_flags = 0;
split_size = 0;
movie_time = 0;
dump_nal = 0;
FullInter = HintInter = encode = do_log = old_interleave = do_saf = do_hash = verbose = 0;
#ifndef GPAC_DISABLE_SCENE_DUMP
dump_mode = GF_SM_DUMP_NONE;
#endif
Frag = force_ocr = remove_sys_tracks = agg_samples = remove_hint = keep_sys_tracks = remove_root_od = single_group = 0;
conv_type = HintIt = needSave = print_sdp = print_info = regular_iod = dump_std = open_edit = dump_isom = dump_rtp = dump_cr = dump_srt = dump_ttxt = force_new = dump_timestamps = dump_m2ts = dump_cart = import_subtitle = force_cat = pack_wgt = dash_live = 0;
no_fragments_defaults = 0;
single_traf_per_moof = 0,
/*align cat is the new default behaviour for -cat*/
align_cat = 1;
subsegs_per_sidx = 0;
track_dump_type = 0;
crypt = 0;
time_shift_depth = 0;
file = NULL;
itunes_tags = pes_dump = NULL;
seg_name = dash_ctx_file = NULL;
initial_moof_sn = 0;
initial_tfdt = 0;
#ifndef GPAC_DISABLE_SCENE_ENCODER
memset(&opts, 0, sizeof(opts));
#endif
trackID = stat_level = hint_flags = 0;
program_number = 0;
info_track_id = 0;
do_flat = 0;
inName = outName = mediaSource = input_ctx = output_ctx = drm_file = avi2raw = cprt = chap_file = pack_file = raw_cat = NULL;
#ifndef GPAC_DISABLE_SWF_IMPORT
swf_flags = GF_SM_SWF_SPLIT_TIMELINE;
#endif
swf_flatten_angle = 0.0f;
tmpdir = NULL;
for (i = 1; i < (u32) argc ; i++) {
if (!strcmp(argv[i], "-mem-track")) {
#ifdef GPAC_MEMORY_TRACKING
enable_mem_tracker = 1;
#else
fprintf(stderr, "WARNING - GPAC not compiled with Memory Tracker - ignoring \"-mem-track\"\n");
#endif
break;
}
}
/*init libgpac*/
gf_sys_init(enable_mem_tracker);
if (argc < 2) {
PrintUsage();
MP4BOX_EXIT_WITH_CODE(1);
}
/*parse our args*/
for (i = 1; i < (u32) argc ; i++) {
arg = argv[i];
/*input file(s)*/
if ((arg[0] != '-') || !stricmp(arg, "--")) {
char *arg_val = arg;
if (!stricmp(arg, "--")) {
CHECK_NEXT_ARG
arg_val = argv[i+1];
i++;
}
if (argc < 3) {
fprintf(stderr, "Error - only one input file found as argument, please check usage\n");
MP4BOX_EXIT_WITH_CODE(1);
} else if (inName) {
if (dash_duration) {
if (!nb_dash_inputs) {
dash_inputs = set_dash_input(dash_inputs, inName, &nb_dash_inputs);
}
dash_inputs = set_dash_input(dash_inputs, arg_val, &nb_dash_inputs);
} else {
fprintf(stderr, "Error - 2 input names specified, please check usage\n");
MP4BOX_EXIT_WITH_CODE(1);
}
} else {
inName = arg_val;
}
}
else if (!stricmp(arg, "-?")) {
PrintUsage();
MP4BOX_EXIT_WITH_CODE(0);
}
else if (!stricmp(arg, "-version")) {
PrintVersion();
MP4BOX_EXIT_WITH_CODE(0);
}
else if (!stricmp(arg, "-sdp")) print_sdp = 1;
else if (!stricmp(arg, "-quiet")) quiet = 2;
else if (!strcmp(argv[i], "-mem-track")) continue;
else if (!stricmp(arg, "-logs")) {
CHECK_NEXT_ARG
gf_logs = argv[i+1];
if (gf_logs)
gf_log_set_tools_levels(gf_logs);
i++;
}
else if (!strcmp(arg, "-log-file") || !strcmp(arg, "-lf")) {
logfile = gf_fopen(argv[i+1], "wt");
gf_log_set_callback(logfile, on_gpac_log);
i++;
}
else if (!stricmp(arg, "-noprog")) quiet = 1;
else if (!stricmp(arg, "-info")) {
print_info = 1;
if ((i+1<(u32) argc) && (sscanf(argv[i+1], "%u", &info_track_id)==1)) {
char szTk[20];
sprintf(szTk, "%u", info_track_id);
if (!strcmp(szTk, argv[i+1])) i++;
else info_track_id=0;
} else {
info_track_id=0;
}
}
#if !defined(GPAC_DISABLE_STREAMING)
else if (!stricmp(arg, "-grab-ts")) {
CHECK_NEXT_ARG
grab_m2ts = argv[i+1];
i++;
}
else if (!stricmp(arg, "-ifce")) {
CHECK_NEXT_ARG
grab_ifce = argv[i+1];
i++;
}
#endif
#if !defined(GPAC_DISABLE_CORE_TOOLS)
else if (!stricmp(arg, "-wget")) {
CHECK_NEXT_ARG
do_wget = argv[i+1];
i++;
}
#endif
/*******************************************************************************/
else if (!stricmp(arg, "-dvbhdemux")) {
dvbhdemux = 1;
}
/********************************************************************************/
#ifndef GPAC_DISABLE_MEDIA_EXPORT
else if (!stricmp(arg, "-raw")) {
CHECK_NEXT_ARG
track_dump_type = create_new_track_action(argv[i+1], &tracks, &nb_track_act, GF_EXPORT_NATIVE);
i++;
}
else if (!stricmp(arg, "-raw-layer")) {
CHECK_NEXT_ARG
track_dump_type = create_new_track_action(argv[i+1], &tracks, &nb_track_act, GF_EXPORT_NATIVE | GF_EXPORT_SVC_LAYER);
i++;
}
else if (!stricmp(arg, "-qcp")) {
CHECK_NEXT_ARG
track_dump_type = create_new_track_action(argv[i+1], &tracks, &nb_track_act, GF_EXPORT_NATIVE | GF_EXPORT_USE_QCP);
i++;
}
else if (!stricmp(arg, "-aviraw")) {
CHECK_NEXT_ARG
if (argv[i+1] && !stricmp(argv[i+1], "video")) trackID = 1;
else if (argv[i+1] && !stricmp(argv[i+1], "audio")) {
if (strlen(argv[i+1])==5) trackID = 2;
else trackID = 1 + atoi(argv[i+1] + 5);
}
else {
fprintf(stderr, "Usage: \"-aviraw video\" or \"-aviraw audio\"\n");
MP4BOX_EXIT_WITH_CODE(1);
}
track_dump_type = GF_EXPORT_AVI_NATIVE;
i++;
}
else if (!stricmp(arg, "-raws")) {
CHECK_NEXT_ARG
track_dump_type = create_new_track_action(argv[i+1], &tracks, &nb_track_act, GF_EXPORT_RAW_SAMPLES);
i++;
}
else if (!stricmp(arg, "-nhnt")) {
CHECK_NEXT_ARG
track_dump_type = create_new_track_action(argv[i+1], &tracks, &nb_track_act, GF_EXPORT_NHNT);
i++;
}
else if (!stricmp(arg, "-nhml")) {
CHECK_NEXT_ARG
track_dump_type = create_new_track_action(argv[i+1], &tracks, &nb_track_act, GF_EXPORT_NHML);
i++;
}
else if (!stricmp(arg, "-webvtt-raw")) {
CHECK_NEXT_ARG
track_dump_type = create_new_track_action(argv[i+1], &tracks, &nb_track_act, GF_EXPORT_WEBVTT_META);
i++;
}
else if (!stricmp(arg, "-six")) {
CHECK_NEXT_ARG
track_dump_type = create_new_track_action(argv[i+1], &tracks, &nb_track_act, GF_EXPORT_SIX);
i++;
}
else if (!stricmp(arg, "-avi")) {
CHECK_NEXT_ARG
track_dump_type = create_new_track_action(argv[i+1], &tracks, &nb_track_act, GF_EXPORT_AVI);
i++;
}
#endif /*GPAC_DISABLE_MEDIA_EXPORT*/
#if !defined(GPAC_DISABLE_STREAMING) && !defined(GPAC_DISABLE_SENG)
else if (!stricmp(arg, "-rtp")) {
stream_rtp = 1;
}
else if (!stricmp(arg, "-live")) {
live_scene = 1;
}
#endif
else if (!stricmp(arg, "-diod")) {
dump_iod = 1;
}
#ifndef GPAC_DISABLE_VRML
else if (!stricmp(arg, "-node")) {
CHECK_NEXT_ARG PrintNode(argv[i+1], 0);
MP4BOX_EXIT_WITH_CODE(0);
}
else if (!stricmp(arg, "-xnode")) {
CHECK_NEXT_ARG PrintNode(argv[i+1], 1);
MP4BOX_EXIT_WITH_CODE(0);
}
else if (!stricmp(arg, "-nodes")) {
PrintBuiltInNodes(0);
MP4BOX_EXIT_WITH_CODE(0);
}
else if (!stricmp(arg, "-xnodes")) {
PrintBuiltInNodes(1);
MP4BOX_EXIT_WITH_CODE(0);
}
#endif
#ifndef GPAC_DISABLE_SVG
else if (!stricmp(arg, "-snode")) {
CHECK_NEXT_ARG PrintNode(argv[i+1], 2);
MP4BOX_EXIT_WITH_CODE(0);
}
else if (!stricmp(arg, "-snodes")) {
PrintBuiltInNodes(2);
MP4BOX_EXIT_WITH_CODE(0);
}
#endif
else if (!stricmp(arg, "-std")) dump_std = 2;
else if (!stricmp(arg, "-stdb")) dump_std = 1;
#if !defined(GPAC_DISABLE_MEDIA_EXPORT) && !defined(GPAC_DISABLE_SCENE_DUMP)
else if (!stricmp(arg, "-bt")) dump_mode = GF_SM_DUMP_BT;
else if (!stricmp(arg, "-xmt")) dump_mode = GF_SM_DUMP_XMTA;
else if (!stricmp(arg, "-wrl")) dump_mode = GF_SM_DUMP_VRML;
else if (!stricmp(arg, "-x3dv")) dump_mode = GF_SM_DUMP_X3D_VRML;
else if (!stricmp(arg, "-x3d")) dump_mode = GF_SM_DUMP_X3D_XML;
else if (!stricmp(arg, "-lsr")) dump_mode = GF_SM_DUMP_LASER;
else if (!stricmp(arg, "-svg")) dump_mode = GF_SM_DUMP_SVG;
#endif /*defined(GPAC_DISABLE_MEDIA_EXPORT) && !defined(GPAC_DISABLE_SCENE_DUMP)*/
else if (!stricmp(arg, "-stat")) stat_level = 1;
else if (!stricmp(arg, "-stats")) stat_level = 2;
else if (!stricmp(arg, "-statx")) stat_level = 3;
else if (!stricmp(arg, "-diso")) dump_isom = 1;
else if (!stricmp(arg, "-dump-cover")) dump_cart = 1;
else if (!stricmp(arg, "-dump-chap")) dump_chap = 1;
else if (!stricmp(arg, "-dump-chap-ogg")) dump_chap = 2;
else if (!stricmp(arg, "-hash")) do_hash = 1;
else if (!stricmp(arg, "-bin")) do_bin_nhml = 1;
else if (!stricmp(arg, "-dump-udta")) {
char *sep, *code;
CHECK_NEXT_ARG
sep = strchr(argv[i+1], ':');
if (sep) {
sep[0] = 0;
dump_udta_track = atoi(argv[i+1]);
sep[0] = ':';
code = &sep[1];
} else {
code = argv[i+1];
}
dump_udta_type = GF_4CC(code[0], code[1], code[2], code[3]);
i++;
}
#if 0
else if (!stricmp(arg, "-conf")) {
if (i+1==(u32)argc) {
fprintf(stderr, "Missing arg - please check usage\n");
MP4BOX_EXIT_WITH_CODE(1);
}
if (i+2==(u32)argc) {
gf_check_isom_files(NULL, argv[i+1]);
} else {
gf_check_isom_files(argv[i+1], argv[i+2]);
}
MP4BOX_EXIT_WITH_CODE(0);
}
#endif
else if (!stricmp(arg, "-dmp4")) {
dump_isom = 1;
fprintf(stderr, "WARNING: \"-dmp4\" is deprecated - use \"-diso\" option\n");
}
else if (!stricmp(arg, "-drtp")) dump_rtp = 1;
else if (!stricmp(arg, "-dts")) {
dump_timestamps = 1;
if ( ((i+1<(u32) argc) && inName) || (i+2<(u32) argc) ) {
if (argv[i+1][0] != '-') program_number = atoi(argv[i+1]);
i++;
}
} else if (!stricmp(arg, "-dnal")) {
CHECK_NEXT_ARG
dump_nal = atoi(argv[i+1]);
i++;
}
else if (!stricmp(arg, "-dcr")) dump_cr = 1;
else if (!stricmp(arg, "-ttxt") || !stricmp(arg, "-srt")) {
if ((i+1<(u32) argc) && (sscanf(argv[i+1], "%u", &trackID)==1)) {
char szTk[20];
sprintf(szTk, "%d", trackID);
if (!strcmp(szTk, argv[i+1])) i++;
else trackID=0;
} else {
trackID = 0;
}
#ifdef GPAC_DISABLE_ISOM_WRITE
if (trackID) {
fprintf(stderr, "Error: Read-Only version - subtitle conversion not available\n");
MP4BOX_EXIT_WITH_CODE(1);
}
#endif
if (!stricmp(arg, "-ttxt")) dump_ttxt = GF_TRUE;
else dump_srt = GF_TRUE;
import_subtitle = 1;
} else if (!stricmp(arg, "-dm2ts")) {
dump_m2ts = 1;
if ( ((i+1<(u32) argc) && inName) || (i+2<(u32) argc) ) {
if (argv[i+1][0] != '-') pes_dump = argv[i+1];
i++;
}
}
#ifndef GPAC_DISABLE_SWF_IMPORT
/*SWF importer options*/
else if (!stricmp(arg, "-global")) swf_flags |= GF_SM_SWF_STATIC_DICT;
else if (!stricmp(arg, "-no-ctrl")) swf_flags &= ~GF_SM_SWF_SPLIT_TIMELINE;
else if (!stricmp(arg, "-no-text")) swf_flags |= GF_SM_SWF_NO_TEXT;
else if (!stricmp(arg, "-no-font")) swf_flags |= GF_SM_SWF_NO_FONT;
else if (!stricmp(arg, "-no-line")) swf_flags |= GF_SM_SWF_NO_LINE;
else if (!stricmp(arg, "-no-grad")) swf_flags |= GF_SM_SWF_NO_GRADIENT;
else if (!stricmp(arg, "-quad")) swf_flags |= GF_SM_SWF_QUAD_CURVE;
else if (!stricmp(arg, "-xlp")) swf_flags |= GF_SM_SWF_SCALABLE_LINE;
else if (!stricmp(arg, "-ic2d")) swf_flags |= GF_SM_SWF_USE_IC2D;
else if (!stricmp(arg, "-same-app")) swf_flags |= GF_SM_SWF_REUSE_APPEARANCE;
else if (!stricmp(arg, "-flatten")) {
CHECK_NEXT_ARG
swf_flatten_angle = (Float) atof(argv[i+1]);
i++;
}
#endif
#ifndef GPAC_DISABLE_ISOM_WRITE
else if (!stricmp(arg, "-isma")) {
conv_type = GF_ISOM_CONV_TYPE_ISMA;
open_edit = 1;
}
else if (!stricmp(arg, "-3gp")) {
conv_type = GF_ISOM_CONV_TYPE_3GPP;
open_edit = 1;
}
else if (!stricmp(arg, "-ipod")) {
conv_type = GF_ISOM_CONV_TYPE_IPOD;
open_edit = 1;
}
else if (!stricmp(arg, "-psp")) {
conv_type = GF_ISOM_CONV_TYPE_PSP;
open_edit = 1;
}
else if (!stricmp(arg, "-ismax")) {
conv_type = GF_ISOM_CONV_TYPE_ISMA_EX;
open_edit = 1;
}
else if (!stricmp(arg, "-no-sys") || !stricmp(arg, "-nosys")) {
remove_sys_tracks = 1;
open_edit = 1;
}
else if (!stricmp(arg, "-no-iod")) {
remove_root_od = 1;
open_edit = 1;
}
else if (!stricmp(arg, "-out")) {
CHECK_NEXT_ARG outName = argv[i+1];
i++;
}
else if (!stricmp(arg, "-tmp")) {
CHECK_NEXT_ARG tmpdir = argv[i+1];
i++;
}
else if (!stricmp(arg, "-co64")) {
force_co64 = GF_TRUE;
open_edit = 1;
}
else if (!stricmp(arg, "-write-buffer")) {
CHECK_NEXT_ARG
gf_isom_set_output_buffering(NULL, atoi(argv[i+1]));
i++;
}
else if (!stricmp(arg, "-cprt")) {
CHECK_NEXT_ARG cprt = argv[i+1];
i++;
if (!dash_duration) open_edit = 1;
}
else if (!stricmp(arg, "-chap")) {
CHECK_NEXT_ARG chap_file = argv[i+1];
i++;
open_edit = 1;
}
else if (!strcmp(arg, "-strict-error")) {
gf_log_set_strict_error(1);
} else if (!stricmp(arg, "-inter") || !stricmp(arg, "-old-inter")) {
CHECK_NEXT_ARG
interleaving_time = atof(argv[i+1]) / 1000;
open_edit = 1;
needSave = 1;
if (!stricmp(arg, "-old-inter")) old_interleave = 1;
i++;
} else if (!stricmp(arg, "-frag")) {
CHECK_NEXT_ARG
interleaving_time = atof(argv[i+1]) / 1000;
needSave = 1;
i++;
Frag = 1;
} else if (!stricmp(arg, "-dash")) {
CHECK_NEXT_ARG
dash_duration = atof(argv[i+1]) / 1000;
if (dash_duration == 0.0) {
fprintf(stderr, "\tERROR: \"-dash-dash_duration\": invalid parameter %s\n", argv[i+1]);
MP4BOX_EXIT_WITH_CODE(1);
}
i++;
} else if (!stricmp(arg, "-subdur")) {
CHECK_NEXT_ARG
dash_subduration = atof(argv[i+1]) / 1000;
i++;
} else if (!stricmp(arg, "-dash-scale")) {
CHECK_NEXT_ARG
dash_scale = atoi(argv[i+1]);
if (!dash_scale) {
fprintf(stderr, "\tERROR: \"-dash-scale\": invalid parameter %s\n", argv[i+1]);
MP4BOX_EXIT_WITH_CODE(1);
}
i++;
} else if (!stricmp(arg, "-dash-ts-prog")) {
CHECK_NEXT_ARG
program_number = atoi(argv[i+1]);
i++;
} else if (!stricmp(arg, "-subsegs-per-sidx") || !stricmp(arg, "-frags-per-sidx")) {
CHECK_NEXT_ARG
subsegs_per_sidx = atoi(argv[i+1]);
i++;
} else if (!stricmp(arg, "-segment-name")) {
CHECK_NEXT_ARG
seg_name = argv[i+1];
i++;
} else if (!stricmp(arg, "-segment-ext")) {
CHECK_NEXT_ARG
seg_ext = argv[i+1];
i++;
} else if (!stricmp(arg, "-bs-switching")) {
CHECK_NEXT_ARG
if (!stricmp(argv[i+1], "no") || !stricmp(argv[i+1], "off")) bitstream_switching_mode = GF_DASH_BSMODE_NONE;
else if (!stricmp(argv[i+1], "merge")) bitstream_switching_mode = GF_DASH_BSMODE_MERGED;
else if (!stricmp(argv[i+1], "multi")) bitstream_switching_mode = GF_DASH_BSMODE_MULTIPLE_ENTRIES;
else if (!stricmp(argv[i+1], "single")) bitstream_switching_mode = GF_DASH_BSMODE_SINGLE;
else if (!stricmp(argv[i+1], "inband")) bitstream_switching_mode = GF_DASH_BSMODE_INBAND;
else {
fprintf(stderr, "\tWARNING: Unrecognized bitstream switchin mode \"%s\" - please check usage\n", argv[i+1]);
MP4BOX_EXIT_WITH_CODE(1);
}
i++;
}
else if (!stricmp(arg, "-dynamic")) {
dash_mode = GF_DASH_DYNAMIC;
}
else if (!stricmp(arg, "-last-dynamic")) {
dash_mode = GF_DASH_DYNAMIC_LAST;
}
else if (!stricmp(arg, "-frag-rt")) {
frag_real_time = GF_TRUE;
}
else if (!strnicmp(arg, "-dash-live", 10) || !strnicmp(arg, "-ddbg-live", 10)) {
dash_mode = !strnicmp(arg, "-ddbg-live", 10) ? GF_DASH_DYNAMIC_DEBUG : GF_DASH_DYNAMIC;
dash_live = 1;
if (arg[10]=='=') {
dash_ctx_file = arg+11;
}
CHECK_NEXT_ARG
dash_duration = atof(argv[i+1]) / 1000;
i++;
}
else if (!stricmp(arg, "-mpd-duration")) {
CHECK_NEXT_ARG mpd_live_duration = atof(argv[i+1]);
i++;
}
else if (!stricmp(arg, "-mpd-refresh")) {
CHECK_NEXT_ARG mpd_update_time = atof(argv[i+1]);
i++;
}
else if (!stricmp(arg, "-time-shift")) {
CHECK_NEXT_ARG
time_shift_depth = (u32) atoi(argv[i+1]);
i++;
}
else if (!stricmp(arg, "-min-buffer")) {
CHECK_NEXT_ARG
min_buffer = atoi(argv[i+1]);
min_buffer /= 1000;
i++;
}
else if (!stricmp(arg, "-ast-offset")) {
CHECK_NEXT_ARG
ast_offset_ms = atoi(argv[i+1]);
i++;
}
else if (!stricmp(arg, "-moof-sn")) {
CHECK_NEXT_ARG
initial_moof_sn = (u32) atoi(argv[i+1]);
i++;
}
else if (!stricmp(arg, "-tfdt")) {
CHECK_NEXT_ARG
sscanf(argv[i+1], LLU, &initial_tfdt);
i++;
}
else if (!stricmp(arg, "-no-frags-default")) {
no_fragments_defaults = 1;
}
else if (!stricmp(arg, "-single-traf")) {
single_traf_per_moof = 1;
}
else if (!stricmp(arg, "-mpd-title")) {
CHECK_NEXT_ARG dash_title = argv[i+1];
i++;
}
else if (!stricmp(arg, "-mpd-source")) {
CHECK_NEXT_ARG dash_source = argv[i+1];
i++;
}
else if (!stricmp(arg, "-mpd-info-url")) {
CHECK_NEXT_ARG dash_more_info = argv[i+1];
i++;
}
else if (!stricmp(arg, "-base-url")) {
CHECK_NEXT_ARG
dash_more_info = argv[i+1];
mpd_base_urls = gf_realloc(mpd_base_urls, (nb_mpd_base_urls+1)*sizeof(char**));
mpd_base_urls[nb_mpd_base_urls] = argv[i+1];
nb_mpd_base_urls++;
i++;
}
else if (!stricmp(arg, "-dash-ctx")) {
CHECK_NEXT_ARG
dash_ctx_file = argv[i+1];
i++;
} else if (!stricmp(arg, "-daisy-chain")) {
daisy_chain_sidx = 1;
} else if (!stricmp(arg, "-single-segment")) {
single_segment = 1;
} else if (!stricmp(arg, "-single-file")) {
single_file = 1;
} else if (!stricmp(arg, "-pssh-moof")) {
pssh_in_moof = 1;
} else if (!stricmp(arg, "-sample-groups-traf")) {
samplegroups_in_traf = 1;
} else if (!stricmp(arg, "-dash-profile") || !stricmp(arg, "-profile")) {
CHECK_NEXT_ARG
if (!stricmp(argv[i+1], "live") || !stricmp(argv[i+1], "simple")) dash_profile = GF_DASH_PROFILE_LIVE;
else if (!stricmp(argv[i+1], "onDemand")) dash_profile = GF_DASH_PROFILE_ONDEMAND;
else if (!stricmp(argv[i+1], "hbbtv1.5:live")) {
dash_profile = GF_DASH_PROFILE_HBBTV_1_5_ISOBMF_LIVE;
} else if (!stricmp(argv[i+1], "dashavc264:live")) {
dash_profile = GF_DASH_PROFILE_AVC264_LIVE;
} else if (!stricmp(argv[i+1], "dashavc264:onDemand")) {
dash_profile = GF_DASH_PROFILE_AVC264_ONDEMAND;
} else if (!stricmp(argv[i+1], "main")) dash_profile = GF_DASH_PROFILE_MAIN;
else dash_profile = GF_DASH_PROFILE_FULL;
i++;
} else if (!stricmp(arg, "-profile-ext")) {
CHECK_NEXT_ARG
dash_profile_extension = argv[i+1];
i++;
} else if (!strnicmp(arg, "-url-template", 13)) {
use_url_template = 1;
if ((arg[13]=='=') && arg[14]) {
if (!strcmp( &arg[14], "simulate")) use_url_template = 2;
}
} else if (!stricmp(arg, "-segment-timeline")) {
segment_timeline = 1;
} else if (!stricmp(arg, "-mem-frags")) {
memory_frags = 1;
} else if (!stricmp(arg, "-segment-marker")) {
char *m;
CHECK_NEXT_ARG
m = argv[i+1];
segment_marker = GF_4CC(m[0], m[1], m[2], m[3]);
i++;
} else if (!stricmp(arg, "-insert-utc")) {
insert_utc = GF_TRUE;
} else if (!stricmp(arg, "-itags")) {
CHECK_NEXT_ARG itunes_tags = argv[i+1];
i++;
open_edit = 1;
}
#ifndef GPAC_DISABLE_ISOM_HINTING
else if (!stricmp(arg, "-hint")) {
open_edit = 1;
HintIt = 1;
}
else if (!stricmp(arg, "-unhint")) {
open_edit = 1;
remove_hint = 1;
}
else if (!stricmp(arg, "-copy")) HintCopy = 1;
else if (!stricmp(arg, "-tight")) {
FullInter = 1;
open_edit = 1;
needSave = 1;
} else if (!stricmp(arg, "-ocr")) force_ocr = 1;
else if (!stricmp(arg, "-latm")) hint_flags |= GP_RTP_PCK_USE_LATM_AAC;
else if (!stricmp(arg, "-rap")) {
if ((i+1 < (u32)argc) && (argv[i+1][0] != '-')) {
if (sscanf(argv[i+1], "%d", &trackID) == 1) {
tracks = gf_realloc(tracks, sizeof(TrackAction) * (nb_track_act+1));
memset(&tracks[nb_track_act], 0, sizeof(TrackAction) );
tracks[nb_track_act].act_type = TRAC_ACTION_REM_NON_RAP;
tracks[nb_track_act].trackID = trackID;
nb_track_act++;
i++;
open_edit = 1;
}
}
hint_flags |= GP_RTP_PCK_SIGNAL_RAP;
seg_at_rap=1;
}
else if (!stricmp(arg, "-frag-rap")) {
frag_at_rap=1;
}
else if (!stricmp(arg, "-ts")) hint_flags |= GP_RTP_PCK_SIGNAL_TS;
else if (!stricmp(arg, "-size")) hint_flags |= GP_RTP_PCK_SIGNAL_SIZE;
else if (!stricmp(arg, "-idx")) hint_flags |= GP_RTP_PCK_SIGNAL_AU_IDX;
else if (!stricmp(arg, "-static")) hint_flags |= GP_RTP_PCK_USE_STATIC_ID;
else if (!stricmp(arg, "-multi")) {
hint_flags |= GP_RTP_PCK_USE_MULTI;
if ((i+1<(u32) argc) && (sscanf(argv[i+1], "%u", &max_ptime)==1)) {
char szPt[20];
sprintf(szPt, "%u", max_ptime);
if (!strcmp(szPt, argv[i+1])) i++;
else max_ptime=0;
}
}
#endif
else if (!stricmp(arg, "-mpeg4")) {
#ifndef GPAC_DISABLE_ISOM_HINTING
hint_flags |= GP_RTP_PCK_FORCE_MPEG4;
#endif
#ifndef GPAC_DISABLE_MEDIA_IMPORT
import_flags |= GF_IMPORT_FORCE_MPEG4;
#endif
}
#ifndef GPAC_DISABLE_ISOM_HINTING
else if (!stricmp(arg, "-mtu")) {
CHECK_NEXT_ARG MTUSize = atoi(argv[i+1]);
i++;
}
else if (!stricmp(arg, "-cardur")) {
CHECK_NEXT_ARG car_dur = atoi(argv[i+1]);
i++;
}
else if (!stricmp(arg, "-rate")) {
CHECK_NEXT_ARG rtp_rate = atoi(argv[i+1]);
i++;
}
#ifndef GPAC_DISABLE_SENG
else if (!stricmp(arg, "-add-sdp") || !stricmp(arg, "-sdp_ex")) {
char *id;
CHECK_NEXT_ARG
sdp_lines = gf_realloc(sdp_lines, sizeof(SDPLine) * (nb_sdp_ex+1) );
id = strchr(argv[i+1], ':');
if (id) {
id[0] = 0;
if (sscanf(argv[i+1], "%u", &sdp_lines[0].trackID)==1) {
id[0] = ':';
sdp_lines[nb_sdp_ex].line = id+1;
} else {
id[0] = ':';
sdp_lines[nb_sdp_ex].line = argv[i+1];
sdp_lines[nb_sdp_ex].trackID = 0;
}
} else {
sdp_lines[nb_sdp_ex].line = argv[i+1];
sdp_lines[nb_sdp_ex].trackID = 0;
}
open_edit = 1;
nb_sdp_ex++;
i++;
}
#endif /*GPAC_DISABLE_SENG*/
#endif /*GPAC_DISABLE_ISOM_HINTING*/
else if (!stricmp(arg, "-single")) {
#ifndef GPAC_DISABLE_MEDIA_EXPORT
CHECK_NEXT_ARG
track_dump_type = GF_EXPORT_MP4;
tracks = gf_realloc(tracks, sizeof(TrackAction) * (nb_track_act+1));
memset(&tracks[nb_track_act], 0, sizeof(TrackAction) );
tracks[nb_track_act].act_type = TRAC_ACTION_RAW_EXTRACT;
tracks[nb_track_act].trackID = atoi(argv[i+1]);
tracks[nb_track_act].dump_type = GF_EXPORT_MP4;
nb_track_act++;
i++;
#endif
}
else if (!stricmp(arg, "-iod")) regular_iod = 1;
else if (!stricmp(arg, "-flat")) {
open_edit = 1;
do_flat = 1;
}
else if (!stricmp(arg, "-keep-utc")) keep_utc = 1;
else if (!stricmp(arg, "-new")) force_new = 1;
else if (!stricmp(arg, "-timescale")) {
CHECK_NEXT_ARG
timescale = atoi(argv[i+1]);
open_edit = 1;
i++;
}
else if (!stricmp(arg, "-udta")) {
CHECK_NEXT_ARG
create_new_track_action(argv[i+1], &tracks, &nb_track_act, 0);
tracks[nb_track_act-1].act_type = TRAC_ACTION_SET_UDTA;
open_edit = 1;
i++;
}
else if (!stricmp(arg, "-add") || !stricmp(arg, "-import") || !stricmp(arg, "-convert")) {
CHECK_NEXT_ARG
if (!stricmp(arg, "-import")) fprintf(stderr, "\tWARNING: \"-import\" is deprecated - use \"-add\"\n");
else if (!stricmp(arg, "-convert")) fprintf(stderr, "\tWARNING: \"-convert\" is deprecated - use \"-add\"\n");
nb_add++;
i++;
}
else if (!stricmp(arg, "-cat") || !stricmp(arg, "-catx")) {
CHECK_NEXT_ARG
nb_cat++;
i++;
}
else if (!stricmp(arg, "-time")) {
struct tm time;
CHECK_NEXT_ARG
memset(&time, 0, sizeof(struct tm));
sscanf(argv[i+1], "%d/%d/%d-%d:%d:%d", &time.tm_mday, &time.tm_mon, &time.tm_year, &time.tm_hour, &time.tm_min, &time.tm_sec);
time.tm_isdst=0;
time.tm_year -= 1900;
time.tm_mon -= 1;
open_edit = 1;
movie_time = 2082758400;
movie_time += mktime(&time);
i++;
}
else if (!stricmp(arg, "-force-cat")) force_cat = 1;
else if (!stricmp(arg, "-align-cat")) align_cat = 1;
else if (!stricmp(arg, "-unalign-cat")) align_cat = 0;
else if (!stricmp(arg, "-raw-cat")) {
CHECK_NEXT_ARG
raw_cat = argv[i+1];
i++;
}
else if (!stricmp(arg, "-rem") || !stricmp(arg, "-disable") || !stricmp(arg, "-enable")) {
CHECK_NEXT_ARG
tracks = gf_realloc(tracks, sizeof(TrackAction) * (nb_track_act+1));
memset(&tracks[nb_track_act], 0, sizeof(TrackAction) );
if (!stricmp(arg, "-enable")) tracks[nb_track_act].act_type = TRAC_ACTION_ENABLE;
else if (!stricmp(arg, "-disable")) tracks[nb_track_act].act_type = TRAC_ACTION_DISABLE;
else tracks[nb_track_act].act_type = TRAC_ACTION_REM_TRACK;
tracks[nb_track_act].trackID = atoi(argv[i+1]);
open_edit = 1;
nb_track_act++;
i++;
}
else if (!stricmp(arg, "-set-track-id")) {
char *sep;
CHECK_NEXT_ARG
tracks = gf_realloc(tracks, sizeof(TrackAction) * (nb_track_act+1));
memset(&tracks[nb_track_act], 0, sizeof(TrackAction) );
tracks[nb_track_act].act_type = TRAC_ACTION_SET_ID;
sep = strchr(argv[i+1], ':');
if (!sep) {
fprintf(stderr, "Bad format for -set-track-id - expecting \"id1:id2\" got \"%s\"\n", argv[i+1]);
MP4BOX_EXIT_WITH_CODE(1);
}
*sep = 0;
tracks[nb_track_act].trackID = atoi(argv[i+1]);
*sep = ':';
sep++;
tracks[nb_track_act].newTrackID = atoi(sep);
open_edit = 1;
nb_track_act++;
i++;
}
else if (!stricmp(arg, "-par")) {
char szTK[20], *ext;
CHECK_NEXT_ARG
tracks = gf_realloc(tracks, sizeof(TrackAction) * (nb_track_act+1));
memset(&tracks[nb_track_act], 0, sizeof(TrackAction) );
tracks[nb_track_act].act_type = TRAC_ACTION_SET_PAR;
assert(strlen(argv[i+1])+1 <= sizeof(szTK));
strncpy(szTK, argv[i+1], sizeof(szTK));
ext = strchr(szTK, '=');
if (!ext) {
fprintf(stderr, "Bad format for track par - expecting ID=PAR_NUM:PAR_DEN got %s\n", argv[i+1]);
MP4BOX_EXIT_WITH_CODE(1);
}
if (!stricmp(ext+1, "none")) {
tracks[nb_track_act].par_num = tracks[nb_track_act].par_den = -1;
} else {
sscanf(ext+1, "%d", &tracks[nb_track_act].par_num);
ext = strchr(ext+1, ':');
if (!ext) {
fprintf(stderr, "Bad format for track par - expecting ID=PAR_NUM:PAR_DEN got %s\n", argv[i+1]);
MP4BOX_EXIT_WITH_CODE(1);
}
sscanf(ext+1, "%d", &tracks[nb_track_act].par_den);
}
ext[0] = 0;
tracks[nb_track_act].trackID = atoi(szTK);
open_edit = 1;
nb_track_act++;
i++;
}
else if (!stricmp(arg, "-lang")) {
char szTK[20], *ext;
CHECK_NEXT_ARG
tracks = gf_realloc(tracks, sizeof(TrackAction) * (nb_track_act+1));
memset(&tracks[nb_track_act], 0, sizeof(TrackAction) );
tracks[nb_track_act].act_type = TRAC_ACTION_SET_LANGUAGE;
tracks[nb_track_act].trackID = 0;
strcpy(szTK, argv[i+1]);
ext = strchr(szTK, '=');
if (!strnicmp(argv[i+1], "all=", 4)) {
tracks[nb_track_act].lang = gf_strdup(argv[i+1]+4);
} else if (!ext) {
tracks[nb_track_act].lang = gf_strdup(argv[i+1]);
} else {
tracks[nb_track_act].lang = gf_strdup(ext+1);
ext[0] = 0;
tracks[nb_track_act].trackID = atoi(szTK);
ext[0] = '=';
}
open_edit = 1;
nb_track_act++;
i++;
}
else if (!stricmp(arg, "-kind") || !stricmp(arg, "-kind-rem")) {
char szTK[200], *ext;
char *scheme_start = NULL;
Bool has_track_id = GF_FALSE;
CHECK_NEXT_ARG
tracks = gf_realloc(tracks, sizeof(TrackAction) * (nb_track_act+1));
memset(&tracks[nb_track_act], 0, sizeof(TrackAction) );
if (!stricmp(arg, "-kind")) {
tracks[nb_track_act].act_type = TRAC_ACTION_SET_KIND;
} else {
tracks[nb_track_act].act_type = TRAC_ACTION_REM_KIND;
}
tracks[nb_track_act].trackID = 0;
if (!strnicmp(argv[i+1], "all=", 4)) {
scheme_start = argv[i+1]+4;
has_track_id = GF_TRUE;
}
if (!scheme_start) {
if (strlen(argv[i+1])>200) {
GF_LOG(GF_LOG_WARNING, GF_LOG_ALL, ("Warning: track kind parameter is too long!"));
}
strncpy(szTK, argv[i+1], 200);
ext = strchr(szTK, '=');
if (ext && !has_track_id) {
ext[0] = 0;
has_track_id = (sscanf(szTK, "%d", &tracks[nb_track_act].trackID) == 1 ? GF_TRUE : GF_FALSE);
if (has_track_id) {
scheme_start = ext+1;
} else {
scheme_start = szTK;
}
ext[0] = '=';
} else {
scheme_start = szTK;
}
}
ext = strchr(scheme_start, '=');
if (!ext) {
tracks[nb_track_act].kind_scheme = gf_strdup(scheme_start);
} else {
ext[0] = 0;
tracks[nb_track_act].kind_scheme = gf_strdup(scheme_start);
ext[0] = '=';
tracks[nb_track_act].kind_value = gf_strdup(ext+1);
}
open_edit = 1;
nb_track_act++;
i++;
}
else if (!stricmp(arg, "-delay")) {
char szTK[20], *ext;
CHECK_NEXT_ARG
tracks = gf_realloc(tracks, sizeof(TrackAction) * (nb_track_act+1));
memset(&tracks[nb_track_act], 0, sizeof(TrackAction) );
strcpy(szTK, argv[i+1]);
ext = strchr(szTK, '=');
if (!ext) {
fprintf(stderr, "Bad format for track delay - expecting ID=DLAY got %s\n", argv[i+1]);
MP4BOX_EXIT_WITH_CODE(1);
}
tracks[nb_track_act].act_type = TRAC_ACTION_SET_DELAY;
tracks[nb_track_act].delay_ms = atoi(ext+1);
ext[0] = 0;
tracks[nb_track_act].trackID = atoi(szTK);
open_edit = 1;
nb_track_act++;
i++;
}
else if (!stricmp(arg, "-ref")) {
char *szTK, *ext;
CHECK_NEXT_ARG
tracks = gf_realloc(tracks, sizeof(TrackAction) * (nb_track_act+1));
memset(&tracks[nb_track_act], 0, sizeof(TrackAction) );
szTK = argv[i+1];
ext = strchr(szTK, ':');
if (!ext) {
fprintf(stderr, "Bad format for track reference - expecting ID:XXXX:refID got %s\n", argv[i+1]);
MP4BOX_EXIT_WITH_CODE(1);
}
tracks[nb_track_act].act_type = TRAC_ACTION_REFERENCE;
ext[0] = 0;
tracks[nb_track_act].trackID = atoi(szTK);
ext[0] = ':';
szTK = ext+1;
ext = strchr(szTK, ':');
if (!ext) {
fprintf(stderr, "Bad format for track reference - expecting ID:XXXX:refID got %s\n", argv[i+1]);
MP4BOX_EXIT_WITH_CODE(1);
}
ext[0] = 0;
tracks[nb_track_act].lang = gf_strdup(szTK);
ext[0] = ':';
tracks[nb_track_act].delay_ms = (s32) atoi(ext+1);
open_edit = 1;
nb_track_act++;
i++;
}
else if (!stricmp(arg, "-name")) {
char szTK[GF_MAX_PATH], *ext;
CHECK_NEXT_ARG
tracks = gf_realloc(tracks, sizeof(TrackAction) * (nb_track_act+1));
memset(&tracks[nb_track_act], 0, sizeof(TrackAction) );
strcpy(szTK, argv[i+1]);
ext = strchr(szTK, '=');
if (!ext) {
fprintf(stderr, "Bad format for track name - expecting ID=name got %s\n", argv[i+1]);
MP4BOX_EXIT_WITH_CODE(1);
}
tracks[nb_track_act].act_type = TRAC_ACTION_SET_HANDLER_NAME;
tracks[nb_track_act].hdl_name = strchr(argv[i+1], '=') + 1;
ext[0] = 0;
tracks[nb_track_act].trackID = atoi(szTK);
ext[0] = '=';
open_edit = 1;
nb_track_act++;
i++;
}
#if !defined(GPAC_DISABLE_MEDIA_EXPORT) && !defined(GPAC_DISABLE_MEDIA_IMPORT)
else if (!stricmp(arg, "-dref")) import_flags |= GF_IMPORT_USE_DATAREF;
else if (!stricmp(arg, "-no-drop") || !stricmp(arg, "-nodrop")) import_flags |= GF_IMPORT_NO_FRAME_DROP;
else if (!stricmp(arg, "-packed")) import_flags |= GF_IMPORT_FORCE_PACKED;
else if (!stricmp(arg, "-sbr")) import_flags |= GF_IMPORT_SBR_IMPLICIT;
else if (!stricmp(arg, "-sbrx")) import_flags |= GF_IMPORT_SBR_EXPLICIT;
else if (!stricmp(arg, "-ps")) import_flags |= GF_IMPORT_PS_IMPLICIT;
else if (!stricmp(arg, "-psx")) import_flags |= GF_IMPORT_PS_EXPLICIT;
else if (!stricmp(arg, "-ovsbr")) import_flags |= GF_IMPORT_OVSBR;
else if (!stricmp(arg, "-fps")) {
CHECK_NEXT_ARG
if (!strcmp(argv[i+1], "auto")) import_fps = GF_IMPORT_AUTO_FPS;
else if (strchr(argv[i+1], '-')) {
u32 ticks, dts_inc;
sscanf(argv[i+1], "%u-%u", &ticks, &dts_inc);
if (!dts_inc) dts_inc=1;
import_fps = ticks;
import_fps /= dts_inc;
} else import_fps = atof(argv[i+1]);
i++;
}
else if (!stricmp(arg, "-agg")) {
CHECK_NEXT_ARG agg_samples = atoi(argv[i+1]);
i++;
}
else if (!stricmp(arg, "-keep-all") || !stricmp(arg, "-keepall")) import_flags |= GF_IMPORT_KEEP_ALL_TRACKS;
#endif /*!defined(GPAC_DISABLE_MEDIA_EXPORT) && !defined(GPAC_DISABLE_MEDIA_IMPORT*/
else if (!stricmp(arg, "-keep-sys") || !stricmp(arg, "-keepsys")) keep_sys_tracks = 1;
else if (!stricmp(arg, "-ms")) {
CHECK_NEXT_ARG mediaSource = argv[i+1];
i++;
}
else if (!stricmp(arg, "-mp4")) {
encode = 1;
open_edit = 1;
}
else if (!stricmp(arg, "-saf")) {
do_saf = 1;
}
else if (!stricmp(arg, "-log")) {
do_log = 1;
}
#ifndef GPAC_DISABLE_MPD
else if (!stricmp(arg, "-mpd")) {
do_mpd = 1;
CHECK_NEXT_ARG
inName = argv[i+1];
i++;
}
#endif
#ifndef GPAC_DISABLE_SCENE_ENCODER
else if (!stricmp(arg, "-def")) opts.flags |= GF_SM_ENCODE_USE_NAMES;
else if (!stricmp(arg, "-sync")) {
CHECK_NEXT_ARG
opts.flags |= GF_SM_ENCODE_RAP_INBAND;
opts.rap_freq = atoi(argv[i+1]);
i++;
} else if (!stricmp(arg, "-shadow")) {
CHECK_NEXT_ARG
opts.flags &= ~GF_SM_ENCODE_RAP_INBAND;
opts.flags |= GF_SM_ENCODE_RAP_SHADOW;
opts.rap_freq = atoi(argv[i+1]);
i++;
} else if (!stricmp(arg, "-carousel")) {
CHECK_NEXT_ARG
opts.flags &= ~(GF_SM_ENCODE_RAP_INBAND | GF_SM_ENCODE_RAP_SHADOW);
opts.rap_freq = atoi(argv[i+1]);
i++;
}
/*LASeR options*/
else if (!stricmp(arg, "-resolution")) {
CHECK_NEXT_ARG
opts.resolution = atoi(argv[i+1]);
i++;
}
#ifndef GPAC_DISABLE_SCENE_STATS
else if (!stricmp(arg, "-auto-quant")) {
CHECK_NEXT_ARG
opts.resolution = atoi(argv[i+1]);
opts.auto_quant = 1;
i++;
}
#endif
else if (!stricmp(arg, "-coord-bits")) {
CHECK_NEXT_ARG
opts.coord_bits = atoi(argv[i+1]);
i++;
}
else if (!stricmp(arg, "-scale-bits")) {
CHECK_NEXT_ARG
opts.scale_bits = atoi(argv[i+1]);
i++;
}
else if (!stricmp(arg, "-global-quant")) {
CHECK_NEXT_ARG
opts.resolution = atoi(argv[i+1]);
opts.auto_quant = 2;
i++;
}
/*chunk encoding*/
else if (!stricmp(arg, "-ctx-out") || !stricmp(arg, "-outctx")) {
CHECK_NEXT_ARG output_ctx = argv[i+1];
i++;
}
else if (!stricmp(arg, "-ctx-in") || !stricmp(arg, "-inctx")) {
CHECK_NEXT_ARG
chunk_mode = 1;
input_ctx = argv[i+1];
i++;
}
#endif /*GPAC_DISABLE_SCENE_ENCODER*/
else if (!strcmp(arg, "-crypt")) {
CHECK_NEXT_ARG
crypt = 1;
drm_file = argv[i+1];
open_edit = 1;
i += 1;
}
else if (!strcmp(arg, "-decrypt")) {
CHECK_NEXT_ARG
crypt = 2;
if (get_file_type_by_ext(argv[i+1])!=1) {
drm_file = argv[i+1];
i += 1;
}
open_edit = 1;
}
else if (!stricmp(arg, "-set-kms")) {
char szTK[20], *ext;
CHECK_NEXT_ARG
tracks = gf_realloc(tracks, sizeof(TrackAction) * (nb_track_act+1));
memset(&tracks[nb_track_act], 0, sizeof(TrackAction) );
strncpy(szTK, argv[i+1], 19);
ext = strchr(szTK, '=');
tracks[nb_track_act].act_type = TRAC_ACTION_SET_KMS_URI;
tracks[nb_track_act].trackID = 0;
if (!strnicmp(argv[i+1], "all=", 4)) {
tracks[nb_track_act].kms = argv[i+1] + 4;
} else if (!ext) {
tracks[nb_track_act].kms = argv[i+1];
} else {
tracks[nb_track_act].kms = ext+1;
ext[0] = 0;
tracks[nb_track_act].trackID = atoi(szTK);
ext[0] = '=';
}
open_edit = 1;
nb_track_act++;
i++;
}
else if (!stricmp(arg, "-split")) {
CHECK_NEXT_ARG
split_duration = atof(argv[i+1]);
if (split_duration<0) split_duration=0;;
i++;
split_size = 0;
}
else if (!stricmp(arg, "-split-rap") || !stricmp(arg, "-splitr")) {
CHECK_NEXT_ARG
split_duration = -1;
split_size = -1;
}
else if (!stricmp(arg, "-split-size") || !stricmp(arg, "-splits")) {
CHECK_NEXT_ARG
split_size = (u32) atoi(argv[i+1]);
i++;
split_duration = 0;
}
else if (!stricmp(arg, "-split-chunk") || !stricmp(arg, "-splitx") || !stricmp(arg, "-splitz")) {
CHECK_NEXT_ARG
if (!strstr(argv[i+1], ":")) {
fprintf(stderr, "Chunk extraction usage: \"-splitx start:end\" expressed in seconds\n");
MP4BOX_EXIT_WITH_CODE(1);
}
if (strstr(argv[i+1], "end")) {
sscanf(argv[i+1], "%lf:end", &split_start);
split_duration = -2;
} else {
sscanf(argv[i+1], "%lf:%lf", &split_start, &split_duration);
split_duration -= split_start;
}
split_size = 0;
if (!stricmp(arg, "-splitz")) adjust_split_end = 1;
i++;
}
/*meta*/
else if (!stricmp(arg, "-set-meta")) {
metas = gf_realloc(metas, sizeof(MetaAction) * (nb_meta_act+1));
parse_meta_args(&metas[nb_meta_act], META_ACTION_SET_TYPE, argv[i+1]);
nb_meta_act++;
open_edit = 1;
i++;
}
else if (!stricmp(arg, "-add-item")) {
metas = gf_realloc(metas, sizeof(MetaAction) * (nb_meta_act+1));
parse_meta_args(&metas[nb_meta_act], META_ACTION_ADD_ITEM, argv[i+1]);
nb_meta_act++;
open_edit = 1;
i++;
}
else if (!stricmp(arg, "-rem-item")) {
metas = gf_realloc(metas, sizeof(MetaAction) * (nb_meta_act+1));
parse_meta_args(&metas[nb_meta_act], META_ACTION_REM_ITEM, argv[i+1]);
nb_meta_act++;
open_edit = 1;
i++;
}
else if (!stricmp(arg, "-set-primary")) {
metas = gf_realloc(metas, sizeof(MetaAction) * (nb_meta_act+1));
parse_meta_args(&metas[nb_meta_act], META_ACTION_SET_PRIMARY_ITEM, argv[i+1]);
nb_meta_act++;
open_edit = 1;
i++;
}
else if (!stricmp(arg, "-set-xml")) {
metas = gf_realloc(metas, sizeof(MetaAction) * (nb_meta_act+1));
parse_meta_args(&metas[nb_meta_act], META_ACTION_SET_XML, argv[i+1]);
nb_meta_act++;
open_edit = 1;
i++;
}
else if (!stricmp(arg, "-rem-xml")) {
metas = gf_realloc(metas, sizeof(MetaAction) * (nb_meta_act+1));
if (parse_meta_args(&metas[nb_meta_act], META_ACTION_REM_XML, argv[i+1])) i++;
nb_meta_act++;
open_edit = 1;
}
else if (!stricmp(arg, "-dump-xml")) {
metas = gf_realloc(metas, sizeof(MetaAction) * (nb_meta_act+1));
parse_meta_args(&metas[nb_meta_act], META_ACTION_DUMP_XML, argv[i+1]);
nb_meta_act++;
i++;
}
else if (!stricmp(arg, "-dump-item")) {
metas = gf_realloc(metas, sizeof(MetaAction) * (nb_meta_act+1));
parse_meta_args(&metas[nb_meta_act], META_ACTION_DUMP_ITEM, argv[i+1]);
nb_meta_act++;
i++;
}
else if (!stricmp(arg, "-group-add") || !stricmp(arg, "-group-rem-track") || !stricmp(arg, "-group-rem")) {
TSELActionType act_type;
if (!stricmp(arg, "-group-rem")) {
act_type = TSEL_ACTION_REMOVE_ALL_TSEL_IN_GROUP;
} else if ( !stricmp(arg, "-group-rem-track")) {
act_type = TSEL_ACTION_REMOVE_TSEL;
} else {
act_type = TSEL_ACTION_SET_PARAM;
}
if (parse_tsel_args(&tsel_acts, argv[i+1], &nb_tsel_acts, act_type)==0) {
fprintf(stderr, "Invalid group syntax - check usage\n");
MP4BOX_EXIT_WITH_CODE(1);
}
open_edit=1;
i++;
}
else if (!stricmp(arg, "-group-clean")) {
tsel_acts[nb_tsel_acts].act_type = TSEL_ACTION_REMOVE_ALL_TSEL_IN_FILE;
nb_tsel_acts++;
open_edit=1;
}
else if (!stricmp(arg, "-group-single")) {
single_group = 1;
}
else if (!stricmp(arg, "-package")) {
CHECK_NEXT_ARG
pack_file = argv[i+1];
i++;
}
else if (!stricmp(arg, "-mgt")) {
CHECK_NEXT_ARG
pack_file = argv[i+1];
pack_wgt = 1;
i++;
}
else if (!stricmp(arg, "-brand")) {
char *b = argv[i+1];
CHECK_NEXT_ARG
major_brand = GF_4CC(b[0], b[1], b[2], b[3]);
open_edit = 1;
if (b[4]==':') minor_version = atoi(b+5);
i++;
}
else if (!stricmp(arg, "-ab")) {
char *b = argv[i+1];
CHECK_NEXT_ARG
brand_add = gf_realloc(brand_add, sizeof(u32) * (nb_alt_brand_add+1));
brand_add[nb_alt_brand_add] = GF_4CC(b[0], b[1], b[2], b[3]);
nb_alt_brand_add++;
open_edit = 1;
i++;
}
else if (!stricmp(arg, "-rb")) {
char *b = argv[i+1];
CHECK_NEXT_ARG
brand_rem = gf_realloc(brand_rem, sizeof(u32) * (nb_alt_brand_rem+1));
brand_rem[nb_alt_brand_rem] = GF_4CC(b[0], b[1], b[2], b[3]);
nb_alt_brand_rem++;
open_edit = 1;
i++;
}
#endif
else if (!stricmp(arg, "-languages")) {
PrintLanguages();
MP4BOX_EXIT_WITH_CODE(0);
}
else if (!stricmp(arg, "-h")) {
if (i+1== (u32) argc) PrintUsage();
else if (!strcmp(argv[i+1], "general")) PrintGeneralUsage();
else if (!strcmp(argv[i+1], "extract")) PrintExtractUsage();
else if (!strcmp(argv[i+1], "dash")) PrintDASHUsage();
else if (!strcmp(argv[i+1], "dump")) PrintDumpUsage();
else if (!strcmp(argv[i+1], "import")) PrintImportUsage();
else if (!strcmp(argv[i+1], "format")) PrintFormats();
else if (!strcmp(argv[i+1], "hint")) PrintHintUsage();
else if (!strcmp(argv[i+1], "encode")) PrintEncodeUsage();
else if (!strcmp(argv[i+1], "crypt")) PrintEncryptUsage();
else if (!strcmp(argv[i+1], "meta")) PrintMetaUsage();
else if (!strcmp(argv[i+1], "swf")) PrintSWFUsage();
#if !defined(GPAC_DISABLE_STREAMING) && !defined(GPAC_DISABLE_SENG)
else if (!strcmp(argv[i+1], "rtp")) PrintStreamerUsage();
else if (!strcmp(argv[i+1], "live")) PrintLiveUsage ();
#endif
else if (!strcmp(argv[i+1], "all")) {
PrintGeneralUsage();
PrintExtractUsage();
PrintDASHUsage();
PrintDumpUsage();
PrintImportUsage();
PrintFormats();
PrintHintUsage();
PrintEncodeUsage();
PrintEncryptUsage();
PrintMetaUsage();
PrintSWFUsage();
#if !defined(GPAC_DISABLE_STREAMING) && !defined(GPAC_DISABLE_SENG)
PrintStreamerUsage();
PrintLiveUsage ();
#endif
}
else PrintUsage();
MP4BOX_EXIT_WITH_CODE(0);
}
else if (!stricmp(arg, "-v")) verbose++;
else if (!stricmp(arg, "-tag-list")) {
fprintf(stderr, "Supported iTunes tag modifiers:\n");
for (i=0; i<nb_itunes_tags; i++) {
fprintf(stderr, "\t%s\t%s\n", itags[i].name, itags[i].comment);
}
MP4BOX_EXIT_WITH_CODE(0);
} else if (!live_scene && !stream_rtp) {
fprintf(stderr, "Option %s unknown. Please check usage\n", arg);
MP4BOX_EXIT_WITH_CODE(1);
}
}
if (!inName && dump_std)
inName = "std";
if (!inName) {
PrintUsage();
MP4BOX_EXIT_WITH_CODE(1);
}
if (!strcmp(inName, "std")) dump_std = 2;
if (!strcmp(inName, "stdb")) {
inName = "std";
dump_std = 1;
}
if (!interleaving_time) {
/*by default use single fragment per dash segment*/
if (dash_duration)
interleaving_time = dash_duration;
else
interleaving_time = 0.5;
}
if (dump_std)
outName = "std";
if (dump_std==2) {
#ifdef WIN32
if ( _setmode(_fileno(stdout), _O_BINARY) == -1 )
#else
if ( freopen(NULL, "wb", stdout) == NULL)
#endif
{
fprintf(stderr, "Fatal error: cannot reopen stdout in binary mode.\n");
MP4BOX_EXIT_WITH_CODE(1);
}
}
#if !defined(GPAC_DISABLE_STREAMING) && !defined(GPAC_DISABLE_SENG)
if (live_scene) {
int ret = live_session(argc, argv);
MP4BOX_EXIT_WITH_CODE(ret);
}
if (stream_rtp) {
int ret = stream_file_rtp(argc, argv);
MP4BOX_EXIT_WITH_CODE(ret);
}
#endif
if (raw_cat) {
char chunk[4096];
FILE *fin, *fout;
s64 to_copy, done;
fin = gf_fopen(raw_cat, "rb");
if (!fin) MP4BOX_EXIT_WITH_CODE(1);
fout = gf_fopen(inName, "a+b");
if (!fout) {
gf_fclose(fin);
MP4BOX_EXIT_WITH_CODE(1);
}
gf_fseek(fin, 0, SEEK_END);
to_copy = gf_ftell(fin);
gf_fseek(fin, 0, SEEK_SET);
done = 0;
while (1) {
u32 nb_bytes = (u32) fread(chunk, 1, 4096, fin);
gf_fwrite(chunk, 1, nb_bytes, fout);
done += nb_bytes;
fprintf(stderr, "Appending file %s - %02.2f done\r", raw_cat, 100.0*done/to_copy);
if (done >= to_copy) break;
}
gf_fclose(fin);
gf_fclose(fout);
MP4BOX_EXIT_WITH_CODE(0);
}
#if !defined(GPAC_DISABLE_STREAMING)
if (grab_m2ts) {
return grab_live_m2ts(grab_m2ts, grab_ifce, inName);
}
#endif
if (gf_logs) {
//gf_log_set_tools_levels(gf_logs);
} else {
u32 level = verbose ? GF_LOG_DEBUG : GF_LOG_INFO;
gf_log_set_tool_level(GF_LOG_CONTAINER, level);
gf_log_set_tool_level(GF_LOG_SCENE, level);
gf_log_set_tool_level(GF_LOG_PARSER, level);
gf_log_set_tool_level(GF_LOG_AUTHOR, level);
gf_log_set_tool_level(GF_LOG_CODING, level);
#ifdef GPAC_MEMORY_TRACKING
if (enable_mem_tracker)
gf_log_set_tool_level(GF_LOG_MEMORY, level);
#endif
if (quiet) {
if (quiet==2) gf_log_set_tool_level(GF_LOG_ALL, GF_LOG_QUIET);
gf_set_progress_callback(NULL, progress_quiet);
}
}
#if !defined(DISABLE_CORE_TOOLS)
if (do_wget != NULL) {
e = gf_dm_wget(do_wget, inName, 0, 0, NULL);
if (e != GF_OK) {
fprintf(stderr, "Cannot retrieve %s: %s\n", do_wget, gf_error_to_string(e) );
}
MP4BOX_EXIT_WITH_CODE(1);
}
#endif
#ifndef GPAC_DISABLE_MPD
if (do_mpd) {
Bool remote = GF_FALSE;
char *mpd_base_url = NULL;
if (!strnicmp(inName, "http://", 7)) {
#if !defined(GPAC_DISABLE_CORE_TOOLS)
e = gf_dm_wget(inName, "tmp_main.m3u8", 0, 0, &mpd_base_url);
if (e != GF_OK) {
fprintf(stderr, "Cannot retrieve M3U8 (%s): %s\n", inName, gf_error_to_string(e));
if (mpd_base_url) gf_free(mpd_base_url);
MP4BOX_EXIT_WITH_CODE(1);
}
remote = GF_TRUE;
#else
gf_free(mpd_base_url);
fprintf(stderr, "HTTP Downloader disabled in this build\n");
MP4BOX_EXIT_WITH_CODE(1);
#endif
}
e = gf_m3u8_to_mpd(remote ? "tmp_main.m3u8" : inName, mpd_base_url ? mpd_base_url : inName, (outName ? outName : inName), 0, "video/mp2t", GF_TRUE, use_url_template, NULL);
if (mpd_base_url) gf_free(mpd_base_url);
if (remote) {
//gf_delete_file("tmp_main.m3u8");
}
if (e != GF_OK) {
fprintf(stderr, "Error converting M3U8 (%s) to MPD (%s): %s\n", inName, outName, gf_error_to_string(e));
MP4BOX_EXIT_WITH_CODE(1);
} else {
fprintf(stderr, "Done converting M3U8 (%s) to MPD (%s)\n", inName, outName);
MP4BOX_EXIT_WITH_CODE(0);
}
}
#endif
if (dash_duration && !nb_dash_inputs) {
dash_inputs = set_dash_input(dash_inputs, inName, &nb_dash_inputs);
}
if (do_saf && !encode) {
switch (get_file_type_by_ext(inName)) {
case GF_FILE_TYPE_BT_WRL_X3DV:
case GF_FILE_TYPE_XMT_X3D:
case GF_FILE_TYPE_SVG:
encode = 1;
break;
case GF_FILE_TYPE_NOT_SUPPORTED:
case GF_FILE_TYPE_ISO_MEDIA:
case GF_FILE_TYPE_SWF:
case GF_FILE_TYPE_LSR_SAF:
break;
}
}
#ifndef GPAC_DISABLE_SCENE_DUMP
if (dump_mode == GF_SM_DUMP_SVG) {
if (strstr(inName, ".srt") || strstr(inName, ".ttxt")) import_subtitle = 2;
}
#endif
if (import_subtitle && !trackID) {
/* We import the subtitle file,
i.e. we parse it and store the content as samples of a 3GPP Timed Text track in an ISO file,
possibly for later export (e.g. when converting SRT to TTXT, ...) */
#ifndef GPAC_DISABLE_MEDIA_IMPORT
GF_MediaImporter import;
/* Prepare the importer */
file = gf_isom_open("ttxt_convert", GF_ISOM_OPEN_WRITE, NULL);
if (timescale && file) gf_isom_set_timescale(file, timescale);
memset(&import, 0, sizeof(GF_MediaImporter));
import.dest = file;
import.in_name = inName;
/* Start the import */
e = gf_media_import(&import);
if (e) {
fprintf(stderr, "Error importing %s: %s\n", inName, gf_error_to_string(e));
gf_isom_delete(file);
gf_delete_file("ttxt_convert");
MP4BOX_EXIT_WITH_CODE(1);
}
/* Prepare the export */
strcpy(outfile, inName);
if (strchr(outfile, '.')) {
while (outfile[strlen(outfile)-1] != '.') outfile[strlen(outfile)-1] = 0;
outfile[strlen(outfile)-1] = 0;
}
#ifndef GPAC_DISABLE_ISOM_DUMP
/* Start the export of the track #1, in the appropriate dump type, indicating it's a conversion */
dump_timed_text_track(file, gf_isom_get_track_id(file, 1),
dump_std ? NULL : outfile,
GF_TRUE,
(import_subtitle==2) ? GF_TEXTDUMPTYPE_SVG : (dump_srt ? GF_TEXTDUMPTYPE_SRT : GF_TEXTDUMPTYPE_TTXT));
#endif
/* Clean the importer */
gf_isom_delete(file);
gf_delete_file("ttxt_convert");
if (e) {
fprintf(stderr, "Error converting %s: %s\n", inName, gf_error_to_string(e));
MP4BOX_EXIT_WITH_CODE(1);
}
MP4BOX_EXIT_WITH_CODE(0);
#else
fprintf(stderr, "Feature not supported\n");
MP4BOX_EXIT_WITH_CODE(1);
#endif
}
#if !defined(GPAC_DISABLE_MEDIA_IMPORT) && !defined(GPAC_DISABLE_ISOM_WRITE)
if (nb_add) {
u8 open_mode = GF_ISOM_OPEN_EDIT;
if (force_new) {
open_mode = (do_flat) ? GF_ISOM_OPEN_WRITE : GF_ISOM_WRITE_EDIT;
} else {
FILE *test = gf_fopen(inName, "rb");
if (!test) {
open_mode = (do_flat) ? GF_ISOM_OPEN_WRITE : GF_ISOM_WRITE_EDIT;
if (!outName) outName = inName;
} else {
gf_fclose(test);
if (! gf_isom_probe_file(inName) ) {
open_mode = (do_flat) ? GF_ISOM_OPEN_WRITE : GF_ISOM_WRITE_EDIT;
if (!outName) outName = inName;
}
}
}
open_edit = 1;
file = gf_isom_open(inName, open_mode, tmpdir);
if (!file) {
fprintf(stderr, "Cannot open destination file %s: %s\n", inName, gf_error_to_string(gf_isom_last_error(NULL)) );
MP4BOX_EXIT_WITH_CODE(1);
}
for (i=0; i<(u32) argc; i++) {
if (!strcmp(argv[i], "-add")) {
char *src = argv[i+1];
e = import_file(file, src, import_flags, import_fps, agg_samples);
if (e) {
while (src) {
char *sep = strchr(src, '+');
if (sep) {
sep[0] = 0;
} else {
break;
}
e = import_file(file, src, import_flags, import_fps, agg_samples);
if (sep) {
sep[0] = '+';
src = sep+1;
} else {
src= NULL;
}
if (e)
break;
}
if (e) {
fprintf(stderr, "Error importing %s: %s\n", argv[i+1], gf_error_to_string(e));
gf_isom_delete(file);
MP4BOX_EXIT_WITH_CODE(1);
}
}
i++;
}
}
/*unless explicitly asked, remove all systems tracks*/
if (!keep_sys_tracks) remove_systems_tracks(file);
needSave = 1;
}
if (nb_cat) {
if (!file) {
u8 open_mode = GF_ISOM_OPEN_EDIT;
if (force_new) {
open_mode = (do_flat) ? GF_ISOM_OPEN_WRITE : GF_ISOM_WRITE_EDIT;
} else {
FILE *test = gf_fopen(inName, "rb");
if (!test) {
open_mode = (do_flat) ? GF_ISOM_OPEN_WRITE : GF_ISOM_WRITE_EDIT;
if (!outName) outName = inName;
}
else gf_fclose(test);
}
open_edit = 1;
file = gf_isom_open(inName, open_mode, tmpdir);
if (!file) {
fprintf(stderr, "Cannot open destination file %s: %s\n", inName, gf_error_to_string(gf_isom_last_error(NULL)) );
MP4BOX_EXIT_WITH_CODE(1);
}
}
for (i=0; i<(u32)argc; i++) {
if (!strcmp(argv[i], "-cat") || !strcmp(argv[i], "-catx")) {
e = cat_isomedia_file(file, argv[i+1], import_flags, import_fps, agg_samples, tmpdir, force_cat, align_cat, !strcmp(argv[i], "-catx") ? GF_TRUE : GF_FALSE);
if (e) {
fprintf(stderr, "Error appending %s: %s\n", argv[i+1], gf_error_to_string(e));
gf_isom_delete(file);
MP4BOX_EXIT_WITH_CODE(1);
}
i++;
}
}
/*unless explicitly asked, remove all systems tracks*/
if (!keep_sys_tracks) remove_systems_tracks(file);
needSave = 1;
if (conv_type && can_convert_to_isma(file)) conv_type = GF_ISOM_CONV_TYPE_ISMA;
}
#endif
#if !defined(GPAC_DISABLE_ISOM_WRITE) && !defined(GPAC_DISABLE_SCENE_ENCODER) && !defined(GPAC_DISABLE_MEDIA_IMPORT)
else if (chunk_mode) {
if (!inName) {
fprintf(stderr, "chunk encoding syntax: [-outctx outDump] -inctx inScene auFile\n");
MP4BOX_EXIT_WITH_CODE(1);
}
e = EncodeFileChunk(inName, outName ? outName : inName, input_ctx, output_ctx, tmpdir);
if (e) fprintf(stderr, "Error encoding chunk file %s\n", gf_error_to_string(e));
MP4BOX_EXIT_WITH_CODE( e ? 1 : 0 );
}
#endif
else if (encode) {
#if !defined(GPAC_DISABLE_ISOM_WRITE) && !defined(GPAC_DISABLE_SCENE_ENCODER) && !defined(GPAC_DISABLE_MEDIA_IMPORT)
FILE *logs = NULL;
if (do_log) {
char logfile[5000];
strcpy(logfile, inName);
if (strchr(logfile, '.')) {
while (logfile[strlen(logfile)-1] != '.') logfile[strlen(logfile)-1] = 0;
logfile[strlen(logfile)-1] = 0;
}
strcat(logfile, "_enc.logs");
logs = gf_fopen(logfile, "wt");
}
strcpy(outfile, outName ? outName : inName);
if (strchr(outfile, '.')) {
while (outfile[strlen(outfile)-1] != '.') outfile[strlen(outfile)-1] = 0;
outfile[strlen(outfile)-1] = 0;
}
strcat(outfile, ".mp4");
file = gf_isom_open(outfile, GF_ISOM_WRITE_EDIT, tmpdir);
opts.mediaSource = mediaSource ? mediaSource : outfile;
e = EncodeFile(inName, file, &opts, logs);
if (logs) gf_fclose(logs);
if (e) goto err_exit;
needSave = 1;
if (do_saf) {
needSave = 0;
open_edit = 0;
}
#endif
}
#ifndef GPAC_DISABLE_ISOM_WRITE
else if (pack_file) {
char *fileName = strchr(pack_file, ':');
if (fileName && ((fileName - pack_file)==4)) {
fileName[0] = 0;
file = package_file(fileName + 1, pack_file, tmpdir, pack_wgt);
fileName[0] = ':';
} else {
file = package_file(pack_file, NULL, tmpdir, pack_wgt);
}
if (!outName) outName = inName;
needSave = 1;
open_edit = 1;
}
#endif
if (dash_duration) {
Bool del_file = GF_FALSE;
char szMPD[GF_MAX_PATH], *sep;
GF_Config *dash_ctx = NULL;
u32 do_abort = 0;
GF_DASHSegmenter *dasher;
gf_log_set_tool_level(GF_LOG_DASH, GF_LOG_INFO);
strcpy(outfile, outName ? outName : gf_url_get_resource_name(inName) );
sep = strrchr(outfile, '.');
if (sep) sep[0] = 0;
if (!outName) strcat(outfile, "_dash");
strcpy(szMPD, outfile);
strcat(szMPD, ".mpd");
if ((dash_subduration>0) && (dash_duration > dash_subduration)) {
fprintf(stderr, "Warning: -subdur parameter (%g s) should be greater than segment duration (%g s), using segment duration instead\n", dash_subduration, dash_duration);
dash_subduration = dash_duration;
}
if (dash_mode && dash_live)
fprintf(stderr, "Live DASH-ing - press 'q' to quit, 's' to save context and quit\n");
if (!dash_ctx_file && dash_live) {
dash_ctx = gf_cfg_new(NULL, NULL);
} else if (dash_ctx_file) {
if (force_new)
gf_delete_file(dash_ctx_file);
dash_ctx = gf_cfg_force_new(NULL, dash_ctx_file);
}
if (dash_profile==GF_DASH_PROFILE_UNKNOWN)
dash_profile = dash_mode ? GF_DASH_PROFILE_LIVE : GF_DASH_PROFILE_FULL;
if (!dash_mode) {
time_shift_depth = 0;
mpd_update_time = 0;
} else if ((dash_profile>=GF_DASH_PROFILE_MAIN) && !use_url_template && !mpd_update_time) {
/*use a default MPD update of dash_duration sec*/
mpd_update_time = (Double) (dash_subduration ? dash_subduration : dash_duration);
fprintf(stderr, "Using default MPD refresh of %g seconds\n", mpd_update_time);
}
if (file && needSave) {
gf_isom_close(file);
file = NULL;
del_file = GF_TRUE;
}
/*setup dash*/
dasher = gf_dasher_new(szMPD, dash_profile, tmpdir, dash_scale, dash_ctx);
if (!dasher) {
MP4BOX_EXIT_WITH_CODE( 1 );
return GF_OUT_OF_MEM;
}
e = gf_dasher_set_info(dasher, dash_title, cprt, dash_more_info, dash_source);
if (e) { fprintf(stderr, "DASH Error: %s\n", gf_error_to_string(e)); MP4BOX_EXIT_WITH_CODE( 1 ); }
//e = gf_dasher_set_location(dasher, mpd_source);
for (i=0; i < nb_mpd_base_urls; i++) {
e = gf_dasher_add_base_url(dasher, mpd_base_urls[i]);
if (e) { fprintf(stderr, "DASH Error: %s\n", gf_error_to_string(e)); MP4BOX_EXIT_WITH_CODE( 1 ); }
}
e = gf_dasher_enable_url_template(dasher, (Bool) use_url_template, seg_name, seg_ext);
if (!e) e = gf_dasher_enable_segment_timeline(dasher, segment_timeline);
if (!e) e = gf_dasher_enable_single_segment(dasher, single_segment);
if (!e) e = gf_dasher_enable_single_file(dasher, single_file);
if (!e) e = gf_dasher_set_switch_mode(dasher, bitstream_switching_mode);
if (!e) e = gf_dasher_set_durations(dasher, dash_duration, interleaving_time);
if (!e) e = gf_dasher_enable_rap_splitting(dasher, seg_at_rap, frag_at_rap);
if (!e) e = gf_dasher_set_segment_marker(dasher, segment_marker);
if (!e) e = gf_dasher_enable_sidx(dasher, (subsegs_per_sidx>=0) ? 1 : 0, (u32) subsegs_per_sidx, daisy_chain_sidx);
if (!e) e = gf_dasher_set_dynamic_mode(dasher, dash_mode, mpd_update_time, time_shift_depth, mpd_live_duration);
if (!e) e = gf_dasher_set_min_buffer(dasher, min_buffer);
if (!e) e = gf_dasher_set_ast_offset(dasher, ast_offset_ms);
if (!e) e = gf_dasher_enable_memory_fragmenting(dasher, memory_frags);
if (!e) e = gf_dasher_set_initial_isobmf(dasher, initial_moof_sn, initial_tfdt);
if (!e) e = gf_dasher_configure_isobmf_default(dasher, no_fragments_defaults, pssh_in_moof, samplegroups_in_traf, single_traf_per_moof);
if (!e) e = gf_dasher_enable_utc_ref(dasher, insert_utc);
if (!e) e = gf_dasher_enable_real_time(dasher, frag_real_time);
if (!e) e = gf_dasher_set_profile_extension(dasher, dash_profile_extension);
for (i=0; i < nb_dash_inputs; i++) {
if (!e) e = gf_dasher_add_input(dasher, &dash_inputs[i]);
}
if (e) {
fprintf(stderr, "DASH Setup Error: %s\n", gf_error_to_string(e));
MP4BOX_EXIT_WITH_CODE( 1 );
}
while (1) {
if (do_abort>=2) {
e = gf_dasher_set_dynamic_mode(dasher, GF_DASH_DYNAMIC_LAST, 0, time_shift_depth, mpd_live_duration);
}
if (!e) e = gf_dasher_process(dasher, dash_subduration);
if (do_abort)
break;
//this happens when reading file while writing them (local playback of the live session ...)
if (dash_live && (e==GF_IO_ERR) ) {
fprintf(stderr, "Error dashing file (%s) but continuing ...\n", gf_error_to_string(e) );
e = GF_OK;
}
if (e) break;
if (dash_live) {
u32 slept = gf_sys_clock();
u32 sleep_for = gf_dasher_next_update_time(dasher);
fprintf(stderr, "Next generation scheduled in %d ms\n", sleep_for);
while (1) {
if (gf_prompt_has_input()) {
char c = (char) gf_prompt_get_char();
if (c=='X') {
do_abort = 1;
break;
}
if (c=='q') {
do_abort = 2;
break;
}
if (c=='s') {
do_abort = 3;
break;
}
}
if (dash_mode == GF_DASH_DYNAMIC_DEBUG) {
break;
}
if (!sleep_for) break;
gf_sleep(10);
sleep_for = gf_dasher_next_update_time(dasher);
if (sleep_for<10) {
fprintf(stderr, "Slept for %d ms before generation\n", gf_sys_clock() - slept);
break;
}
}
} else {
break;
}
}
gf_dasher_del(dasher);
if (dash_ctx) {
if (do_abort==3) {
if (!dash_ctx_file) {
char szName[1024];
fprintf(stderr, "Enter file name to save dash context:\n");
if (scanf("%s", szName) == 1) {
gf_cfg_set_filename(dash_ctx, szName);
gf_cfg_save(dash_ctx);
}
}
}
gf_cfg_del(dash_ctx);
}
if (e) fprintf(stderr, "Error DASHing file: %s\n", gf_error_to_string(e));
if (file) gf_isom_delete(file);
if (del_file)
gf_delete_file(inName);
MP4BOX_EXIT_WITH_CODE( (e!=GF_OK) ? 1 : 0 );
}
else if (!file
#ifndef GPAC_DISABLE_MEDIA_EXPORT
&& !(track_dump_type & GF_EXPORT_AVI_NATIVE)
#endif
) {
FILE *st = gf_fopen(inName, "rb");
Bool file_exists = 0;
if (st) {
file_exists = 1;
gf_fclose(st);
}
switch (get_file_type_by_ext(inName)) {
case 1:
file = gf_isom_open(inName, (u8) (open_edit ? GF_ISOM_OPEN_EDIT : ( ((dump_isom>0) || print_info) ? GF_ISOM_OPEN_READ_DUMP : GF_ISOM_OPEN_READ) ), tmpdir);
if (!file && (gf_isom_last_error(NULL) == GF_ISOM_INCOMPLETE_FILE) && !open_edit) {
u64 missing_bytes;
e = gf_isom_open_progressive(inName, 0, 0, &file, &missing_bytes);
fprintf(stderr, "Truncated file - missing "LLD" bytes\n", missing_bytes);
}
if (!file) {
if (open_edit && nb_meta_act) {
file = gf_isom_open(inName, GF_ISOM_WRITE_EDIT, tmpdir);
if (!outName && file) outName = inName;
}
if (!file) {
fprintf(stderr, "Error opening file %s: %s\n", inName, gf_error_to_string(gf_isom_last_error(NULL)));
MP4BOX_EXIT_WITH_CODE(1);
}
}
break;
/*allowed for bt<->xmt*/
case 2:
case 3:
/*allowed for svg->lsr**/
case 4:
/*allowed for swf->bt, swf->xmt, swf->svg*/
case 5:
break;
/*used for .saf / .lsr dump*/
case 6:
#ifndef GPAC_DISABLE_SCENE_DUMP
if ((dump_mode==GF_SM_DUMP_LASER) || (dump_mode==GF_SM_DUMP_SVG)) {
break;
}
#endif
default:
if (!open_edit && file_exists && !gf_isom_probe_file(inName) && track_dump_type) {
}
#ifndef GPAC_DISABLE_ISOM_WRITE
else if (!open_edit && file_exists /* && !gf_isom_probe_file(inName) */
#ifndef GPAC_DISABLE_SCENE_DUMP
&& dump_mode == GF_SM_DUMP_NONE
#endif
) {
/*************************************************************************************************/
#ifndef GPAC_DISABLE_MEDIA_IMPORT
if(dvbhdemux)
{
GF_MediaImporter import;
file = gf_isom_open("ttxt_convert", GF_ISOM_OPEN_WRITE, NULL);
memset(&import, 0, sizeof(GF_MediaImporter));
import.dest = file;
import.in_name = inName;
import.flags = GF_IMPORT_MPE_DEMUX;
e = gf_media_import(&import);
if (e) {
fprintf(stderr, "Error importing %s: %s\n", inName, gf_error_to_string(e));
gf_isom_delete(file);
gf_delete_file("ttxt_convert");
MP4BOX_EXIT_WITH_CODE(1);
}
}
#endif /*GPAC_DISABLE_MEDIA_IMPORT*/
if (dump_m2ts) {
#ifndef GPAC_DISABLE_MPEG2TS
dump_mpeg2_ts(inName, pes_dump, program_number);
#endif
} else if (dump_timestamps) {
#ifndef GPAC_DISABLE_MPEG2TS
dump_mpeg2_ts(inName, pes_dump, program_number);
#endif
} else if (do_bin_nhml) {
nhml_bs_to_bin(inName, outName, dump_std);
} else if (do_hash) {
hash_file(inName, dump_std);
} else {
#ifndef GPAC_DISABLE_MEDIA_IMPORT
convert_file_info(inName, info_track_id);
#endif
}
MP4BOX_EXIT_WITH_CODE(0);
}
#endif /*GPAC_DISABLE_ISOM_WRITE*/
else if (open_edit) {
file = gf_isom_open(inName, GF_ISOM_WRITE_EDIT, tmpdir);
if (!outName && file) outName = inName;
} else if (!file_exists) {
fprintf(stderr, "Error creating file %s: %s\n", inName, gf_error_to_string(GF_URL_ERROR));
MP4BOX_EXIT_WITH_CODE(1);
} else {
fprintf(stderr, "Cannot open %s - extension not supported\n", inName);
MP4BOX_EXIT_WITH_CODE(1);
}
}
}
if (file && keep_utc && open_edit) {
gf_isom_keep_utc_times(file, 1);
}
strcpy(outfile, outName ? outName : inName);
if (strrchr(outfile, '.')) {
char *szExt = strrchr(outfile, '.');
/*turn on 3GP saving*/
if (!stricmp(szExt, ".3gp") || !stricmp(szExt, ".3gpp") || !stricmp(szExt, ".3g2"))
conv_type = GF_ISOM_CONV_TYPE_3GPP;
else if (!stricmp(szExt, ".m4a") || !stricmp(szExt, ".m4v"))
conv_type = GF_ISOM_CONV_TYPE_IPOD;
else if (!stricmp(szExt, ".psp"))
conv_type = GF_ISOM_CONV_TYPE_PSP;
while (outfile[strlen(outfile)-1] != '.') outfile[strlen(outfile)-1] = 0;
outfile[strlen(outfile)-1] = 0;
}
#ifndef GPAC_DISABLE_MEDIA_EXPORT
if (track_dump_type & GF_EXPORT_AVI_NATIVE) {
char szFile[1024];
GF_MediaExporter mdump;
memset(&mdump, 0, sizeof(mdump));
mdump.in_name = inName;
mdump.flags = GF_EXPORT_AVI_NATIVE;
mdump.trackID = trackID;
if (dump_std) {
mdump.out_name = "std";
} else if (outName) {
mdump.out_name = outName;
} else if (trackID>2) {
sprintf(szFile, "%s_audio%d", outfile, trackID-1);
mdump.out_name = szFile;
} else {
sprintf(szFile, "%s_%s", outfile, (trackID==1) ? "video" : "audio");
mdump.out_name = szFile;
}
e = gf_media_export(&mdump);
if (e) goto err_exit;
MP4BOX_EXIT_WITH_CODE(0);
}
if (!open_edit && !gf_isom_probe_file(inName) && track_dump_type) {
GF_MediaExporter mdump;
char szFile[1024];
for (i=0; i<nb_track_act; i++) {
TrackAction *tka = &tracks[i];
if (tka->act_type != TRAC_ACTION_RAW_EXTRACT) continue;
memset(&mdump, 0, sizeof(mdump));
mdump.in_name = inName;
mdump.flags = tka->dump_type;
mdump.trackID = tka->trackID;
mdump.sample_num = raw_sample_num;
if (outName) {
mdump.out_name = outName;
mdump.flags |= GF_EXPORT_MERGE;
} else if (nb_track_act>1) {
sprintf(szFile, "%s_track%d", outfile, mdump.trackID);
mdump.out_name = szFile;
} else {
mdump.out_name = outfile;
}
e = gf_media_export(&mdump);
if (e) goto err_exit;
}
MP4BOX_EXIT_WITH_CODE(0);
}
#endif /*GPAC_DISABLE_MEDIA_EXPORT*/
#ifndef GPAC_DISABLE_SCENE_DUMP
if (dump_mode != GF_SM_DUMP_NONE) {
e = dump_file_text(inName, dump_std ? NULL : outfile, dump_mode, do_log);
if (e) goto err_exit;
}
#endif
#ifndef GPAC_DISABLE_SCENE_STATS
if (stat_level) dump_scene_stats(inName, dump_std ? NULL : outfile, stat_level);
#endif
#ifndef GPAC_DISABLE_ISOM_HINTING
if (!HintIt && print_sdp) DumpSDP(file, dump_std ? NULL : outfile);
#endif
if (print_info) {
if (!file) {
fprintf(stderr, "Cannot print info on a non ISOM file (%s)\n", inName);
} else {
if (info_track_id) DumpTrackInfo(file, info_track_id, 1);
else DumpMovieInfo(file);
}
}
#ifndef GPAC_DISABLE_ISOM_DUMP
if (dump_isom) dump_isom_xml(file, dump_std ? NULL : outfile);
if (dump_cr) dump_file_ismacryp(file, dump_std ? NULL : outfile);
if ((dump_ttxt || dump_srt) && trackID) dump_timed_text_track(file, trackID, dump_std ? NULL : outfile, 0, dump_srt ? GF_TEXTDUMPTYPE_SRT : GF_TEXTDUMPTYPE_TTXT);
#ifndef GPAC_DISABLE_ISOM_HINTING
if (dump_rtp) dump_file_rtp(file, dump_std ? NULL : outfile);
#endif
#endif
if (dump_timestamps) dump_file_timestamps(file, dump_std ? NULL : outfile);
if (dump_nal) dump_file_nal(file, dump_nal, dump_std ? NULL : outfile);
if (do_hash) {
e = hash_file(inName, dump_std);
if (e) goto err_exit;
}
if (do_bin_nhml) {
e = nhml_bs_to_bin(inName, outName, dump_std);
if (e) goto err_exit;
}
if (dump_cart) dump_cover_art(file, outfile);
if (dump_chap) dump_chapters(file, outfile, (dump_chap==2) ? 1 : 0);
if (dump_udta_type) dump_udta(file, outfile, dump_udta_type, dump_udta_track);
if (dump_iod) {
GF_InitialObjectDescriptor *iod = (GF_InitialObjectDescriptor *)gf_isom_get_root_od(file);
if (!iod) {
fprintf(stderr, "File %s has no IOD", inName);
} else {
char szName[GF_MAX_PATH];
FILE *iodf;
GF_BitStream *bs = NULL;
sprintf(szName, "%s.iod", outfile);
iodf = gf_fopen(szName, "wb");
if (!iodf) {
fprintf(stderr, "Cannot open destination %s\n", szName);
} else {
char *desc;
u32 size;
bs = gf_bs_from_file(iodf, GF_BITSTREAM_WRITE);
if (gf_odf_desc_write((GF_Descriptor *)iod, &desc, &size)==GF_OK) {
gf_fwrite(desc, 1, size, iodf);
gf_free(desc);
} else {
fprintf(stderr, "Error writing IOD %s\n", szName);
}
gf_fclose(iodf);
}
gf_free(bs);
}
}
#if !(definedGPAC_DISABLE_ISOM_WRITE) && !defined(GPAC_DISABLE_MEDIA_IMPORT)
if (split_duration || split_size) {
split_isomedia_file(file, split_duration, split_size, inName, interleaving_time, split_start, adjust_split_end, outName, tmpdir);
/*never save file when splitting is desired*/
open_edit = 0;
needSave = 0;
}
#endif
#ifndef GPAC_DISABLE_MEDIA_EXPORT
if (track_dump_type) {
char szFile[1024];
GF_MediaExporter mdump;
for (i=0; i<nb_track_act; i++) {
TrackAction *tka = &tracks[i];
if (tka->act_type != TRAC_ACTION_RAW_EXTRACT) continue;
memset(&mdump, 0, sizeof(mdump));
mdump.file = file;
mdump.flags = tka->dump_type;
mdump.trackID = tka->trackID;
mdump.sample_num = raw_sample_num;
if (tka->out_name) {
mdump.out_name = tka->out_name;
} else if (outName) {
mdump.out_name = outName;
mdump.flags |= GF_EXPORT_MERGE;
} else {
sprintf(szFile, "%s_track%d", outfile, mdump.trackID);
mdump.out_name = szFile;
}
if (tka->trackID==(u32) -1) {
u32 j;
for (j=0; j<gf_isom_get_track_count(file); j++) {
mdump.trackID = gf_isom_get_track_id(file, j+1);
sprintf(szFile, "%s_track%d", outfile, mdump.trackID);
mdump.out_name = szFile;
e = gf_media_export(&mdump);
if (e) goto err_exit;
}
} else {
e = gf_media_export(&mdump);
if (e) goto err_exit;
}
}
} else if (do_saf) {
GF_MediaExporter mdump;
memset(&mdump, 0, sizeof(mdump));
mdump.file = file;
mdump.flags = GF_EXPORT_SAF;
mdump.out_name = outfile;
e = gf_media_export(&mdump);
if (e) goto err_exit;
}
#endif
for (i=0; i<nb_meta_act; i++) {
u32 tk = 0;
Bool self_ref;
MetaAction *meta = &metas[i];
if (meta->trackID) tk = gf_isom_get_track_by_id(file, meta->trackID);
switch (meta->act_type) {
#ifndef GPAC_DISABLE_ISOM_WRITE
case META_ACTION_SET_TYPE:
/*note: we don't handle file brand modification, this is an author stuff and cannot be guessed from meta type*/
e = gf_isom_set_meta_type(file, meta->root_meta, tk, meta->meta_4cc);
gf_isom_modify_alternate_brand(file, GF_ISOM_BRAND_ISO2, 1);
needSave = 1;
break;
case META_ACTION_ADD_ITEM:
self_ref = !stricmp(meta->szPath, "NULL") || !stricmp(meta->szPath, "this") || !stricmp(meta->szPath, "self");
e = gf_isom_add_meta_item(file, meta->root_meta, tk, self_ref, self_ref ? NULL : meta->szPath,
strlen(meta->szName) ? meta->szName : NULL,
meta->item_id,
strlen(meta->mime_type) ? meta->mime_type : NULL,
strlen(meta->enc_type) ? meta->enc_type : NULL,
meta->use_dref ? meta->szPath : NULL, NULL);
needSave = 1;
break;
case META_ACTION_REM_ITEM:
e = gf_isom_remove_meta_item(file, meta->root_meta, tk, meta->item_id);
needSave = 1;
break;
case META_ACTION_SET_PRIMARY_ITEM:
e = gf_isom_set_meta_primary_item(file, meta->root_meta, tk, meta->item_id);
needSave = 1;
break;
case META_ACTION_SET_XML:
case META_ACTION_SET_BINARY_XML:
e = gf_isom_set_meta_xml(file, meta->root_meta, tk, meta->szPath, (meta->act_type==META_ACTION_SET_BINARY_XML) ? 1 : 0);
needSave = 1;
break;
case META_ACTION_REM_XML:
if (gf_isom_get_meta_item_count(file, meta->root_meta, tk)) {
e = gf_isom_remove_meta_xml(file, meta->root_meta, tk);
needSave = 1;
} else {
fprintf(stderr, "No meta box in input file\n");
}
break;
case META_ACTION_DUMP_ITEM:
if (gf_isom_get_meta_item_count(file, meta->root_meta, tk)) {
e = gf_isom_extract_meta_item(file, meta->root_meta, tk, meta->item_id, strlen(meta->szPath) ? meta->szPath : NULL);
} else {
fprintf(stderr, "No meta box in input file\n");
}
break;
#endif
case META_ACTION_DUMP_XML:
if (gf_isom_has_meta_xml(file, meta->root_meta, tk)) {
e = gf_isom_extract_meta_xml(file, meta->root_meta, tk, meta->szPath, NULL);
} else {
fprintf(stderr, "No meta box in input file\n");
}
break;
default:
break;
}
if (e) goto err_exit;
}
if (!open_edit && !needSave) {
if (file) gf_isom_delete(file);
MP4BOX_EXIT_WITH_CODE(0);
}
#ifndef GPAC_DISABLE_ISOM_WRITE
for (i=0; i<nb_tsel_acts; i++) {
switch (tsel_acts[i].act_type) {
case TSEL_ACTION_SET_PARAM:
e = gf_isom_set_track_switch_parameter(file,
gf_isom_get_track_by_id(file, tsel_acts[i].trackID),
tsel_acts[i].refTrackID ? gf_isom_get_track_by_id(file, tsel_acts[i].refTrackID) : 0,
tsel_acts[i].is_switchGroup ? 1 : 0,
&tsel_acts[i].switchGroupID,
tsel_acts[i].criteria, tsel_acts[i].nb_criteria);
if (e) goto err_exit;
needSave = 1;
break;
case TSEL_ACTION_REMOVE_TSEL:
e = gf_isom_reset_track_switch_parameter(file, gf_isom_get_track_by_id(file, tsel_acts[i].trackID), 0);
if (e) goto err_exit;
needSave = 1;
break;
case TSEL_ACTION_REMOVE_ALL_TSEL_IN_GROUP:
e = gf_isom_reset_track_switch_parameter(file, gf_isom_get_track_by_id(file, tsel_acts[i].trackID), 1);
if (e) goto err_exit;
needSave = 1;
break;
case TSEL_ACTION_REMOVE_ALL_TSEL_IN_FILE:
e = gf_isom_reset_switch_parameters(file);
if (e) goto err_exit;
needSave = 1;
break;
default:
break;
}
}
if (remove_sys_tracks) {
#ifndef GPAC_DISABLE_AV_PARSERS
remove_systems_tracks(file);
#endif
needSave = 1;
if (conv_type < GF_ISOM_CONV_TYPE_ISMA_EX) conv_type = 0;
}
if (remove_root_od) {
gf_isom_remove_root_od(file);
needSave = 1;
}
#ifndef GPAC_DISABLE_ISOM_HINTING
if (remove_hint) {
for (i=0; i<gf_isom_get_track_count(file); i++) {
if (gf_isom_get_media_type(file, i+1) == GF_ISOM_MEDIA_HINT) {
fprintf(stderr, "Removing hint track ID %d\n", gf_isom_get_track_id(file, i+1));
gf_isom_remove_track(file, i+1);
i--;
}
}
gf_isom_sdp_clean(file);
needSave = 1;
}
#endif
if (timescale && (timescale != gf_isom_get_timescale(file))) {
gf_isom_set_timescale(file, timescale);
needSave = 1;
}
if (!encode) {
if (!file) {
fprintf(stderr, "Nothing to do - exiting\n");
MP4BOX_EXIT_WITH_CODE(0);
}
if (outName) {
strcpy(outfile, outName);
} else {
char *rel_name = strrchr(inName, GF_PATH_SEPARATOR);
if (!rel_name) rel_name = strrchr(inName, '/');
strcpy(outfile, "");
if (tmpdir) {
strcpy(outfile, tmpdir);
if (!strchr("\\/", tmpdir[strlen(tmpdir)-1])) strcat(outfile, "/");
}
if (!pack_file) strcat(outfile, "out_");
strcat(outfile, rel_name ? rel_name + 1 : inName);
if (pack_file) {
strcpy(outfile, rel_name ? rel_name + 1 : inName);
rel_name = strrchr(outfile, '.');
if (rel_name) rel_name[0] = 0;
strcat(outfile, ".m21");
}
}
#ifndef GPAC_DISABLE_MEDIA_IMPORT
if ((conv_type == GF_ISOM_CONV_TYPE_ISMA) || (conv_type == GF_ISOM_CONV_TYPE_ISMA_EX)) {
fprintf(stderr, "Converting to ISMA Audio-Video MP4 file...\n");
/*keep ESIDs when doing ISMACryp*/
e = gf_media_make_isma(file, crypt ? 1 : 0, 0, (conv_type==GF_ISOM_CONV_TYPE_ISMA_EX) ? 1 : 0);
if (e) goto err_exit;
needSave = 1;
}
if (conv_type == GF_ISOM_CONV_TYPE_3GPP) {
fprintf(stderr, "Converting to 3GP file...\n");
e = gf_media_make_3gpp(file);
if (e) goto err_exit;
needSave = 1;
}
if (conv_type == GF_ISOM_CONV_TYPE_PSP) {
fprintf(stderr, "Converting to PSP file...\n");
e = gf_media_make_psp(file);
if (e) goto err_exit;
needSave = 1;
}
#endif /*GPAC_DISABLE_MEDIA_IMPORT*/
if (conv_type == GF_ISOM_CONV_TYPE_IPOD) {
u32 major_brand = 0;
fprintf(stderr, "Setting up iTunes/iPod file...\n");
for (i=0; i<gf_isom_get_track_count(file); i++) {
u32 mType = gf_isom_get_media_type(file, i+1);
switch (mType) {
case GF_ISOM_MEDIA_VISUAL:
major_brand = GF_4CC('M','4','V',' ');
gf_isom_set_ipod_compatible(file, i+1);
#if 0
switch (gf_isom_get_media_subtype(file, i+1, 1)) {
case GF_ISOM_SUBTYPE_AVC_H264:
case GF_ISOM_SUBTYPE_AVC2_H264:
case GF_ISOM_SUBTYPE_AVC3_H264:
case GF_ISOM_SUBTYPE_AVC4_H264:
fprintf(stderr, "Forcing AVC/H264 SAR to 1:1...\n");
gf_media_change_par(file, i+1, 1, 1);
break;
}
#endif
break;
case GF_ISOM_MEDIA_AUDIO:
if (!major_brand) major_brand = GF_4CC('M','4','A',' ');
else gf_isom_modify_alternate_brand(file, GF_4CC('M','4','A',' '), 1);
break;
case GF_ISOM_MEDIA_TEXT:
/*this is a text track track*/
if (gf_isom_get_media_subtype(file, i+1, 1) == GF_4CC('t','x','3','g')) {
u32 j;
Bool is_chap = 0;
for (j=0; j<gf_isom_get_track_count(file); j++) {
s32 count = gf_isom_get_reference_count(file, j+1, GF_4CC('c','h','a','p'));
if (count>0) {
u32 tk, k;
for (k=0; k<(u32) count; k++) {
gf_isom_get_reference(file, j+1, GF_4CC('c','h','a','p'), k+1, &tk);
if (tk==i+1) {
is_chap = 1;
break;
}
}
if (is_chap) break;
}
if (is_chap) break;
}
/*this is a subtitle track*/
if (!is_chap)
gf_isom_set_media_type(file, i+1, GF_ISOM_MEDIA_SUBT);
}
break;
}
}
gf_isom_set_brand_info(file, major_brand, 1);
gf_isom_modify_alternate_brand(file, GF_ISOM_BRAND_MP42, 1);
needSave = 1;
}
#ifndef GPAC_DISABLE_MCRYPT
if (crypt) {
if (!drm_file) {
fprintf(stderr, "Missing DRM file location - usage '-%s drm_file input_file\n", (crypt==1) ? "crypt" : "decrypt");
e = GF_BAD_PARAM;
goto err_exit;
}
if (crypt == 1) {
e = gf_crypt_file(file, drm_file);
} else if (crypt ==2) {
e = gf_decrypt_file(file, drm_file);
}
if (e) goto err_exit;
needSave = 1;
}
#endif /*GPAC_DISABLE_MCRYPT*/
} else if (outName) {
strcpy(outfile, outName);
}
for (i=0; i<nb_track_act; i++) {
TrackAction *tka = &tracks[i];
u32 track = tka->trackID ? gf_isom_get_track_by_id(file, tka->trackID) : 0;
u32 timescale = gf_isom_get_timescale(file);
switch (tka->act_type) {
case TRAC_ACTION_REM_TRACK:
e = gf_isom_remove_track(file, track);
if (e) {
fprintf(stderr, "Error Removing track ID %d: %s\n", tka->trackID, gf_error_to_string(e));
} else {
fprintf(stderr, "Removing track ID %d\n", tka->trackID);
}
needSave = 1;
break;
case TRAC_ACTION_SET_LANGUAGE:
for (i=0; i<gf_isom_get_track_count(file); i++) {
if (track && (track != i+1)) continue;
e = gf_isom_set_media_language(file, i+1, tka->lang);
if (e) goto err_exit;
needSave = 1;
}
needSave = 1;
break;
case TRAC_ACTION_SET_KIND:
for (i=0; i<gf_isom_get_track_count(file); i++) {
if (track && (track != i+1)) continue;
e = gf_isom_add_track_kind(file, i+1, tka->kind_scheme, tka->kind_value);
if (e) goto err_exit;
needSave = 1;
}
needSave = 1;
break;
case TRAC_ACTION_REM_KIND:
for (i=0; i<gf_isom_get_track_count(file); i++) {
if (track && (track != i+1)) continue;
e = gf_isom_remove_track_kind(file, i+1, tka->kind_scheme, tka->kind_value);
if (e) goto err_exit;
needSave = 1;
}
needSave = 1;
break;
case TRAC_ACTION_SET_DELAY:
if (tka->delay_ms) {
u64 tk_dur;
gf_isom_remove_edit_segments(file, track);
tk_dur = gf_isom_get_track_duration(file, track);
if (gf_isom_get_edit_segment_count(file, track))
needSave = 1;
if (tka->delay_ms>0) {
gf_isom_append_edit_segment(file, track, (timescale*tka->delay_ms)/1000, 0, GF_ISOM_EDIT_EMPTY);
gf_isom_append_edit_segment(file, track, tk_dur, 0, GF_ISOM_EDIT_NORMAL);
needSave = 1;
} else {
u64 to_skip = (timescale*(-tka->delay_ms))/1000;
if (to_skip<tk_dur) {
u64 media_time = (-tka->delay_ms)*gf_isom_get_media_timescale(file, track) / 1000;
gf_isom_append_edit_segment(file, track, tk_dur-to_skip, media_time, GF_ISOM_EDIT_NORMAL);
needSave = 1;
} else {
fprintf(stderr, "Warning: request negative delay longer than track duration - ignoring\n");
}
}
} else if (gf_isom_get_edit_segment_count(file, track)) {
gf_isom_remove_edit_segments(file, track);
needSave = 1;
}
break;
case TRAC_ACTION_SET_KMS_URI:
for (i=0; i<gf_isom_get_track_count(file); i++) {
if (track && (track != i+1)) continue;
if (!gf_isom_is_media_encrypted(file, i+1, 1)) continue;
if (!gf_isom_is_ismacryp_media(file, i+1, 1)) continue;
e = gf_isom_change_ismacryp_protection(file, i+1, 1, NULL, (char *) tka->kms);
if (e) goto err_exit;
needSave = 1;
}
break;
case TRAC_ACTION_SET_ID:
if (track) {
u32 newTrack;
newTrack = gf_isom_get_track_by_id(file, tka->newTrackID);
if (newTrack != 0) {
fprintf(stderr, "Error: Cannot set track id with value %d because a track already exists - ignoring", tka->newTrackID);
} else {
e = gf_isom_set_track_id(file, track, tka->newTrackID);
needSave = 1;
}
} else {
fprintf(stderr, "Error: Cannot change id for track %d because it does not exist - ignoring", tka->trackID);
}
break;
case TRAC_ACTION_SET_PAR:
e = gf_media_change_par(file, track, tka->par_num, tka->par_den);
needSave = 1;
break;
case TRAC_ACTION_SET_HANDLER_NAME:
e = gf_isom_set_handler_name(file, track, tka->hdl_name);
needSave = 1;
break;
case TRAC_ACTION_ENABLE:
if (!gf_isom_is_track_enabled(file, track)) {
e = gf_isom_set_track_enabled(file, track, 1);
needSave = 1;
}
break;
case TRAC_ACTION_DISABLE:
if (gf_isom_is_track_enabled(file, track)) {
e = gf_isom_set_track_enabled(file, track, 0);
needSave = 1;
}
break;
case TRAC_ACTION_REFERENCE:
e = gf_isom_set_track_reference(file, track, GF_4CC(tka->lang[0], tka->lang[1], tka->lang[2], tka->lang[3]), (u32) tka->delay_ms);
needSave = 1;
break;
case TRAC_ACTION_REM_NON_RAP:
fprintf(stderr, "Removing non-rap samples from track %d\n", tka->trackID);
e = gf_media_remove_non_rap(file, track);
needSave = 1;
break;
case TRAC_ACTION_SET_UDTA:
set_file_udta(file, track, tka->udta_type, tka->src_name, tka->sample_num ? GF_TRUE : GF_FALSE);
needSave = 1;
break;
default:
break;
}
if (e) goto err_exit;
}
if (itunes_tags) {
char *tags = itunes_tags;
while (tags) {
char *val;
char *sep = strchr(tags, ':');
u32 tlen, itag = 0;
if (sep) {
while (sep) {
for (itag=0; itag<nb_itunes_tags; itag++) {
if (!strnicmp(sep+1, itags[itag].name, strlen(itags[itag].name))) break;
}
if (itag<nb_itunes_tags) {
break;
}
sep = strchr(sep+1, ':');
}
if (sep) sep[0] = 0;
}
for (itag=0; itag<nb_itunes_tags; itag++) {
if (!strnicmp(tags, itags[itag].name, strlen(itags[itag].name))) {
break;
}
}
if (itag==nb_itunes_tags) {
fprintf(stderr, "Invalid iTune tag format \"%s\" - ignoring\n", tags);
tags = NULL;
continue;
}
itag = itags[itag].code;
val = strchr(tags, '=');
if (!val) {
fprintf(stderr, "Invalid iTune tag format \"%s\" (expecting '=') - ignoring\n", tags);
tags = NULL;
continue;
}
if (val) {
val ++;
if ((val[0]==':') || !val[0] || !stricmp(val, "NULL") ) val = NULL;
}
tlen = val ? (u32) strlen(val) : 0;
switch (itag) {
case GF_ISOM_ITUNE_COVER_ART:
{
char *d, *ext;
FILE *t = gf_fopen(val, "rb");
gf_fseek(t, 0, SEEK_END);
tlen = (u32) gf_ftell(t);
gf_fseek(t, 0, SEEK_SET);
d = gf_malloc(sizeof(char) * tlen);
tlen = (u32) fread(d, sizeof(char), tlen, t);
gf_fclose(t);
ext = strrchr(val, '.');
if (!stricmp(ext, ".png")) tlen |= 0x80000000;
e = gf_isom_apple_set_tag(file, GF_ISOM_ITUNE_COVER_ART, d, tlen);
gf_free(d);
}
break;
case GF_ISOM_ITUNE_TEMPO:
gf_isom_apple_set_tag(file, itag, NULL, atoi(val) );
break;
case GF_ISOM_ITUNE_GENRE:
{
u8 _v = id3_get_genre_tag(val);
if (_v) {
gf_isom_apple_set_tag(file, itag, NULL, _v);
} else {
if (!val) val="";
gf_isom_apple_set_tag(file, itag, val, (u32) strlen(val) );
}
}
break;
case GF_ISOM_ITUNE_DISK:
case GF_ISOM_ITUNE_TRACKNUMBER:
{
u32 n, t;
char _t[8];
n = t = 0;
memset(_t, 0, sizeof(char)*8);
tlen = (itag==GF_ISOM_ITUNE_DISK) ? 6 : 8;
if (sscanf(val, "%u/%u", &n, &t) == 2) {
_t[3]=n;
_t[2]=n>>8;
_t[5]=t;
_t[4]=t>>8;
}
else if (sscanf(val, "%u", &n) == 1) {
_t[3]=n;
_t[2]=n>>8;
}
else tlen = 0;
if (tlen) gf_isom_apple_set_tag(file, itag, _t, tlen);
}
break;
case GF_ISOM_ITUNE_GAPLESS:
case GF_ISOM_ITUNE_COMPILATION:
{
char _t[1];
if (val && !stricmp(val, "yes")) _t[0] = 1;
else _t[0] = 0;
gf_isom_apple_set_tag(file, itag, _t, 1);
}
break;
default:
gf_isom_apple_set_tag(file, itag, val, tlen);
break;
}
needSave = 1;
if (sep) {
sep[0] = ':';
tags = sep+1;
} else {
tags = NULL;
}
}
}
if (movie_time) {
gf_isom_set_creation_time(file, movie_time);
for (i=0; i<gf_isom_get_track_count(file); i++) {
gf_isom_set_track_creation_time(file, i+1, movie_time);
}
needSave = 1;
}
#ifndef GPAC_DISABLE_ISOM_FRAGMENTS
if (Frag) {
if (!interleaving_time) interleaving_time = 0.5;
if (HintIt) fprintf(stderr, "Warning: cannot hint and fragment - ignoring hint\n");
fprintf(stderr, "Fragmenting file (%.3f seconds fragments)\n", interleaving_time);
e = gf_media_fragment_file(file, outfile, interleaving_time);
if (e) fprintf(stderr, "Error while fragmenting file: %s\n", gf_error_to_string(e));
gf_isom_delete(file);
if (!e && !outName && !force_new) {
if (gf_delete_file(inName)) fprintf(stderr, "Error removing file %s\n", inName);
else if (gf_move_file(outfile, inName)) fprintf(stderr, "Error renaming file %s to %s\n", outfile, inName);
}
MP4BOX_EXIT_WITH_CODE( (e!=GF_OK) ? 1 : 0 );
}
#endif
#ifndef GPAC_DISABLE_ISOM_HINTING
if (HintIt) {
if (force_ocr) SetupClockReferences(file);
fprintf(stderr, "Hinting file with Path-MTU %d Bytes\n", MTUSize);
MTUSize -= 12;
e = HintFile(file, MTUSize, max_ptime, rtp_rate, hint_flags, HintCopy, HintInter, regular_iod, single_group);
if (e) goto err_exit;
needSave = 1;
if (print_sdp) DumpSDP(file, dump_std ? NULL : outfile);
}
#endif
/*full interleave (sample-based) if just hinted*/
if (FullInter) {
e = gf_isom_set_storage_mode(file, GF_ISOM_STORE_TIGHT);
} else if (!interleaving_time) {
e = gf_isom_set_storage_mode(file, GF_ISOM_STORE_STREAMABLE);
needSave = 1;
} else if (do_flat) {
e = gf_isom_set_storage_mode(file, GF_ISOM_STORE_FLAT);
needSave = 1;
} else {
e = gf_isom_make_interleave(file, interleaving_time);
if (!e && old_interleave) e = gf_isom_set_storage_mode(file, GF_ISOM_STORE_INTERLEAVED);
}
if (force_co64)
gf_isom_force_64bit_chunk_offset(file, GF_TRUE);
if (e) goto err_exit;
#if !defined(GPAC_DISABLE_ISOM_HINTING) && !defined(GPAC_DISABLE_SENG)
for (i=0; i<nb_sdp_ex; i++) {
if (sdp_lines[i].trackID) {
u32 track = gf_isom_get_track_by_id(file, sdp_lines[i].trackID);
if (gf_isom_get_media_type(file, track)!=GF_ISOM_MEDIA_HINT) {
s32 ref_count;
u32 j, k, count = gf_isom_get_track_count(file);
for (j=0; j<count; j++) {
if (gf_isom_get_media_type(file, j+1)!=GF_ISOM_MEDIA_HINT) continue;
ref_count = gf_isom_get_reference_count(file, j+1, GF_ISOM_REF_HINT);
if (ref_count<0) continue;
for (k=0; k<(u32) ref_count; k++) {
u32 refTk;
if (gf_isom_get_reference(file, j+1, GF_ISOM_REF_HINT, k+1, &refTk)) continue;
if (refTk==track) {
track = j+1;
j=count;
break;
}
}
}
}
gf_isom_sdp_add_track_line(file, track, sdp_lines[i].line);
needSave = 1;
} else {
gf_isom_sdp_add_line(file, sdp_lines[i].line);
needSave = 1;
}
}
#endif /*!defined(GPAC_DISABLE_ISOM_HINTING) && !defined(GPAC_DISABLE_SENG)*/
if (cprt) {
e = gf_isom_set_copyright(file, "und", cprt);
needSave = 1;
if (e) goto err_exit;
}
if (chap_file) {
#ifndef GPAC_DISABLE_MEDIA_IMPORT
e = gf_media_import_chapters(file, chap_file, import_fps);
needSave = 1;
#else
fprintf(stderr, "Warning: GPAC compiled without Media Import, chapters can't be imported\n");
e = GF_NOT_SUPPORTED;
#endif
if (e) goto err_exit;
}
if (major_brand) {
gf_isom_set_brand_info(file, major_brand, minor_version);
needSave = 1;
}
for (i=0; i<nb_alt_brand_add; i++) {
gf_isom_modify_alternate_brand(file, brand_add[i], 1);
needSave = 1;
}
for (i=0; i<nb_alt_brand_rem; i++) {
gf_isom_modify_alternate_brand(file, brand_rem[i], 0);
needSave = 1;
}
if (!encode && !force_new) gf_isom_set_final_name(file, outfile);
if (needSave) {
if (outName) {
fprintf(stderr, "Saving to %s: ", outfile);
gf_isom_set_final_name(file, outfile);
} else if (encode || pack_file) {
fprintf(stderr, "Saving to %s: ", gf_isom_get_filename(file) );
} else {
fprintf(stderr, "Saving %s: ", inName);
}
if (HintIt && FullInter) fprintf(stderr, "Hinted file - Full Interleaving\n");
else if (FullInter) fprintf(stderr, "Full Interleaving\n");
else if (do_flat || !interleaving_time) fprintf(stderr, "Flat storage\n");
else fprintf(stderr, "%.3f secs Interleaving%s\n", interleaving_time, old_interleave ? " - no drift control" : "");
e = gf_isom_close(file);
if (!e && !outName && !encode && !force_new && !pack_file) {
if (gf_delete_file(inName)) fprintf(stderr, "Error removing file %s\n", inName);
else if (gf_move_file(outfile, inName)) fprintf(stderr, "Error renaming file %s to %s\n", outfile, inName);
}
} else {
gf_isom_delete(file);
}
if (e) fprintf(stderr, "Error: %s\n", gf_error_to_string(e));
MP4BOX_EXIT_WITH_CODE( (e!=GF_OK) ? 1 : 0 );
#else
/*close libgpac*/
gf_isom_delete(file);
fprintf(stderr, "Error: Read-only version of MP4Box.\n");
MP4BOX_EXIT_WITH_CODE(1);
#endif
err_exit:
/*close libgpac*/
if (file) gf_isom_delete(file);
fprintf(stderr, "\n\tError: %s\n", gf_error_to_string(e));
MP4BOX_EXIT_WITH_CODE(1);
exit:
#ifdef GPAC_MEMORY_TRACKING
if (enable_mem_tracker && (gf_memory_size() || gf_file_handles_count() )) {
gf_memory_print();
return 2;
}
#endif
return 0;
}