summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjstebbins <[email protected]>2011-03-08 16:12:57 +0000
committerjstebbins <[email protected]>2011-03-08 16:12:57 +0000
commit673a841b1ef2dcd31647fce00829dc4a3f2b0715 (patch)
treeb11d12d19c798463a8756d8f5f989e6d2865765b
parent6444014c71cd881ad4874e96a6138ea268be8b4d (diff)
make keyint match between 1st and 2nd passes of vfr and pfr encodes.
make keyint and fps settings consistent across video encoders. make interjob->vrate changes for pfr mode like we do for vfr since pfr is the same as vfr except when it hits it's peak. in mkv, set track default duration to actual measured vrate on 2 pass encodes. thanks to Rodeo for the corrections in encx264 git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@3831 b64f7644-9d1e-0410-96f1-a4d463321fa5
-rw-r--r--libhb/common.c3
-rw-r--r--libhb/common.h2
-rw-r--r--libhb/encavcodec.c16
-rw-r--r--libhb/enctheora.c34
-rw-r--r--libhb/encx264.c42
-rw-r--r--libhb/hb.h4
-rw-r--r--libhb/muxmkv.c15
-rw-r--r--libhb/render.c9
-rw-r--r--libhb/work.c45
9 files changed, 102 insertions, 68 deletions
diff --git a/libhb/common.c b/libhb/common.c
index 06fb00645..2387aa4ef 100644
--- a/libhb/common.c
+++ b/libhb/common.c
@@ -520,9 +520,8 @@ int hb_calc_bitrate( hb_job_t * job, int size )
if( size == -1 )
{
- hb_interjob_t * interjob = hb_interjob_get( job->h );
avail = job->vbitrate * 125 * length;
- avail += length * interjob->vrate * overhead / interjob->vrate_base;
+ avail += length * job->vrate * overhead / job->vrate_base;
}
/* Video overhead */
diff --git a/libhb/common.h b/libhb/common.h
index bd1eaddc8..031b8b642 100644
--- a/libhb/common.h
+++ b/libhb/common.h
@@ -230,6 +230,8 @@ struct hb_job_s
int vcodec;
float vquality;
int vbitrate;
+ int pfr_vrate;
+ int pfr_vrate_base;
int vrate;
int vrate_base;
int vfr;
diff --git a/libhb/encavcodec.c b/libhb/encavcodec.c
index eaf7b7020..07fc748a8 100644
--- a/libhb/encavcodec.c
+++ b/libhb/encavcodec.c
@@ -77,8 +77,18 @@ int encavcodecInit( hb_work_object_t * w, hb_job_t * job )
}
context->width = job->width;
context->height = job->height;
- rate_num = job->vrate_base;
- rate_den = job->vrate;
+
+ if( job->pass == 2 )
+ {
+ hb_interjob_t * interjob = hb_interjob_get( job->h );
+ rate_num = interjob->vrate_base;
+ rate_den = interjob->vrate;
+ }
+ else
+ {
+ rate_num = job->vrate_base;
+ rate_den = job->vrate;
+ }
if (rate_den == 27000000)
{
int ii;
@@ -103,7 +113,7 @@ int encavcodecInit( hb_work_object_t * w, hb_job_t * job )
rate_den >>= 1;
}
context->time_base = (AVRational) { rate_num, rate_den };
- context->gop_size = 10 * job->vrate / job->vrate_base;
+ context->gop_size = 10 * (int)( (double)job->vrate / (double)job->vrate_base + 0.5 );
context->pix_fmt = PIX_FMT_YUV420P;
if( job->anamorphic.mode )
diff --git a/libhb/enctheora.c b/libhb/enctheora.c
index 042262c76..2ced60693 100644
--- a/libhb/enctheora.c
+++ b/libhb/enctheora.c
@@ -66,8 +66,17 @@ int enctheoraInit( hb_work_object_t * w, hb_job_t * job )
ti.frame_height = (job->height + 0xf) & ~0xf;
ti.pic_x = ti.pic_y = 0;
- ti.fps_numerator = job->vrate;
- ti.fps_denominator = job->vrate_base;
+ if( job->pass == 2 )
+ {
+ hb_interjob_t * interjob = hb_interjob_get( job->h );
+ ti.fps_numerator = interjob->vrate;
+ ti.fps_denominator = interjob->vrate_base;
+ }
+ else
+ {
+ ti.fps_numerator = job->vrate;
+ ti.fps_denominator = job->vrate_base;
+ }
if( job->anamorphic.mode )
{
ti.aspect_numerator = job->anamorphic.par_width;
@@ -98,30 +107,13 @@ int enctheoraInit( hb_work_object_t * w, hb_job_t * job )
}
}
- if ( job->pass == 2 && !job->cfr )
- {
- /* Even though the framerate might be different due to VFR,
- we still want the same keyframe intervals as the 1st pass,
- so the 1st pass stats won't conflict on frame decisions. */
- hb_interjob_t * interjob = hb_interjob_get( job->h );
- keyframe_frequency = ( 10 * interjob->vrate / interjob->vrate_base ) + 1;
- }
- else
- {
- int fps = job->vrate / job->vrate_base;
+ keyframe_frequency = 10 * (int)( (double)job->vrate / (double)job->vrate_base + 0.5 );
- /* adjust +1 when fps has remainder to bump
- { 23.976, 29.976, 59.94 } to { 24, 30, 60 } */
- if (job->vrate % job->vrate_base)
- fps += 1;
+ hb_log("theora: keyint: %i", keyframe_frequency);
- keyframe_frequency = fps * 10;
- }
int tmp = keyframe_frequency - 1;
for (log_keyframe = 0; tmp; log_keyframe++)
tmp >>= 1;
-
- hb_log("theora: keyint: %i", keyframe_frequency);
ti.keyframe_granule_shift = log_keyframe;
diff --git a/libhb/encx264.c b/libhb/encx264.c
index 270692c8a..2c64321ba 100644
--- a/libhb/encx264.c
+++ b/libhb/encx264.c
@@ -98,8 +98,17 @@ int encx264Init( hb_work_object_t * w, hb_job_t * job )
param.i_threads = ( hb_get_cpu_count() * 3 / 2 );
param.i_width = job->width;
param.i_height = job->height;
- param.i_fps_num = job->vrate;
- param.i_fps_den = job->vrate_base;
+ if( job->pass == 2 )
+ {
+ hb_interjob_t * interjob = hb_interjob_get( job->h );
+ param.i_fps_num = interjob->vrate;
+ param.i_fps_den = interjob->vrate_base;
+ }
+ else
+ {
+ param.i_fps_num = job->vrate;
+ param.i_fps_den = job->vrate_base;
+ }
if ( job->cfr == 1 )
{
param.i_timebase_num = 0;
@@ -115,26 +124,11 @@ int encx264Init( hb_work_object_t * w, hb_job_t * job )
/* Disable annexb. Inserts size into nal header instead of start code */
param.b_annexb = 0;
- /* Set min:max key intervals ratio to 1:10 of fps.
- * This section is skipped if fps=25 (default).
- */
- if (job->vrate_base != 1080000)
- {
- if (job->pass == 2 && !job->cfr )
- {
- /* Even though the framerate might be different due to VFR,
- we still want the same keyframe intervals as the 1st pass,
- so the 1st pass stats won't conflict on frame decisions. */
- hb_interjob_t * interjob = hb_interjob_get( job->h );
- param.i_keyint_max = 10 * (int)( (double)interjob->vrate / (double)interjob->vrate_base + 0.5 );
- }
- else
- {
- /* adjust +0.5 for when fps has remainder to bump
- { 23.976, 29.976, 59.94 } to { 24, 30, 60 } */
- param.i_keyint_max = 10 * (int)( (double)job->vrate / (double)job->vrate_base + 0.5 );
- }
- }
+ /* Set min:max keyframe intervals to 1:10 of fps.
+ adjust +0.5 for when fps has remainder to bump
+ { 23.976, 29.976, 59.94 } to { 24, 30, 60 } */
+ param.i_keyint_min = (int)( (double)job->vrate / (double)job->vrate_base + 0.5 );
+ param.i_keyint_max = 10 * param.i_keyint_min;
param.i_log_level = X264_LOG_INFO;
@@ -211,7 +205,9 @@ int encx264Init( hb_work_object_t * w, hb_job_t * job )
job->areBframes = 0;
}
- if( param.i_keyint_min != X264_KEYINT_MIN_AUTO || param.i_keyint_max != 250 )
+ /* For 25 fps sources, HandBrake's explicit keyints will match the x264 defaults:
+ min-keyint 25 (same as auto), keyint 250 */
+ if( param.i_keyint_min != 25 || param.i_keyint_max != 250 )
{
int min_auto;
diff --git a/libhb/hb.h b/libhb/hb.h
index 38634b2a5..56566f330 100644
--- a/libhb/hb.h
+++ b/libhb/hb.h
@@ -82,8 +82,8 @@ typedef struct hb_interjob_s
int frame_count; /* number of frames counted by sync */
uint64_t total_time; /* real length in 90khz (i.e. / 90000 */
int render_dropped; /* frames droped by telecine */
- int vrate; /* initial assigned vrate */
- int vrate_base; /* initial assigned vrate_base */
+ int vrate; /* actual measured output vrate from 1st pass */
+ int vrate_base; /* actual measured output vrate_base from 1st pass */
hb_subtitle_t *select_subtitle; /* foreign language scan subtitle */
} hb_interjob_t;
diff --git a/libhb/muxmkv.c b/libhb/muxmkv.c
index 073b39f45..f169e3de1 100644
--- a/libhb/muxmkv.c
+++ b/libhb/muxmkv.c
@@ -148,8 +148,19 @@ static int MKVInit( hb_mux_object_t * m )
track->extra.video.displayWidth = job->width;
}
-
- track->defaultDuration = (int64_t)(((float)job->vrate_base / (float)job->vrate) * 1000000000);
+ int vrate_base, vrate;
+ if( job->pass == 2 )
+ {
+ hb_interjob_t * interjob = hb_interjob_get( job->h );
+ vrate_base = interjob->vrate_base;
+ vrate = interjob->vrate;
+ }
+ else
+ {
+ vrate_base = job->vrate_base;
+ vrate = job->vrate;
+ }
+ track->defaultDuration = (int64_t)(((float)vrate_base / (float)vrate) * 1000000000);
mux_data->track = mk_createTrack(m->file, track);
diff --git a/libhb/render.c b/libhb/render.c
index c16b9403d..0af7148c1 100644
--- a/libhb/render.c
+++ b/libhb/render.c
@@ -779,7 +779,14 @@ int renderInit( hb_work_object_t * w, hb_job_t * job )
pv->chapter_time = 0;
pv->chapter_val = 0;
- pv->frame_rate = (double)job->vrate_base * (1./300.);
+ if ( job->cfr == 2 )
+ {
+ pv->frame_rate = (double)job->pfr_vrate_base * (1./300.);
+ }
+ else
+ {
+ pv->frame_rate = (double)job->vrate_base * (1./300.);
+ }
/* Setup filters */
/* TODO: Move to work.c? */
diff --git a/libhb/work.c b/libhb/work.c
index d05a22aa7..a5f0e7418 100644
--- a/libhb/work.c
+++ b/libhb/work.c
@@ -200,20 +200,23 @@ void hb_display_job_info( hb_job_t * job )
hb_log( " + bitrate %d kbps", title->video_bitrate / 1000 );
}
- if( !job->cfr )
+ if( job->cfr == 0 )
{
hb_log( " + frame rate: same as source (around %.3f fps)",
(float) title->rate / (float) title->rate_base );
}
- else
+ else if( job->cfr == 1 )
{
- static const char *frtypes[] = {
- "", "constant", "peak rate limited to"
- };
- hb_log( " + frame rate: %.3f fps -> %s %.3f fps",
- (float) title->rate / (float) title->rate_base, frtypes[job->cfr],
+ hb_log( " + frame rate: %.3f fps -> constant %.3f fps",
+ (float) title->rate / (float) title->rate_base,
(float) job->vrate / (float) job->vrate_base );
}
+ else if( job->cfr == 2 )
+ {
+ hb_log( " + frame rate: %.3f fps -> peak rate limited to %.3f fps",
+ (float) title->rate / (float) title->rate_base,
+ (float) job->pfr_vrate / (float) job->pfr_vrate_base );
+ }
if( job->anamorphic.mode )
{
@@ -380,13 +383,11 @@ void correct_framerate( hb_job_t * job )
if( ( job->sequence_id & 0xFFFFFF ) != ( interjob->last_job & 0xFFFFFF) )
return; // Interjob information is for a different encode.
- /* Cache the original framerate before altering it. */
- interjob->vrate = job->vrate;
- interjob->vrate_base = job->vrate_base;
-
+ // compute actual output vrate from first pass
real_frames = interjob->frame_count - interjob->render_dropped;
- job->vrate = job->vrate_base * ( (double)real_frames * 90000 / interjob->total_time );
+ interjob->vrate = job->vrate_base * ( (double)real_frames * 90000 / interjob->total_time );
+ interjob->vrate_base = job->vrate_base;
}
static int check_ff_audio( hb_list_t *list_audio, hb_audio_t *ff_audio )
@@ -442,7 +443,7 @@ static void do_job( hb_job_t * job )
title = job->title;
interjob = hb_interjob_get( job->h );
- if( job->pass == 2 && !job->cfr )
+ if( job->pass == 2 )
{
correct_framerate( job );
}
@@ -492,8 +493,25 @@ static void do_job( hb_job_t * job )
if ( job->cfr == 0 )
{
/* Ensure we're using "Same as source" FPS */
+ job->vrate = title->rate;
job->vrate_base = title->rate_base;
}
+ else if ( job->cfr == 2 )
+ {
+ job->pfr_vrate = job->vrate;
+ job->pfr_vrate_base = job->vrate_base;
+
+ // Ensure we're using "Same as source" FPS, with peak set by pfr_vrate_*
+ // For PFR, we want the framerate based on the source's actual
+ // framerate, unless it's higher than the specified peak framerate.
+ double source_fps = (double)job->title->rate / job->title->rate_base;
+ double peak_l_fps = (double)job->vrate / job->vrate_base;
+ if ( source_fps < peak_l_fps )
+ {
+ job->vrate_base = title->rate_base;
+ job->vrate = title->rate;
+ }
+ }
job->fifo_mpeg2 = hb_fifo_init( FIFO_LARGE, FIFO_LARGE_WAKE );
job->fifo_raw = hb_fifo_init( FIFO_SMALL, FIFO_SMALL_WAKE );
@@ -1221,7 +1239,6 @@ static void work_loop( void * _w )
}
break;
}
-
// Invalidate buf_out so that if there is no output
// we don't try to pass along junk.
buf_out = NULL;