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 )
/* 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 && !stop_at_pts && !start_at_preview )
+ if( chapter_start && chapter_end && !stop_at_pts && !start_at_preview && !stop_at_frame )
{
job->chapter_start = MAX( job->chapter_start,
chapter_start );
subtitle_scan = 0;
}
+ if( stop_at_frame )
+ {
+ job->frame_to_stop = stop_at_frame;
+ subtitle_scan = 0;
+ }
+
if( subtitle_scan )
{
char *x264opts_tmp;
static void ShowHelp()
{
int i;
+ FILE* const out = stdout;
- fprintf( stderr,
+ fprintf( out,
"Syntax: HandBrakeCLI [options] -i <device> -o <file>\n"
"\n"
"### General Handbrake Options------------------------------------------------\n\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-duration <#> Stop encoding after a given duration in seconds.\n"
- " --stop-at-pts <#> Stop encoding at a given timestamp (90,000Hz clock).\n"
- " (--stop-at-pts and --stop-at-duration are mutually exclusive options)\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"
" -r, --rate Set video framerate (" );
for( i = 0; i < hb_video_rates_count; i++ )
{
- fprintf( stderr, hb_video_rates[i].string );
+ fprintf( out, hb_video_rates[i].string );
if( i != hb_video_rates_count - 1 )
- fprintf( stderr, "/" );
+ fprintf( out, "/" );
}
- fprintf( stderr, ")\n"
+ fprintf( out, ")\n"
" Be aware that not specifying a framerate lets\n"
" HandBrake preserve a source's time stamps,\n"
" potentially creating variable framerate video\n"
" input.\n"
" (\"none\" for no audio, \"1,2,3\" for multiple\n"
" tracks, default: first one)\n"
- " -E, --aencoder <string> Audio encoder(s) (faac/lame/vorbis/ac3) \n"
- " ac3 meaning passthrough\n"
+ " -E, --aencoder <string> Audio encoder(s) (faac/lame/vorbis/ac3/dts) \n"
+ " ac3 and dts meaning passthrough\n"
" Separated by commas for more than one audio track.\n"
" (default: guessed)\n"
" -B, --ab <kb/s> Set audio bitrate(s) (default: 160)\n"
" -R, --arate Set audio samplerate(s) (" );
for( i = 0; i < hb_audio_rates_count; i++ )
{
- fprintf( stderr, hb_audio_rates[i].string );
+ fprintf( out, hb_audio_rates[i].string );
if( i != hb_audio_rates_count - 1 )
- fprintf( stderr, "/" );
+ fprintf( out, "/" );
}
- fprintf( stderr, " kHz)\n"
+ fprintf( out, " kHz)\n"
" Separated by commas for more than one audio track.\n"
" -D, --drc <float> Apply extra dynamic range compression to the audio,\n"
" making soft sounds louder. Range is 1.0 to 4.0\n"
#define PREVIEWS 257
#define START_AT_PREVIEW 258
- #define STOP_AT_PTS 259
- #define STOP_AT_DURATION 260
+ #define STOP_AT 259
for( ;; )
{
{ "color-matrix",required_argument, NULL, 'M' },
{ "previews", required_argument, NULL, PREVIEWS },
{ "start-at-preview", required_argument, NULL, START_AT_PREVIEW },
- { "stop-at-pts", required_argument, NULL, STOP_AT_PTS },
- { "stop-at-duration", required_argument, NULL, STOP_AT_DURATION },
+ { "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 );
case START_AT_PREVIEW:
start_at_preview = atoi( optarg );
break;
- case STOP_AT_PTS:
- sscanf( optarg, "%"SCNd64, &stop_at_pts );
- break;
- case STOP_AT_DURATION:
- sscanf( optarg, "%"SCNd64, &stop_at_pts );
- stop_at_pts *= 90000LL;
+ 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 )
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 );
}
/****************************************************************************