]> git.sesse.net Git - casparcg/commitdiff
2.0.2: ffmpeg_producer: Improved nb_frames accuracy.
authorronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Sun, 27 Nov 2011 19:14:41 +0000 (19:14 +0000)
committerronag <ronag@362d55ac-95cf-4e76-9f9a-cbaa9c17b72d>
Sun, 27 Nov 2011 19:14:41 +0000 (19:14 +0000)
git-svn-id: https://casparcg.svn.sourceforge.net/svnroot/casparcg/server/branches/2.0.2@1684 362d55ac-95cf-4e76-9f9a-cbaa9c17b72d

modules/ffmpeg/producer/ffmpeg_producer.cpp
modules/ffmpeg/producer/util/util.cpp

index 9c3bc7a876c9ebf119b7dd84e1fcb40ec8c51354..4d6dbf94c3e7e7b06029d0e2f65de1d69cf92ca6 100644 (file)
@@ -172,9 +172,9 @@ public:
                if(input_.nb_loops() < 1) // input still hasn't counted all frames\r
                {\r
                        auto video_nb_frames = video_decoder_ ? video_decoder_->nb_frames() : std::numeric_limits<int64_t>::max();\r
-                       auto audio_nb_frames = audio_decoder_ ? audio_decoder_->nb_frames() : std::numeric_limits<int64_t>::max();\r
+                       //auto audio_nb_frames = audio_decoder_ ? audio_decoder_->nb_frames() : std::numeric_limits<int64_t>::max();\r
 \r
-                       nb_frames = std::max(nb_frames, std::max(video_nb_frames, audio_nb_frames));\r
+                       nb_frames = std::max(nb_frames, video_nb_frames);\r
                }\r
 \r
                nb_frames = std::min(static_cast<int64_t>(length_), nb_frames);\r
@@ -197,7 +197,7 @@ public:
                        return L"ffmpeg[" + boost::filesystem::wpath(filename_).filename() + L"|" \r
                                                          + boost::lexical_cast<std::wstring>(video_decoder_->width()) + L"x" + boost::lexical_cast<std::wstring>(video_decoder_->height())\r
                                                          + (video_decoder_->is_progressive() ? L"p" : L"i")  + boost::lexical_cast<std::wstring>(video_decoder_->is_progressive() ? video_decoder_->fps() : 2.0 * video_decoder_->fps())\r
-                                                         + L"]";\r
+                                                         + L"|" + boost::lexical_cast<std::wstring>(nb_frames()) + L"]";\r
                }\r
                \r
                return L"ffmpeg[" + boost::filesystem::wpath(filename_).filename() + L"]";\r
index bdbdfea98bb4246e756b68494f0357e7f286dbdf..7cdd05384dcc5b8fdb59d01b625dd6ed9ecd597c 100644 (file)
@@ -284,87 +284,85 @@ void fix_meta_data(AVFormatContext& context)
        auto video_index = av_find_best_stream(&context, AVMEDIA_TYPE_VIDEO, -1, -1, 0, 0);\r
        auto audio_index = av_find_best_stream(&context, AVMEDIA_TYPE_AUDIO, -1, -1, 0, 0);\r
 \r
