X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=test%2Ftest.c;h=30c9bfab276d9f0af92f0bc4f84493e77dbe4168;hb=93b82f5fb7457e2e07dcf88e8d23e1739a9b0afe;hp=3d665a7af843b9b7f2f303849c90134e821b4cbb;hpb=8fecfabb5a3859af102a1d02f4a97f4c62931447;p=handbrake-jp%2Fhandbrake-jp-git.git diff --git a/test/test.c b/test/test.c index 3d665a7a..30c9bfab 100644 --- a/test/test.c +++ b/test/test.c @@ -30,14 +30,15 @@ #endif /* Options */ -static int debug = HB_DEBUG_NONE; +static int debug = HB_DEBUG_ALL; static int update = 0; -static int dvdnav = 0; +static int dvdnav = 1; static char * input = NULL; static char * output = NULL; static char * format = NULL; static int titleindex = 1; -static int longest_title = 0; +static int titlescan = 0; +static int main_feature = 0; static char * native_language = NULL; static int native_dub = 0; static int twoPass = 0; @@ -51,6 +52,8 @@ static int detelecine = 0; static char * detelecine_opt = 0; static int decomb = 0; static char * decomb_opt = 0; +static int rotate = 0; +static char * rotate_opt = 0; static int grayscale = 0; static int vcodec = HB_VCODEC_FFMPEG; static int h264_13 = 0; @@ -72,6 +75,11 @@ static char ** subtracks = NULL; static char ** subforce = NULL; static char * subburn = NULL; static char * subdefault = NULL; +static char ** srtfile = NULL; +static char ** srtcodeset = NULL; +static char ** srtoffset = NULL; +static char ** srtlang = NULL; +static int srtdefault = -1; static int subtitle_scan = 0; static int width = 0; static int height = 0; @@ -94,13 +102,12 @@ static int chapter_start = 0; static int chapter_end = 0; static int chapter_markers = 0; static char * marker_file = NULL; -static int crf = 1; static char *x264opts = NULL; static char *x264opts2 = NULL; static int maxHeight = 0; static int maxWidth = 0; static int turbo_opts_enabled = 0; -static char * turbo_opts = "ref=1:subme=1:me=dia:analyse=none:trellis=0:no-fast-pskip=0:8x8dct=0:weightb=0"; +static char * turbo_opts = "ref=1:subme=2:me=dia:analyse=none:trellis=0:no-fast-pskip=0:8x8dct=0:weightb=0"; static int largeFileSize = 0; static int preset = 0; static char * preset_name = 0; @@ -111,6 +118,10 @@ static int color_matrix = 0; static int preview_count = 10; static int store_previews = 0; static int start_at_preview = 0; +static int64_t start_at_pts = 0; +static int start_at_frame = 0; +static char * start_at_string = NULL; +static char * start_at_token = NULL; static int64_t stop_at_pts = 0; static int stop_at_frame = 0; static char * stop_at_string = NULL; @@ -137,7 +148,7 @@ static char* bsd_name_for_path(char *path); static int device_is_dvd(char *device); static io_service_t get_iokit_service( char *device ); static int is_dvd_service( io_service_t service ); -static is_whole_media_service( io_service_t service ); +static int is_whole_media_service( io_service_t service ); #endif /* Only print the "Muxing..." message once */ @@ -177,11 +188,6 @@ int main( int argc, char ** argv ) return 1; } -#if defined( PTW32_STATIC_LIB ) - pthread_win32_process_attach_np(); - pthread_win32_thread_attach_np(); -#endif - /* Register our error handler */ hb_register_error_handler(&hb_cli_error_handler); @@ -208,6 +214,7 @@ int main( int argc, char ** argv ) "date.\n" ); } hb_close( &h ); + hb_global_close(); return 0; } @@ -227,9 +234,9 @@ int main( int argc, char ** argv ) /* Feed libhb with a DVD to scan */ fprintf( stderr, "Opening %s...\n", input ); - if (longest_title) { + if (main_feature) { /* - * We need to scan for all the titles in order to find the longest + * We need to scan for all the titles in order to find the main feature */ titleindex = 0; } @@ -319,6 +326,7 @@ int main( int argc, char ** argv ) /* Clean up */ hb_close( &h ); + hb_global_close(); if( input ) free( input ); if( output ) free( output ); if( format ) free( format ); @@ -347,14 +355,10 @@ int main( int argc, char ** argv ) if( x264opts2 ) free (x264opts2 ); if (preset_name) free (preset_name); if( stop_at_string ) free( stop_at_string ); + if( start_at_string ) free( start_at_string ); fprintf( stderr, "HandBrake has exited.\n" ); -#if defined( PTW32_STATIC_LIB ) - pthread_win32_thread_detach_np(); - pthread_win32_process_detach_np(); -#endif - return 0; } @@ -374,9 +378,20 @@ static void PrintTitleInfo( hb_title_t * title ) int i; fprintf( stderr, "+ title %d:\n", title->index ); - fprintf( stderr, " + vts %d, ttn %d, cells %d->%d (%d blocks)\n", - title->vts, title->ttn, title->cell_start, title->cell_end, - title->block_count ); + if ( title->index == title->job->feature ) + { + fprintf( stderr, " + Main Feature\n" ); + } + if ( title->type == HB_STREAM_TYPE ) + { + fprintf( stderr, " + stream: %s\n", title->path ); + } + else if ( title->type == HB_DVD_TYPE ) + { + fprintf( stderr, " + vts %d, ttn %d, cells %d->%d (%d blocks)\n", + title->vts, title->ttn, title->cell_start, title->cell_end, + title->block_count ); + } if (dvdnav) fprintf( stderr, " + angle(s) %d\n", title->angle_count ); fprintf( stderr, " + duration: %02d:%02d:%02d\n", @@ -405,12 +420,19 @@ static void PrintTitleInfo( hb_title_t * title ) audio = hb_list_audio_config_item( title->list_audio, i ); if( ( audio->in.codec == HB_ACODEC_AC3 ) || ( audio->in.codec == HB_ACODEC_DCA) ) { - fprintf( stderr, " + %d, %s, %dHz, %dbps\n", i + 1, - audio->lang.description, audio->in.samplerate, audio->in.bitrate ); + fprintf( stderr, " + %d, %s (iso639-2: %s), %dHz, %dbps\n", + i + 1, + audio->lang.description, + audio->lang.iso639_2, + audio->in.samplerate, + audio->in.bitrate ); } else { - fprintf( stderr, " + %d, %s\n", i + 1, audio->lang.description ); + fprintf( stderr, " + %d, %s (iso639-2: %s)\n", + i + 1, + audio->lang.description, + audio->lang.iso639_2 ); } } fprintf( stderr, " + subtitle tracks:\n" ); @@ -465,7 +487,7 @@ static int HandleEvents( hb_handle_t * h ) case HB_STATE_SCANNING: /* Show what title is currently being scanned */ fprintf( stderr, "Scanning title %d", p.title_cur ); - if( !titleindex ) + if( !titleindex || titlescan ) fprintf( stderr, " of %d", p.title_count ); fprintf( stderr, "...\n" ); break; @@ -496,15 +518,15 @@ static int HandleEvents( hb_handle_t * h ) die = 1; break; } - if( longest_title ) + if( main_feature ) { int i; - int longest_title_idx=0; - int longest_title_pos=-1; - int longest_title_time=0; + int main_feature_idx=0; + int main_feature_pos=-1; + int main_feature_time=0; int title_time; - fprintf( stderr, "Searching for longest title...\n" ); + fprintf( stderr, "Searching for main feature title...\n" ); for( i = 0; i < hb_list_count( list ); i++ ) { @@ -512,29 +534,36 @@ static int HandleEvents( hb_handle_t * h ) title_time = (title->hours*60*60 ) + (title->minutes *60) + (title->seconds); fprintf( stderr, " + Title (%d) index %d has length %dsec\n", i, title->index, title_time ); - if( longest_title_time < title_time ) + if( main_feature_time < title_time ) { - longest_title_time = title_time; - longest_title_pos = i; - longest_title_idx = title->index; + main_feature_time = title_time; + main_feature_pos = i; + main_feature_idx = title->index; + } + if( title->job->feature == title->index ) + { + main_feature_time = title_time; + main_feature_pos = i; + main_feature_idx = title->index; + break; } } - if( longest_title_pos == -1 ) + if( main_feature_pos == -1 ) { - fprintf( stderr, "No longest title found.\n" ); + fprintf( stderr, "No main feature title found.\n" ); die = 1; break; } - titleindex = longest_title_idx; - fprintf( stderr, "Found longest title, setting title to %d\n", - longest_title_idx); + titleindex = main_feature_idx; + fprintf( stderr, "Found main feature title, setting title to %d\n", + main_feature_idx); - title = hb_list_item( list, longest_title_pos); + title = hb_list_item( list, main_feature_pos); } else { title = hb_list_item( list, 0 ); } - if( !titleindex ) + if( !titleindex || titlescan ) { /* Scan-only mode, print infos and exit */ int i; @@ -552,7 +581,7 @@ static int HandleEvents( hb_handle_t * h ) PrintTitleInfo( title ); - if( chapter_start && chapter_end && !stop_at_pts && !start_at_preview && !stop_at_frame ) + if( chapter_start && chapter_end && !stop_at_pts && !start_at_preview && !stop_at_frame && !start_at_pts && !start_at_frame ) { job->chapter_start = MAX( job->chapter_start, chapter_start ); @@ -579,7 +608,6 @@ static int HandleEvents( hb_handle_t * h ) } vcodec = HB_VCODEC_X264; job->vquality = 20.0; - job->crf = 1; if( !atracks ) { atracks = strdup("1,1"); @@ -607,7 +635,7 @@ static int HandleEvents( hb_handle_t * h ) maxWidth = 720; if( !x264opts ) { - x264opts = strdup("cabac=0:ref=2:mixed-refs=1:me=umh"); + x264opts = strdup("cabac=0:ref=2:me=umh:bframes=0:8x8dct=0:trellis=0:subme=6"); } anamorphic_mode = 2; job->chapter_markers = 1; @@ -649,7 +677,7 @@ static int HandleEvents( hb_handle_t * h ) maxWidth = 320; if( !x264opts ) { - x264opts = strdup("level=30:bframes=0:cabac=0:ref=1:vbv-maxrate=768:vbv-bufsize=2000:analyse=all:me=umh:no-fast-pskip=1"); + x264opts = strdup("level=30:bframes=0:cabac=0:ref=1:vbv-maxrate=768:vbv-bufsize=2000:analyse=all:me=umh:no-fast-pskip=1:subme=6:8x8dct=0:trellis=0"); } job->chapter_markers = 1; } @@ -662,7 +690,6 @@ static int HandleEvents( hb_handle_t * h ) } vcodec = HB_VCODEC_X264; job->vquality = 20.0; - job->crf = 1; if( !atracks ) { atracks = strdup("1"); @@ -690,7 +717,7 @@ static int HandleEvents( hb_handle_t * h ) maxWidth = 480; if( !x264opts ) { - x264opts = strdup("cabac=0:ref=2:mixed-refs:me=umh"); + x264opts = strdup("cabac=0:ref=2:me=umh:bframes=0:subme=6:8x8dct=0:trellis=0"); } job->chapter_markers = 1; } @@ -704,7 +731,6 @@ static int HandleEvents( hb_handle_t * h ) job->largeFileSize = 1; vcodec = HB_VCODEC_X264; job->vquality = 20.0; - job->crf = 1; if( !atracks ) { atracks = strdup("1,1"); @@ -732,7 +758,7 @@ static int HandleEvents( hb_handle_t * h ) maxWidth = 960; if( !x264opts ) { - x264opts = strdup("cabac=0:ref=2:mixed-refs=1:bframes=3:me=umh:subme=7:b-adapt=2:8x8dct=1"); + x264opts = strdup("cabac=0:ref=2:me=umh:b-adapt=2:weightb=0:trellis=0:weightp=0:vbv-maxrate=9500:vbv-bufsize=9500"); } anamorphic_mode = 2; job->chapter_markers = 1; @@ -746,7 +772,6 @@ static int HandleEvents( hb_handle_t * h ) } vcodec = HB_VCODEC_X264; job->vquality = 20.0; - job->crf = 1; if( !atracks ) { atracks = strdup("1"); @@ -773,7 +798,7 @@ static int HandleEvents( hb_handle_t * h ) } if( !x264opts ) { - x264opts = strdup("ref=2:bframes=2:me=umh"); + x264opts = strdup("ref=2:bframes=2:subme=6:mixed-refs=0:weightb=0:8x8dct=0:trellis=0"); } anamorphic_mode = 1; job->chapter_markers = 1; @@ -787,7 +812,6 @@ static int HandleEvents( hb_handle_t * h ) } vcodec = HB_VCODEC_X264; job->vquality = 20.0; - job->crf = 1; if( !atracks ) { atracks = strdup("1,1"); @@ -814,7 +838,7 @@ static int HandleEvents( hb_handle_t * h ) } if( !x264opts ) { - x264opts = strdup("ref=3:mixed-refs:bframes=3:weightb:b-pyramid:b-adapt=2:me=umh:subme=9:analyse=all:8x8dct"); + x264opts = strdup("b-adapt=2:rc-lookahead=50"); } detelecine = 1; decomb = 1; @@ -890,7 +914,7 @@ static int HandleEvents( hb_handle_t * h ) } if( !x264opts ) { - x264opts = strdup("bframes=3:ref=1:subme=5:me=umh:no-fast-pskip=1:cabac=0"); + x264opts = strdup("ref=1:subme=5:me=umh:no-fast-pskip=1:cabac=0:weightb=0:8x8dct=0:trellis=0"); } anamorphic_mode = 1; job->chapter_markers = 1; @@ -932,7 +956,7 @@ static int HandleEvents( hb_handle_t * h ) maxWidth = 480; if( !x264opts ) { - x264opts = strdup("level=30:cabac=0:ref=1:analyse=all:me=umh:no-fast-pskip=1:psy-rd=0,0"); + x264opts = strdup("level=30:cabac=0:ref=1:analyse=all:me=umh:no-fast-pskip=1:psy-rd=0,0:bframes=0:subme=6:8x8dct=0:trellis=0"); } job->chapter_markers = 1; } @@ -973,7 +997,7 @@ static int HandleEvents( hb_handle_t * h ) maxWidth = 640; if( !x264opts ) { - x264opts = strdup("level=30:bframes=0:cabac=0:ref=1:vbv-maxrate=1500:vbv-bufsize=2000:analyse=all:me=umh:no-fast-pskip=1:psy-rd=0,0"); + x264opts = strdup("level=30:bframes=0:cabac=0:ref=1:vbv-maxrate=1500:vbv-bufsize=2000:analyse=all:me=umh:no-fast-pskip=1:psy-rd=0,0:subme=6:8x8dct=0:trellis=0"); } job->chapter_markers = 1; } @@ -1057,6 +1081,12 @@ static int HandleEvents( hb_handle_t * h ) /* Add selected filters */ job->filters = hb_list_init(); + + if( rotate ) + { + hb_filter_rotate.settings = rotate_opt; + hb_list_add( job->filters, &hb_filter_rotate); + } if( detelecine ) { hb_filter_detelecine.settings = detelecine_opt; @@ -1118,7 +1148,7 @@ static int HandleEvents( hb_handle_t * h ) if (modulus) { - job->anamorphic.modulus = modulus; + job->modulus = modulus; } if( itu_par ) @@ -1143,7 +1173,7 @@ static int HandleEvents( hb_handle_t * h ) if (modulus) { - job->anamorphic.modulus = modulus; + job->modulus = modulus; } if( itu_par ) @@ -1370,7 +1400,8 @@ static int HandleEvents( hb_handle_t * h ) } } - if( hb_list_count(audios) == 0 ) + if( hb_list_count(audios) == 0 && + hb_list_count(job->title->list_audio) > 0 ) { /* Create a new audio track with default settings */ audio = calloc(1, sizeof(*audio)); @@ -1790,6 +1821,44 @@ static int HandleEvents( hb_handle_t * h ) } } + if( srtfile ) + { + char * token; + int i, pos; + hb_subtitle_config_t sub_config; + + pos = 0; + for( i=0; srtfile[i] != NULL; i++ ) + { + char *codeset = "L1"; + int64_t offset = 0; + char *lang = "und"; + + pos++; + token = srtfile[i]; + if( srtcodeset && srtcodeset[i] ) + { + codeset = srtcodeset[i]; + } + if( srtoffset && srtoffset[i] ) + { + offset = strtoll( srtoffset[i], &srtoffset[i], 0 ); + } + if ( srtlang && srtlang[i] ) + { + lang = srtlang[i]; + } + sub_config.default_track = + ( srtdefault != -1 ) && ( srtdefault == i + 1 ); + sub_config.force = 0; + strncpy( sub_config.src_filename, srtfile[i], 128); + strncpy( sub_config.src_codeset, codeset, 40); + sub_config.offset = offset; + + hb_srt_add( job, &sub_config, lang); + } + } + if( native_language ) { char audio_lang[4]; @@ -1886,11 +1955,6 @@ static int HandleEvents( hb_handle_t * h ) job->file = strdup( output ); - if( crf ) - { - job->crf = 1; - } - if( color_matrix ) { job->color_matrix = color_matrix; @@ -1927,6 +1991,18 @@ static int HandleEvents( hb_handle_t * h ) subtitle_scan = 0; } + if( start_at_pts ) + { + job->pts_to_start = start_at_pts; + subtitle_scan = 0; + } + + if( start_at_frame ) + { + job->frame_to_start = start_at_frame; + subtitle_scan = 0; + } + if( subtitle_scan ) { char *x264opts_tmp; @@ -2030,6 +2106,17 @@ static int HandleEvents( hb_handle_t * h ) } #define p s.param.working + case HB_STATE_SEARCHING: + fprintf( stdout, "\rEncoding: task %d of %d, Searching for start time, %.2f %%", + p.job_cur, p.job_count, 100.0 * p.progress ); + if( p.seconds > -1 ) + { + fprintf( stdout, " (ETA %02dh%02dm%02ds)", + p.hours, p.minutes, p.seconds ); + } + fflush(stdout); + break; + case HB_STATE_WORKING: fprintf( stdout, "\rEncoding: task %d of %d, %.2f %%", p.job_cur, p.job_count, 100.0 * p.progress ); @@ -2118,14 +2205,16 @@ static void ShowHelp() " if the preset name has spaces, surround it with\n" " double quotation marks\n" " -z, --preset-list See a list of available built-in presets\n" - " --dvdnav Use dvdnav (Experimental)\n" + " --no-dvdnav Do not use dvdnav for reading DVDs\n" + " (experimental, enabled by default for testing)\n" "\n" "### Source Options-----------------------------------------------------------\n\n" " -i, --input Set input device\n" - " -t, --title Select a title to encode (0 to scan only,\n" + " -t, --title Select a title to encode (0 to scan all titles only,\n" " default: 1)\n" - " -L, --longest Select the longest title\n" + " --scan Scan selected title only.\n" + " --main-feature Detect and select the main feature title.\n" " -c, --chapters Select chapters (e.g. \"1-3\" for chapters\n" " 1 to 3, or \"3\" for chapter 3 only,\n" " default: all chapters)\n" @@ -2134,13 +2223,15 @@ static void ShowHelp() " and whether or not they're stored to disk (0 or 1).\n" " (default: 10:0)\n" " --start-at-preview <#> Start encoding at a given preview.\n" + " --start-at Start encoding at a given frame, duration (in seconds),\n" + " or pts (on a 90kHz clock)\n" " --stop-at Stop encoding at a given frame, duration (in seconds),\n" " or pts (on a 90kHz clock)" "\n" "### Destination Options------------------------------------------------------\n\n" " -o, --output Set output file name\n" - " -f, --format Set output format (avi/mp4/ogm/mkv, default:\n" + " -f, --format Set output format (mp4/mkv, default:\n" " autodetected from file name)\n" " -m, --markers Add chapter markers (mp4 and mkv output formats only)\n" " -4, --large-file Use 64-bit mp4 files that can hold more than\n" @@ -2156,8 +2247,7 @@ static void ShowHelp() " -x, --x264opts Specify advanced x264 options in the\n" " same style as mencoder:\n" " option1=value1:option2=value2\n" - " -q, --quality Set video quality (0.0..1.0)\n" - " -Q, --cqp Use with -q for CQP instead of CRF\n" + " -q, --quality Set video quality\n" " -S, --size Set target size\n" " -b, --vb Set video bitrate (default: 1000)\n" " -2, --two-pass Use two-pass mode\n" @@ -2252,8 +2342,8 @@ static void ShowHelp() " --itu-par Use wider, ITU pixel aspect values for loose and\n" " custom anamorphic, useful with underscanned sources\n" " --modulus Set the number you want the scaled pixel dimensions\n" - " to divide cleanly by, for loose and custom\n" - " anamorphic modes (default: 16)\n" + " to divide cleanly by. Does not affect strict\n" + " anamorphic mode, which is always mod 2 (default: 16)\n" " -M --color-matrix Set the color space signaled by the output\n" " <601 or 709> (Bt.601 is mostly for SD content, Bt.709 for HD,\n" " default: set by resolution)\n" @@ -2266,18 +2356,21 @@ static void ShowHelp() " or\n" " \n" " -5, --decomb Selectively deinterlaces when it detects combing\n" - " (default: 1:2:6:9:80:16:16)\n" + " \n" + " (default: 7:2:6:9:80:16:16:10:20:20:4:2:50:24:1:-1)\n" " -9, --detelecine Detelecine (ivtc) video with pullup filter\n" " Note: this filter drops duplicate frames to\n" " restore the pre-telecine framerate, unless you\n" " specify a constant framerate (--rate 29.97)\n" - " (default 1:1:4:4:0:0)\n" + " (default 1:1:4:4:0:0:-1)\n" " -8, --denoise Denoise video with hqdn3d filter\n" " (default 4:3:6:4.5)\n" " or\n" " \n" " -7, --deblock Deblock video with pp7 filter\n" " (default 5:2)\n" + " --rotate Flips images axes\n" + " (default 3)\n" " -g, --grayscale Grayscale encoding\n" "\n" @@ -2304,7 +2397,7 @@ static void ShowHelp() " --subtitle-burn \"Burn\" the selected subtitle into the video track\n" " If \"number\" is omitted, the first trac is burned.\n" " --subtitle-default Flag the selected subtitle as the default subtitle\n" - " to be displayed upon playback. Settings no default\n" + " to be displayed upon playback. Setting no default\n" " means no subtitle will be automatically displayed\n" " If \"number\" is omitted, the first trac is default.\n" " -N, --native-language Specifiy the your language preference. When the first\n" @@ -2319,7 +2412,22 @@ static void ShowHelp() " that matches the --native-language. If there are no\n" " matching audio tracks then the first matching\n" " subtitle track is used instead.\n" - + " --srt-file SubRip SRT filename(s), separated by commas.\n" + " --srt-codeset Character codeset(s) that the SRT file(s) are\n" + " encoded in, separted by commas.\n" + " Use 'iconv -l' for a list of valid\n" + " codesets. If not specified latin1 is assumed\n" + " --srt-offset Offset in milli-seconds to apply to the SRT file(s)\n" + " separted by commas. If not specified zero is assumed.\n" + " Offsets may be negative.\n" + " --srt-lang Language as an iso639-2 code fra, eng, spa et cetera)\n" + " for the SRT file(s) separated by commas. If not specified\n" + " then 'und' is used.\n" + " --srt-default Flag the selected srt as the default subtitle\n" + " to be displayed upon playback. Setting no default\n" + " means no subtitle will be automatically displayed\n" + " If \"number\" is omitted, the first srt is default.\n" + " \"number\" is an 1 based index into the srt-file list\n" "\n" @@ -2333,21 +2441,21 @@ static void ShowPresets() { printf("\n< Apple\n"); - printf("\n + Universal: -e x264 -q 20.0 -a 1,1 -E faac,ac3 -B 160,160 -6 dpl2,auto -R 48,Auto -D 0.0,0.0 -f mp4 -X 720 --loose-anamorphic -m -x cabac=0:ref=2:mixed-refs=1:me=umh\n"); + printf("\n + Universal: -e x264 -q 20.0 -a 1,1 -E faac,ac3 -B 160,160 -6 dpl2,auto -R 48,Auto -D 0.0,0.0 -f mp4 -X 720 --loose-anamorphic -m -x cabac=0:ref=2:me=umh:bframes=0:8x8dct=0:trellis=0:subme=6\n"); - printf("\n + iPod: -e x264 -b 700 -a 1 -E faac -B 160 -6 dpl2 -R 48 -D 0.0 -f mp4 -I -X 320 -m -x level=30:bframes=0:cabac=0:ref=1:vbv-maxrate=768:vbv-bufsize=2000:analyse=all:me=umh:no-fast-pskip=1\n"); + printf("\n + iPod: -e x264 -b 700 -a 1 -E faac -B 160 -6 dpl2 -R 48 -D 0.0 -f mp4 -I -X 320 -m -x level=30:bframes=0:cabac=0:ref=1:vbv-maxrate=768:vbv-bufsize=2000:analyse=all:me=umh:no-fast-pskip=1:subme=6:8x8dct=0:trellis=0\n"); - printf("\n + iPhone & iPod Touch: -e x264 -q 20.0 -a 1 -E faac -B 128 -6 dpl2 -R 48 -D 0.0 -f mp4 -X 480 -m -x cabac=0:ref=2:mixed-refs:me=umh\n"); + printf("\n + iPhone & iPod Touch: -e x264 -q 20.0 -a 1 -E faac -B 128 -6 dpl2 -R 48 -D 0.0 -f mp4 -X 480 -m -x cabac=0:ref=2:me=umh:bframes=0:subme=6:8x8dct=0:trellis=0\n"); - printf("\n + AppleTV: -e x264 -q 20.0 -a 1,1 -E faac,ac3 -B 160,160 -6 dpl2,auto -R 48,Auto -D 0.0,0.0 -f mp4 -4 -X 960 --loose-anamorphic -m -x cabac=0:ref=2:mixed-refs=1:bframes=3:me=umh:subme=7:b-adapt=2:8x8dct=1\n"); + printf("\n + AppleTV: -e x264 -q 20.0 -a 1,1 -E faac,ac3 -B 160,160 -6 dpl2,auto -R 48,Auto -D 0.0,0.0 -f mp4 -4 -X 960 --loose-anamorphic -m -x cabac=0:ref=2:me=umh:b-adapt=2:weightb=0:trellis=0:weightp=0:vbv-maxrate=9500:vbv-bufsize=9500\n"); printf("\n>\n"); printf("\n< Regular\n"); - printf("\n + Normal: -e x264 -q 20.0 -a 1 -E faac -B 160 -6 dpl2 -R 48 -D 0.0 -f mp4 --strict-anamorphic -m -x ref=2:bframes=2:me=umh\n"); + printf("\n + Normal: -e x264 -q 20.0 -a 1 -E faac -B 160 -6 dpl2 -R 48 -D 0.0 -f mp4 --strict-anamorphic -m -x ref=2:bframes=2:subme=6:mixed-refs=0:weightb=0:8x8dct=0:trellis=0\n"); - printf("\n + High Profile: -e x264 -q 20.0 -a 1,1 -E faac,ac3 -B 160,160 -6 dpl2,auto -R 48,Auto -D 0.0,0.0 -f mp4 --detelecine --decomb --loose-anamorphic -m -x ref=3:mixed-refs:bframes=3:weightb:b-pyramid:b-adapt=2:me=umh:subme=9:analyse=all:8x8dct\n"); + printf("\n + High Profile: -e x264 -q 20.0 -a 1,1 -E faac,ac3 -B 160,160 -6 dpl2,auto -R 48,Auto -D 0.0,0.0 -f mp4 --detelecine --decomb --loose-anamorphic -m -x b-adapt=2:rc-lookahead=50\n"); printf("\n>\n"); @@ -2355,24 +2463,34 @@ static void ShowPresets() printf("\n + Classic: -b 1000 -a 1 -E faac -B 160 -6 dpl2 -R 48 -D 0.0 -f mp4\n"); - printf("\n + AppleTV Legacy: -e x264 -b 2500 -a 1,1 -E faac,ac3 -B 160,160 -6 dpl2,auto -R 48,Auto -D 0.0,0.0 -f mp4 -4 --strict-anamorphic -m -x bframes=3:ref=1:subme=5:me=umh:no-fast-pskip=1:cabac=0\n"); + printf("\n + AppleTV Legacy: -e x264 -b 2500 -a 1,1 -E faac,ac3 -B 160,160 -6 dpl2,auto -R 48,Auto -D 0.0,0.0 -f mp4 -4 --strict-anamorphic -m -x ref=1:subme=5:me=umh:no-fast-pskip=1:cabac=0:weightb=0:8x8dct=0:trellis=0\n"); - printf("\n + iPhone Legacy: -e x264 -b 960 -a 1 -E faac -B 128 -6 dpl2 -R 48 -D 0.0 -f mp4 -I -X 480 -m -x level=30:cabac=0:ref=1:analyse=all:me=umh:no-fast-pskip=1:psy-rd=0,0\n"); + printf("\n + iPhone Legacy: -e x264 -b 960 -a 1 -E faac -B 128 -6 dpl2 -R 48 -D 0.0 -f mp4 -I -X 480 -m -x level=30:cabac=0:ref=1:analyse=all:me=umh:no-fast-pskip=1:psy-rd=0,0:bframes=0:subme=6:8x8dct=0:trellis=0\n"); - printf("\n + iPod Legacy: -e x264 -b 1500 -a 1 -E faac -B 160 -6 dpl2 -R 48 -D 0.0 -f mp4 -I -X 640 -m -x level=30:bframes=0:cabac=0:ref=1:vbv-maxrate=1500:vbv-bufsize=2000:analyse=all:me=umh:no-fast-pskip=1:psy-rd=0,0\n"); + printf("\n + iPod Legacy: -e x264 -b 1500 -a 1 -E faac -B 160 -6 dpl2 -R 48 -D 0.0 -f mp4 -I -X 640 -m -x level=30:bframes=0:cabac=0:ref=1:vbv-maxrate=1500:vbv-bufsize=2000:analyse=all:me=umh:no-fast-pskip=1:psy-rd=0,0:subme=6:8x8dct=0:trellis=0\n"); printf("\n>\n"); } -static char** str_split( char *str, char *delem ) +static char * hb_strndup( char * str, int len ) +{ + char * res; + int str_len = strlen( str ); + + res = malloc( len > str_len ? str_len + 1 : len + 1 ); + strncpy( res, str, len ); + res[len] = '\0'; + return res; +} + +static char** str_split( char *str, char delem ) { - char * token; - char * copy_str; char * pos; + char * end; char ** ret; int count, i; - if ( str == NULL || delem == NULL || str[0] == 0 ) + if ( str == NULL || str[0] == 0 ) { ret = malloc( sizeof(char*) ); *ret = NULL; @@ -2382,24 +2500,23 @@ static char** str_split( char *str, char *delem ) // Find number of elements in the string count = 1; pos = str; - while ( ( pos = strstr( pos+1, delem ) ) != NULL ) + while ( ( pos = strchr( pos, delem ) ) != NULL ) { - if ( *(pos+1) != 0 ) - count++; + count++; + pos++; } - ret = calloc( ( count + 1 ), sizeof(char*) ); - copy_str = strdup( str ); - token = strtok( copy_str, delem ); + ret = calloc( ( count + 1 ), sizeof(char*) ); - i = 0; - while( token != NULL && i < count ) + pos = str; + for ( i = 0; i < count - 1; i++ ) { - ret[i] = strdup( token ); - token = strtok(NULL, ","); - i++; + end = strchr( pos, delem ); + ret[i] = hb_strndup(pos, end - pos); + pos = end + 1; } - free( copy_str ); + ret[i] = strdup(pos); + return ret; } @@ -2411,16 +2528,25 @@ static int ParseOptions( int argc, char ** argv ) #define PREVIEWS 257 #define START_AT_PREVIEW 258 - #define STOP_AT 259 - #define ANGLE 260 - #define DVDNAV 261 - #define DISPLAY_WIDTH 262 - #define PIXEL_ASPECT 263 - #define MODULUS 264 - #define KEEP_DISPLAY_ASPECT 265 - #define SUB_BURNED 266 - #define SUB_DEFAULT 267 - #define NATIVE_DUB 268 + #define START_AT 259 + #define STOP_AT 260 + #define ANGLE 261 + #define DVDNAV 262 + #define DISPLAY_WIDTH 263 + #define PIXEL_ASPECT 264 + #define MODULUS 265 + #define KEEP_DISPLAY_ASPECT 266 + #define SUB_BURNED 267 + #define SUB_DEFAULT 268 + #define NATIVE_DUB 269 + #define SRT_FILE 270 + #define SRT_CODESET 271 + #define SRT_OFFSET 272 + #define SRT_LANG 273 + #define SRT_DEFAULT 274 + #define ROTATE_FILTER 275 + #define SCAN_ONLY 276 + #define MAIN_FEATURE 277 for( ;; ) { @@ -2430,7 +2556,7 @@ static int ParseOptions( int argc, char ** argv ) { "update", no_argument, NULL, 'u' }, { "verbose", optional_argument, NULL, 'v' }, { "cpu", required_argument, NULL, 'C' }, - { "dvdnav", no_argument, NULL, DVDNAV }, + { "no-dvdnav", no_argument, NULL, DVDNAV }, { "format", required_argument, NULL, 'f' }, { "input", required_argument, NULL, 'i' }, @@ -2440,7 +2566,8 @@ static int ParseOptions( int argc, char ** argv ) { "ipod-atom", no_argument, NULL, 'I' }, { "title", required_argument, NULL, 't' }, - { "longest", no_argument, NULL, 'L' }, + { "scan", no_argument, NULL, SCAN_ONLY }, + { "main-feature",no_argument, NULL, MAIN_FEATURE }, { "chapters", required_argument, NULL, 'c' }, { "angle", required_argument, NULL, ANGLE }, { "markers", optional_argument, NULL, 'm' }, @@ -2451,9 +2578,13 @@ static int ParseOptions( int argc, char ** argv ) { "subtitle-forced", optional_argument, NULL, 'F' }, { "subtitle-burned", optional_argument, NULL, SUB_BURNED }, { "subtitle-default", optional_argument, NULL, SUB_DEFAULT }, + { "srt-file", required_argument, NULL, SRT_FILE }, + { "srt-codeset", required_argument, NULL, SRT_CODESET }, + { "srt-offset", required_argument, NULL, SRT_OFFSET }, + { "srt-lang", required_argument, NULL, SRT_LANG }, + { "srt-default", optional_argument, NULL, SRT_DEFAULT }, { "native-language", required_argument, NULL,'N' }, { "native-dub", no_argument, NULL, NATIVE_DUB }, - { "encoder", required_argument, NULL, 'e' }, { "aencoder", required_argument, NULL, 'E' }, { "two-pass", no_argument, NULL, '2' }, @@ -2463,6 +2594,7 @@ static int ParseOptions( int argc, char ** argv ) { "detelecine", optional_argument, NULL, '9' }, { "decomb", optional_argument, NULL, '5' }, { "grayscale", no_argument, NULL, 'g' }, + { "rotate", optional_argument, NULL, ROTATE_FILTER }, { "strict-anamorphic", no_argument, &anamorphic_mode, 1 }, { "loose-anamorphic", no_argument, &anamorphic_mode, 2 }, { "custom-anamorphic", no_argument, &anamorphic_mode, 3 }, @@ -2481,7 +2613,6 @@ static int ParseOptions( int argc, char ** argv ) { "ab", required_argument, NULL, 'B' }, { "rate", required_argument, NULL, 'r' }, { "arate", required_argument, NULL, 'R' }, - { "cqp", no_argument, NULL, 'Q' }, { "x264opts", required_argument, NULL, 'x' }, { "turbo", no_argument, NULL, 'T' }, { "maxHeight", required_argument, NULL, 'Y' }, @@ -2493,6 +2624,7 @@ static int ParseOptions( int argc, char ** argv ) { "color-matrix",required_argument, NULL, 'M' }, { "previews", required_argument, NULL, PREVIEWS }, { "start-at-preview", required_argument, NULL, START_AT_PREVIEW }, + { "start-at", required_argument, NULL, START_AT }, { "stop-at", required_argument, NULL, STOP_AT }, { "vfr", no_argument, &cfr, 0 }, { "cfr", no_argument, &cfr, 1 }, @@ -2504,7 +2636,7 @@ static int ParseOptions( int argc, char ** argv ) int c; c = getopt_long( argc, argv, - "hv::uC:f:4i:Io:t:Lc:m::M:a:A:6:s:UFN:e:E:2dD:7895gOw:l:n:b:q:S:B:r:R:Qx:TY:X:Z:z", + "hv::uC:f:4i:Io:t:Lc:m::M:a:A:6:s:UF::N:e:E:2dD:7895gOw:l:n:b:q:S:B:r:R:x:TY:X:Z:z", long_options, &option_index ); if( c < 0 ) { @@ -2544,7 +2676,7 @@ static int ParseOptions( int argc, char ** argv ) ShowPresets(); exit ( 0 ); case DVDNAV: - dvdnav = 1; + dvdnav = 0; break; case 'f': @@ -2582,8 +2714,11 @@ static int ParseOptions( int argc, char ** argv ) case 't': titleindex = atoi( optarg ); break; - case 'L': - longest_title = 1; + case SCAN_ONLY: + titlescan = 1; + break; + case MAIN_FEATURE: + main_feature = 1; break; case 'c': { @@ -2640,10 +2775,10 @@ static int ParseOptions( int argc, char ** argv ) } break; case 's': - subtracks = str_split( optarg, "," ); + subtracks = str_split( optarg, ',' ); break; case 'F': - subtracks = str_split( optarg, "," ); + subforce = str_split( optarg, ',' ); break; case SUB_BURNED: if( optarg != NULL ) @@ -2671,6 +2806,28 @@ static int ParseOptions( int argc, char ** argv ) case NATIVE_DUB: native_dub = 1; break; + case SRT_FILE: + srtfile = str_split( optarg, ',' ); + break; + case SRT_CODESET: + srtcodeset = str_split( optarg, ',' ); + break; + case SRT_OFFSET: + srtoffset = str_split( optarg, ',' ); + break; + case SRT_LANG: + srtlang = str_split( optarg, ',' ); + break; + case SRT_DEFAULT: + if( optarg != NULL ) + { + srtdefault = atoi( optarg ); + } + else + { + srtdefault = 1 ; + } + break; case '2': twoPass = 1; break; @@ -2742,6 +2899,13 @@ static int ParseOptions( int argc, char ** argv ) case 'g': grayscale = 1; break; + case ROTATE_FILTER: + if( optarg != NULL ) + { + rotate_opt = strdup( optarg ); + } + rotate = 1; + break; case DISPLAY_WIDTH: if( optarg != NULL ) { @@ -2857,9 +3021,6 @@ static int ParseOptions( int argc, char ** argv ) abitrates = strdup( optarg ); } break; - case 'Q': - crf = 0; - break; case 'x': x264opts = strdup( optarg ); break; @@ -2884,6 +3045,26 @@ static int ParseOptions( int argc, char ** argv ) case START_AT_PREVIEW: start_at_preview = atoi( optarg ); break; + case START_AT: + start_at_string = strdup( optarg ); + start_at_token = strtok( start_at_string, ":"); + if( !strcmp( start_at_token, "frame" ) ) + { + start_at_token = strtok( NULL, ":"); + start_at_frame = atoi(start_at_token); + } + else if( !strcmp( start_at_token, "pts" ) ) + { + start_at_token = strtok( NULL, ":"); + sscanf( start_at_token, "%"SCNd64, &start_at_pts ); + } + else if( !strcmp( start_at_token, "duration" ) ) + { + start_at_token = strtok( NULL, ":"); + sscanf( start_at_token, "%"SCNd64, &start_at_pts ); + start_at_pts *= 90000LL; + } + break; case STOP_AT: stop_at_string = strdup( optarg ); stop_at_token = strtok( stop_at_string, ":"); @@ -2934,7 +3115,7 @@ static int CheckOptions( int argc, char ** argv ) } /* Parse format */ - if( titleindex > 0 ) + if( titleindex > 0 && !titlescan ) { if( output == NULL || *output == '\0' ) { @@ -2948,12 +3129,7 @@ static int CheckOptions( int argc, char ** argv ) char * p = strrchr( output, '.' ); /* autodetect */ - if( p && !strcasecmp( p, ".avi" ) ) - { - mux = HB_MUX_AVI; - default_acodec = HB_ACODEC_LAME; - } - else if( p && ( !strcasecmp( p, ".mp4" ) || + if( p && ( !strcasecmp( p, ".mp4" ) || !strcasecmp( p, ".m4v" ) ) ) { if ( h264_30 == 1 ) @@ -2962,12 +3138,6 @@ static int CheckOptions( int argc, char ** argv ) mux = HB_MUX_MP4; default_acodec = HB_ACODEC_FAAC; } - else if( p && ( !strcasecmp( p, ".ogm" ) || - !strcasecmp( p, ".ogg" ) ) ) - { - mux = HB_MUX_OGM; - default_acodec = HB_ACODEC_VORBIS; - } else if( p && !strcasecmp(p, ".mkv" ) ) { mux = HB_MUX_MKV; @@ -2980,11 +3150,6 @@ static int CheckOptions( int argc, char ** argv ) return 0; } } - else if( !strcasecmp( format, "avi" ) ) - { - mux = HB_MUX_AVI; - default_acodec = HB_ACODEC_LAME; - } else if( !strcasecmp( format, "mp4" ) || !strcasecmp( format, "m4v" ) ) { @@ -2994,12 +3159,6 @@ static int CheckOptions( int argc, char ** argv ) mux = HB_MUX_MP4; default_acodec = HB_ACODEC_FAAC; } - else if( !strcasecmp( format, "ogm" ) || - !strcasecmp( format, "ogg" ) ) - { - mux = HB_MUX_OGM; - default_acodec = HB_ACODEC_VORBIS; - } else if( !strcasecmp( format, "mkv" ) ) { mux = HB_MUX_MKV; @@ -3008,7 +3167,7 @@ static int CheckOptions( int argc, char ** argv ) else { fprintf( stderr, "Invalid output format (%s). Possible " - "choices are avi, mp4, m4v, ogm, ogg and mkv\n.", format ); + "choices are mp4, m4v and mkv\n.", format ); return 1; } } @@ -3206,7 +3365,7 @@ static int is_dvd_service( io_service_t service ) * The whole media object is indicated in the IORegistry by the presence of a * property with the key "Whole" and value "Yes". ****************************************************************************/ -static is_whole_media_service( io_service_t service ) +static int is_whole_media_service( io_service_t service ) { int result = 0;