X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=test%2Ftest.c;h=fc753d24f09ccf2a3b531f9beabb966f53ad7912;hb=3166f4bf518b12ef658ce4a249f9a265b16693bd;hp=6355746d47b60c247defc6e1b4b8d829b8f84385;hpb=aa977471ffda35319ae31e0480bf71846b414814;p=handbrake-jp%2Fhandbrake-jp-git.git diff --git a/test/test.c b/test/test.c index 6355746d..fc753d24 100644 --- a/test/test.c +++ b/test/test.c @@ -30,6 +30,12 @@ #endif /* Options */ +#if defined( __APPLE_CC__ ) +#define EXTRA_VLC_DYLD_PATH "/Applications/VLC.app/Contents/MacOS/lib" +#define DEFAULT_DYLD_PATH "/usr/local/lib:/usr/lib" + +static int no_vlc_dylib = 0; +#endif static int debug = HB_DEBUG_ALL; static int update = 0; static int dvdnav = 1; @@ -37,7 +43,8 @@ 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; @@ -55,8 +62,6 @@ static int rotate = 0; static char * rotate_opt = 0; static int grayscale = 0; static int vcodec = HB_VCODEC_FFMPEG; -static int h264_13 = 0; -static int h264_30 = 0; static hb_list_t * audios = NULL; static hb_audio_config_t * audio = NULL; static int num_audio_tracks = 0; @@ -67,8 +72,11 @@ static char * arates = NULL; static char * abitrates = NULL; static char * acodecs = NULL; static char * anames = NULL; +#ifdef __APPLE_CC__ +static int default_acodec = HB_ACODEC_CA_AAC; +#else static int default_acodec = HB_ACODEC_FAAC; -static int default_abitrate = 160; +#endif static int audio_explicit = 0; static char ** subtracks = NULL; static char ** subforce = NULL; @@ -125,6 +133,7 @@ static int64_t stop_at_pts = 0; static int stop_at_frame = 0; static char * stop_at_string = NULL; static char * stop_at_token = NULL; +static uint64_t min_title_duration = 900000LL; /* Exit cleanly on Ctrl-C */ static volatile int die = 0; @@ -187,11 +196,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); @@ -218,6 +222,7 @@ int main( int argc, char ** argv ) "date.\n" ); } hb_close( &h ); + hb_global_close(); return 0; } @@ -237,14 +242,14 @@ 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; } - hb_scan( h, input, titleindex, preview_count, store_previews ); + hb_scan( h, input, titleindex, preview_count, store_previews, min_title_duration ); /* Wait... */ while( !die ) @@ -329,6 +334,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 ); @@ -359,13 +365,10 @@ int main( int argc, char ** argv ) if( stop_at_string ) free( stop_at_string ); if( start_at_string ) free( start_at_string ); + // write a carriage return to stdout - avoids overlap / line wrapping when stderr is redirected + fprintf( stdout, "\n" ); fprintf( stderr, "HandBrake has exited.\n" ); -#if defined( PTW32_STATIC_LIB ) - pthread_win32_thread_detach_np(); - pthread_win32_process_detach_np(); -#endif - return 0; } @@ -385,17 +388,21 @@ static void PrintTitleInfo( hb_title_t * title ) int i; fprintf( stderr, "+ title %d:\n", title->index ); + 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", + fprintf( stderr, " + vts %d, ttn %d, cells %d->%d (%"PRIu64" blocks)\n", title->vts, title->ttn, title->cell_start, title->cell_end, title->block_count ); } - if (dvdnav) + if (title->angle_count > 1) fprintf( stderr, " + angle(s) %d\n", title->angle_count ); fprintf( stderr, " + duration: %02d:%02d:%02d\n", title->hours, title->minutes, title->seconds ); @@ -411,7 +418,7 @@ static void PrintTitleInfo( hb_title_t * title ) for( i = 0; i < hb_list_count( title->list_chapter ); i++ ) { chapter = hb_list_item( title->list_chapter, i ); - fprintf( stderr, " + %d: cells %d->%d, %d blocks, duration " + fprintf( stderr, " + %d: cells %d->%d, %"PRIu64" blocks, duration " "%02d:%02d:%02d\n", chapter->index, chapter->cell_start, chapter->cell_end, chapter->block_count, chapter->hours, chapter->minutes, @@ -442,10 +449,11 @@ static void PrintTitleInfo( hb_title_t * title ) for( i = 0; i < hb_list_count( title->list_subtitle ); i++ ) { subtitle = hb_list_item( title->list_subtitle, i ); - fprintf( stderr, " + %d, %s (iso639-2: %s) (%s)\n", + fprintf( stderr, " + %d, %s (iso639-2: %s) (%s)(%s)\n", i + 1, subtitle->lang, subtitle->iso639_2, - (subtitle->format == TEXTSUB) ? "Text" : "Bitmap"); + (subtitle->format == TEXTSUB) ? "Text" : "Bitmap", + hb_subsource_name(subtitle->source)); } if(title->detected_interlacing) @@ -456,11 +464,11 @@ static void PrintTitleInfo( hb_title_t * title ) } -static int test_sub_list( char ** list, char * needle, int pos ) +static int test_sub_list( char ** list, int pos ) { int i; - if ( list == NULL || needle == NULL ) + if ( list == NULL || pos == 0 ) return 0; if ( list[0] == NULL && pos == 1 ) @@ -468,8 +476,9 @@ static int test_sub_list( char ** list, char * needle, int pos ) for ( i = 0; list[i] != NULL; i++ ) { - if ( strcasecmp( list[i], needle ) == 0 ) - return i + 1; + int idx = strtol( list[i], NULL, 0 ); + if ( idx == pos ) + return 1; } return 0; } @@ -490,7 +499,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; @@ -521,15 +530,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++ ) { @@ -537,29 +546,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; @@ -594,409 +610,567 @@ static int HandleEvents( hb_handle_t * h ) if (preset) { - fprintf( stderr, "+ Using preset: %s", preset_name); + fprintf( stderr, "+ Using preset: %s\n", preset_name); if (!strcmp(preset_name, "Universal")) - { - if( !mux ) - { - mux = HB_MUX_MP4; - } - vcodec = HB_VCODEC_X264; - job->vquality = 20.0; - if( !atracks ) - { - atracks = strdup("1,1"); - } - if( !acodecs ) - { - acodecs = strdup("faac,ac3"); - } - if( !abitrates ) - { - abitrates = strdup("160,160"); - } - if( !mixdowns ) - { - mixdowns = strdup("dpl2,auto"); - } - if( !arates ) - { - arates = strdup("48,Auto"); - } - if( !dynamic_range_compression ) - { - dynamic_range_compression = strdup("0.0,0.0"); - } - maxWidth = 720; - if( !x264opts ) - { - x264opts = strdup("cabac=0:ref=2:me=umh:bframes=0:8x8dct=0:trellis=0:subme=6"); - } - anamorphic_mode = 2; - job->chapter_markers = 1; - } - - if (!strcmp(preset_name, "iPod")) - { - if( !mux ) - { - mux = HB_MUX_MP4; - } - job->ipod_atom = 1; - vcodec = HB_VCODEC_X264; - job->vbitrate = 700; - if( !atracks ) - { - atracks = strdup("1"); - } - if( !acodecs ) - { - acodecs = strdup("faac"); - } - if( !abitrates ) - { - abitrates = strdup("160"); - } - if( !mixdowns ) - { - mixdowns = strdup("dpl2"); - } - if( !arates ) - { - arates = strdup("48"); - } - if( !dynamic_range_compression ) - { - dynamic_range_compression = strdup("0.0"); - } - 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:subme=6:8x8dct=0:trellis=0"); - } - job->chapter_markers = 1; - } - - if (!strcmp(preset_name, "iPhone & iPod Touch")) - { - if( !mux ) - { - mux = HB_MUX_MP4; - } - vcodec = HB_VCODEC_X264; - job->vquality = 20.0; - if( !atracks ) - { - atracks = strdup("1"); - } - if( !acodecs ) - { - acodecs = strdup("faac"); - } - if( !abitrates ) - { - abitrates = strdup("128"); - } - if( !mixdowns ) - { - mixdowns = strdup("dpl2"); - } - if( !arates ) - { - arates = strdup("48"); - } - if( !dynamic_range_compression ) - { - dynamic_range_compression = strdup("0.0"); - } - maxWidth = 480; - if( !x264opts ) - { - x264opts = strdup("cabac=0:ref=2:me=umh:bframes=0:subme=6:8x8dct=0:trellis=0"); - } - job->chapter_markers = 1; - } - - if (!strcmp(preset_name, "AppleTV")) - { - if( !mux ) - { - mux = HB_MUX_MP4; - } - job->largeFileSize = 1; - vcodec = HB_VCODEC_X264; - job->vquality = 20.0; - if( !atracks ) - { - atracks = strdup("1,1"); - } - if( !acodecs ) - { - acodecs = strdup("faac,ac3"); - } - if( !abitrates ) - { - abitrates = strdup("160,160"); - } - if( !mixdowns ) - { - mixdowns = strdup("dpl2,auto"); - } - if( !arates ) - { - arates = strdup("48,Auto"); - } - if( !dynamic_range_compression ) - { - dynamic_range_compression = strdup("0.0,0.0"); - } - maxWidth = 960; - if( !x264opts ) - { - x264opts = strdup("cabac=0:ref=2:me=umh:b-adapt=2:weightb=0:trellis=0:weightp=0"); - } - anamorphic_mode = 2; - job->chapter_markers = 1; - } - - if (!strcmp(preset_name, "Normal")) - { - if( !mux ) - { - mux = HB_MUX_MP4; - } - vcodec = HB_VCODEC_X264; - job->vquality = 20.0; - if( !atracks ) - { - atracks = strdup("1"); - } - if( !acodecs ) - { - acodecs = strdup("faac"); - } - if( !abitrates ) - { - abitrates = strdup("160"); - } - if( !mixdowns ) - { - mixdowns = strdup("dpl2"); - } - if( !arates ) - { - arates = strdup("48"); - } - if( !dynamic_range_compression ) - { - dynamic_range_compression = strdup("0.0"); - } - if( !x264opts ) - { - x264opts = strdup("ref=2:bframes=2:subme=6:mixed-refs=0:weightb=0:8x8dct=0:trellis=0"); - } - anamorphic_mode = 1; - job->chapter_markers = 1; - } - - if (!strcmp(preset_name, "High Profile")) - { - if( !mux ) - { - mux = HB_MUX_MP4; - } - vcodec = HB_VCODEC_X264; - job->vquality = 20.0; - if( !atracks ) - { - atracks = strdup("1,1"); - } - if( !acodecs ) - { - acodecs = strdup("faac,ac3"); - } - if( !abitrates ) - { - abitrates = strdup("160,160"); - } - if( !mixdowns ) - { - mixdowns = strdup("dpl2,auto"); - } - if( !arates ) - { - arates = strdup("48,Auto"); - } - if( !dynamic_range_compression ) - { - dynamic_range_compression = strdup("0.0,0.0"); - } - if( !x264opts ) - { - x264opts = strdup("b-adapt=2:rc-lookahead=50"); - } - detelecine = 1; - decomb = 1; - anamorphic_mode = 2; - job->chapter_markers = 1; - } - - if (!strcmp(preset_name, "Classic")) - { - if( !mux ) - { - mux = HB_MUX_MP4; - } - job->vbitrate = 1000; - if( !atracks ) - { - atracks = strdup("1"); - } - if( !acodecs ) - { - acodecs = strdup("faac"); - } - if( !abitrates ) - { - abitrates = strdup("160"); - } - if( !mixdowns ) - { - mixdowns = strdup("dpl2"); - } - if( !arates ) - { - arates = strdup("48"); - } - if( !dynamic_range_compression ) - { - dynamic_range_compression = strdup("0.0"); - } - } - - if (!strcmp(preset_name, "AppleTV Legacy")) - { - if( !mux ) - { - mux = HB_MUX_MP4; - } - job->largeFileSize = 1; - vcodec = HB_VCODEC_X264; - job->vbitrate = 2500; - if( !atracks ) - { - atracks = strdup("1,1"); - } - if( !acodecs ) - { - acodecs = strdup("faac,ac3"); - } - if( !abitrates ) - { - abitrates = strdup("160,160"); - } - if( !mixdowns ) - { - mixdowns = strdup("dpl2,auto"); - } - if( !arates ) - { - arates = strdup("48,Auto"); - } - if( !dynamic_range_compression ) - { - dynamic_range_compression = strdup("0.0,0.0"); - } - if( !x264opts ) - { - 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; - } - - if (!strcmp(preset_name, "iPhone Legacy")) - { - if( !mux ) - { - mux = HB_MUX_MP4; - } - job->ipod_atom = 1; - vcodec = HB_VCODEC_X264; - job->vbitrate = 960; - if( !atracks ) - { - atracks = strdup("1"); - } - if( !acodecs ) - { - acodecs = strdup("faac"); - } - if( !abitrates ) - { - abitrates = strdup("128"); - } - if( !mixdowns ) - { - mixdowns = strdup("dpl2"); - } - if( !arates ) - { - arates = strdup("48"); - } - if( !dynamic_range_compression ) - { - dynamic_range_compression = strdup("0.0"); - } - maxWidth = 480; - if( !x264opts ) - { - 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; - } - - if (!strcmp(preset_name, "iPod Legacy")) - { - if( !mux ) - { - mux = HB_MUX_MP4; - } - job->ipod_atom = 1; - vcodec = HB_VCODEC_X264; - job->vbitrate = 1500; - if( !atracks ) - { - atracks = strdup("1"); - } - if( !acodecs ) - { - acodecs = strdup("faac"); - } - if( !abitrates ) - { - abitrates = strdup("160"); - } - if( !mixdowns ) - { - mixdowns = strdup("dpl2"); - } - if( !arates ) - { - arates = strdup("48"); - } - if( !dynamic_range_compression ) - { - dynamic_range_compression = strdup("0.0"); - } - 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:subme=6:8x8dct=0:trellis=0"); - } - job->chapter_markers = 1; - } + { + if( !mux ) + { + mux = HB_MUX_MP4; + } + vcodec = HB_VCODEC_X264; + job->vquality = 20.0; + if( !atracks ) + { + atracks = strdup("1,1"); + } + if( !acodecs ) + { + acodecs = strdup("faac,copy:ac3"); + } + if( !abitrates ) + { + abitrates = strdup("160,160"); + } + if( !mixdowns ) + { + mixdowns = strdup("dpl2,auto"); + } + if( !arates ) + { + arates = strdup("Auto,Auto"); + } + if( !dynamic_range_compression ) + { + dynamic_range_compression = strdup("0.0,0.0"); + } + maxWidth = 720; + if( !x264opts ) + { + x264opts = strdup("cabac=0:ref=2:me=umh:bframes=0:weightp=0:8x8dct=0:trellis=0:subme=6"); + } + if( !anamorphic_mode ) + { + anamorphic_mode = 2; + } + job->chapter_markers = 1; + + } + + if (!strcmp(preset_name, "iPod")) + { + if( !mux ) + { + mux = HB_MUX_MP4; + } + job->ipod_atom = 1; + vcodec = HB_VCODEC_X264; + job->vbitrate = 700; + if( !atracks ) + { + atracks = strdup("1"); + } + if( !acodecs ) + { + acodecs = strdup("faac"); + } + if( !abitrates ) + { + abitrates = strdup("160"); + } + if( !mixdowns ) + { + mixdowns = strdup("dpl2"); + } + if( !arates ) + { + arates = strdup("Auto"); + } + if( !dynamic_range_compression ) + { + dynamic_range_compression = strdup("0.0"); + } + maxWidth = 320; + if( !x264opts ) + { + x264opts = strdup("level=30:bframes=0:weightp=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; + + } + + if (!strcmp(preset_name, "iPhone & iPod Touch")) + { + if( !mux ) + { + mux = HB_MUX_MP4; + } + vcodec = HB_VCODEC_X264; + job->vquality = 20.0; + if( !atracks ) + { + atracks = strdup("1"); + } + if( !acodecs ) + { + acodecs = strdup("faac"); + } + if( !abitrates ) + { + abitrates = strdup("128"); + } + if( !mixdowns ) + { + mixdowns = strdup("dpl2"); + } + if( !arates ) + { + arates = strdup("Auto"); + } + if( !dynamic_range_compression ) + { + dynamic_range_compression = strdup("0.0"); + } + maxWidth = 480; + if( !x264opts ) + { + x264opts = strdup("cabac=0:ref=2:me=umh:bframes=0:weightp=0:subme=6:8x8dct=0:trellis=0"); + } + job->chapter_markers = 1; + + } + + if (!strcmp(preset_name, "iPhone 4")) + { + if( !mux ) + { + mux = HB_MUX_MP4; + } + job->largeFileSize = 1; + vcodec = HB_VCODEC_X264; + job->vquality = 20.0; + job->vrate_base = 900900; + job->cfr = 2; + if( !atracks ) + { + atracks = strdup("1"); + } + if( !acodecs ) + { + acodecs = strdup("faac"); + } + if( !abitrates ) + { + abitrates = strdup("160"); + } + if( !mixdowns ) + { + mixdowns = strdup("dpl2"); + } + if( !arates ) + { + arates = strdup("Auto"); + } + if( !dynamic_range_compression ) + { + dynamic_range_compression = strdup("0.0"); + } + maxWidth = 960; + if( !anamorphic_mode ) + { + anamorphic_mode = 2; + } + job->chapter_markers = 1; + + } + + if (!strcmp(preset_name, "iPad")) + { + if( !mux ) + { + mux = HB_MUX_MP4; + } + job->largeFileSize = 1; + vcodec = HB_VCODEC_X264; + job->vquality = 20.0; + job->vrate_base = 900900; + job->cfr = 2; + if( !atracks ) + { + atracks = strdup("1"); + } + if( !acodecs ) + { + acodecs = strdup("faac"); + } + if( !abitrates ) + { + abitrates = strdup("160"); + } + if( !mixdowns ) + { + mixdowns = strdup("dpl2"); + } + if( !arates ) + { + arates = strdup("Auto"); + } + if( !dynamic_range_compression ) + { + dynamic_range_compression = strdup("0.0"); + } + maxWidth = 1024; + if( !anamorphic_mode ) + { + anamorphic_mode = 2; + } + job->chapter_markers = 1; + + } + + if (!strcmp(preset_name, "AppleTV")) + { + if( !mux ) + { + mux = HB_MUX_MP4; + } + job->largeFileSize = 1; + vcodec = HB_VCODEC_X264; + job->vquality = 20.0; + if( !atracks ) + { + atracks = strdup("1,1"); + } + if( !acodecs ) + { + acodecs = strdup("faac,copy:ac3"); + } + if( !abitrates ) + { + abitrates = strdup("160,160"); + } + if( !mixdowns ) + { + mixdowns = strdup("dpl2,auto"); + } + if( !arates ) + { + arates = strdup("Auto,Auto"); + } + if( !dynamic_range_compression ) + { + dynamic_range_compression = strdup("0.0,0.0"); + } + maxWidth = 960; + if( !x264opts ) + { + x264opts = strdup("cabac=0:ref=2:me=umh:b-pyramid=none:b-adapt=2:weightb=0:trellis=0:weightp=0:vbv-maxrate=9500:vbv-bufsize=9500"); + } + if( !anamorphic_mode ) + { + anamorphic_mode = 2; + } + job->chapter_markers = 1; + + } + + if (!strcmp(preset_name, "AppleTV 2")) + { + if( !mux ) + { + mux = HB_MUX_MP4; + } + job->largeFileSize = 1; + vcodec = HB_VCODEC_X264; + job->vquality = 20.0; + job->vrate_base = 900900; + job->cfr = 2; + if( !atracks ) + { + atracks = strdup("1,1"); + } + if( !acodecs ) + { + acodecs = strdup("faac,copy:ac3"); + } + if( !abitrates ) + { + abitrates = strdup("160,160"); + } + if( !mixdowns ) + { + mixdowns = strdup("dpl2,auto"); + } + if( !arates ) + { + arates = strdup("Auto,Auto"); + } + if( !dynamic_range_compression ) + { + dynamic_range_compression = strdup("0.0,0.0"); + } + maxWidth = 1280; + if( !anamorphic_mode ) + { + anamorphic_mode = 2; + } + job->chapter_markers = 1; + + } + + if (!strcmp(preset_name, "Normal")) + { + if( !mux ) + { + mux = HB_MUX_MP4; + } + vcodec = HB_VCODEC_X264; + job->vquality = 20.0; + if( !atracks ) + { + atracks = strdup("1"); + } + if( !acodecs ) + { + acodecs = strdup("faac"); + } + if( !abitrates ) + { + abitrates = strdup("160"); + } + if( !mixdowns ) + { + mixdowns = strdup("dpl2"); + } + if( !arates ) + { + arates = strdup("Auto"); + } + if( !dynamic_range_compression ) + { + dynamic_range_compression = strdup("0.0"); + } + if( !x264opts ) + { + x264opts = strdup("ref=2:bframes=2:subme=6:mixed-refs=0:weightb=0:8x8dct=0:trellis=0"); + } + if( !anamorphic_mode ) + { + anamorphic_mode = 1; + } + job->chapter_markers = 1; + + } + + if (!strcmp(preset_name, "High Profile")) + { + if( !mux ) + { + mux = HB_MUX_MP4; + } + vcodec = HB_VCODEC_X264; + job->vquality = 20.0; + if( !atracks ) + { + atracks = strdup("1,1"); + } + if( !acodecs ) + { + acodecs = strdup("faac,copy:ac3"); + } + if( !abitrates ) + { + abitrates = strdup("160,160"); + } + if( !mixdowns ) + { + mixdowns = strdup("dpl2,auto"); + } + if( !arates ) + { + arates = strdup("Auto,Auto"); + } + if( !dynamic_range_compression ) + { + dynamic_range_compression = strdup("0.0,0.0"); + } + if( !x264opts ) + { + x264opts = strdup("b-adapt=2:rc-lookahead=50"); + } + detelecine = 1; + decomb = 1; + if( !anamorphic_mode ) + { + anamorphic_mode = 2; + } + job->chapter_markers = 1; + + } + + if (!strcmp(preset_name, "Classic")) + { + if( !mux ) + { + mux = HB_MUX_MP4; + } + job->vbitrate = 1000; + if( !atracks ) + { + atracks = strdup("1"); + } + if( !acodecs ) + { + acodecs = strdup("faac"); + } + if( !abitrates ) + { + abitrates = strdup("160"); + } + if( !mixdowns ) + { + mixdowns = strdup("dpl2"); + } + if( !arates ) + { + arates = strdup("Auto"); + } + if( !dynamic_range_compression ) + { + dynamic_range_compression = strdup("0.0"); + } + + } + + if (!strcmp(preset_name, "AppleTV Legacy")) + { + if( !mux ) + { + mux = HB_MUX_MP4; + } + job->largeFileSize = 1; + vcodec = HB_VCODEC_X264; + job->vbitrate = 2500; + if( !atracks ) + { + atracks = strdup("1,1"); + } + if( !acodecs ) + { + acodecs = strdup("faac,copy:ac3"); + } + if( !abitrates ) + { + abitrates = strdup("160,160"); + } + if( !mixdowns ) + { + mixdowns = strdup("dpl2,auto"); + } + if( !arates ) + { + arates = strdup("Auto,Auto"); + } + if( !dynamic_range_compression ) + { + dynamic_range_compression = strdup("0.0,0.0"); + } + if( !x264opts ) + { + x264opts = strdup("ref=1:b-pyramid=none:weightp=0:subme=5:me=umh:no-fast-pskip=1:cabac=0:weightb=0:8x8dct=0:trellis=0"); + } + if( !anamorphic_mode ) + { + anamorphic_mode = 1; + } + job->chapter_markers = 1; + + } + + if (!strcmp(preset_name, "iPhone Legacy")) + { + if( !mux ) + { + mux = HB_MUX_MP4; + } + job->ipod_atom = 1; + vcodec = HB_VCODEC_X264; + job->vbitrate = 960; + if( !atracks ) + { + atracks = strdup("1"); + } + if( !acodecs ) + { + acodecs = strdup("faac"); + } + if( !abitrates ) + { + abitrates = strdup("128"); + } + if( !mixdowns ) + { + mixdowns = strdup("dpl2"); + } + if( !arates ) + { + arates = strdup("Auto"); + } + if( !dynamic_range_compression ) + { + dynamic_range_compression = strdup("0.0"); + } + maxWidth = 480; + if( !x264opts ) + { + x264opts = strdup("level=30:cabac=0:ref=1:analyse=all:me=umh:no-fast-pskip=1:psy-rd=0,0:bframes=0:weightp=0:subme=6:8x8dct=0:trellis=0"); + } + job->chapter_markers = 1; + + } + + if (!strcmp(preset_name, "iPod Legacy")) + { + if( !mux ) + { + mux = HB_MUX_MP4; + } + job->ipod_atom = 1; + vcodec = HB_VCODEC_X264; + job->vbitrate = 1500; + if( !atracks ) + { + atracks = strdup("1"); + } + if( !acodecs ) + { + acodecs = strdup("faac"); + } + if( !abitrates ) + { + abitrates = strdup("160"); + } + if( !mixdowns ) + { + mixdowns = strdup("dpl2"); + } + if( !arates ) + { + arates = strdup("Auto"); + } + if( !dynamic_range_compression ) + { + dynamic_range_compression = strdup("0.0"); + } + maxWidth = 640; + if( !x264opts ) + { + x264opts = strdup("level=30:bframes=0:weightp=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; + + } + } if ( chapter_markers ) @@ -1113,6 +1287,11 @@ static int HandleEvents( hb_handle_t * h ) { case 0: // Non-anamorphic + if (modulus) + { + job->modulus = modulus; + } + if( width && height ) { job->width = width; @@ -1121,15 +1300,27 @@ static int HandleEvents( hb_handle_t * h ) else if( width ) { job->width = width; + // do not exceed source dimensions by default + if( !maxHeight ) + job->maxHeight = title->height; hb_fix_aspect( job, HB_KEEP_WIDTH ); } else if( height ) { job->height = height; + // do not exceed source dimensions by default + if( !maxWidth ) + job->maxWidth = title->width; hb_fix_aspect( job, HB_KEEP_HEIGHT ); } else if( !width && !height ) { + /* Default to cropped width when one isn't specified + * avoids rounding to mod 16 regardless of modulus */ + job->width = title->width - job->crop[2] - job->crop[3]; + // do not exceed source dimensions by default + if( !maxHeight ) + job->maxHeight = title->height; hb_fix_aspect( job, HB_KEEP_WIDTH ); } @@ -1144,7 +1335,7 @@ static int HandleEvents( hb_handle_t * h ) if (modulus) { - job->anamorphic.modulus = modulus; + job->modulus = modulus; } if( itu_par ) @@ -1169,7 +1360,7 @@ static int HandleEvents( hb_handle_t * h ) if (modulus) { - job->anamorphic.modulus = modulus; + job->modulus = modulus; } if( itu_par ) @@ -1256,7 +1447,7 @@ static int HandleEvents( hb_handle_t * h ) break; } - if( vquality >= 0.0 && ( ( vquality <= 1.0 ) || ( vcodec == HB_VCODEC_X264 ) || (vcodec == HB_VCODEC_FFMPEG) ) ) + if( vquality >= 0.0 ) { job->vquality = vquality; job->vbitrate = 0; @@ -1270,14 +1461,6 @@ static int HandleEvents( hb_handle_t * h ) { job->vcodec = vcodec; } - if( h264_13 ) - { - job->h264_level = 13; - } - if( h264_30 ) - { - job->h264_level = 30; - } if( vrate ) { job->cfr = cfr; @@ -1330,7 +1513,7 @@ static int HandleEvents( hb_handle_t * h ) } else { - fprintf(stderr, "ERROR: Unable to parse audio input \"%s\", skipping.", + fprintf(stderr, "ERROR: Unable to parse audio input \"%s\", skipping.\n", token); free(audio); } @@ -1517,6 +1700,10 @@ static int HandleEvents( hb_handle_t * h ) if( audio != NULL ) { + if ( !strcasecmp( token, "auto" ) ) + { + arate = audio->in.samplerate; + } if (!is_sample_rate_valid(arate)) { fprintf(stderr, "Invalid sample rate %d, using input rate %d\n", arate, audio->in.samplerate); @@ -1548,6 +1735,52 @@ static int HandleEvents( hb_handle_t * h ) } } /* Sample Rate */ + + /* Audio Mixdown */ + i = 0; + if ( mixdowns ) + { + char * token = strtok(mixdowns, ","); + if (token == NULL) + token = mixdowns; + while ( token != NULL ) + { + mixdown = hb_mixdown_get_mixdown_from_short_name(token); + audio = hb_list_audio_config_item(job->list_audio, i); + if( audio != NULL ) + { + audio->out.mixdown = mixdown; + if( (++i) >= num_audio_tracks ) + break; /* We have more inputs than audio tracks, oops */ + } + else + { + fprintf(stderr, "Ignoring mixdown, no audio tracks\n"); + } + token = strtok(NULL, ","); + } + } + if (i < num_audio_tracks) + { + /* We have fewer inputs than audio tracks, use the default mixdown for the rest. Unless + * we only have one input, then use that. + */ + int use_default = 0; + if (i != 1) + use_default = 1; + + for (; i < num_audio_tracks; i++) + { + audio = hb_list_audio_config_item(job->list_audio, i); + if (use_default) + { + // Get default for this tracks codec and layout + mixdown = hb_get_default_mixdown( audio->out.codec, audio->in.channel_layout ); + } + audio->out.mixdown = mixdown; + } + } + /* Audio Mixdown */ /* Audio Bitrate */ i = 0; @@ -1580,11 +1813,19 @@ static int HandleEvents( hb_handle_t * h ) * for the remaining tracks. Unless we only have one input, then use * that for all tracks. */ + int use_default = 0; if (i != 1) - abitrate = default_abitrate; + use_default = 1; + for (; i < num_audio_tracks; i++) { audio = hb_list_audio_config_item(job->list_audio, i); + if (use_default) + { + abitrate = hb_get_default_audio_bitrate( + audio->out.codec, audio->out.samplerate, + audio->out.mixdown ); + } audio->out.bitrate = abitrate; } } @@ -1630,45 +1871,6 @@ static int HandleEvents( hb_handle_t * h ) } /* Audio DRC */ - /* Audio Mixdown */ - i = 0; - if ( mixdowns ) - { - char * token = strtok(mixdowns, ","); - if (token == NULL) - token = mixdowns; - while ( token != NULL ) - { - mixdown = hb_mixdown_get_mixdown_from_short_name(token); - audio = hb_list_audio_config_item(job->list_audio, i); - if( audio != NULL ) - { - audio->out.mixdown = mixdown; - if( (++i) >= num_audio_tracks ) - break; /* We have more inputs than audio tracks, oops */ - } - else - { - fprintf(stderr, "Ignoring mixdown, no audio tracks\n"); - } - token = strtok(NULL, ","); - } - } - if (i < num_audio_tracks) - { - /* We have fewer inputs than audio tracks, use DPLII for the rest. Unless - * we only have one input, then use that. - */ - if (i != 1) - mixdown = HB_AMIXDOWN_DOLBYPLII; - for (; i < num_audio_tracks; i++) - { - audio = hb_list_audio_config_item(job->list_audio, i); - audio->out.mixdown = mixdown; - } - } - /* Audio Mixdown */ - /* Audio Track Names */ i = 0; if ( anames ) @@ -1705,6 +1907,39 @@ static int HandleEvents( hb_handle_t * h ) } /* Audio Track Names */ + /* Fix up passthru that needs to fallback to ac3 encode */ + for( i = 0; i < hb_list_count( job->list_audio ); ) + { + audio = hb_list_audio_config_item( job->list_audio, i ); + if ( ( audio->out.codec & HB_ACODEC_AC3 ) && + ( audio->out.codec & HB_ACODEC_PASS_FLAG ) && + !( audio->out.codec & audio->in.codec ) ) + { + // AC3 passthru not possible, fallback to AC3 encoder. + fprintf( stderr, "AC3 passthru requested and input codec is not AC3 for track %d, using AC3 encoder\n", + audio->out.track ); + audio->out.codec = HB_ACODEC_AC3; + audio->out.mixdown = hb_get_default_mixdown( audio->out.codec, audio->in.channel_layout ); + audio->out.bitrate = hb_get_default_audio_bitrate( audio->out.codec, audio->out.samplerate, + audio->out.mixdown ); + } + // fix 'copy' to select a specific codec + if ( audio->out.codec & HB_ACODEC_PASS_FLAG ) + { + audio->out.codec &= (audio->in.codec | HB_ACODEC_PASS_FLAG); + if ( !( audio->out.codec & HB_ACODEC_MASK ) ) + { + // Passthru not possible, drop audio. + fprintf( stderr, "Passthru requested and input codec is not the same as output codec for track %d, dropping track\n", + audio->out.track ); + hb_audio_t * item = hb_list_item( job->list_audio, i ); + hb_list_rem( job->list_audio, item ); + continue; + } + } + i++; + } + if( size ) { job->vbitrate = hb_calc_bitrate( job, size ); @@ -1715,12 +1950,15 @@ static int HandleEvents( hb_handle_t * h ) if( subtracks ) { char * token; - int i, pos; + int i; + int burnpos = 0, defaultpos = 0; - pos = 0; + if ( subburn ) + burnpos = strtol( subburn, NULL, 0 ); + if ( subdefault ) + defaultpos = strtol( subdefault, NULL, 0 ); for ( i = 0; subtracks[i] != NULL; i++ ) { - pos++; token = subtracks[i]; if( strcasecmp(token, "scan" ) == 0 ) { @@ -1728,21 +1966,21 @@ static int HandleEvents( hb_handle_t * h ) if ( subburn != NULL ) { - burn = ( pos == 1 && subburn[0] == 0 ) || - ( strcmp( "scan", subburn ) == 0 ); + burn = ( i == 0 && subburn[0] == 0 ) || + ( burnpos == i+1 ); } if ( subdefault != NULL ) { - def = ( pos == 1 && subdefault[0] == 0 ) || - ( strcmp( "scan", subdefault ) == 0 ); + def = ( i == 0 && subdefault[0] == 0 ) || + ( defaultpos == i+1 ); } - force = test_sub_list( subforce, "scan", pos ); + force = test_sub_list( subforce, i+1 ); - if ( !burn && mux == HB_MUX_MKV ) + if ( !burn ) { job->select_subtitle_config.dest = PASSTHRUSUB; } - else if ( burn ) + else { if ( sub_burned ) { @@ -1750,14 +1988,9 @@ static int HandleEvents( hb_handle_t * h ) } sub_burned = 1; } - if ( !( !burn && mux == HB_MUX_MP4 ) ) - { - job->select_subtitle_config.force = force; - job->select_subtitle_config.default_track = def; - subtitle_scan = 1; - } else { - fprintf( stderr, "Warning: Subtitle Scan for MP4 requires the '--subtitle-burn' option to be selected\n"); - } + job->select_subtitle_config.force = force; + job->select_subtitle_config.default_track = def; + subtitle_scan = 1; } else { @@ -1777,30 +2010,22 @@ static int HandleEvents( hb_handle_t * h ) if ( subburn != NULL ) { - burn = ( pos == 1 && subburn[0] == 0 ) || - ( strcmp( token, subburn ) == 0 ); + burn = ( i == 0 && subburn[0] == 0 ) || + ( burnpos == i+1 ); } if ( subdefault != NULL ) { - def = ( pos == 1 && subdefault[0] == 0 ) || - ( strcmp( token, subdefault ) == 0 ); + def = ( i == 0 && subdefault[0] == 0 ) || + ( defaultpos == i+1 ); } - force = test_sub_list(subforce, token, pos); - - if ( !burn && mux == HB_MUX_MKV && - subtitle->format == PICTURESUB) - { - sub_config.dest = PASSTHRUSUB; - } - else if (!burn && mux == HB_MUX_MP4 && - subtitle->format == PICTURESUB) - { - // Skip any non-burned vobsubs when output is mp4 - fprintf( stderr, "Warning: Skipping subtitle track %d, can't pass-through VOBSUBs in an MP4 container,\nadd '--subtitle-burn %d' to the command line\n", track+1, track+1 ); - continue; - } - else if ( burn && subtitle->format == PICTURESUB ) + force = test_sub_list(subforce, i+1); + + int supports_burn = + ( subtitle->source == VOBSUB ) || + ( subtitle->source == SSASUB ); + + if ( burn && supports_burn ) { // Only allow one subtitle to be burned into video if ( sub_burned ) @@ -1809,6 +2034,13 @@ static int HandleEvents( hb_handle_t * h ) continue; } sub_burned = 1; + + // Mark as burn-in + sub_config.dest = RENDERSUB; + } + else + { + sub_config.dest = PASSTHRUSUB; } sub_config.force = force; sub_config.default_track = def; @@ -1820,17 +2052,15 @@ static int HandleEvents( hb_handle_t * h ) if( srtfile ) { char * token; - int i, pos; + int i; 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] ) { @@ -1847,8 +2077,10 @@ static int HandleEvents( hb_handle_t * h ) 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); + strncpy( sub_config.src_filename, srtfile[i], 255); + sub_config.src_filename[255] = 0; + strncpy( sub_config.src_codeset, codeset, 39); + sub_config.src_codeset[39] = 0; sub_config.offset = offset; hb_srt_add( job, &sub_config, lang); @@ -2207,9 +2439,10 @@ static void ShowHelp() "### 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" @@ -2242,7 +2475,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, --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" @@ -2282,23 +2515,29 @@ static void ShowHelp() #ifdef __APPLE_CC__ fprintf( out, - " -E, --aencoder Audio encoder(s) (ca_aac/faac/lame/vorbis/ac3/dts) \n" - " ac3 and dts meaning passthrough\n" + " -E, --aencoder Audio encoder(s)\n" + " (ca_aac/faac/lame/vorbis/ac3/copy/copy:ac3/copy:dts)\n" + " copy, copy:ac3 and copy:dts meaning passthrough.\n" + " copy will passthrough either ac3 or dts.\n" " Separated by commas for more than one audio track.\n" - " (default: guessed)\n" ); + " (default: ca_aac)\n" ); #else fprintf( out, - " -E, --aencoder Audio encoder(s) (faac/lame/vorbis/ac3/dts) \n" - " ac3 and dts meaning passthrough\n" + " -E, --aencoder Audio encoder(s):\n" + " (faac/lame/vorbis/ac3/copy/copy:ac3/copy:dts)\n" + " copy, copy:ac3 and copy:dts meaning passthrough.\n" + " copy will passthrough either ac3 or dts.\n" " Separated by commas for more than one audio track.\n" - " (default: guessed)\n" ); + " (default: faac for mp4, lame for mkv)\n" ); #endif fprintf( out, - " -B, --ab Set audio bitrate(s) (default: 160)\n" + " -B, --ab Set audio bitrate(s) (default: depends on the\n" + " selected codec, mixdown and samplerate)\n" " Separated by commas for more than one audio track.\n" " -6, --mixdown Format(s) for surround sound downmixing\n" " Separated by commas for more than one audio track.\n" - " (mono/stereo/dpl1/dpl2/6ch, default: dpl2)\n" + " (mono/stereo/dpl1/dpl2/6ch, default: up to 6ch for ac3,\n" + " up to dpl2 for other encoders)\n" " -R, --arate Set audio samplerate(s) (" ); for( i = 0; i < hb_audio_rates_count; i++ ) { @@ -2337,8 +2576,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" @@ -2373,7 +2612,7 @@ static void ShowHelp() " -s, --subtitle Select subtitle track(s), separated by commas\n" " More than one output track can be used for one\n" " input.\n" - " (\"1,2,3\" for multiple tracks.\n" + " Example: \"1,2,3\" for multiple tracks.\n" " A special track name \"scan\" adds an extra 1st pass.\n" " This extra pass scans subtitles matching the\n" " language of the first audio or the language \n" @@ -2383,18 +2622,22 @@ static void ShowHelp() " for short foreign language segments. Best used in\n" " conjunction with --subtitle-forced.\n" " -F, --subtitle-forced Only display subtitles from the selected stream if\n" - " the subtitle has the forced flag set. May be used in\n" - " conjunction with \"scan\" track to auto-select\n" - " a stream if it contains forced subtitles.\n" + " the subtitle has the forced flag set. The values in\n" + " \"string\" are indexes into the subtitle list\n" + " specified with '--subtitle'.\n" " Separated by commas for more than one audio track.\n" - " (\"1,2,3\" for multiple tracks.\n" - " If \"string\" is omitted, the first trac is forced.\n" + " Example: \"1,2,3\" for multiple tracks.\n" + " If \"string\" is omitted, the first track is forced.\n" " --subtitle-burn \"Burn\" the selected subtitle into the video track\n" - " If \"number\" is omitted, the first trac is burned.\n" + " If \"number\" is omitted, the first track is burned.\n" + " \"number\" is an index into the subtitle list\n" + " specified with '--subtitle'.\n" " --subtitle-default Flag the selected subtitle 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 trac is default.\n" + " If \"number\" is omitted, the first track is default.\n" + " \"number\" is an index into the subtitle list\n" + " specified with '--subtitle'.\n" " -N, --native-language Specifiy the your language preference. When the first\n" " audio track does not match your native language then\n" " select the first subtitle that does. When used in\n" @@ -2434,37 +2677,46 @@ static void ShowHelp() ****************************************************************************/ 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: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: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: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:me=umh:b-adapt=2:weightb=0:trellis=0:weightp=0\n"); - + fprintf( stderr, "%s - %s - %s\n", HB_PROJECT_TITLE, HB_PROJECT_BUILD_TITLE, HB_PROJECT_URL_WEBSITE ); + + printf("\n< Apple\n"); + + printf("\n + Universal: -e x264 -q 20.0 -a 1,1 -E faac,copy:ac3 -B 160,160 -6 dpl2,auto -R Auto,Auto -D 0.0,0.0 -f mp4 -X 720 --loose-anamorphic -m -x cabac=0:ref=2:me=umh:bframes=0:weightp=0:8x8dct=0:trellis=0:subme=6\n"); + + printf("\n + iPod: -e x264 -b 700 -a 1 -E faac -B 160 -6 dpl2 -R Auto -D 0.0 -f mp4 -I -X 320 -m -x level=30:bframes=0:weightp=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 Auto -D 0.0 -f mp4 -X 480 -m -x cabac=0:ref=2:me=umh:bframes=0:weightp=0:subme=6:8x8dct=0:trellis=0\n"); + + printf("\n + iPhone 4: -e x264 -q 20.0 -r 29.97 --pfr -a 1 -E faac -B 160 -6 dpl2 -R Auto -D 0.0 -f mp4 -4 -X 960 --loose-anamorphic -m\n"); + + printf("\n + iPad: -e x264 -q 20.0 -r 29.97 --pfr -a 1 -E faac -B 160 -6 dpl2 -R Auto -D 0.0 -f mp4 -4 -X 1024 --loose-anamorphic -m\n"); + + printf("\n + AppleTV: -e x264 -q 20.0 -a 1,1 -E faac,copy:ac3 -B 160,160 -6 dpl2,auto -R Auto,Auto -D 0.0,0.0 -f mp4 -4 -X 960 --loose-anamorphic -m -x cabac=0:ref=2:me=umh:b-pyramid=none:b-adapt=2:weightb=0:trellis=0:weightp=0:vbv-maxrate=9500:vbv-bufsize=9500\n"); + + printf("\n + AppleTV 2: -e x264 -q 20.0 -r 29.97 --pfr -a 1,1 -E faac,copy:ac3 -B 160,160 -6 dpl2,auto -R Auto,Auto -D 0.0,0.0 -f mp4 -4 -X 1280 --loose-anamorphic -m\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: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 b-adapt=2:rc-lookahead=50\n"); - + + printf("\n + Normal: -e x264 -q 20.0 -a 1 -E faac -B 160 -6 dpl2 -R Auto -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,copy:ac3 -B 160,160 -6 dpl2,auto -R Auto,Auto -D 0.0,0.0 -f mp4 --detelecine --decomb --loose-anamorphic -m -x b-adapt=2:rc-lookahead=50\n"); + printf("\n>\n"); - + printf("\n< Legacy\n"); - - 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 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: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:subme=6:8x8dct=0:trellis=0\n"); - + + printf("\n + Classic: -b 1000 -a 1 -E faac -B 160 -6 dpl2 -R Auto -D 0.0 -f mp4\n"); + + printf("\n + AppleTV Legacy: -e x264 -b 2500 -a 1,1 -E faac,copy:ac3 -B 160,160 -6 dpl2,auto -R Auto,Auto -D 0.0,0.0 -f mp4 -4 --strict-anamorphic -m -x ref=1:b-pyramid=none:weightp=0: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 Auto -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:weightp=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 Auto -D 0.0 -f mp4 -I -X 640 -m -x level=30:bframes=0:weightp=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 * hb_strndup( char * str, int len ) @@ -2540,6 +2792,9 @@ static int ParseOptions( int argc, char ** argv ) #define SRT_LANG 273 #define SRT_DEFAULT 274 #define ROTATE_FILTER 275 + #define SCAN_ONLY 276 + #define MAIN_FEATURE 277 + #define MIN_DURATION 278 for( ;; ) { @@ -2559,7 +2814,9 @@ static int ParseOptions( int argc, char ** argv ) { "ipod-atom", no_argument, NULL, 'I' }, { "title", required_argument, NULL, 't' }, - { "longest", no_argument, NULL, 'L' }, + { "min-duration",required_argument, NULL, MIN_DURATION }, + { "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' }, @@ -2621,14 +2878,20 @@ static int ParseOptions( int argc, char ** argv ) { "vfr", no_argument, &cfr, 0 }, { "cfr", no_argument, &cfr, 1 }, { "pfr", no_argument, &cfr, 2 }, +#if defined( __APPLE_CC__ ) + { "no-vlc-dylib-path", no_argument, &no_vlc_dylib, 1 }, +#endif { 0, 0, 0, 0 } }; int option_index = 0; int c; + int cur_optind; - c = getopt_long( argc, argv, - "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", + cur_optind = optind; + c = getopt_long( argc, argv, + "hv::uC:f:4i:Io:t:c: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 ) { @@ -2706,8 +2969,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': { @@ -2922,16 +3188,6 @@ static int ParseOptions( int argc, char ** argv ) { vcodec = HB_VCODEC_X264; } - else if( !strcasecmp( optarg, "x264b13" ) ) - { - vcodec = HB_VCODEC_X264; - h264_13 = 1; - } - else if( !strcasecmp( optarg, "x264b30" ) ) - { - vcodec = HB_VCODEC_X264; - h264_30 = 1; - } else if( !strcasecmp( optarg, "theora" ) ) { vcodec = HB_VCODEC_THEORA; @@ -3080,8 +3336,11 @@ static int ParseOptions( int argc, char ** argv ) else if( atoi( optarg ) == 709 ) color_matrix = 2; break; + case MIN_DURATION: + min_title_duration = strtol( optarg, NULL, 0 ); + break; default: - fprintf( stderr, "unknown option (%s)\n", argv[optind] ); + fprintf( stderr, "unknown option (%s)\n", argv[cur_optind] ); return -1; } } @@ -3089,8 +3348,109 @@ static int ParseOptions( int argc, char ** argv ) return 0; } +char * str_printf(const char *fmt, ...) +{ + /* Guess we need no more than 100 bytes. */ + int len; + va_list ap; + int size = 100; + char *tmp, *str = NULL; + + str = (char*)malloc(size); + while (1) + { + /* Try to print in the allocated space. */ + va_start(ap, fmt); + len = vsnprintf(str, size, fmt, ap); + va_end(ap); + + /* If that worked, return the string. */ + if (len > -1 && len < size) { + return str; + } + + /* Else try again with more space. */ + if (len > -1) /* glibc 2.1 */ + size = len+1; /* precisely what is needed */ + else /* glibc 2.0 */ + size *= 2; /* twice the old size */ + + tmp = (char*)realloc(str, size); + if (tmp == NULL) { + return str; + } + str = tmp; + } +} + static int CheckOptions( int argc, char ** argv ) { +#if defined( __APPLE_CC__ ) + // If OSX, add VLC dylib path and exec to make it stick. + char *dylib_path; + + if ( !no_vlc_dylib ) + { + dylib_path = getenv("DYLD_FALLBACK_LIBRARY_PATH"); + if ( dylib_path == NULL || + strstr( dylib_path, "/Applications/VLC.app/Contents/MacOS/lib" ) == NULL ) + { + char *path = NULL; + char *home; + int result = -1; + + home = getenv("HOME"); + + if ( dylib_path == NULL ) + { + // Set the system default of $HOME/lib:/usr/local/lib:/usr/lib + // And add our extra path + if ( home != NULL ) + { + path = str_printf("%s/lib:%s:%s:%s%s", home, + DEFAULT_DYLD_PATH, + EXTRA_VLC_DYLD_PATH, + home, EXTRA_VLC_DYLD_PATH); + } + else + { + path = str_printf("%s:%s", DEFAULT_DYLD_PATH, EXTRA_VLC_DYLD_PATH); + } + if ( path != NULL ) + result = setenv("DYLD_FALLBACK_LIBRARY_PATH", path, 1); + } + else + { + // add our extra path + if ( home != NULL ) + { + path = str_printf("%s:%s:%s%s", dylib_path, EXTRA_VLC_DYLD_PATH, + home, EXTRA_VLC_DYLD_PATH); + } + else + { + path = str_printf("%s:%s", dylib_path, EXTRA_VLC_DYLD_PATH); + } + if ( path != NULL ) + result = setenv("DYLD_FALLBACK_LIBRARY_PATH", path, 1); + } + if ( result == 0 ) + { + const char ** new_argv; + int i; + + new_argv = (const char**)malloc( (argc + 2) * sizeof(char*) ); + new_argv[0] = argv[0]; + new_argv[1] = "--no-vlc-dylib-path"; + for (i = 1; i < argc; i++) + new_argv[i+1] = argv[i]; + new_argv[i+1] = NULL; + execv(new_argv[0], (char* const*)new_argv); + } + } + } +#endif + if( update ) { return 0; @@ -3104,7 +3464,7 @@ static int CheckOptions( int argc, char ** argv ) } /* Parse format */ - if( titleindex > 0 ) + if( titleindex > 0 && !titlescan ) { if( output == NULL || *output == '\0' ) { @@ -3119,18 +3479,17 @@ static int CheckOptions( int argc, char ** argv ) /* autodetect */ if( p && ( !strcasecmp( p, ".mp4" ) || - !strcasecmp( p, ".m4v" ) ) ) + !strcasecmp( p, ".m4v" ) ) ) { - if ( h264_30 == 1 ) - mux = HB_MUX_IPOD; - else - mux = HB_MUX_MP4; - default_acodec = HB_ACODEC_FAAC; + mux = HB_MUX_MP4; } else if( p && !strcasecmp(p, ".mkv" ) ) { mux = HB_MUX_MKV; - default_acodec = HB_ACODEC_AC3; +#ifndef __APPLE_CC__ + // default to Lame for MKV (except under OS X where Core Audio is available) + default_acodec = HB_ACODEC_LAME; +#endif } else { @@ -3142,16 +3501,15 @@ static int CheckOptions( int argc, char ** argv ) else if( !strcasecmp( format, "mp4" ) || !strcasecmp( format, "m4v" ) ) { - if ( h264_30 == 1) - mux = HB_MUX_IPOD; - else - mux = HB_MUX_MP4; - default_acodec = HB_ACODEC_FAAC; + mux = HB_MUX_MP4; } else if( !strcasecmp( format, "mkv" ) ) { mux = HB_MUX_MKV; - default_acodec = HB_ACODEC_AC3; +#ifndef __APPLE_CC__ + // default to Lame for MKV (except under OS X where Core Audio is available) + default_acodec = HB_ACODEC_LAME; +#endif } else { @@ -3170,9 +3528,17 @@ static int get_acodec_for_string( char *codec ) { return HB_ACODEC_AC3; } - else if( !strcasecmp( codec, "dts" ) || !strcasecmp( codec, "dca" ) ) + else if( !strcasecmp( codec, "copy" ) ) + { + return HB_ACODEC_AC3_PASS | HB_ACODEC_DCA_PASS; + } + else if( !strcasecmp( codec, "copy:ac3" ) ) + { + return HB_ACODEC_AC3_PASS; + } + else if( !strcasecmp( codec, "copy:dts" ) || !strcasecmp( codec, "copy:dca" ) ) { - return HB_ACODEC_DCA; + return HB_ACODEC_DCA_PASS; } else if( !strcasecmp( codec, "lame" ) ) {