summaryrefslogtreecommitdiffstats
path: root/libhb
diff options
context:
space:
mode:
Diffstat (limited to 'libhb')
-rw-r--r--libhb/encfaac.c5
-rw-r--r--libhb/sync.c46
-rw-r--r--libhb/work.c40
3 files changed, 37 insertions, 54 deletions
diff --git a/libhb/encfaac.c b/libhb/encfaac.c
index 645628a8e..ae2e54b36 100644
--- a/libhb/encfaac.c
+++ b/libhb/encfaac.c
@@ -206,7 +206,10 @@ static hb_buffer_t *Flush( hb_work_object_t *w, hb_buffer_t *bufin )
}
}
// add the eof marker to the end of our buf chain
- buf->next = bufin;
+ if ( buf )
+ buf->next = bufin;
+ else
+ bufout = bufin;
return bufout;
}
diff --git a/libhb/sync.c b/libhb/sync.c
index 7f0ac86c4..09ef0d9a2 100644
--- a/libhb/sync.c
+++ b/libhb/sync.c
@@ -39,8 +39,11 @@ typedef struct
struct hb_work_private_s
{
hb_job_t * job;
- int done;
-
+ int busy; // bitmask with one bit for each active input
+ // (bit 0 = video; 1 = audio 0, 2 = audio 1, ...
+ // appropriate bit is cleared when input gets
+ // an eof buf. syncWork returns done when all
+ // bits are clear.
/* Video */
hb_subtitle_t * subtitle;
int64_t pts_offset;
@@ -69,7 +72,7 @@ struct hb_work_private_s
* Local prototypes
**********************************************************************/
static void InitAudio( hb_work_object_t * w, int i );
-static int SyncVideo( hb_work_object_t * w );
+static void SyncVideo( hb_work_object_t * w );
static void SyncAudio( hb_work_object_t * w, int i );
static void InsertSilence( hb_work_object_t * w, int i, int64_t d );
static void UpdateState( hb_work_object_t * w );
@@ -92,7 +95,6 @@ int syncInit( hb_work_object_t * w, hb_job_t * job )
pv->job = job;
pv->pts_offset = INT64_MIN;
- pv->count_frames = 0;
/* Calculate how many video frames we are expecting */
duration = 0;
@@ -106,18 +108,18 @@ int syncInit( hb_work_object_t * w, hb_job_t * job )
pv->count_frames_max = duration * job->vrate / job->vrate_base / 90000;
hb_log( "sync: expecting %d video frames", pv->count_frames_max );
+ pv->busy |= 1;
/* Initialize libsamplerate for every audio track we have */
for( i = 0; i < hb_list_count( title->list_audio ); i++ )
{
+ pv->busy |= ( 1 << (i + 1) );
InitAudio( w, i );
}
/* Get subtitle info, if any */
pv->subtitle = hb_list_item( title->list_subtitle, 0 );
- pv->video_sequence = 0;
-
return 0;
}
@@ -180,17 +182,20 @@ int syncWork( hb_work_object_t * w, hb_buffer_t ** unused1,
hb_work_private_t * pv = w->private_data;
int i;
+ if ( pv->busy & 1 )
+ SyncVideo( w );
+
/* If we ever got a video frame, handle audio now */
if( pv->pts_offset != INT64_MIN )
{
for( i = 0; i < hb_list_count( pv->job->title->list_audio ); i++ )
{
- SyncAudio( w, i );
+ if ( pv->busy & ( 1 << (i + 1) ) )
+ SyncAudio( w, i );
}
}
- /* Handle video */
- return SyncVideo( w );
+ return ( pv->busy? HB_WORK_OK : HB_WORK_DONE );
}
hb_work_object_t hb_sync =
@@ -263,29 +268,24 @@ static void InitAudio( hb_work_object_t * w, int i )
***********************************************************************
*
**********************************************************************/
-static int SyncVideo( hb_work_object_t * w )
+static void SyncVideo( hb_work_object_t * w )
{
hb_work_private_t * pv = w->private_data;
hb_buffer_t * cur, * next, * sub = NULL;
hb_job_t * job = pv->job;
- if( pv->done )
- {
- return HB_WORK_DONE;
- }
-
if( !pv->cur && !( pv->cur = hb_fifo_get( job->fifo_raw ) ) )
{
/* We haven't even got a frame yet */
- return HB_WORK_OK;
+ return;
}
cur = pv->cur;
if( cur->size == 0 )
{
/* we got an end-of-stream. Feed it downstream & signal that we're done. */
hb_fifo_push( job->fifo_sync, hb_buffer_init( 0 ) );
- pv->done = 1;
- return HB_WORK_DONE;
+ pv->busy &=~ 1;
+ return;
}
/* At this point we have a frame to process. Let's check
@@ -304,8 +304,8 @@ static int SyncVideo( hb_work_object_t * w )
* video (we don't know its duration). On DVDs the final frame
* is often strange and dropping it seems to be a good idea. */
hb_fifo_push( job->fifo_sync, hb_buffer_init( 0 ) );
- pv->done = 1;
- return HB_WORK_DONE;
+ pv->busy &=~ 1;
+ return;
}
if( pv->pts_offset == INT64_MIN )
{
@@ -618,15 +618,14 @@ static int SyncVideo( hb_work_object_t * w )
{
hb_log( "sync: got too many frames (%d), exiting early",
pv->count_frames );
- pv->done = 1;
// 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 ) );
- return HB_WORK_DONE;
+ pv->busy &=~ 1;
+ return;
}
}
- return HB_WORK_OK;
}
static void OutputAudioFrame( hb_job_t *job, hb_audio_t *audio, hb_buffer_t *buf,
@@ -723,6 +722,7 @@ static void SyncAudio( hb_work_object_t * w, int i )
{
buf = hb_fifo_get( audio->priv.fifo_raw );
hb_fifo_push( fifo, buf );
+ pv->busy &=~ (1 << (i + 1) );
return;
}
if ( (int64_t)( buf->start - sync->next_pts ) < 0 )
diff --git a/libhb/work.c b/libhb/work.c
index f7d050b6a..5dddf26cb 100644
--- a/libhb/work.c
+++ b/libhb/work.c
@@ -125,11 +125,9 @@ static void do_job( hb_job_t * job, int cpu_count )
hb_title_t * title;
int i, j;
hb_work_object_t * w;
- hb_work_object_t * final_w = NULL;
hb_audio_t * audio;
hb_subtitle_t * subtitle;
- int done;
unsigned int subtitle_highest = 0;
unsigned int subtitle_highest_id = 0;
unsigned int subtitle_lowest = -1;
@@ -265,7 +263,7 @@ static void do_job( hb_job_t * job, int cpu_count )
}
hb_log (" + PixelRatio: %d, width:%d, height: %d",job->pixel_ratio,job->width, job->height);
- job->fifo_mpeg2 = hb_fifo_init( 128 );
+ job->fifo_mpeg2 = hb_fifo_init( 256 );
job->fifo_raw = hb_fifo_init( FIFO_CPU_MULT * cpu_count );
job->fifo_sync = hb_fifo_init( FIFO_CPU_MULT * cpu_count );
job->fifo_render = hb_fifo_init( FIFO_CPU_MULT * cpu_count );
@@ -287,15 +285,6 @@ static void do_job( hb_job_t * job, int cpu_count )
hb_list_add( job->list_work, ( w = hb_get_work( WORK_RENDER ) ) );
w->fifo_in = job->fifo_sync;
w->fifo_out = job->fifo_render;
- if ( job->indepth_scan )
- {
- /*
- * if we're doing a subtitle scan the last thread in the
- * processing pipeline is render - remember it so we can
- * wait for its completion below.
- */
- final_w = w;
- }
if( !job->indepth_scan )
{
@@ -327,13 +316,6 @@ static void do_job( hb_job_t * job, int cpu_count )
w->config = &job->config;
hb_list_add( job->list_work, w );
-
- /*
- * if we're not doing a subtitle scan the last thread in the
- * processing pipeline is the encoder - remember it so we can
- * wait for its completion below.
- */
- final_w = w;
}
if( job->select_subtitle && !job->indepth_scan )
@@ -661,17 +643,12 @@ static void do_job( hb_job_t * job, int cpu_count )
// init routines so we have to init the muxer last.
job->muxer = job->indepth_scan? NULL : hb_muxer_init( job );
- done = 0;
w = hb_list_item( job->list_work, 0 );
- w->thread_sleep_interval = 50;
+ w->thread_sleep_interval = 10;
w->init( w, job );
while( !*job->die )
{
- if ( !done && ( w->status = w->work( w, NULL, NULL ) ) == HB_WORK_DONE )
- {
- done = 1;
- }
- if( done && final_w->status == HB_WORK_DONE )
+ if ( ( w->status = w->work( w, NULL, NULL ) ) == HB_WORK_DONE )
{
break;
}
@@ -680,9 +657,14 @@ static void do_job( hb_job_t * job, int cpu_count )
hb_list_rem( job->list_work, w );
w->close( w );
free( w );
- job->done = 1;
cleanup:
+ /* Stop the write thread (thread_close will block until the muxer finishes) */
+ if( job->muxer != NULL )
+ hb_thread_close( &job->muxer );
+
+ job->done = 1;
+
/* Close work objects */
while( ( w = hb_list_item( job->list_work, 0 ) ) )
{
@@ -697,11 +679,9 @@ cleanup:
hb_list_close( &job->list_work );
- /* Stop read & write threads */
+ /* Stop the read thread */
if( job->reader != NULL )
hb_thread_close( &job->reader );
- if( job->muxer != NULL )
- hb_thread_close( &job->muxer );
/* Close fifos */
hb_fifo_close( &job->fifo_mpeg2 );