#include <sys/time.h>
#include <time.h>
#include <unistd.h>
+#include <inttypes.h>
#include "hb.h"
#include "parsecsv.h"
static int mp4_optimize = 0;
static int ipod_atom = 0;
static int color_matrix = 0;
+static int preview_count = 10;
+static int store_previews = 0;
+static int start_at_preview = 0;
+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;
/* Exit cleanly on Ctrl-C */
static volatile int die = 0;
return 1;
}
+#ifdef 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);
h = hb_init( debug, update );
/* Show version */
- fprintf( stderr, "HandBrake %s (%d) - http://handbrake.fr/\n",
- hb_get_version( h ), hb_get_build( h ) );
+ fprintf( stderr, "%s - %s - %s\n",
+ HB_PROJECT_TITLE, HB_PROJECT_BUILD_TITLE, HB_PROJECT_URL_WEBSITE );
/* Check for update */
if( update )
*/
titleindex = 0;
}
- hb_scan( h, input, titleindex );
+
+ hb_scan( h, input, titleindex, preview_count, store_previews );
/* Wait... */
while( !die )
{
-#if !defined(SYS_BEOS)
+#if !defined(SYS_BEOS) && !defined(__MINGW32__)
fd_set fds;
struct timeval tv;
int ret;
if( x264opts ) free (x264opts );
if( x264opts2 ) free (x264opts2 );
if (preset_name) free (preset_name);
+ if( stop_at_string ) free( stop_at_string );
fprintf( stderr, "HandBrake has exited.\n" );
+#ifdef PTW32_STATIC_LIB
+ pthread_win32_thread_detach_np();
+ pthread_win32_process_detach_np();
+#endif
+
return 0;
}
PrintTitleInfo( title );
- if( chapter_start && chapter_end )
+ if( chapter_start && chapter_end && !stop_at_pts && !start_at_preview && !stop_at_frame )
{
job->chapter_start = MAX( job->chapter_start,
chapter_start );
job->chapter_markers = 1;
}
+ if (!strcmp(preset_name, "iPod"))
+ {
+ mux = HB_MUX_MP4;
+ job->ipod_atom = 1;
+ vcodec = HB_VCODEC_X264;
+ job->vbitrate = 700;
+ if( !atracks )
+ {
+ atracks = strdup("1");
+ }
+ if( !abitrates )
+ {
+ abitrates = strdup("160");
+ }
+ if( !arates )
+ {
+ arates = strdup("48");
+ }
+ if( !acodecs )
+ {
+ acodecs = strdup("faac");
+ }
+ if( !mixdowns )
+ {
+ mixdowns = strdup("dpl2");
+ }
+ 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");
+ }
+ job->chapter_markers = 1;
+ }
+
+ if (!strcmp(preset_name, "iPhone & iPod Touch"))
+ {
+ mux = HB_MUX_MP4;
+ vcodec = HB_VCODEC_X264;
+ job->vquality = 0.589999973773956;
+ job->crf = 1;
+ if( !atracks )
+ {
+ atracks = strdup("1");
+ }
+ if( !abitrates )
+ {
+ abitrates = strdup("128");
+ }
+ if( !arates )
+ {
+ arates = strdup("48");
+ }
+ if( !acodecs )
+ {
+ acodecs = strdup("faac");
+ }
+ if( !mixdowns )
+ {
+ mixdowns = strdup("dpl2");
+ }
+ maxWidth = 480;
+ if( !x264opts )
+ {
+ x264opts = strdup("level=30:cabac=0:ref=2:mixed-refs:analyse=all:me=umh:no-fast-pskip=1");
+ }
+ job->chapter_markers = 1;
+ }
+
if (!strcmp(preset_name, "AppleTV"))
{
mux = HB_MUX_MP4;
maxWidth = 960;
if( !x264opts )
{
- x264opts = strdup("level=30:cabac=0:ref=3:mixed-refs=1:bframes=6:weightb=1:direct=auto:no-fast-pskip=1:me=umh:subq=9:analyse=all");
+ x264opts = strdup("level=30:cabac=0:ref=3:mixed-refs=1:bframes=6:weightb=1:direct=auto:no-fast-pskip=1:me=umh:subq=7:analyse=all");
}
pixelratio = 2;
job->chapter_markers = 1;
}
- if (!strcmp(preset_name, "iPod Classic & iPod Nano"))
+ if (!strcmp(preset_name, "QuickTime"))
{
mux = HB_MUX_MP4;
- job->ipod_atom = 1;
vcodec = HB_VCODEC_X264;
- job->vbitrate = 700;
+ job->vbitrate = 1800;
if( !atracks )
{
atracks = strdup("1");
}
if( !arates )
{
- arates = strdup("48");
+ arates = strdup("Auto");
}
if( !acodecs )
{
{
mixdowns = strdup("dpl2");
}
- 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("ref=3:mixed-refs:bframes=3:weightb:direct=auto:me=umh:subme=7:analyse=all:8x8dct:trellis=1:no-fast-pskip=1:psy-rd=1,1");
}
+ pixelratio = 1;
job->chapter_markers = 1;
+ twoPass = 1;
+ turbo_opts_enabled = 1;
}
- if (!strcmp(preset_name, "iPhone & iPod Touch"))
+ if (!strcmp(preset_name, "AppleTV Legacy"))
{
mux = HB_MUX_MP4;
- job->ipod_atom = 1;
+ job->largeFileSize = 1;
vcodec = HB_VCODEC_X264;
- job->vbitrate = 960;
+ job->vbitrate = 2500;
if( !atracks )
{
- atracks = strdup("1");
+ atracks = strdup("1,1");
}
if( !abitrates )
{
- abitrates = strdup("128");
+ abitrates = strdup("160,auto");
}
if( !arates )
{
- arates = strdup("48");
+ arates = strdup("48,Auto");
}
if( !acodecs )
{
- acodecs = strdup("faac");
+ acodecs = strdup("faac,ac3");
}
if( !mixdowns )
{
- mixdowns = strdup("dpl2");
+ mixdowns = strdup("dpl2,auto");
}
- maxWidth = 480;
if( !x264opts )
{
- x264opts = strdup("level=30:cabac=0:ref=1:analyse=all:me=umh:no-fast-pskip=1:trellis=1");
+ x264opts = strdup("bframes=3:ref=1:subme=5:me=umh:no-fast-pskip=1:trellis=1:cabac=0");
}
+ pixelratio = 1;
job->chapter_markers = 1;
}
- if (!strcmp(preset_name, "iPod Legacy"))
+ if (!strcmp(preset_name, "iPhone Legacy"))
{
mux = HB_MUX_MP4;
job->ipod_atom = 1;
vcodec = HB_VCODEC_X264;
- job->vbitrate = 1500;
+ job->vbitrate = 960;
if( !atracks )
{
atracks = strdup("1");
}
if( !abitrates )
{
- abitrates = strdup("160");
+ abitrates = strdup("128");
}
if( !arates )
{
{
mixdowns = strdup("dpl2");
}
- maxWidth = 640;
+ maxWidth = 480;
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");
+ x264opts = strdup("level=30:cabac=0:ref=1:analyse=all:me=umh:no-fast-pskip=1:trellis=1");
}
job->chapter_markers = 1;
}
- if (!strcmp(preset_name, "QuickTime"))
+ if (!strcmp(preset_name, "iPod Legacy"))
{
mux = HB_MUX_MP4;
+ job->ipod_atom = 1;
vcodec = HB_VCODEC_X264;
- job->vbitrate = 1800;
+ job->vbitrate = 1500;
if( !atracks )
{
atracks = strdup("1");
}
if( !arates )
{
- arates = strdup("Auto");
+ arates = strdup("48");
}
if( !acodecs )
{
{
mixdowns = strdup("dpl2");
}
+ maxWidth = 640;
if( !x264opts )
{
- x264opts = strdup("ref=3:mixed-refs:bframes=3:weightb:direct=auto:me=umh:subme=7:analyse=all:8x8dct:trellis=1:no-fast-pskip=1:psy-rd=1,1");
+ x264opts = strdup("level=30:bframes=0:cabac=0:ref=1:vbv-maxrate=1500:vbv-bufsize=2000:analyse=all:me=umh:no-fast-pskip=1");
}
- pixelratio = 1;
job->chapter_markers = 1;
- twoPass = 1;
- turbo_opts_enabled = 1;
}
if (!strcmp(preset_name, "Normal"))
x264opts = strdup("level=40:ref=2:mixed-refs:bframes=3:weightb:subme=9:direct=auto:b-pyramid:me=umh:analyse=all:no-fast-pskip:filter=-2,-1");
}
pixelratio = 1;
- }
+ }
}
if ( chapter_markers )
job->grayscale = grayscale;
if (loosePixelratio)
{
- job->pixel_ratio = 2;
+ job->anamorphic.mode = 2;
if (modulus)
{
- job->modulus = modulus;
+ job->anamorphic.modulus = modulus;
}
if( par_width && par_height )
{
- job->pixel_ratio = 3;
- job->pixel_aspect_width = par_width;
- job->pixel_aspect_height = par_height;
+ job->anamorphic.mode = 3;
+ job->anamorphic.par_width = par_width;
+ job->anamorphic.par_height = par_height;
}
}
else
{
- job->pixel_ratio = pixelratio;
+ job->anamorphic.mode = pixelratio;
}
/* Add selected filters */
job->subtitle_force = subtitle_force;
}
+ if( start_at_preview )
+ {
+ job->start_at_preview = start_at_preview - 1;
+ job->seek_points = preview_count;
+ }
+
+ if( stop_at_pts )
+ {
+ job->pts_to_stop = stop_at_pts;
+ subtitle_scan = 0;
+ }
+
+ if( stop_at_frame )
+ {
+ job->frame_to_stop = stop_at_frame;
+ subtitle_scan = 0;
+ }
+
if( subtitle_scan )
{
char *x264opts_tmp;
" -c, --chapters <string> Select chapters (e.g. \"1-3\" for chapters\n"
" 1 to 3, or \"3\" for chapter 3 only,\n"
" default: all chapters)\n"
+ " --previews <#:B> Select how many preview images are generated (max 30),\n"
+ " 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"
+ " --stop-at <unit:#> Stop encoding at a given frame, duration (in seconds),\n"
+ " or pts (on a 90kHz clock)"
"\n"
"### Destination Options------------------------------------------------------\n\n"
printf("\n + Universal: -e x264 -q 0.589999973773956 -a 1,1 -E faac,ac3 -B 160,auto -R 48,Auto -6 dpl2,auto -f mp4 -X 720 -P -m -x level=30:cabac=0:ref=3:mixed-refs=1:analyse=all:me=umh:no-fast-pskip=1\n");
- printf("\n + AppleTV: -e x264 -q 0.589999973773956 -a 1,1 -E faac,ac3 -B 160,auto -R 48,Auto -6 dpl2,auto -f mp4 -4 -X 960 -P -m -x level=30:cabac=0:ref=3:mixed-refs=1:bframes=6:weightb=1:direct=auto:no-fast-pskip=1:me=umh:subq=9:analyse=all\n");
+ printf("\n + iPod: -e x264 -b 700 -a 1 -E faac -B 160 -R 48 -6 dpl2 -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 & iPhone\n");
+ printf("\n + iPhone & iPod Touch: -e x264 -q 0.589999973773956 -a 1 -E faac -B 128 -R 48 -6 dpl2 -f mp4 -X 480 -m -x level=30:cabac=0:ref=2:mixed-refs:analyse=all:me=umh:no-fast-pskip=1\n");
- printf("\n + iPod Classic & iPod Nano: -e x264 -b 700 -a 1 -E faac -B 160 -R 48 -6 dpl2 -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 + AppleTV: -e x264 -q 0.589999973773956 -a 1,1 -E faac,ac3 -B 160,auto -R 48,Auto -6 dpl2,auto -f mp4 -4 -X 960 -P -m -x level=30:cabac=0:ref=3:mixed-refs=1:bframes=6:weightb=1:direct=auto:no-fast-pskip=1:me=umh:subq=7:analyse=all\n");
- printf("\n + iPhone & iPod Touch: -e x264 -b 960 -a 1 -E faac -B 128 -R 48 -6 dpl2 -f mp4 -I -X 480 -m -x level=30:cabac=0:ref=1:analyse=all:me=umh:no-fast-pskip=1:trellis=1\n");
+ printf("\n + QuickTime: -e x264 -b 1800 -a 1 -E faac -B 160 -R Auto -6 dpl2 -f mp4 -p -m -2 -T -x ref=3:mixed-refs:bframes=3:weightb:direct=auto:me=umh:subme=7:analyse=all:8x8dct:trellis=1:no-fast-pskip=1:psy-rd=1,1\n");
+
+ printf("\n << Legacy\n");
+
+ printf("\n + AppleTV Legacy: -e x264 -b 2500 -a 1,1 -E faac,ac3 -B 160,auto -R 48,Auto -6 dpl2,auto -f mp4 -4 -p -m -x bframes=3:ref=1:subme=5:me=umh:no-fast-pskip=1:trellis=1:cabac=0\n");
+
+ printf("\n + iPhone Legacy: -e x264 -b 960 -a 1 -E faac -B 128 -R 48 -6 dpl2 -f mp4 -I -X 480 -m -x level=30:cabac=0:ref=1:analyse=all:me=umh:no-fast-pskip=1:trellis=1\n");
printf("\n + iPod Legacy: -e x264 -b 1500 -a 1 -E faac -B 160 -R 48 -6 dpl2 -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\n");
printf("\n >>\n");
- printf("\n + QuickTime: -e x264 -b 1800 -a 1 -E faac -B 160 -R Auto -6 dpl2 -f mp4 -p -m -2 -T -x ref=3:mixed-refs:bframes=3:weightb:direct=auto:me=umh:subme=7:analyse=all:8x8dct:trellis=1:no-fast-pskip=1:psy-rd=1,1\n");
-
printf("\n>\n");
printf("\n< Basic\n");
printf("\n + Xbox 360: -e x264 -b 2000 -a 1 -E faac -B 160 -R 48 -6 dpl2 -f mp4 -p -x level=40:ref=2:mixed-refs:bframes=3:weightb:subme=9:direct=auto:b-pyramid:me=umh:analyse=all:no-fast-pskip:filter=-2,-1\n");
printf("\n>\n");
+
}
/****************************************************************************
****************************************************************************/
static int ParseOptions( int argc, char ** argv )
{
+
+ #define PREVIEWS 257
+ #define START_AT_PREVIEW 258
+ #define STOP_AT 259
+
for( ;; )
{
static struct option long_options[] =
{ "aname", required_argument, NULL, 'A' },
{ "color-matrix",required_argument, NULL, 'M' },
+ { "previews", required_argument, NULL, PREVIEWS },
+ { "start-at-preview", required_argument, NULL, START_AT_PREVIEW },
+ { "stop-at", required_argument, NULL, STOP_AT },
{ 0, 0, 0, 0 }
};
break;
case 'i':
input = strdup( optarg );
- #ifdef __APPLE_CC__
- char *devName = bsd_name_for_path( input );
- if( devName == NULL )
- {
- break;
- }
- if( device_is_dvd( devName ) )
+#ifdef __APPLE_CC__
+ char *devName = bsd_name_for_path( input ); // alloc
+ if( devName )
{
- char *newInput = malloc( strlen("/dev/") + strlen( devName ) + 1);
- sprintf( newInput, "/dev/%s", devName );
- free(input);
- input = newInput;
+ if( device_is_dvd( devName ))
+ {
+ free( input );
+ input = malloc( strlen( "/dev/" ) + strlen( devName ) + 1 );
+ sprintf( input, "/dev/%s", devName );
+ }
+ free( devName );
}
- #endif
+#endif
break;
case 'o':
output = strdup( optarg );
anames = strdup( optarg );
}
break;
+ case PREVIEWS:
+ sscanf( optarg, "%i:%i", &preview_count, &store_previews );
+ break;
+ case START_AT_PREVIEW:
+ start_at_preview = atoi( optarg );
+ break;
+ case STOP_AT:
+ stop_at_string = strdup( optarg );
+ stop_at_token = strtok( stop_at_string, ":");
+ if( !strcmp( stop_at_token, "frame" ) )
+ {
+ stop_at_token = strtok( NULL, ":");
+ stop_at_frame = atoi(stop_at_token);
+ }
+ else if( !strcmp( stop_at_token, "pts" ) )
+ {
+ stop_at_token = strtok( NULL, ":");
+ sscanf( stop_at_token, "%"SCNd64, &stop_at_pts );
+ }
+ else if( !strcmp( stop_at_token, "duration" ) )
+ {
+ stop_at_token = strtok( NULL, ":");
+ sscanf( stop_at_token, "%"SCNd64, &stop_at_pts );
+ stop_at_pts *= 90000LL;
+ }
+ break;
case 'M':
if( atoi( optarg ) == 601 )
color_matrix = 1;
return NULL;
}
- // A version 4 GetVolParmsInfoBuffer contains the BSD node name in the
- // vMDeviceID field. It is actually a char * value. This is mentioned in the
- // header CoreServices/CarbonCore/Files.h.
- return volumeParms.vMDeviceID;
+ // A version 4 GetVolParmsInfoBuffer contains the BSD node name in the vMDeviceID field.
+ // It is actually a char * value. This is mentioned in the header CoreServices/CarbonCore/Files.h.
+ if( volumeParms.vMVersion < 4 )
+ {
+ return NULL;
+ }
+
+ // vMDeviceID might be zero as is reported with experimental ZFS (zfs-119) support in Leopard.
+ if( !volumeParms.vMDeviceID )
+ {
+ return NULL;
+ }
+
+ return strdup( volumeParms.vMDeviceID );
}
/****************************************************************************