Fix crash when loading old state files.
authorCarl Hetherington <cth@carlh.net>
Thu, 2 Jun 2016 20:14:24 +0000 (21:14 +0100)
committerCarl Hetherington <cth@carlh.net>
Thu, 2 Jun 2016 20:14:24 +0000 (21:14 +0100)
ChangeLog
src/lib/audio_content.cc
src/lib/audio_content.h
src/lib/dcp_content.cc
src/lib/ffmpeg_content.cc
src/lib/film.cc
src/lib/subtitle_content.cc

index b49063e769e3a69d06fda3b3f7a304c34fb6acea..3364fb76da6189925ff3b37a57443da469926375 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,7 @@
 2016-06-02  Carl Hetherington  <cth@carlh.net>
 
+       * Fix crash when loading projects from pre-2.8.5.
+
        * Fix broken content properties under translation.
 
        * Version 2.8.7 released.
index 2b402991cf3696d6a8f303369c8e1f16c624d427..7a4ca63a90f7703214e8403b3e1907a80d1a0916 100644 (file)
@@ -58,8 +58,19 @@ AudioContent::AudioContent (Content* parent)
 }
 
 shared_ptr<AudioContent>
-AudioContent::from_xml (Content* parent, cxml::ConstNodePtr node)
+AudioContent::from_xml (Content* parent, cxml::ConstNodePtr node, int version)
 {
+       if (version < 34) {
+               /* With old metadata FFmpeg content has the audio-related tags even with no
+                  audio streams, so check for that.
+               */
+               if (node->string_child("Type") == "FFmpeg" && node->node_children("AudioStream").empty()) {
+                       return shared_ptr<AudioContent> ();
+               }
+
+               /* Otherwise we can drop through to the newer logic */
+       }
+
        if (!node->optional_number_child<double> ("AudioGain")) {
                return shared_ptr<AudioContent> ();
        }
index da00bfeb1eff35765751b2d09434a76f3d733d9e..92491bf89414745648a3658b6a022fe01fd06139 100644 (file)
@@ -82,7 +82,7 @@ public:
 
        void add_properties (std::list<UserProperty> &) const;
 
-       static boost::shared_ptr<AudioContent> from_xml (Content* parent, cxml::ConstNodePtr);
+       static boost::shared_ptr<AudioContent> from_xml (Content* parent, cxml::ConstNodePtr, int version);
 
 private:
 
index d23b4e351db8b1a2abfc847185f11e12833bbf4d..b46b3dab7abdd216425865bba6bebcf1264ce907 100644 (file)
@@ -75,7 +75,7 @@ DCPContent::DCPContent (shared_ptr<const Film> film, cxml::ConstNodePtr node, in
        : Content (film, node)
 {
        video = VideoContent::from_xml (this, node, version);
-       audio = AudioContent::from_xml (this, node);
+       audio = AudioContent::from_xml (this, node, version);
        subtitle = SubtitleContent::from_xml (this, node, version);
 
        audio->set_stream (
index 0f66180d0a6cd80da8f7d4ff16e99e247d8b3f27..b2b67e5656c13e1a3d928b43a5f92e1e19b939c7 100644 (file)
@@ -73,7 +73,7 @@ FFmpegContent::FFmpegContent (shared_ptr<const Film> film, cxml::ConstNodePtr no
        : Content (film, node)
 {
        video = VideoContent::from_xml (this, node, version);
-       audio = AudioContent::from_xml (this, node);
+       audio = AudioContent::from_xml (this, node, version);
        subtitle = SubtitleContent::from_xml (this, node, version);
 
        list<cxml::NodePtr> c = node->node_children ("SubtitleStream");
index 6b3625d9e727d34faec4effa67da7304aa1d832f..c8dfdfe63b6d87d46fd7a602713b66f04ed01c32 100644 (file)
@@ -108,8 +108,11 @@ using boost::is_any_of;
  *
  * 32 -> 33
  * Changed <Period> to <Subtitle> in FFmpegSubtitleStream
+ * 33 -> 34
+ * Content only contains audio/subtitle-related tags if those things
+ * are present.
  */
-int const Film::current_state_version = 33;
+int const Film::current_state_version = 34;
 
 /** Construct a Film object in a given directory.
  *
index a45b0a24f5a92f08eb10762e28ad4bb8d0a0624e..5b3b453b6eaf12d7614c0a3b6beb2f2b87da3bdb 100644 (file)
@@ -69,6 +69,17 @@ SubtitleContent::SubtitleContent (Content* parent)
 shared_ptr<SubtitleContent>
 SubtitleContent::from_xml (Content* parent, cxml::ConstNodePtr node, int version)
 {
+       if (version < 34) {
+               /* With old metadata FFmpeg content has the subtitle-related tags even with no
+                  subtitle streams, so check for that.
+               */
+               if (node->string_child("Type") == "FFmpeg" && node->node_children("SubtitleStream").empty()) {
+                       return shared_ptr<SubtitleContent> ();
+               }
+
+               /* Otherwise we can drop through to the newer logic */
+       }
+
        if (!node->optional_number_child<double>("SubtitleXOffset") && !node->optional_number_child<double>("SubtitleOffset")) {
                return shared_ptr<SubtitleContent> ();
        }