{
hb_log( " + keeping source display aspect ratio");
}
- if( job->anamorphic.modulus != 16 )
- {
- hb_log( " + modulus: %i", job->anamorphic.modulus );
- }
- hb_log( " + storage dimensions: %d * %d -> %d * %d, crop %d/%d/%d/%d",
+ hb_log( " + storage dimensions: %d * %d -> %d * %d, crop %d/%d/%d/%d, mod %i",
title->width, title->height, job->width, job->height,
- job->crop[0], job->crop[1], job->crop[2], job->crop[3] );
+ job->crop[0], job->crop[1], job->crop[2], job->crop[3], job->modulus );
if( job->anamorphic.itu_par )
{
hb_log( " + using ITU pixel aspect ratio values");
hb_title_t * title;
int i, j;
hb_work_object_t * w;
+ hb_work_object_t * sync;
hb_work_object_t * muxer;
hb_interjob_t * interjob;
// So if the encoder is lame we need the output to be stereo (or multichannel
// matrixed into stereo like dpl). If the decoder is not AC3 or DCA the
// encoder has to handle the input format since we can't do a mixdown.
-#define CAN_MIXDOWN(a) ( a->config.in.codec & (HB_ACODEC_AC3|HB_ACODEC_DCA) )
#define STEREO_ONLY(a) ( a->config.out.codec & HB_ACODEC_LAME )
switch (audio->config.in.channel_layout & HB_INPUT_CH_LAYOUT_DISCRETE_NO_LFE_MASK)
case HB_INPUT_CH_LAYOUT_MONO:
if ( STEREO_ONLY( audio ) )
{
- if ( !CAN_MIXDOWN( audio ) )
- {
- // XXX we're hosed - we can't mix up & lame can't handle
- // the input format. The user shouldn't be able to make
- // this choice. It's too late to do anything about it now
- // so complain in the log & let things abort in lame.
- hb_log( "ERROR - can't use lame mp3 audio output with "
- "mono audio stream %x - output will be messed up",
- audio->id );
- }
audio->config.out.mixdown = HB_AMIXDOWN_STEREO;
}
else
// the A52 flags don't allow for a way to distinguish between DPL1 and
// DPL2 on a DVD so we always assume a DPL1 source for A52_DOLBY.
case HB_INPUT_CH_LAYOUT_DOLBY:
- if ( STEREO_ONLY( audio ) || !CAN_MIXDOWN( audio ) ||
+ if ( STEREO_ONLY( audio ) ||
audio->config.out.mixdown > HB_AMIXDOWN_DOLBY )
{
audio->config.out.mixdown = HB_AMIXDOWN_DOLBY;
// 4 channel discrete
case HB_INPUT_CH_LAYOUT_2F2R:
case HB_INPUT_CH_LAYOUT_3F1R:
- if ( CAN_MIXDOWN( audio ) )
- {
- if ( STEREO_ONLY( audio ) ||
- audio->config.out.mixdown > HB_AMIXDOWN_DOLBY )
- {
- audio->config.out.mixdown = HB_AMIXDOWN_DOLBY;
- }
- }
- else
+ if ( STEREO_ONLY( audio ) ||
+ audio->config.out.mixdown > HB_AMIXDOWN_DOLBY )
{
- // XXX we can't mixdown & don't have any way to specify
- // 4 channel discrete output so we're hosed.
- hb_log( "ERROR - can't handle 4 channel discrete audio stream "
- "%x - output will be messed up", audio->id );
+ audio->config.out.mixdown = HB_AMIXDOWN_DOLBY;
}
break;
// 5 or 6 channel discrete
case HB_INPUT_CH_LAYOUT_3F2R:
- if ( CAN_MIXDOWN( audio ) )
+ if ( STEREO_ONLY( audio ) )
{
- if ( STEREO_ONLY( audio ) )
+ if ( audio->config.out.mixdown < HB_AMIXDOWN_STEREO )
{
- if ( audio->config.out.mixdown < HB_AMIXDOWN_STEREO )
- {
- audio->config.out.mixdown = HB_AMIXDOWN_STEREO;
- }
- else if ( audio->config.out.mixdown > HB_AMIXDOWN_DOLBYPLII )
- {
- audio->config.out.mixdown = HB_AMIXDOWN_DOLBYPLII;
- }
+ audio->config.out.mixdown = HB_AMIXDOWN_STEREO;
}
- else if ( ! ( audio->config.in.channel_layout &
- HB_INPUT_CH_LAYOUT_HAS_LFE ) )
+ else if ( audio->config.out.mixdown > HB_AMIXDOWN_DOLBYPLII )
{
- // we don't do 5 channel discrete so mixdown to DPLII
audio->config.out.mixdown = HB_AMIXDOWN_DOLBYPLII;
}
}
else if ( ! ( audio->config.in.channel_layout &
- HB_INPUT_CH_LAYOUT_HAS_LFE ) )
- {
- // XXX we can't mixdown & don't have any way to specify
- // 5 channel discrete output so we're hosed.
- hb_log( "ERROR - can't handle 5 channel discrete audio stream "
- "%x - output will be messed up", audio->id );
- }
- else
+ HB_INPUT_CH_LAYOUT_HAS_LFE ) )
{
- // we can't mixdown so force 6 channel discrete
- audio->config.out.mixdown = HB_AMIXDOWN_6CH;
+ // we don't do 5 channel discrete so mixdown to DPLII
+ audio->config.out.mixdown = HB_AMIXDOWN_DOLBYPLII;
}
break;
}
}
/* Synchronization */
- if( hb_sync_init( job ) )
- {
- hb_error( "Failure to initialise sync" );
- *job->die = 1;
- goto cleanup;
- }
+ sync = hb_sync_init( job );
/* Video decoder */
int vcodec = title->video_codec? title->video_codec : WORK_DECMPEG2;
/* Video renderer */
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 )
+ w->fifo_out = job->fifo_render;
+ else
+ w->fifo_out = NULL;
if( !job->indepth_scan )
{
*subtitle = *(interjob->select_subtitle);
free( interjob->select_subtitle );
interjob->select_subtitle = NULL;
+ break;
}
}
}
}
}
}
+
+ if( job->chapter_markers && job->chapter_start == job->chapter_end )
+ {
+ job->chapter_markers = 0;
+ hb_log("work: only 1 chapter, disabling chapter markers");
+ }
/* Display settings */
hb_display_job_info( job );
job->done = 0;
/* Launch processing threads */
- for( i = 1; i < hb_list_count( job->list_work ); i++ )
+ for( i = 0; i < hb_list_count( job->list_work ); i++ )
{
w = hb_list_item( job->list_work, i );
w->done = &job->done;
HB_LOW_PRIORITY );
}
- // The muxer requires track information that's set up by the encoder
- // init routines so we have to init the muxer last.
- muxer = job->indepth_scan? NULL : hb_muxer_init( job );
+ if ( job->indepth_scan )
+ {
+ muxer = NULL;
+ w = sync;
+ sync->done = &job->done;
+ }
+ else
+ {
+ sync->done = &job->done;
+ sync->thread_sleep_interval = 10;
+ if( sync->init( w, job ) )
+ {
+ hb_error( "Failure to initialise thread '%s'", w->name );
+ *job->die = 1;
+ goto cleanup;
+ }
+ sync->thread = hb_thread_init( sync->name, work_loop, sync,
+ HB_LOW_PRIORITY );
- w = hb_list_item( job->list_work, 0 );
- while( !*job->die && w->status != HB_WORK_DONE )
+ // The muxer requires track information that's set up by the encoder
+ // init routines so we have to init the muxer last.
+ muxer = hb_muxer_init( job );
+ w = muxer;
+ }
+
+ while ( !*job->die && !*w->done && w->status != HB_WORK_DONE )
{
hb_buffer_t * buf_in, * buf_out;
if ( buf_in == NULL )
continue;
if ( *job->die )
+ {
+ if( buf_in )
+ {
+ hb_buffer_close( &buf_in );
+ }
break;
+ }
+ buf_out = NULL;
w->status = w->work( w, &buf_in, &buf_out );
if( buf_in )
{
hb_buffer_close( &buf_in );
}
+ if ( buf_out && w->fifo_out == NULL )
+ {
+ hb_buffer_close( &buf_out );
+ }
if( buf_out )
{
- hb_fifo_push_wait( w->fifo_out, buf_out );
+ while ( !*job->die )
+ {
+ if ( hb_fifo_full_wait( w->fifo_out ) )
+ {
+ hb_fifo_push( w->fifo_out, buf_out );
+ break;
+ }
+ }
}
}
- hb_list_rem( job->list_work, w );
- w->close( w );
- free( w );
+
+ job->done = 1;
+ if( muxer != NULL )
+ {
+ muxer->close( muxer );
+ free( muxer );
+
+ if( sync->thread != NULL )
+ {
+ hb_thread_close( &sync->thread );
+ sync->close( sync );
+ }
+ free( sync );
+ }
hb_handle_t * h = job->h;
hb_state_t state;
cleanup:
/* Stop the write thread (thread_close will block until the muxer finishes) */
- if( muxer != NULL )
- {
- hb_thread_close( &muxer->thread );
- muxer->close( muxer );
- }
-
job->done = 1;
/* Close work objects */
if ( buf_in == NULL )
continue;
if ( *w->done )
+ {
+ if( buf_in )
+ {
+ hb_buffer_close( &buf_in );
+ }
break;
+ }
w->status = w->work( w, &buf_in, &buf_out );
if( buf_in && buf_out && buf_in->new_chap && buf_in->start == buf_out->start)
{
// restore log below to debug chapter mark propagation problems
- //hb_log("work %s: Copying Chapter Break @ %lld", w->name, buf_in->start);
+ //hb_log("work %s: Copying Chapter Break @ %"PRId64, w->name, buf_in->start);
buf_out->new_chap = buf_in->new_chap;
}
{
hb_buffer_close( &buf_in );
}
+ if ( buf_out && w->fifo_out == NULL )
+ {
+ hb_buffer_close( &buf_out );
+ }
if( buf_out )
{
- hb_fifo_push_wait( w->fifo_out, buf_out );
+ while ( !*w->done )
+ {
+ if ( hb_fifo_full_wait( w->fifo_out ) )
+ {
+ hb_fifo_push( w->fifo_out, buf_out );
+ break;
+ }
+ }
}
}
+ // Consume data in incoming fifo till job complete so that
+ // residual data does not stall the pipeline
+ while( !*w->done )
+ {
+ buf_in = hb_fifo_get_wait( w->fifo_in );
+ if ( buf_in != NULL )
+ hb_buffer_close( &buf_in );
+ }
}