Catch failures to read missing DCPs in various places.
authorCarl Hetherington <cth@carlh.net>
Wed, 16 Nov 2016 00:19:29 +0000 (00:19 +0000)
committerCarl Hetherington <cth@carlh.net>
Wed, 16 Nov 2016 00:19:29 +0000 (00:19 +0000)
ChangeLog
src/lib/dcp_content.cc
src/wx/content_menu.cc

index 5ae17f323fed04f3cd37c7da4b066793c027ad71..45552c3de6b38edb0267c6bb204d846ff804db4e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2016-11-16  Carl Hetherington  <cth@carlh.net>
+
+       * Fix various crahes in films with missing DCP content.
+
 2016-11-15  Carl Hetherington  <cth@carlh.net>
 
        * Fix error on using the CPL selection menu on OS X.
index dc32a243e89245221ec37b9906626bf31a39d6b3..8c1b2d8a1994e9019196f51b84014b21b8a8bcaf 100644 (file)
@@ -428,10 +428,18 @@ DCPContent::can_reference (function<shared_ptr<ContentPart> (shared_ptr<const Co
 
        list<DCPTimePeriod> const fr = film()->reels ();
 
+       list<DCPTimePeriod> reel_list;
+       try {
+               reel_list = reels ();
+       } catch (dcp::DCPReadError) {
+               /* We couldn't read the DCP; it's probably missing */
+               return false;
+       }
+
        /* fr must contain reels().  It can also contain other reels, but it must at
           least contain reels().
        */
-       BOOST_FOREACH (DCPTimePeriod i, reels()) {
+       BOOST_FOREACH (DCPTimePeriod i, reel_list) {
                if (find (fr.begin(), fr.end(), i) == fr.end ()) {
                        why_not.push_back (_("The reel lengths in the film differ from those in the DCP; set the reel mode to 'split by video content'."));
                        return false;
@@ -461,8 +469,15 @@ DCPContent::can_reference_video (list<string>& why_not) const
 bool
 DCPContent::can_reference_audio (list<string>& why_not) const
 {
-        DCPDecoder decoder (shared_from_this(), film()->log());
-        BOOST_FOREACH (shared_ptr<dcp::Reel> i, decoder.reels()) {
+       shared_ptr<DCPDecoder> decoder;
+       try {
+               decoder.reset (new DCPDecoder (shared_from_this(), film()->log()));
+       } catch (dcp::DCPReadError) {
+               /* We couldn't read the DCP, so it's probably missing */
+               return false;
+       }
+
+        BOOST_FOREACH (shared_ptr<dcp::Reel> i, decoder->reels()) {
                 if (!i->main_sound()) {
                         why_not.push_back (_("The DCP does not have sound in all reels."));
                         return false;
@@ -475,8 +490,15 @@ DCPContent::can_reference_audio (list<string>& why_not) const
 bool
 DCPContent::can_reference_subtitle (list<string>& why_not) const
 {
-        DCPDecoder decoder (shared_from_this(), film()->log());
-        BOOST_FOREACH (shared_ptr<dcp::Reel> i, decoder.reels()) {
+       shared_ptr<DCPDecoder> decoder;
+       try {
+               decoder.reset (new DCPDecoder (shared_from_this(), film()->log()));
+       } catch (dcp::DCPReadError) {
+               /* We couldn't read the DCP, so it's probably missing */
+               return false;
+       }
+
+        BOOST_FOREACH (shared_ptr<dcp::Reel> i, decoder->reels()) {
                 if (!i->main_subtitle()) {
                         why_not.push_back (_("The DCP does not have subtitles in all reels."));
                         return false;
index 2d49ac4be583ee34e1ae45ffd7a11a7d3d23cd51..14632d984797f83cbcc3949e6dfb62859d615591 100644 (file)
@@ -36,6 +36,7 @@
 #include "lib/ffmpeg_content.h"
 #include "lib/audio_content.h"
 #include <dcp/cpl.h>
+#include <dcp/exceptions.h>
 #include <wx/wx.h>
 #include <wx/dirdlg.h>
 #include <boost/foreach.hpp>
@@ -132,21 +133,25 @@ ContentMenu::popup (weak_ptr<Film> film, ContentList c, TimelineContentViewList
                if (dcp) {
                        _kdm->Enable (dcp->encrypted ());
                        _ov->Enable (dcp->needs_assets ());
-                       DCPExaminer ex (dcp);
-                       list<shared_ptr<dcp::CPL> > cpls = ex.cpls ();
-                       _choose_cpl->Enable (cpls.size() > 1);
-                       /* We can't have 0 as a menu item ID on OS X */
-                       int id = 1;
-                       BOOST_FOREACH (shared_ptr<dcp::CPL> i, cpls) {
-                               wxMenuItem* item = _cpl_menu->AppendCheckItem (
-                                       id++,
-                                       wxString::Format (
-                                               "%s (%s)",
-                                               std_to_wx(i->annotation_text()).data(),
-                                               std_to_wx(i->id()).data()
-                                               )
-                                       );
-                               item->Check (dcp->cpl() && dcp->cpl() == i->id());
+                       try {
+                               DCPExaminer ex (dcp);
+                               list<shared_ptr<dcp::CPL> > cpls = ex.cpls ();
+                               _choose_cpl->Enable (cpls.size() > 1);
+                               /* We can't have 0 as a menu item ID on OS X */
+                               int id = 1;
+                               BOOST_FOREACH (shared_ptr<dcp::CPL> i, cpls) {
+                                       wxMenuItem* item = _cpl_menu->AppendCheckItem (
+                                               id++,
+                                               wxString::Format (
+                                                       "%s (%s)",
+                                                       std_to_wx(i->annotation_text()).data(),
+                                                       std_to_wx(i->id()).data()
+                                                       )
+                                               );
+                                       item->Check (dcp->cpl() && dcp->cpl() == i->id());
+                               }
+                       } catch (dcp::DCPReadError) {
+                               /* The DCP is probably missing */
                        }
                } else {
                        _kdm->Enable (false);