summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjstebbins <[email protected]>2013-05-28 18:20:43 +0000
committerjstebbins <[email protected]>2013-05-28 18:20:43 +0000
commitbbcd6ff1ec36b81935c1a059a19580a1c1bee98d (patch)
treef3f7ecb27159f5fb39a15895037d673fc33df01f
parent63737375030dd596a52c7a9b73664aaa11977977 (diff)
Make initialization of vfr filter work as I intended.
Also fix signalling of framerate in output file when PFR is used. git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@5522 b64f7644-9d1e-0410-96f1-a4d463321fa5
-rw-r--r--libhb/common.h2
-rw-r--r--libhb/vfr.c54
-rw-r--r--libhb/work.c32
-rw-r--r--macosx/Controller.m24
-rwxr-xr-xscripts/manicure.rb14
-rw-r--r--test/test.c54
6 files changed, 95 insertions, 85 deletions
diff --git a/libhb/common.h b/libhb/common.h
index 443127e9e..2951def5d 100644
--- a/libhb/common.h
+++ b/libhb/common.h
@@ -969,8 +969,6 @@ typedef struct hb_filter_init_s
int crop[4];
int vrate_base;
int vrate;
- int title_rate_base;
- int title_rate;
int cfr;
} hb_filter_init_t;
diff --git a/libhb/vfr.c b/libhb/vfr.c
index c2156f72d..009f88c43 100644
--- a/libhb/vfr.c
+++ b/libhb/vfr.c
@@ -308,10 +308,8 @@ static int hb_vfr_init(hb_filter_object_t *filter, hb_filter_init_t *init)
build_gamma_lut(pv);
pv->cfr = init->cfr;
- pv->vrate = init->vrate;
- pv->vrate_base = init->vrate_base;
- pv->input_vrate = init->title_rate;
- pv->input_vrate_base = init->title_rate_base;
+ pv->input_vrate = pv->vrate = init->vrate;
+ pv->input_vrate_base = pv->vrate_base = init->vrate_base;
if (filter->settings != NULL)
{
sscanf(filter->settings, "%d:%d:%d",
@@ -337,18 +335,27 @@ static int hb_vfr_init(hb_filter_object_t *filter, hb_filter_init_t *init)
pv->lost_time[0] = 0; pv->lost_time[1] = 0; pv->lost_time[2] = 0; pv->lost_time[3] = 0;
pv->frame_metric = 1000; // Force first frame
- if (!pv->cfr)
+ if (pv->cfr == 2)
{
- /* Ensure we're using "Same as source" FPS */
- pv->vrate_base = pv->input_vrate_base;
- pv->vrate = pv->input_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)init->vrate / init->vrate_base;
+ double peak_fps = (double)pv->vrate / pv->vrate_base;
+ if (source_fps > peak_fps)
+ {
+ // peak framerate is lower than the source framerate.
+ // so signal that the framerate will be the peak fps.
+ init->vrate = pv->vrate;
+ init->vrate_base = pv->vrate_base;
+ }
+ }
+ else
+ {
+ init->vrate = pv->vrate;
+ init->vrate_base = pv->vrate_base;
}
pv->frame_rate = (double)pv->vrate_base * 90000. / pv->vrate;
init->cfr = pv->cfr;
- init->vrate = pv->vrate;
- init->vrate_base = pv->vrate_base;
- init->title_rate = pv->input_vrate;
- init->title_rate_base = pv->input_vrate_base;
return 0;
}
@@ -362,8 +369,27 @@ static int hb_vfr_info( hb_filter_object_t * filter,
return 1;
memset( info, 0, sizeof( hb_filter_info_t ) );
- info->out.vrate_base = pv->vrate_base;
- info->out.vrate = pv->vrate;
+ info->out.vrate_base = pv->input_vrate_base;
+ info->out.vrate = pv->input_vrate;
+ if (pv->cfr == 2)
+ {
+ // 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)pv->input_vrate / pv->input_vrate_base;
+ double peak_fps = (double)pv->vrate / pv->vrate_base;
+ if (source_fps > peak_fps)
+ {
+ // peak framerate is lower than the source framerate.
+ // so signal that the framerate will be the peak fps.
+ info->out.vrate = pv->vrate;
+ info->out.vrate_base = pv->vrate_base;
+ }
+ }
+ else
+ {
+ info->out.vrate = pv->vrate;
+ info->out.vrate_base = pv->vrate_base;
+ }
info->out.cfr = pv->cfr;
if ( pv->cfr == 0 )
{
diff --git a/libhb/work.c b/libhb/work.c
index dfaa5d760..72d758eed 100644
--- a/libhb/work.c
+++ b/libhb/work.c
@@ -243,24 +243,6 @@ void hb_display_job_info( hb_job_t * job )
hb_log( " + bitrate %d kbps", title->video_bitrate / 1000 );
}
- if( job->cfr == 0 )
- {
- hb_log( " + frame rate: same as source (around %.3f fps)",
- (float) title->rate / (float) title->rate_base );
- }
- else if( job->cfr == 1 )
- {
- 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->vrate / (float) job->vrate_base );
- }
-
// Filters can modify dimensions. So show them first.
if( hb_list_count( job->list_filter ) )
{
@@ -691,15 +673,13 @@ static void do_job( hb_job_t * job )
init.job = job;
init.pix_fmt = AV_PIX_FMT_YUV420P;
- init.width = title->width;
- init.height = title->height;
+ init.width = title->width - (title->crop[2] + title->crop[3]);
+ init.height = title->height - (title->crop[0] + title->crop[1]);
init.par_width = job->anamorphic.par_width;
init.par_height = job->anamorphic.par_height;
- memcpy(init.crop, job->crop, sizeof(int[4]));
- init.vrate_base = job->vrate_base;
- init.vrate = job->vrate;
- init.title_rate_base = title->rate_base;
- init.title_rate = title->rate;
+ memcpy(init.crop, title->crop, sizeof(int[4]));
+ init.vrate_base = title->rate_base;
+ init.vrate = title->rate;
init.cfr = 0;
for( i = 0; i < hb_list_count( job->list_filter ); )
{
@@ -721,8 +701,6 @@ static void do_job( hb_job_t * job )
memcpy(job->crop, init.crop, sizeof(int[4]));
job->vrate_base = init.vrate_base;
job->vrate = init.vrate;
- title->rate_base = init.title_rate_base;
- title->rate = init.title_rate;
job->cfr = init.cfr;
}
diff --git a/macosx/Controller.m b/macosx/Controller.m
index a71eb67cc..93c61f8b5 100644
--- a/macosx/Controller.m
+++ b/macosx/Controller.m
@@ -3313,6 +3313,8 @@ fWorkingCount = 0;
[fSrcTitlePopUp indexOfSelectedItem] );
hb_job_t * job = title->job;
hb_filter_object_t * filter;
+ int vrate, vrate_base;
+
/* set job->angle for libdvdnav */
job->angle = [fSrcAnglePopUp indexOfSelectedItem] + 1;
/* Chapter selection */
@@ -3383,8 +3385,8 @@ fWorkingCount = 0;
if( [fVidRatePopUp indexOfSelectedItem] > 0 )
{
/* a specific framerate has been chosen */
- job->vrate = 27000000;
- job->vrate_base = hb_video_rates[[fVidRatePopUp indexOfSelectedItem]-1].rate;
+ vrate = 27000000;
+ vrate_base = hb_video_rates[[fVidRatePopUp indexOfSelectedItem]-1].rate;
if ([fFramerateMatrix selectedRow] == 1)
{
// CFR
@@ -3399,8 +3401,8 @@ fWorkingCount = 0;
else
{
/* same as source */
- job->vrate = title->rate;
- job->vrate_base = title->rate_base;
+ vrate = title->rate;
+ vrate_base = title->rate_base;
if ([fFramerateMatrix selectedRow] == 1)
{
// CFR
@@ -3723,7 +3725,7 @@ bool one_burned = FALSE;
/* Add framerate shaping filter */
filter = hb_filter_init( HB_FILTER_VFR );
hb_add_filter( job, filter, [[NSString stringWithFormat:@"%d:%d:%d",
- job->cfr, job->vrate, job->vrate_base] UTF8String] );
+ job->cfr, vrate, vrate_base] UTF8String] );
}
@@ -3740,6 +3742,8 @@ bool one_burned = FALSE;
hb_job_t * job = title->job;
hb_audio_config_t * audio;
hb_filter_object_t * filter;
+ int vrate, vrate_base;
+
/* Title Angle for dvdnav */
job->angle = [[queueToApply objectForKey:@"TitleAngle"] intValue];
@@ -3938,8 +3942,8 @@ bool one_burned = FALSE;
if( [[queueToApply objectForKey:@"JobIndexVideoFramerate"] intValue] > 0 )
{
/* a specific framerate has been chosen */
- job->vrate = 27000000;
- job->vrate_base = hb_video_rates[[[queueToApply objectForKey:@"JobIndexVideoFramerate"] intValue]-1].rate;
+ vrate = 27000000;
+ vrate_base = hb_video_rates[[[queueToApply objectForKey:@"JobIndexVideoFramerate"] intValue]-1].rate;
if ([[queueToApply objectForKey:@"VideoFramerateMode"] isEqualToString:@"cfr"])
{
// CFR
@@ -3954,8 +3958,8 @@ bool one_burned = FALSE;
else
{
/* same as source */
- job->vrate = [[queueToApply objectForKey:@"JobVrate"] intValue];
- job->vrate_base = [[queueToApply objectForKey:@"JobVrateBase"] intValue];
+ vrate = [[queueToApply objectForKey:@"JobVrate"] intValue];
+ vrate_base = [[queueToApply objectForKey:@"JobVrateBase"] intValue];
if ([[queueToApply objectForKey:@"VideoFramerateMode"] isEqualToString:@"cfr"])
{
// CFR
@@ -4282,7 +4286,7 @@ bool one_burned = FALSE;
/* Add framerate shaping filter */
filter = hb_filter_init( HB_FILTER_VFR );
hb_add_filter( job, filter, [[NSString stringWithFormat:@"%d:%d:%d",
- job->cfr, job->vrate, job->vrate_base] UTF8String] );
+ job->cfr, vrate, vrate_base] UTF8String] );
[self writeToActivityLog: "prepareJob exiting"];
}
diff --git a/scripts/manicure.rb b/scripts/manicure.rb
index 9e83750bf..4dc9b8db7 100755
--- a/scripts/manicure.rb
+++ b/scripts/manicure.rb
@@ -1073,23 +1073,23 @@ class Display
#FPS
if hash["VideoFramerate"] != "Same as source"
if hash["VideoFramerate"] == "23.976 (NTSC Film)"
- commandString << "job->vrate_base = " << "1126125;\n "
+ commandString << "filter_vrate_base = " << "1126125;\n "
elsif hash["VideoFramerate"] == "29.97 (NTSC Video)"
- commandString << "job->vrate_base = " << "900900;\n "
+ commandString << "filter_vrate_base = " << "900900;\n "
elsif hash["VideoFramerate"] == "25 (PAL Film/Video)"
- commandString << "job->vrate_base = " << "1080000;\n "
+ commandString << "filter_vrate_base = " << "1080000;\n "
else
- commandString << "job->vrate_base = " << (27000000 / hash["VideoFramerate"].to_i).to_s << ";\n "
+ commandString << "filter_vrate_base = " << (27000000 / hash["VideoFramerate"].to_i).to_s << ";\n "
end
# not same as source: pfr, else default (cfr)
if hash["VideoFramerateMode"] == "pfr"
- commandString << "job->cfr = 2;\n "
+ commandString << "filter_cfr = 2;\n "
else
- commandString << "job->cfr = 1;\n "
+ commandString << "filter_cfr = 1;\n "
end
# same as source: cfr, else default (vfr)
elsif hash["VideoFramerateMode"] == "cfr"
- commandString << "job->cfr = 1;\n "
+ commandString << "filter_cfr = 1;\n "
end
#Audio tracks
diff --git a/test/test.c b/test/test.c
index 771682280..efa7ae227 100644
--- a/test/test.c
+++ b/test/test.c
@@ -578,6 +578,7 @@ static int HandleEvents( hb_handle_t * h )
{
hb_state_t s;
int tmp_num_audio_tracks;
+ int filter_vrate, filter_vrate_base, filter_cfr;
hb_get_state( h, &s );
switch( s.state )
@@ -688,6 +689,9 @@ static int HandleEvents( hb_handle_t * h )
/* Set job settings */
job = hb_job_init( title );
+ filter_vrate = job->vrate;
+ filter_vrate_base = job->vrate_base;
+ filter_cfr = job->cfr;
if( chapter_start && chapter_end && !stop_at_pts && !start_at_preview && !stop_at_frame && !start_at_pts && !start_at_frame )
@@ -717,8 +721,8 @@ static int HandleEvents( hb_handle_t * h )
}
vcodec = HB_VCODEC_X264;
job->vquality = 20.0;
- job->vrate_base = 900000;
- job->cfr = 2;
+ filter_vrate_base = 900000;
+ filter_cfr = 2;
if( !atracks )
{
atracks = strdup("1,1");
@@ -787,8 +791,8 @@ static int HandleEvents( hb_handle_t * h )
job->ipod_atom = 1;
vcodec = HB_VCODEC_X264;
job->vquality = 22.0;
- job->vrate_base = 900000;
- job->cfr = 2;
+ filter_vrate_base = 900000;
+ filter_cfr = 2;
if( !atracks )
{
atracks = strdup("1");
@@ -853,8 +857,8 @@ static int HandleEvents( hb_handle_t * h )
job->largeFileSize = 1;
vcodec = HB_VCODEC_X264;
job->vquality = 22.0;
- job->vrate_base = 900000;
- job->cfr = 2;
+ filter_vrate_base = 900000;
+ filter_cfr = 2;
if( !atracks )
{
atracks = strdup("1");
@@ -923,8 +927,8 @@ static int HandleEvents( hb_handle_t * h )
job->largeFileSize = 1;
vcodec = HB_VCODEC_X264;
job->vquality = 20.0;
- job->vrate_base = 900000;
- job->cfr = 2;
+ filter_vrate_base = 900000;
+ filter_cfr = 2;
if( !atracks )
{
atracks = strdup("1");
@@ -993,8 +997,8 @@ static int HandleEvents( hb_handle_t * h )
job->largeFileSize = 1;
vcodec = HB_VCODEC_X264;
job->vquality = 20.0;
- job->vrate_base = 900000;
- job->cfr = 2;
+ filter_vrate_base = 900000;
+ filter_cfr = 2;
if( !atracks )
{
atracks = strdup("1,1");
@@ -1067,8 +1071,8 @@ static int HandleEvents( hb_handle_t * h )
job->largeFileSize = 1;
vcodec = HB_VCODEC_X264;
job->vquality = 20.0;
- job->vrate_base = 900000;
- job->cfr = 2;
+ filter_vrate_base = 900000;
+ filter_cfr = 2;
if( !atracks )
{
atracks = strdup("1,1");
@@ -1137,8 +1141,8 @@ static int HandleEvents( hb_handle_t * h )
job->largeFileSize = 1;
vcodec = HB_VCODEC_X264;
job->vquality = 20.0;
- job->vrate_base = 900000;
- job->cfr = 2;
+ filter_vrate_base = 900000;
+ filter_cfr = 2;
if( !atracks )
{
atracks = strdup("1,1");
@@ -1208,8 +1212,8 @@ static int HandleEvents( hb_handle_t * h )
}
vcodec = HB_VCODEC_X264;
job->vquality = 22.0;
- job->vrate_base = 900000;
- job->cfr = 2;
+ filter_vrate_base = 900000;
+ filter_cfr = 2;
if( !atracks )
{
atracks = strdup("1");
@@ -1276,8 +1280,8 @@ static int HandleEvents( hb_handle_t * h )
}
vcodec = HB_VCODEC_X264;
job->vquality = 22.0;
- job->vrate_base = 900000;
- job->cfr = 2;
+ filter_vrate_base = 900000;
+ filter_cfr = 2;
if( !atracks )
{
atracks = strdup("1");
@@ -1754,20 +1758,20 @@ static int HandleEvents( hb_handle_t * h )
// Add framerate shaping filter
if( vrate )
{
- job->cfr = cfr;
- job->vrate = 27000000;
- job->vrate_base = vrate;
+ filter_cfr = cfr;
+ filter_vrate = 27000000;
+ filter_vrate_base = vrate;
}
else if ( cfr )
{
// cfr or pfr flag with no rate specified implies
// use the title rate.
- job->cfr = cfr;
- job->vrate = title->rate;
- job->vrate_base = title->rate_base;
+ filter_cfr = cfr;
+ filter_vrate = title->rate;
+ filter_vrate_base = title->rate_base;
}
filter_str = hb_strdup_printf("%d:%d:%d",
- job->cfr, job->vrate, job->vrate_base );
+ filter_cfr, filter_vrate, filter_vrate_base );
filter = hb_filter_init( HB_FILTER_VFR );
hb_add_filter( job, filter, filter_str );
free( filter_str );