Optimise decoder_factory for DCPDecoder by offering the old decoder
authorCarl Hetherington <cth@carlh.net>
Thu, 25 Jul 2019 10:37:52 +0000 (11:37 +0100)
committerCarl Hetherington <cth@carlh.net>
Thu, 25 Jul 2019 10:37:52 +0000 (11:37 +0100)
(if available) to recover the list of reels from, rather than having
to scan the filesystem again.

src/lib/dcp_decoder.cc
src/lib/dcp_decoder.h
src/lib/decoder_factory.cc
src/lib/decoder_factory.h
src/lib/player.cc
src/wx/text_panel.cc

index 5a72fb2..b694721 100644 (file)
@@ -56,7 +56,7 @@ using boost::dynamic_pointer_cast;
 using boost::optional;
 using namespace dcpomatic;
 
-DCPDecoder::DCPDecoder (shared_ptr<const Film> film, shared_ptr<const DCPContent> c, bool fast)
+DCPDecoder::DCPDecoder (shared_ptr<const Film> film, shared_ptr<const DCPContent> c, bool fast, shared_ptr<DCPDecoder> old)
        : DCP (c)
        , Decoder (film)
        , _decode_referenced (false)
@@ -74,30 +74,35 @@ DCPDecoder::DCPDecoder (shared_ptr<const Film> film, shared_ptr<const DCPContent
                }
        }
 
-       list<shared_ptr<dcp::CPL> > cpl_list = cpls ();
+       if (old) {
+               _reels = old->_reels;
+       } else {
 
-       if (cpl_list.empty()) {
-               throw DCPError (_("No CPLs found in DCP."));
-       }
+               list<shared_ptr<dcp::CPL> > cpl_list = cpls ();
 
-       shared_ptr<dcp::CPL> cpl;
-       BOOST_FOREACH (shared_ptr<dcp::CPL> i, cpl_list) {
-               if (_dcp_content->cpl() && i->id() == _dcp_content->cpl().get()) {
-                       cpl = i;
+               if (cpl_list.empty()) {
+                       throw DCPError (_("No CPLs found in DCP."));
+               }
+
+               shared_ptr<dcp::CPL> cpl;
+               BOOST_FOREACH (shared_ptr<dcp::CPL> i, cpl_list) {
+                       if (_dcp_content->cpl() && i->id() == _dcp_content->cpl().get()) {
+                               cpl = i;
+                       }
                }
-       }
 
-       if (!cpl) {
-               /* No CPL found; probably an old file that doesn't specify it;
-                  just use the first one.
-               */
-               cpl = cpls().front ();
+               if (!cpl) {
+                       /* No CPL found; probably an old file that doesn't specify it;
+                          just use the first one.
+                       */
+                       cpl = cpls().front ();
+               }
+
+               _reels = cpl->reels ();
        }
 
        set_decode_referenced (false);
 
-       _reels = cpl->reels ();
-
        _reel = _reels.begin ();
        _offset = 0;
        get_readers ();
index 0fc598b..f31d280 100644 (file)
@@ -40,7 +40,12 @@ struct dcp_subtitle_within_dcp_test;
 class DCPDecoder : public DCP, public Decoder
 {
 public:
-       DCPDecoder (boost::shared_ptr<const Film> film, boost::shared_ptr<const DCPContent>, bool fast);
+       DCPDecoder (
+               boost::shared_ptr<const Film> film,
+               boost::shared_ptr<const DCPContent>,
+               bool fast,
+               boost::shared_ptr<DCPDecoder> old = boost::shared_ptr<DCPDecoder>()
+               );
 
        std::list<boost::shared_ptr<dcp::Reel> > reels () const {
                return _reels;
index 4b2a594..5d75895 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2016 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2016-2019 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
 #include "dcp_subtitle_decoder.h"
 #include "video_mxf_content.h"
 #include "video_mxf_decoder.h"
+#include "timer.h"
 #include <boost/foreach.hpp>
 
 using std::list;
 using boost::shared_ptr;
 using boost::dynamic_pointer_cast;
 
+template <class T>
+shared_ptr<T>
+maybe_cast (shared_ptr<Decoder> d)
+{
+       if (!d) {
+               return shared_ptr<T> ();
+       }
+       return dynamic_pointer_cast<T> (d);
+}
+
+/** @param old_decoder A `used' decoder that has been previously made for this piece of content, or 0 */
 shared_ptr<Decoder>
-decoder_factory (shared_ptr<const Film> film, shared_ptr<const Content> content, bool fast)
+decoder_factory (shared_ptr<const Film> film, shared_ptr<const Content> content, bool fast, shared_ptr<Decoder> old_decoder)
 {
        shared_ptr<const FFmpegContent> fc = dynamic_pointer_cast<const FFmpegContent> (content);
        if (fc) {
@@ -47,7 +59,7 @@ decoder_factory (shared_ptr<const Film> film, shared_ptr<const Content> content,
        shared_ptr<const DCPContent> dc = dynamic_pointer_cast<const DCPContent> (content);
        if (dc) {
                try {
-                       return shared_ptr<Decoder> (new DCPDecoder(film, dc, fast));
+                       return shared_ptr<Decoder> (new DCPDecoder(film, dc, fast, maybe_cast<DCPDecoder>(old_decoder)));
                } catch (KDMError& e) {
                        /* This will be found and reported to the user when the content is examined */
                        return shared_ptr<Decoder>();
index d4e39da..cb145c8 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2016 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2016-2019 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
@@ -23,5 +23,6 @@ class ImageDecoder;
 extern boost::shared_ptr<Decoder> decoder_factory (
        boost::shared_ptr<const Film> film,
        boost::shared_ptr<const Content> content,
-       bool fast
+       bool fast,
+       boost::shared_ptr<Decoder> old_decoder
        );
index 08e138f..acde910 100644 (file)
@@ -138,6 +138,7 @@ have_audio (shared_ptr<Piece> piece)
 void
 Player::setup_pieces_unlocked ()
 {
+       list<shared_ptr<Piece> > old_pieces = _pieces;
        _pieces.clear ();
 
        delete _shuffler;
@@ -155,7 +156,15 @@ Player::setup_pieces_unlocked ()
                        continue;
                }
 
-               shared_ptr<Decoder> decoder = decoder_factory (_film, i, _fast);
+               shared_ptr<Decoder> old_decoder;
+               BOOST_FOREACH (shared_ptr<Piece> j, old_pieces) {
+                       if (j->content == i) {
+                               old_decoder = j->decoder;
+                               break;
+                       }
+               }
+
+               shared_ptr<Decoder> decoder = decoder_factory (_film, i, _fast, old_decoder);
                FrameRateChange frc (_film, i);
 
                if (!decoder) {
index 7c48831..98398aa 100644 (file)
@@ -667,7 +667,7 @@ TextPanel::text_view_clicked ()
        ContentList c = _parent->selected_text ();
        DCPOMATIC_ASSERT (c.size() == 1);
 
-       shared_ptr<Decoder> decoder = decoder_factory (_parent->film(), c.front(), false);
+       shared_ptr<Decoder> decoder = decoder_factory (_parent->film(), c.front(), false, shared_ptr<Decoder>());
 
        if (decoder) {
                _text_view = new TextView (this, _parent->film(), c.front(), c.front()->text_of_original_type(_original_type), decoder, _parent->film_viewer());