Allow moving-still-image sources to have their frame rate specified.
authorCarl Hetherington <cth@carlh.net>
Tue, 7 Jan 2014 09:29:06 +0000 (09:29 +0000)
committerCarl Hetherington <cth@carlh.net>
Tue, 7 Jan 2014 09:29:06 +0000 (09:29 +0000)
ChangeLog
src/lib/content.cc
src/lib/image_content.cc
src/lib/image_content.h
src/lib/player.cc
src/lib/video_content.h
src/wx/timing_panel.cc
src/wx/timing_panel.h

index 67187d925dd7a3c94c8aeeb6866fa5857f3b7da5..f46e8cfaac436beb0930f4406137e09eef466424 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2014-01-07  Carl Hetherington  <cth@carlh.net>
+
+       * Allow still-moving-image sources to have their frame rate specified.
+
 2014-01-06  Carl Hetherington  <cth@carlh.net>
 
        * Basics of per-channel audio gain (#247).
index d835a5b0573fd263c6e46f0be4073d830bccde06..ccca46bc02fbedd91e79b6665f6d7858736cb788 100644 (file)
@@ -150,6 +150,10 @@ Content::set_position (Time p)
 {
        {
                boost::mutex::scoped_lock lm (_mutex);
+               if (p == _position) {
+                       return;
+               }
+               
                _position = p;
        }
 
index b05fa6b8d69ce8599503e3d9b3c1e6c5179e6c9a..2d29df0c4bf2fa5a25b32e7e3aa7d200c6c3ca4c 100644 (file)
@@ -144,3 +144,19 @@ ImageContent::still () const
 {
        return number_of_paths() == 1;
 }
+
+void
+ImageContent::set_video_frame_rate (float r)
+{
+       {
+               boost::mutex::scoped_lock lm (_mutex);
+               if (_video_frame_rate == r) {
+                       return;
+               }
+               
+               _video_frame_rate = r;
+       }
+       
+       signal_changed (VideoContentProperty::VIDEO_FRAME_RATE);
+}
+
index 47c5a20e3486298e2e49d307a0136a21a4b80243..e5a0311d97947f816f62dbfc5aefd67a8a9ef282 100644 (file)
@@ -47,6 +47,7 @@ public:
        
        void set_video_length (VideoContent::Frame);
        bool still () const;
+       void set_video_frame_rate (float);
 };
 
 #endif
index e1bf1fdb549ff8a79e258d2a895029bb482735d8..9f859969341fa65a1eacc22d0c3da9b7002387c0 100644 (file)
@@ -524,7 +524,10 @@ Player::content_changed (weak_ptr<Content> w, int property, bool frequent)
                update_subtitle ();
                Changed (frequent);
 
-       } else if (property == VideoContentProperty::VIDEO_CROP || property == VideoContentProperty::VIDEO_RATIO) {
+       } else if (
+               property == VideoContentProperty::VIDEO_CROP || property == VideoContentProperty::VIDEO_RATIO ||
+               property == VideoContentProperty::VIDEO_FRAME_RATE
+               ) {
                
                Changed (frequent);
 
@@ -617,7 +620,7 @@ Player::film_changed (Film::Property p)
           last time we were run.
        */
 
-       if (p == Film::SCALER || p == Film::WITH_SUBTITLES || p == Film::CONTAINER) {
+       if (p == Film::SCALER || p == Film::WITH_SUBTITLES || p == Film::CONTAINER || p == Film::VIDEO_FRAME_RATE) {
                Changed (false);
        }
 }
index effca5c61c314c50c4328d02adb5db7ce92dd48e..141525e01b20b237184c32cf21bc49d7a21791d9 100644 (file)
@@ -129,6 +129,7 @@ protected:
        void take_from_video_examiner (boost::shared_ptr<VideoExaminer>);
 
        VideoContent::Frame _video_length;
+       float _video_frame_rate;
 
 private:
        friend class ffmpeg_pts_offset_test;
@@ -139,7 +140,6 @@ private:
        void setup_default_colour_conversion ();
        
        libdcp::Size _video_size;
-       float _video_frame_rate;
        VideoFrameType _video_frame_type;
        Crop _crop;
        Ratio const * _ratio;
index 79099b1680a5450c71ac469fbaa0ebe9be2a54a1..fdaf9c80705a901d2d919d50b770b767713190ac 100644 (file)
 #include "film_editor.h"
 
 using std::cout;
+using std::string;
 using boost::shared_ptr;
 using boost::dynamic_pointer_cast;
+using boost::lexical_cast;
 
 TimingPanel::TimingPanel (FilmEditor* e)
        : FilmEditorPanel (e, _("Timing"))
@@ -50,11 +52,24 @@ TimingPanel::TimingPanel (FilmEditor* e)
        _play_length = new Timecode (this);
        grid->Add (_play_length);
 
+       {
+               add_label_to_sizer (grid, this, _("Video frame rate"), true);
+               wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL);
+               _video_frame_rate = new wxTextCtrl (this, wxID_ANY);
+               s->Add (_video_frame_rate, 1, wxEXPAND);
+               _set_video_frame_rate = new wxButton (this, wxID_ANY, _("Set"));
+               _set_video_frame_rate->Enable (false);
+               s->Add (_set_video_frame_rate, 0, wxLEFT | wxRIGHT, 8);
+               grid->Add (s, 1, wxEXPAND);
+       }
+
        _position->Changed.connect    (boost::bind (&TimingPanel::position_changed, this));
        _full_length->Changed.connect (boost::bind (&TimingPanel::full_length_changed, this));
        _trim_start->Changed.connect  (boost::bind (&TimingPanel::trim_start_changed, this));
        _trim_end->Changed.connect    (boost::bind (&TimingPanel::trim_end_changed, this));
        _play_length->Changed.connect (boost::bind (&TimingPanel::play_length_changed, this));
