]> granicus.if.org Git - handbrake/commitdiff
Make initialization of vfr filter work as I intended.
authorjstebbins <jstebbins.hb@gmail.com>
Tue, 28 May 2013 18:20:43 +0000 (18:20 +0000)
committerjstebbins <jstebbins.hb@gmail.com>
Tue, 28 May 2013 18:20:43 +0000 (18:20 +0000)
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

libhb/common.h
libhb/vfr.c
libhb/work.c
macosx/Controller.m
scripts/manicure.rb
test/test.c

index 443127e9e4d53f0d4fa90e1e29724b37ec1807dc..2951def5d17a375b641fb2f9fd21d6323b1e00de 100644 (file)
@@ -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;
 
index c2156f72d6f2ad7ed774d0d361db26975f7b0298..009f88c4358765c1a04b1ad5a43aa2ffc9bfd53f 100644 (file)
@@ -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 )
     {
index dfaa5d760bbb8d87a2c7d7e5cb1da0db994ee137..72d758eedc82e8ca2186a7a242b92c702982a5ba 100644 (file)
@@ -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;
     }
 
index a71eb67cc5ae58bbf286e6458cf7baad215436cb..93c61f8b57790c21cbef6a707319234549e3763c 100644 (file)
@@ -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"];    
 }
index 9e83750bf6228235fbb8de6bf33369ec46e2318d..4dc9b8db75ae0c3f108316230d72904f0a36f066 100755 (executable)
@@ -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
index 771682280858409fad1125df396aacc7348282a5..efa7ae2271717624fcec3ee82353c0b93ce63931 100644 (file)
@@ -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 );