[gimp-gap] fixed broken videoapi framerate detection, support mp4 extension



commit 69ff5480852894b2217541d3ac492d86f27108b5
Author: Wolfgang Hofer <wolfgangh svn gnome org>
Date:   Wed Aug 12 16:26:25 2009 +0200

    fixed broken videoapi framerate detection, support mp4 extension

 ChangeLog                         |   16 ++++++++
 gap/gap_story_dialog.c            |    2 +-
 gap/gap_story_file.c              |    2 +
 libgapvidapi/gap_vid_api_ffmpeg.c |   69 ++++++++++++++++++++++++++++---------
 4 files changed, 71 insertions(+), 18 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 14d3857..1b768ad 100755
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2009-08-11 Wolfgang Hofer <hof gimp org>
+
+- detection of videofiles by extension now also accepts.mp4 videos.
+- fixed broken videoapi framerate detection (did not work on some video files)
+  the fix for the libavformat based api now takes care of the
+  ticks_per_frame value of the video codec
+  (that is typically 2 in interlaced videos)
+  an additional fallback uses the container framerate in case the codec delivers
+  unplausible value.
+  now it seems to work, tested with videos of different types mpg, vob, wma, avi, mp4
+
+  * gap/gap_story_file.c
+  * gap/gap_story_dialog.c
+  * libgapvidapi/gap_vid_api_ffmpeg.c  
+ 
+ 
 2009-07-28 Wolfgang Hofer <hof gimp org>
 
 - fixed broken initialisation of default values in case the file
