summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjbrjake <[email protected]>2009-03-31 17:19:37 +0000
committerjbrjake <[email protected]>2009-03-31 17:19:37 +0000
commita9b9604524e9348f61dc1cd5f299d9b1703e41cc (patch)
treec73b1564ac1659d47cd369572e88cb704c16a6d8
parent276345b4d92a23bd125215f07786fee9449ce3cf (diff)
Adds a job->frame_to_stop variable similar to the existing pts_to_stop parameter, for ending an encode after a certain number of decoded frames.
CLI: Replaces --stop-at-pts and --stop-at-duration with a general --stop-at option. The argument is in the form unit:amount. So --stop-at duration:10 for a 10 second encode, --stop-at pts:300300 to end when that timestamp is reached, or --stop-at frame:1000 to stop after reading 1000 frames. git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@2286 b64f7644-9d1e-0410-96f1-a4d463321fa5
-rw-r--r--libhb/common.h1
-rw-r--r--libhb/sync.c22
-rw-r--r--test/test.c48
3 files changed, 57 insertions, 14 deletions
diff --git a/libhb/common.h b/libhb/common.h
index 1121ae8ec..19b8d2217 100644
--- a/libhb/common.h
+++ b/libhb/common.h
@@ -231,6 +231,7 @@ struct hb_job_s
int subtitle_force;
char * native_language;
+ int frame_to_stop; // declare eof when we hit this frame
int64_t pts_to_stop; // declare eof when we pass this pts in
// the time-linearized input stream
int start_at_preview; // if non-zero, encoding will start
diff --git a/libhb/sync.c b/libhb/sync.c
index c391945b0..920a0e388 100644
--- a/libhb/sync.c
+++ b/libhb/sync.c
@@ -100,6 +100,11 @@ int syncInit( hb_work_object_t * w, hb_job_t * job )
{
duration = job->pts_to_stop + 90000;
}
+ else if( job->frame_to_stop )
+ {
+ /* Set the duration to a rough estimate */
+ duration = ( job->frame_to_stop / ( job->vrate / job->vrate_base ) ) * 90000;
+ }
else
{
duration = 0;
@@ -621,6 +626,17 @@ static void SyncVideo( hb_work_object_t * w )
/* Update UI */
UpdateState( w );
+
+ if( job->frame_to_stop && pv->count_frames > job->frame_to_stop )
+ {
+ // Drop an empty buffer into our output to ensure that things
+ // get flushed all the way out.
+ hb_fifo_push( job->fifo_sync, hb_buffer_init( 0 ) );
+ pv->busy &=~ 1;
+ hb_log( "sync: reached %d frames, exiting early (%i busy)",
+ pv->count_frames, pv->busy );
+ return;
+ }
/* Make sure we won't get more frames then expected */
if( pv->count_frames >= pv->count_frames_max * 2)
@@ -734,6 +750,12 @@ static void SyncAudio( hb_work_object_t * w, int i )
pv->busy &=~ (1 << (i + 1) );
return;
}
+ if( job->frame_to_stop && pv->count_frames >= job->frame_to_stop )
+ {
+ hb_fifo_push( fifo, hb_buffer_init(0) );
+ pv->busy &=~ (1 << (i + 1) );
+ return;
+ }
if ( (int64_t)( buf->start - sync->next_pts ) < 0 )
{
// audio time went backwards.
diff --git a/test/test.c b/test/test.c
index e2ab620b4..7b4c67899 100644
--- a/test/test.c
+++ b/test/test.c
@@ -97,6 +97,9 @@ 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;
@@ -292,6 +295,7 @@ int main( int argc, char ** argv )
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" );
@@ -468,7 +472,7 @@ static int HandleEvents( hb_handle_t * h )
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 );
@@ -1683,6 +1687,12 @@ static int HandleEvents( hb_handle_t * h )
subtitle_scan = 0;
}
+ if( stop_at_frame )
+ {
+ job->frame_to_stop = stop_at_frame;
+ subtitle_scan = 0;
+ }
+
if( subtitle_scan )
{
char *x264opts_tmp;
@@ -1895,9 +1905,8 @@ 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"
- " --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"
@@ -2101,8 +2110,7 @@ static int ParseOptions( int argc, char ** argv )
#define PREVIEWS 257
#define START_AT_PREVIEW 258
- #define STOP_AT_PTS 259
- #define STOP_AT_DURATION 260
+ #define STOP_AT 259
for( ;; )
{
@@ -2165,8 +2173,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 },
- { "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 }
};
@@ -2517,12 +2524,25 @@ static int ParseOptions( int argc, char ** argv )
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 )