This source file includes following definitions.
- usage
- parse_args
- main
#include "ts2hds.h"
#ifdef WIN32
#define strnicmp _strnicmp
#endif
#define CHECK_NEXT_ARG if (i+1==(u32)argc) { fprintf(stderr, "Missing arg - please check usage\n"); exit(1); }
#ifdef GPAC_DISABLE_ISOM
#error "Cannot compile TS2HDS if GPAC is not built with ISO File Format support"
#endif
static GFINLINE void usage(const char * progname)
{
fprintf(stderr, "USAGE: %s -i input -o output\n"
"\n"
#ifdef GPAC_MEMORY_TRACKING
"\t-mem-track: enables memory tracker\n"
#endif
, progname);
}
static GFINLINE GF_Err parse_args(int argc, char **argv, char **input, char **output, u64 *curr_time, u32 *segnum)
{
Bool input_found=0, output_found=0;
char *arg = NULL, *error_msg = "no argument found";
s32 i;
for (i=1; i<argc; i++) {
arg = argv[i];
if (!strnicmp(arg, "-h", 2) || strstr(arg, "-help")) {
usage(argv[0]);
return GF_EOS;
} else if (!strnicmp(arg, "-input", 6)) {
CHECK_NEXT_ARG
*input = argv[++i];
input_found = 1;
} else if (!strnicmp(arg, "-output", 6)) {
CHECK_NEXT_ARG
*output = argv[++i];
output_found = 1;
} else if (!strnicmp(arg, "-segnum", 6)) {
CHECK_NEXT_ARG
*segnum = atoi(argv[++i]);
} else if (!strnicmp(arg, "-mem-track", 10)) {
#ifdef GPAC_MEMORY_TRACKING
gf_sys_close();
gf_sys_init(GF_MemTrackerSimple);
gf_log_set_tool_level(GF_LOG_MEMORY, GF_LOG_INFO);
#else
fprintf(stderr, "WARNING - GPAC not compiled with Memory Tracker - ignoring \"-mem-track\"\n");
#endif
} else {
error_msg = "unknown option \"%s\"";
goto error;
}
}
if (input_found && output_found) {
return GF_OK;
} else {
if (!input_found)
fprintf(stderr, "Error: input argument not found\n\n");
if (!output_found)
fprintf(stderr, "Error: output argument not found\n\n");
return GF_BAD_PARAM;
}
error:
if (!arg) {
fprintf(stderr, "Error: %s\n\n", error_msg);
} else {
fprintf(stderr, "Error: %s \"%s\"\n\n", error_msg, arg);
}
return GF_BAD_PARAM;
}
int main(int argc, char **argv)
{
char *input, *output, tmpstr[GF_MAX_PATH];
GF_ISOFile *isom_file_in;
GF_MediaImporter import;
AdobeHDSCtx ctx;
GF_Err e;
u32 i;
gf_sys_init(GF_MemTrackerNone);
gf_log_set_tool_level(GF_LOG_ALL, GF_LOG_WARNING);
input = NULL;
output = NULL;
isom_file_in = NULL;
memset(&import, 0, sizeof(GF_MediaImporter));
e = GF_OK;
memset(&ctx, 0, sizeof(ctx));
ctx.curr_time = 0;
ctx.segnum = 1;
if (GF_OK != parse_args(argc, argv, &input, &output, &ctx.curr_time, &ctx.segnum)) {
usage(argv[0]);
goto exit;
}
ctx.multirate_manifest = adobe_alloc_multirate_manifest(output);
#if 0
{
char metamoov64[GF_MAX_PATH];
u32 metamoov64_len;
unsigned char metamoov[GF_MAX_PATH];
u32 metamoov_len=GF_MAX_PATH;
FILE *f = gf_fopen("metamoov64", "rt");
gf_fseek(f, 0, SEEK_END);
metamoov64_len = (u32)gf_ftell(f);
gf_fseek(f, 0, SEEK_SET);
fread(metamoov64, metamoov64_len, 1, f);
metamoov_len = gf_base64_decode(metamoov64, metamoov64_len, metamoov, metamoov_len);
gf_fclose(f);
f = gf_fopen("metamoov", "wb");
fwrite(metamoov, metamoov_len, 1, f);
gf_fclose(f);
return 0;
}
#endif
#if 0
{
char bootstrap64[GF_MAX_PATH];
u32 bootstrap64_len;
unsigned char bootstrap[GF_MAX_PATH];
u32 bootstrap_len=GF_MAX_PATH;
GF_AdobeBootstrapInfoBox *abst = (GF_AdobeBootstrapInfoBox *)abst_New();
GF_BitStream *bs;
#if 1
FILE *f = gf_fopen("bootstrap64", "rt");
gf_fseek(f, 0, SEEK_END);
bootstrap64_len = (u32)gf_ftell(f);
gf_fseek(f, 0, SEEK_SET);
fread(bootstrap64, bootstrap64_len, 1, f);
bootstrap_len = gf_base64_decode(bootstrap64, bootstrap64_len, bootstrap, bootstrap_len);
#else
FILE *f = gf_fopen("bootstrap.bin", "rb");
gf_fseek(f, 0, SEEK_END);
bootstrap_len = (u32)gf_ftell(f);
gf_fseek(f, 0, SEEK_SET);
fread(bootstrap, bootstrap_len, 1, f);
#endif
bs = gf_bs_new(bootstrap+8, bootstrap_len-8, GF_BITSTREAM_READ);
abst->size = bootstrap[2]*256+bootstrap[3];
assert(abst->size<GF_MAX_PATH);
abst_Read((GF_Box*)abst, bs);
gf_bs_del(bs);
memset(bootstrap, 0, bootstrap_len);
bs = gf_bs_new(bootstrap, bootstrap_len, GF_BITSTREAM_WRITE);
abst_Write((GF_Box*)abst, bs);
bootstrap_len = (u32)gf_bs_get_position(bs);
gf_bs_del(bs);
gf_fclose(f);
f = gf_fopen("bootstrap", "wt");
bootstrap64_len = gf_base64_encode(bootstrap, bootstrap_len, bootstrap64, GF_MAX_PATH);
fwrite(bootstrap64, bootstrap64_len, 1, f);
fprintf(f, "\n\n");
abst_dump((GF_Box*)abst, f);
gf_fclose(f);
abst_del((GF_Box*)abst);
return 0;
}
#endif
import.trackID = 0;
import.in_name = input;
import.flags = GF_IMPORT_PROBE_ONLY;
sprintf(tmpstr, "%s_import.mp4", input);
isom_file_in = gf_isom_open(tmpstr, GF_ISOM_WRITE_EDIT, NULL);
if (!isom_file_in) {
fprintf(stderr, "Error opening output file %s: %s\n", tmpstr, gf_error_to_string(e));
assert(0);
goto exit;
}
import.dest = isom_file_in;
e = gf_media_import(&import);
if (e) {
fprintf(stderr, "Error while importing input file %s: %s\n", input, gf_error_to_string(e));
assert(0);
goto exit;
}
import.flags = 0;
for (i=0; i<import.nb_tracks; i++) {
import.trackID = import.tk_info[i].track_num;
e = gf_media_import(&import);
if (e) {
fprintf(stderr, "Error while importing track number %u, input file %s: %s\n", import.trackID, input, gf_error_to_string(e));
assert(0);
goto exit;
}
}
e = adobize_segment(isom_file_in, &ctx);
if (e) {
fprintf(stderr, "Couldn't turn the ISOM fragmented file into an Adobe f4v segment: %s\n", gf_error_to_string(e));
assert(0);
goto exit;
}
sprintf(tmpstr, "%s_HD_100_Seg%u-Frag1", output, ctx.segnum);
e = gf_media_fragment_file(isom_file_in, tmpstr, 1.0+gf_isom_get_duration(isom_file_in)/gf_isom_get_timescale(isom_file_in));
if (e) {
fprintf(stderr, "Error while fragmenting file to output %s: %s\n", output, gf_error_to_string(e));
assert(0);
goto exit;
}
gf_isom_delete(isom_file_in);
isom_file_in = NULL;
e = adobe_gen_multirate_manifest(ctx.multirate_manifest, ctx.bootstrap, ctx.bootstrap_size);
if (e) {
fprintf(stderr, "Couldn't generate Adobe f4m manifest: %s\n", gf_error_to_string(e));
assert(0);
goto exit;
}
exit:
if (isom_file_in)
gf_isom_delete(isom_file_in);
if (ctx.multirate_manifest)
adobe_free_multirate_manifest(ctx.multirate_manifest);
if (ctx.bootstrap) {
gf_free(ctx.bootstrap);
}
gf_sys_close();
return !e ? 0 : 1;
}