Conversion of frame index to FFmpeg time must always use the original or detected...
authorCarl Hetherington <cth@carlh.net>
Tue, 8 Jul 2014 09:03:58 +0000 (10:03 +0100)
committerCarl Hetherington <cth@carlh.net>
Tue, 8 Jul 2014 09:03:58 +0000 (10:03 +0100)
ChangeLog
src/lib/ffmpeg_decoder.cc
src/lib/video_content.cc
src/lib/video_content.h

index c4e689b64cec4494aa47339e32dc7a0edd416980..acf6b55a1ea2f2b4ac9161484b2127ab71644632 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2014-07-08  Carl Hetherington  <cth@carlh.net>
+
+       * Fix various problems with seek and content
+       being trimmed when its video frame rate is
+       overridden.
+
 2014-07-02  Carl Hetherington  <cth@carlh.net>
 
        * Updated de_DE translation from Carsten Kurz.
index 07f988e2baeaac6d5702e0238781bbce2d651367..f2d434e3bab1415ce38b170b7ae762a82062fc6f 100644 (file)
@@ -334,7 +334,7 @@ FFmpegDecoder::seek (VideoContent::Frame frame, bool accurate)
        }
 
        /* Initial seek time in the stream's timebase */
-       int64_t const initial_vt = ((initial / _ffmpeg_content->video_frame_rate()) - _pts_offset) / time_base;
+       int64_t const initial_vt = ((initial / _ffmpeg_content->original_video_frame_rate()) - _pts_offset) / time_base;
 
        av_seek_frame (_format_context, _video_stream, initial_vt, AVSEEK_FLAG_BACKWARD);
 
@@ -375,7 +375,7 @@ FFmpegDecoder::seek (VideoContent::Frame frame, bool accurate)
                r = avcodec_decode_video2 (video_codec_context(), _frame, &finished, &_packet);
                if (r >= 0 && finished) {
                        _video_position = rint (
-                               (av_frame_get_best_effort_timestamp (_frame) * time_base + _pts_offset) * _ffmpeg_content->video_frame_rate()
+                               (av_frame_get_best_effort_timestamp (_frame) * time_base + _pts_offset) * _ffmpeg_content->original_video_frame_rate()
                                );
 
                        if (_video_position >= (frame - 1)) {
@@ -495,12 +495,12 @@ FFmpegDecoder::decode_video_packet ()
                                /* We just did a seek, so disable any attempts to correct for where we
                                   are / should be.
                                */
-                               _video_position = rint (pts * _ffmpeg_content->video_frame_rate ());
+                               _video_position = rint (pts * _ffmpeg_content->original_video_frame_rate ());
                                _just_sought = false;
                        }
 
-                       double const next = _video_position / _ffmpeg_content->video_frame_rate();
-                       double const one_frame = 1 / _ffmpeg_content->video_frame_rate ();
+                       double const next = _video_position / _ffmpeg_content->original_video_frame_rate();
+                       double const one_frame = 1 / _ffmpeg_content->original_video_frame_rate ();
                        double delta = pts - next;
 
                        while (delta > one_frame) {
index 676a694da6412bc1ba4625d23e4d533e76e88d33..02cc1f810dd6fc114f10ed738a16b6c5e42c1d58 100644 (file)
@@ -58,6 +58,7 @@ vector<VideoContentScale> VideoContentScale::_scales;
 VideoContent::VideoContent (shared_ptr<const Film> f)
        : Content (f)
        , _video_length (0)
+       , _original_video_frame_rate (0)
        , _video_frame_rate (0)
        , _video_frame_type (VIDEO_FRAME_TYPE_2D)
        , _scale (Ratio::from_id ("185"))
@@ -68,6 +69,7 @@ VideoContent::VideoContent (shared_ptr<const Film> f)
 VideoContent::VideoContent (shared_ptr<const Film> f, Time s, VideoContent::Frame len)
        : Content (f, s)
        , _video_length (len)
+       , _original_video_frame_rate (0)
        , _video_frame_rate (0)
        , _video_frame_type (VIDEO_FRAME_TYPE_2D)
        , _scale (Ratio::from_id ("185"))
@@ -78,6 +80,7 @@ VideoContent::VideoContent (shared_ptr<const Film> f, Time s, VideoContent::Fram
 VideoContent::VideoContent (shared_ptr<const Film> f, boost::filesystem::path p)
        : Content (f, p)
        , _video_length (0)
+       , _original_video_frame_rate (0)
        , _video_frame_rate (0)
        , _video_frame_type (VIDEO_FRAME_TYPE_2D)
        , _scale (Ratio::from_id ("185"))
@@ -92,6 +95,7 @@ VideoContent::VideoContent (shared_ptr<const Film> f, shared_ptr<const cxml::Nod
        _video_size.width = node->number_child<int> ("VideoWidth");
        _video_size.height = node->number_child<int> ("VideoHeight");
        _video_frame_rate = node->number_child<float> ("VideoFrameRate");
+       _original_video_frame_rate = node->optional_number_child<float> ("OriginalVideoFrameRate").get_value_or (_video_frame_rate);
        _video_frame_type = static_cast<VideoFrameType> (node->number_child<int> ("VideoFrameType"));
        _crop.left = node->number_child<int> ("LeftCrop");
        _crop.right = node->number_child<int> ("RightCrop");
@@ -148,6 +152,7 @@ VideoContent::VideoContent (shared_ptr<const Film> f, vector<shared_ptr<Content>
        }
 
        _video_size = ref->video_size ();
+       _original_video_frame_rate = ref->original_video_frame_rate ();
        _video_frame_rate = ref->video_frame_rate ();
        _video_frame_type = ref->video_frame_type ();
        _crop = ref->crop ();
@@ -163,6 +168,7 @@ VideoContent::as_xml (xmlpp::Node* node) const
        node->add_child("VideoWidth")->add_child_text (raw_convert<string> (_video_size.width));
        node->add_child("VideoHeight")->add_child_text (raw_convert<string> (_video_size.height));
        node->add_child("VideoFrameRate")->add_child_text (raw_convert<string> (_video_frame_rate));
+       node->add_child("OriginalVideoFrameRate")->add_child_text (raw_convert<string> (_original_video_frame_rate));
        node->add_child("VideoFrameType")->add_child_text (raw_convert<string> (static_cast<int> (_video_frame_type)));
        _crop.as_xml (node);
        _scale.as_xml (node->add_child("Scale"));
@@ -186,6 +192,7 @@ VideoContent::take_from_video_examiner (shared_ptr<VideoExaminer> d)
                boost::mutex::scoped_lock lm (_mutex);
                _video_size = vs;
                _video_frame_rate = vfr;
+               _original_video_frame_rate = vfr;
        }
        
        signal_changed (VideoContentProperty::VIDEO_SIZE);
index d0b907cb8bceb036ffbc02cf0a83190ce7cf4c1b..62459222d84cb823d95682b65d2f44481bcc41bf 100644 (file)
@@ -115,6 +115,11 @@ public:
                return _video_frame_rate;
        }
 
+       float original_video_frame_rate () const {
+               boost::mutex::scoped_lock lm (_mutex);
+               return _original_video_frame_rate;
+       }
+       
        void set_video_frame_type (VideoFrameType);
        void set_video_frame_rate (float);
 
@@ -179,6 +184,7 @@ protected:
        void take_from_video_examiner (boost::shared_ptr<VideoExaminer>);
 
        VideoContent::Frame _video_length;
+       float _original_video_frame_rate;
        float _video_frame_rate;
 
 private: