Save audio mapping to XML; fix initial video display.
authorCarl Hetherington <cth@carlh.net>
Sat, 6 Apr 2013 23:39:34 +0000 (00:39 +0100)
committerCarl Hetherington <cth@carlh.net>
Sat, 6 Apr 2013 23:39:34 +0000 (00:39 +0100)
src/lib/audio_mapping.cc
src/lib/audio_mapping.h
src/lib/film.cc
src/lib/player.cc
src/wx/film_viewer.cc

index 48cc23307504457f1e94a7724635e852ba0d052d..b85ea731402046347a58738be6d5bb550df7fdd3 100644 (file)
 
 */
 
+#include <boost/lexical_cast.hpp>
+#include <libcxml/cxml.h>
 #include "audio_mapping.h"
 
 using std::list;
 using std::cout;
 using std::make_pair;
 using std::pair;
+using std::string;
 using boost::shared_ptr;
+using boost::lexical_cast;
+using boost::dynamic_pointer_cast;
 
 void
 AudioMapping::add (Channel c, libdcp::Channel d)
@@ -83,6 +88,40 @@ AudioMapping::content_to_dcp (Channel c) const
        return d;
 }
 
+void
+AudioMapping::as_xml (xmlpp::Node* node) const
+{
+       for (list<pair<Channel, libdcp::Channel> >::const_iterator i = _content_to_dcp.begin(); i != _content_to_dcp.end(); ++i) {
+               xmlpp::Node* t = node->add_child ("Map");
+               shared_ptr<const AudioContent> c = i->first.content.lock ();
+               t->add_child ("Content")->add_child_text (c->file().string ());
+               t->add_child ("ContentIndex")->add_child_text (lexical_cast<string> (i->first.index));
+               t->add_child ("DCP")->add_child_text (lexical_cast<string> (i->second));
+       }
+}
+
+void
+AudioMapping::set_from_xml (ContentList const & content, shared_ptr<const cxml::Node> node)
+{
+       list<shared_ptr<cxml::Node> > const c = node->node_children ("Map");
+       for (list<shared_ptr<cxml::Node> >::const_iterator i = c.begin(); i != c.end(); ++i) {
+               string const c = (*i)->string_child ("Content");
+               ContentList::const_iterator j = content.begin ();
+               while (j != content.end() && (*j)->file().string() != c) {
+                       ++j;
+               }
+
+               if (j == content.end ()) {
+                       continue;
+               }
+
+               shared_ptr<const AudioContent> ac = dynamic_pointer_cast<AudioContent> (*j);
+               assert (ac);
+
+               add (AudioMapping::Channel (ac, (*i)->number_child<int> ("ContentIndex")), static_cast<libdcp::Channel> ((*i)->number_child<int> ("DCP")));
+       }
+}
+
 bool
 operator== (AudioMapping::Channel const & a, AudioMapping::Channel const & b)
 {
@@ -90,6 +129,3 @@ operator== (AudioMapping::Channel const & a, AudioMapping::Channel const & b)
        shared_ptr<const AudioContent> sb = b.content.lock ();
        return sa == sb && a.index == b.index;
 }
-
-       
-       
index 10ac20b48eb1631076e51204ade111f687fdc0f6..4f2cdb7f83f9c454d855d748c7ca70d193933405 100644 (file)
@@ -29,6 +29,9 @@
 class AudioMapping
 {
 public:
+       void as_xml (xmlpp::Node *) const;
+       void set_from_xml (ContentList const &, boost::shared_ptr<const cxml::Node>);
+       
        struct Channel {
                Channel (boost::weak_ptr<const AudioContent> c, int i)
                        : content (c)
index b1f740ec2c10db725c9adcc5c8e2aa79142225a2..b36dc8f9c0f5dac258533e9879f5103add8bb232 100644 (file)
@@ -418,6 +418,7 @@ Film::write_metadata () const
        _dci_metadata.as_xml (root->add_child ("DCIMetadata"));
        root->add_child("DCPFrameRate")->add_child_text (boost::lexical_cast<string> (_dcp_frame_rate));
        root->add_child("DCIDate")->add_child_text (boost::gregorian::to_iso_string (_dci_date));
+       _audio_mapping.as_xml (root->add_child("AudioMapping"));
 
        for (ContentList::iterator i = the_content.begin(); i != the_content.end(); ++i) {
                (*i)->as_xml (root->add_child ("Content"));
@@ -502,6 +503,9 @@ Film::read_metadata ()
                _content.push_back (c);
        }
 
+       /* This must come after we've loaded the content, as we're looking things up in _content */
+       _audio_mapping.set_from_xml (_content, f.node_child ("AudioMapping"));
+
        _dirty = false;
 
        _playlist->setup (_content);
index 60917ba0949a6bc272fa20d7e321db7d866e1355..d1f04785115c05a15f6ba87bff5913e6dfb67bf1 100644 (file)
@@ -26,6 +26,7 @@
 #include "job.h"
 
 using std::list;
+using std::cout;
 using boost::shared_ptr;
 using boost::weak_ptr;
 using boost::dynamic_pointer_cast;
index 08358c51943d792a50d62dd7448a1148dba71517..4bc5466bcc1f2b98bf0a58a3c6d39a44cb863fc7 100644 (file)
@@ -84,18 +84,18 @@ FilmViewer::FilmViewer (shared_ptr<Film> f, wxWindow* p)
        _play_button->Connect (wxID_ANY, wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, wxCommandEventHandler (FilmViewer::play_clicked), 0, this);
        _timer.Connect (wxID_ANY, wxEVT_TIMER, wxTimerEventHandler (FilmViewer::timer), 0, this);
 
-       set_film (f);
-
-       _player = _film->player ();
+       /* We need a player before we set_film() so that the first frame will be displayed */
+       _player = f->player ();
        _player->disable_audio ();
        _player->disable_video_sync ();
-
        /* Don't disable subtitles here as we may need them, and it's nice to be able to turn them
           on and off without needing obtain a new Player.
        */
        
        _player->Video.connect (bind (&FilmViewer::process_video, this, _1, _2, _3));
 
+       set_film (f);
+
        JobManager::instance()->ActiveJobsChanged.connect (
                bind (&FilmViewer::active_jobs_changed, this, _1)
                );
@@ -392,7 +392,7 @@ FilmViewer::get_frame ()
                _display_frame.reset ();
                return;
        }
-       
+
        try {
                _got_frame = false;
                while (!_got_frame) {