-       if(video_index < 0)\r
-               return;\r
+       if(video_index > -1)\r
+       {\r
+               auto video_context = context.streams[video_index]->codec;\r
+               auto video_stream  = context.streams[video_index];\r
 \r
-       auto& video_context = *context.streams[video_index]->codec;\r
-       auto& video_stream  = *context.streams[video_index];\r
+               auto nb_frames = static_cast<double>(video_stream->duration*video_stream->time_base.num)/static_cast<double>(video_stream->time_base.den);\r
+               nb_frames = (nb_frames*video_context->time_base.den)/video_context->time_base.num;\r
+               video_stream->nb_frames = static_cast<int64_t>(nb_frames+0.5);\r
                                                \r
-       if(boost::filesystem2::path(context.filename).extension() == ".flv")\r
-       {\r
-               try\r
+               if(boost::filesystem2::path(context.filename).extension() == ".flv")\r
                {\r
-                       auto meta = read_flv_meta_info(context.filename);\r
-                       double fps = boost::lexical_cast<double>(meta["framerate"]);\r
-                       video_context.time_base.num = 1000000;\r
-                       video_context.time_base.den = static_cast<int>(fps*1000000.0);\r
-                       video_stream.nb_frames = static_cast<int64_t>(boost::lexical_cast<double>(meta["duration"])*fps);\r
+                       try\r
+                       {\r
+                               auto meta = read_flv_meta_info(context.filename);\r
+                               double fps = boost::lexical_cast<double>(meta["framerate"]);\r
+                               video_context->time_base.num = 1000000;\r
+                               video_context->time_base.den = static_cast<int>(fps*1000000.0);\r
+                               video_stream->nb_frames = static_cast<int64_t>(boost::lexical_cast<double>(meta["duration"])*fps);\r
+                       }\r
+                       catch(...){}\r
                }\r
-               catch(...){}\r
-       }\r
-       else\r
-       {\r
-               if(video_stream.nb_frames == 0)\r
-                       video_stream.nb_frames = (video_stream.duration*video_stream.time_base.num)/video_stream.time_base.den;\r
-               \r
-               if(video_stream.nb_frames == 0)\r
-                       video_stream.nb_frames = video_stream.duration;\r
-\r
-               video_context.time_base.num *= video_context.ticks_per_frame;\r
+               else\r
+               {\r
+                       video_context->time_base.num *= video_context->ticks_per_frame;\r
 \r
-               if(!is_sane_fps(video_context.time_base))\r
-               {                       \r
-                       video_context.time_base = fix_time_base(video_context.time_base);\r
+                       if(!is_sane_fps(video_context->time_base))\r
+                       {                       \r
+                               video_context->time_base = fix_time_base(video_context->time_base);\r
 \r
-                       if(!is_sane_fps(video_context.time_base) && audio_index > -1)\r
-                       {\r
-                               auto& audio_context = *context.streams[audio_index]->codec;\r
-                               auto& audio_stream  = *context.streams[audio_index];\r
+                               if(!is_sane_fps(video_context->time_base) && audio_index > -1)\r
+                               {\r
+                                       auto& audio_context = *context.streams[audio_index]->codec;\r
+                                       auto& audio_stream  = *context.streams[audio_index];\r
 \r
-                               double duration_sec = audio_stream.duration / static_cast<double>(audio_context.sample_rate);\r
+                                       double duration_sec = audio_stream.duration / static_cast<double>(audio_context.sample_rate);\r
                                                                \r
-                               video_context.time_base.num = static_cast<int>(duration_sec*100000.0);\r
-                               video_context.time_base.den = static_cast<int>(video_stream.nb_frames*100000);\r
+                                       video_context->time_base.num = static_cast<int>(duration_sec*100000.0);\r
+                                       video_context->time_base.den = static_cast<int>(video_stream->nb_frames*100000);\r
+                               }\r
                        }\r
+                               \r
+                       //if(audio_index > -1) // Check for invalid double frame-rate\r
+                       //{\r
+                       //      auto& audio_context             = *context.streams[audio_index]->codec;\r
+                       //      auto& audio_stream              = *context.streams[audio_index];\r
+                       //      \r
+                       //      double duration_sec             = audio_stream.duration / static_cast<double>(audio_context.sample_rate);\r
+                       //      double fps                              = static_cast<double>(video_context->time_base.den) / static_cast<double>(video_context->time_base.num);\r
+\r
+                       //      double fps_nb_frames    = static_cast<double>(duration_sec*fps);\r
+                       //      double stream_nb_frames = static_cast<double>(video_stream->nb_frames);\r
+                       //      double diff                             = std::abs(fps_nb_frames - stream_nb_frames*2.0);\r
+                       //      if(diff < fps_nb_frames*0.05)\r
+                       //              video_context->time_base.num *= 2;\r
+                       //}\r
+                       //else\r
+                       //{\r
+                       //      video_context->time_base.den = video_stream->r_frame_rate.num;\r
+                       //      video_context->time_base.num = video_stream->r_frame_rate.den;\r
+                       //}\r
                }\r
 \r
-               //if(audio_index > -1) // Check for invalid double frame-rate\r
-               //{\r
-               //      auto& audio_context             = *context.streams[audio_index]->codec;\r
-               //      auto& audio_stream              = *context.streams[audio_index];\r
-               //      \r
-               //      double duration_sec             = audio_stream.duration / static_cast<double>(audio_context.sample_rate);\r
-               //      double fps                              = static_cast<double>(video_context.time_base.den) / static_cast<double>(video_context.time_base.num);\r
-\r
-               //      double fps_nb_frames    = static_cast<double>(duration_sec*fps);\r
-               //      double stream_nb_frames = static_cast<double>(video_stream.nb_frames);\r
-               //      double diff                             = std::abs(fps_nb_frames - stream_nb_frames*2.0);\r
-               //      if(diff < fps_nb_frames*0.05)\r
-               //              video_context.time_base.num *= 2;\r
-               //}\r
-               //else\r
-               //{\r
-               //      video_context.time_base.den = video_stream.r_frame_rate.num;\r
-               //      video_context.time_base.num = video_stream.r_frame_rate.den;\r
-               //}\r
-       }\r
+               double fps = static_cast<double>(video_context->time_base.den) / static_cast<double>(video_context->time_base.num);\r
 \r
-       double fps = static_cast<double>(video_context.time_base.den) / static_cast<double>(video_context.time_base.num);\r
-\r
-       double closest_fps = 0.0;\r
-       for(int n = 0; n < core::video_format::count; ++n)\r
-       {\r
-               auto format = core::video_format_desc::get(static_cast<core::video_format::type>(n));\r
+               double closest_fps = 0.0;\r
+               for(int n = 0; n < core::video_format::count; ++n)\r
+               {\r
+                       auto format = core::video_format_desc::get(static_cast<core::video_format::type>(n));\r
 \r
-               double diff1 = std::abs(format.fps - fps);\r
-               double diff2 = std::abs(closest_fps - fps);\r
+                       double diff1 = std::abs(format.fps - fps);\r
+                       double diff2 = std::abs(closest_fps - fps);\r
 \r
-               if(diff1 < diff2)\r
-                       closest_fps = format.fps;\r
-       }\r
+                       if(diff1 < diff2)\r
+                               closest_fps = format.fps;\r
+               }\r
        \r
-       video_context.time_base.num = 1000000;\r
-       video_context.time_base.den = static_cast<int>(closest_fps*1000000.0);\r
+               video_context->time_base.num = 1000000;\r
+               video_context->time_base.den = static_cast<int>(closest_fps*1000000.0);\r
+       }\r
 }\r
 \r
 safe_ptr<AVPacket> create_packet()\r