+       _video_frame_rate->Bind       (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&TimingPanel::video_frame_rate_changed, this));
+       _set_video_frame_rate->Bind   (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&TimingPanel::set_video_frame_rate, this));
 }
 
 void
@@ -96,11 +111,24 @@ TimingPanel::film_content_changed (int property)
                        _trim_end->set (0, 24);
                        _play_length->set (0, 24);
                }
-       }       
+       } else if (property == VideoContentProperty::VIDEO_FRAME_RATE) {
+               if (content) {
+                       shared_ptr<VideoContent> vc = dynamic_pointer_cast<VideoContent> (content);
+                       if (vc) {
+                               _video_frame_rate->SetValue (std_to_wx (lexical_cast<string> (vc->video_frame_rate ())));
+                       } else {
+                               _video_frame_rate->SetValue ("24");
+                       }
+               } else {
+                       _video_frame_rate->SetValue ("24");
+               }
+       }
 
        shared_ptr<ImageContent> ic = dynamic_pointer_cast<ImageContent> (content);
        _full_length->set_editable (ic && ic->still ());
        _play_length->set_editable (!ic || !ic->still ());
+       _video_frame_rate->Enable (ic && !ic->still ());
+       _set_video_frame_rate->Enable (false);
 }
 
 void
@@ -152,6 +180,25 @@ TimingPanel::play_length_changed ()
        }
 }
 
+void
+TimingPanel::video_frame_rate_changed ()
+{
+       _set_video_frame_rate->Enable (true);
+}
+
+void
+TimingPanel::set_video_frame_rate ()
+{
+       ContentList c = _editor->selected_content ();
+       if (c.size() == 1) {
+               shared_ptr<ImageContent> ic = dynamic_pointer_cast<ImageContent> (c.front ());
+               if (ic) {
+                       ic->set_video_frame_rate (lexical_cast<float> (wx_to_std (_video_frame_rate->GetValue ())));
+                       _set_video_frame_rate->Enable (false);
+               }
+       }
+}
+
 void
 TimingPanel::content_selection_changed ()
 {
@@ -164,9 +211,11 @@ TimingPanel::content_selection_changed ()
        _trim_start->Enable (single);
        _trim_end->Enable (single);
        _play_length->Enable (single);
+       _video_frame_rate->Enable (single);
        
        film_content_changed (ContentProperty::POSITION);
        film_content_changed (ContentProperty::LENGTH);
        film_content_changed (ContentProperty::TRIM_START);
        film_content_changed (ContentProperty::TRIM_END);
+       film_content_changed (VideoContentProperty::VIDEO_FRAME_RATE);
 }
index ab859a1befc1cfb37acdaabee33d88d5bf367156..d9696a20135671a711fe27a14bc2bd5565df237a 100644 (file)
@@ -35,10 +35,14 @@ private:
        void trim_start_changed ();
        void trim_end_changed ();
        void play_length_changed ();
+       void video_frame_rate_changed ();
+       void set_video_frame_rate ();
        
        Timecode* _position;
        Timecode* _full_length;
        Timecode* _trim_start;
        Timecode* _trim_end;
        Timecode* _play_length;
+       wxTextCtrl* _video_frame_rate;
+       wxButton* _set_video_frame_rate;
 };