static void do_job( hb_job_t *, int cpu_count );
static void work_loop( void * );
-#define FIFO_SIZE 32
+#define FIFO_CPU_MULT 8
/**
* Allocates work object and launches work thread with work_func.
job->height=title->height-job->crop[0]-job->crop[1];
job->width=title->width-job->crop[2]-job->crop[3];
}
+ else if ( job->pixel_ratio == 2 )
+ {
+
+ /* While keeping the DVD storage aspect, resize the job width and height
+ so they fit into the user's specified dimensions. */
+ hb_set_anamorphic_size(job, &job->width, &job->height, &job->pixel_aspect_width, &job->pixel_aspect_height);
+ }
- /* Keep width and height within these boundaries */
- if (job->maxHeight && (job->height > job->maxHeight) )
+ /* Keep width and height within these boundaries,
+ but ignore for "loose" anamorphic encodes, for
+ which this stuff is covered in the pixel_ratio
+ section right above.*/
+ if (job->maxHeight && (job->height > job->maxHeight) && (job->pixel_ratio != 2))
{
job->height = job->maxHeight;
hb_fix_aspect( job, HB_KEEP_HEIGHT );
hb_log("Height out of bounds, scaling down to %i", job->maxHeight);
hb_log("New dimensions %i * %i", job->width, job->height);
}
- if (job->maxWidth && (job->width > job->maxWidth) )
+ if (job->maxWidth && (job->width > job->maxWidth) && (job->pixel_ratio != 2))
{
job->width = job->maxWidth;
hb_fix_aspect( job, HB_KEEP_WIDTH );
hb_log( " + %dx%d -> %dx%d, crop %d/%d/%d/%d",
title->width, title->height, job->width, job->height,
job->crop[0], job->crop[1], job->crop[2], job->crop[3] );
- hb_log( " + grayscale %s", job->grayscale ? "on" : "off" );
+
+ if ( job->grayscale )
+ hb_log( " + grayscale mode" );
+
+ if ( job->vfr )
+ {
+ int detelecine_present = 0;
+ if ( job->filters )
+ {
+ for( i = 0; i < hb_list_count( job->filters ); i++ )
+ {
+ hb_filter_object_t * filter = hb_list_item( job->filters, i );
+ if (filter->id == FILTER_DETELECINE)
+ detelecine_present = 1;
+ }
+ }
+
+ if (!detelecine_present)
+ {
+ /* Allocate the filter. */
+ hb_filter_object_t * filter = malloc( sizeof( hb_filter_object_t ) );
+
+ /* Copy in the contents of the detelecine struct. */
+ memcpy( filter, &hb_filter_detelecine, sizeof( hb_filter_object_t ) );
+
+ /* Set the name to a copy of the template name so render.c has something to free. */
+ filter->name = strdup(hb_filter_detelecine.name);
+
+ /* Add it to the list. */
+ hb_list_add( job->filters, filter );
+
+ hb_log("work: VFR mode -- adding detelecine filter");
+ }
+ }
if( job->filters )
{
}
}
+ if( job->vfr)
+ {
+ hb_log( " + video frame rate: variable (detected %.3f fps)", (float) job->vrate /
+ (float) job->vrate_base );
+ }
+ else
+ {
+ hb_log( " + video frame rate: %.3f fps", (float) job->vrate / (float) job->vrate_base);
+ }
+
if( job->vquality >= 0.0 && job->vquality <= 1.0 )
{
- hb_log( " + %.3f fps, video quality %.2f", (float) job->vrate /
- (float) job->vrate_base, job->vquality );
+ hb_log( " + video quality %.2f", job->vquality );
}
else
{
- hb_log( " + %.3f fps, video bitrate %d kbps, pass %d",
- (float) job->vrate / (float) job->vrate_base,
- job->vbitrate, job->pass );
+ hb_log( " + video bitrate %d kbps, pass %d", job->vbitrate, job->pass );
}
+
hb_log (" + PixelRatio: %d, width:%d, height: %d",job->pixel_ratio,job->width, job->height);
job->fifo_mpeg2 = hb_fifo_init( 2048 );
- job->fifo_raw = hb_fifo_init( FIFO_SIZE );
- job->fifo_sync = hb_fifo_init( FIFO_SIZE );
- job->fifo_render = hb_fifo_init( FIFO_SIZE );
- job->fifo_mpeg4 = hb_fifo_init( FIFO_SIZE );
+ 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 );
+ job->fifo_mpeg4 = hb_fifo_init( FIFO_CPU_MULT * cpu_count );
/* Synchronization */
hb_list_add( job->list_work, ( w = getWork( WORK_SYNC ) ) );
break;
case HB_VCODEC_X264:
hb_log( " + encoder x264" );
+ if( job->x264opts != NULL && *job->x264opts != '\0' )
+ hb_log( " + x264 options: %s", job->x264opts);
w = getWork( WORK_ENCX264 );
break;
}
{
hb_log( " + subtitle %x, %s", subtitle->id, subtitle->lang );
- subtitle->fifo_in = hb_fifo_init( FIFO_SIZE );
- subtitle->fifo_raw = hb_fifo_init( FIFO_SIZE );
+ subtitle->fifo_in = hb_fifo_init( FIFO_CPU_MULT * cpu_count );
+ subtitle->fifo_raw = hb_fifo_init( FIFO_CPU_MULT * cpu_count );
/*
* Disable forced subtitles if we didn't find any in the scan
if( job->acodec & HB_ACODEC_AC3 )
{
hb_log( " + audio AC3 passthrough" );
+
+ /* Hard set correct sample rate for AC3 */
+ job->arate = 48000;
}
else
{
"faac" : ( ( job->acodec & HB_ACODEC_LAME ) ? "lame" :
"vorbis" ) );
}
+
+ if ( job->dynamic_range_compression )
+ hb_log(" + dynamic range compression: %f", job->dynamic_range_compression);
- /* if we are doing AC3 passthru, then remove any non-AC3 audios from the job */
+ /* if we are doing AC3 passthru (at the codec level, not pass-through),
+ * then remove any non-AC3 audios from the job */
/* otherwise, Bad Things will happen */
for( i = 0; i < hb_list_count( title->list_audio ); )
{
int audioCodecsSupport6Ch = ((audio->codec == HB_ACODEC_AC3 ||
audio->codec == HB_ACODEC_DCA) && (job->acodec == HB_ACODEC_FAAC || job->acodec == HB_ACODEC_VORBIS));
+ if( job->audio_mixdowns[i] != HB_AMIXDOWN_AC3 )
+ {
/* find out what the format of our source audio is */
switch (audio->input_channel_layout & HB_INPUT_CH_LAYOUT_DISCRETE_NO_LFE_MASK) {
}
}
+ }
/* log the output mixdown */
for (j = 0; j < hb_audio_mixdowns_count; j++) {
audio->config.vorbis.language = audio->lang_simple;
- /* set up the audio work structures */
+ /* set up the audio work structures */
audio->fifo_in = hb_fifo_init( 2048 );
- audio->fifo_raw = hb_fifo_init( FIFO_SIZE );
- audio->fifo_sync = hb_fifo_init( FIFO_SIZE );
- audio->fifo_out = hb_fifo_init( FIFO_SIZE );
+ audio->fifo_raw = hb_fifo_init( FIFO_CPU_MULT * cpu_count );
+ audio->fifo_sync = hb_fifo_init( FIFO_CPU_MULT * cpu_count );
+ audio->fifo_out = hb_fifo_init( FIFO_CPU_MULT * cpu_count );
+
+ /*
+ * Audio Decoder Thread
+ */
switch( audio->codec )
{
case HB_ACODEC_AC3:
hb_list_add( job->list_work, audio_w );
- switch( job->acodec )
+ /*
+ * Audio Encoder Thread
+ */
+ if( job->audio_mixdowns[i] != HB_AMIXDOWN_AC3 )
{
+ switch( job->acodec )
+ {
case HB_ACODEC_FAAC:
w = getWork( WORK_ENCFAAC );
break;
case HB_ACODEC_VORBIS:
w = getWork( WORK_ENCVORBIS );
break;
+ }
}
- if( job->acodec != HB_ACODEC_AC3 )
+ if( job->acodec != HB_ACODEC_AC3 &&
+ job->audio_mixdowns[i] != HB_AMIXDOWN_AC3)
{
+ /*
+ * Add the encoder thread if not doing AC-3 pass through
+ */
w->fifo_in = audio->fifo_sync;
w->fifo_out = audio->fifo_out;
w->config = &audio->config;
hb_fifo_close( &job->fifo_render );
hb_fifo_close( &job->fifo_mpeg4 );
- hb_buffer_pool_free();
-
for (i=0; i < hb_list_count(title->list_subtitle); i++) {
subtitle = hb_list_item( title->list_subtitle, i);
if( subtitle )
subtitle_lowest_id = subtitle->id;
}
- if ( subtitle->forced_hits > 0 )
+ if( subtitle->forced_hits > 0 )
{
- subtitle_forced_id = subtitle->id;
+ if( subtitle_forced_id == 0 )
+ {
+ subtitle_forced_id = subtitle->id;
+ }
}
}
}
}
+ if( job->filters )
+ {
+ for( i = 0; i < hb_list_count( job->filters ); i++ )
+ {
+ hb_filter_object_t * filter = hb_list_item( job->filters, i );
+ hb_filter_close( &filter );
+ }
+ hb_list_close( &job->filters );
+ }
+
+ hb_buffer_pool_free();
+
hb_title_close( &job->title );
free( job );
}
w->work( w, &buf_in, &buf_out );
- // Propogate any chapter breaks for the worker
- if( buf_in && buf_out && buf_in->new_chap )
+ // Propagate any chapter breaks for the worker if and only if the
+ // output frame has the same time stamp as the input frame (any
+ // worker that delays frames has to propagate the chapter marks itself
+ // and workers that move chapter marks to a different time should set
+ // 'buf_in' to NULL so that this code won't generate spurious duplicates.)
+ if( buf_in && buf_out && buf_in->new_chap && buf_in->start == buf_out->start)
{
- hb_log("WORK: Copying Chapter Break");
+ hb_log("work %s: Copying Chapter Break @ %lld", w->name, buf_in->start);
buf_out->new_chap = 1;
}