diff --git a/gap/gap_story_dialog.c b/gap/gap_story_dialog.c
index af6a20b..a9b9bd3 100644
--- a/gap/gap_story_dialog.c
+++ b/gap/gap_story_dialog.c
@@ -8682,7 +8682,7 @@ p_tabw_master_prop_dialog(GapStbTabWidgets *tabw, gboolean new_flag)
 {
   GapArrArg  argv[12];
   static char *radio_args[4]  = { N_("automatic"), "libmpeg3", "libavformat", "quicktime4linux" };
-  static char *radio_aspect_args[3]  = { N_("none"), "4:3", "16:9"};
+  static char *radio_aspect_args[4]  = { N_("none"), "4:3", "16:9", "3:2"};
   gint   l_ii;
   gint   l_decoder_idx;
   gint   l_aspect_idx;
diff --git a/gap/gap_story_file.c b/gap/gap_story_file.c
index 6238d55..119335a 100644
--- a/gap/gap_story_file.c
+++ b/gap/gap_story_file.c
@@ -1149,6 +1149,8 @@ gap_story_filename_is_videofile_by_ext(const char *filename)
     ||  (strcmp(l_ext, "mpg") == 0)
     ||  (strcmp(l_ext, "MPEG") == 0)
     ||  (strcmp(l_ext, "MPG") == 0)
+    ||  (strcmp(l_ext, "mp4") == 0)
+    ||  (strcmp(l_ext, "MP4") == 0)
     ||  (strcmp(l_ext, "avi") == 0)
     ||  (strcmp(l_ext, "AVI") == 0)
     ||  (strcmp(l_ext, "mov") == 0)   /* Quicktime videos */
diff --git a/libgapvidapi/gap_vid_api_ffmpeg.c b/libgapvidapi/gap_vid_api_ffmpeg.c
index 64aec68..b408a27 100644
--- a/libgapvidapi/gap_vid_api_ffmpeg.c
+++ b/libgapvidapi/gap_vid_api_ffmpeg.c
@@ -3536,7 +3536,7 @@ p_ff_open_input(char *filename, t_GVA_Handle *gvahand, t_GVA_ffmpeg*  handle, gb
   AVFormatContext *ic;
   AVInputFormat *iformat;
   int err, ii, ret;
-  AVRational rfps;
+  int rfps, rfps_base;
 
   if(gap_debug) printf("p_ff_open_input: START  vid_open:%d\n", (int)vid_open);
 
@@ -3614,6 +3614,9 @@ p_ff_open_input(char *filename, t_GVA_Handle *gvahand, t_GVA_ffmpeg*  handle, gb
             if((gvahand->vtracks == gvahand->vid_track)
             || (gvahand->vtracks == 1))
             {
+              gdouble containerFramerate;
+              gdouble codecFramerate;
+              
               if(vid_open)
               {
                 handle->vid_stream_index = ii;
@@ -3629,7 +3632,9 @@ p_ff_open_input(char *filename, t_GVA_Handle *gvahand, t_GVA_ffmpeg*  handle, gb
               p_set_aspect_ratio(gvahand, handle);
               
 
-              rfps = ic->streams[ii]->r_frame_rate;
+              rfps      = ic->streams[ii]->r_frame_rate.num;
+              rfps_base = ic->streams[ii]->r_frame_rate.den;
+
               acc->strict_std_compliance = FF_COMPLIANCE_NORMAL;
               acc->workaround_bugs = FF_BUG_AUTODETECT;
               acc->error_recognition = FF_ER_COMPLIANT;
@@ -3643,26 +3648,56 @@ p_ff_open_input(char *filename, t_GVA_Handle *gvahand, t_GVA_ffmpeg*  handle, gb
               {
                   acc->flags|= CODEC_FLAG_TRUNCATED;
               }
-              
-              if(FALSE)
+
+
+              /* attempt to get the framerate */              
+              containerFramerate = 1.0;
+              codecFramerate = 1.0;
+
+              gvahand->framerate = 1.0;
+              if (acc->time_base.num != 0)
               {
-                if ((acc->time_base.den != rfps.den)
-                || (acc->time_base.num != rfps.num))
+                 codecFramerate = (gdouble)acc->time_base.den / (gdouble)acc->time_base.num;
+                
+                if (acc->ticks_per_frame > 1)
                 {
-                    printf("\nSeems stream %d codec frame rate differs from container frame rate: %2.2f (%d/%d) -> %2.2f (%d/%d)\n"
+                  /* videos with interlaced frames typically deliver framerates at double speed
+                   * because they refere to half-frames per second and have set  ticks_per_frame to value 2.
+                   * therefoe divide by ticks_per_frame to deliver the framerate of full frame
+                   */
+                  codecFramerate /= (gdouble)acc->ticks_per_frame;
+                }
+              }
+
+              if (rfps_base != 0)
+              {
+                containerFramerate = (gdouble)rfps / (gdouble)rfps_base;
+              }
+
+              gvahand->framerate = codecFramerate;
+              if(containerFramerate != codecFramerate)
+              {
+                /* in case the framerate values of the codec and container are different
+                 * pick the smaller value (but only if it is greater than plausibility threshold of 10 fps)
+                 */
+              
+                if((containerFramerate > 10.0)
+                && (containerFramerate < codecFramerate))
+                {
+                   gvahand->framerate = containerFramerate;
+                }
+              
+                printf("\nSeems stream %d codec frame rate differs from container frame rate: %2.2f (%d/%d) -> %2.2f (%d/%d) ticksPerFrame:%d\n"
                          ,ii
-                         , (float)acc->time_base.den / acc->time_base.num
+                         , (float)acc->time_base.den /  (float)acc->time_base.num
                          , acc->time_base.den
                          , acc->time_base.num
-                         , (float)rfps.den / rfps.num
-                         , rfps.den
-                         , rfps.num
+                         , (float)rfps /  (float)rfps_base
+                         , rfps
+                         , rfps_base
+                         , acc->ticks_per_frame
                          );
-                }
               }
-
-              /* update the current frame rate to match the stream frame rate */
-              gvahand->framerate = (gdouble)acc->time_base.den / (gdouble)acc->time_base.num;
             }
             break;
         default:
@@ -5235,8 +5270,8 @@ p_probe_timecode_offset(t_GVA_Handle *master_gvahand)
         printf("p_probe_timecode_offset: step: (%d) timecode offset: %lld, stepsize:%ld (avg_measured: %ld avg: %.3f)\n"
           , (int)l_readsteps
           , master_handle->timecode_offset_frame1
-          , master_handle->timecode_steps[l_readsteps -1]
-          , master_handle->timecode_step_avg
+          , (long)master_handle->timecode_steps[l_readsteps -1]
+          , (long)master_handle->timecode_step_avg
           , (float)avg_fstepsize
           );
       }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]