diff options
-rw-r--r-- | libhb/common.h | 2 | ||||
-rw-r--r-- | libhb/vfr.c | 54 | ||||
-rw-r--r-- | libhb/work.c | 32 | ||||
-rw-r--r-- | macosx/Controller.m | 24 | ||||
-rwxr-xr-x | scripts/manicure.rb | 14 | ||||
-rw-r--r-- | test/test.c | 54 |
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 ); |