Non-working FFmpeg context cache. attic/optimise-decoder-factory
authorCarl Hetherington <cth@carlh.net>
Thu, 25 Jul 2019 14:27:44 +0000 (15:27 +0100)
committerCarl Hetherington <cth@carlh.net>
Thu, 25 Jul 2019 14:27:44 +0000 (15:27 +0100)
src/lib/encrypted_ecinema_kdm.cc
src/lib/encrypted_ecinema_kdm.h
src/lib/ffmpeg.cc
src/lib/ffmpeg.h

index faea034249a5d8c9294737aad8f408182376db4f..c93a7935e3dc76ddf26c1e432c5490ffe8ad886d 100644 (file)
@@ -110,4 +110,11 @@ EncryptedECinemaKDM::as_xml (boost::filesystem::path path) const
        fclose (f);
 }
 
+bool
+operator== (EncryptedECinemaKDM const & a, EncryptedECinemaKDM const & b)
+{
+       return (a.id() == b.id() && a.name() == b.name() && a.data() == b.data());
+}
+
 #endif
+
index 90e13422a40621bdffe43c6be2477b81badbb038..2251142731aff355f3f43049702df8f6f98d3d0b 100644 (file)
@@ -62,6 +62,8 @@ private:
        dcp::Data _data;
 };
 
+bool operator==(EncryptedECinemaKDM const & a, EncryptedECinemaKDM const & b);
+
 #endif
 
 #endif
index adc5c224c6f4e8ea408287de3a7360f3cb3e25fc..d1e071b0a6102416459c155f98516dadae9d59eb 100644 (file)
@@ -47,18 +47,18 @@ using std::string;
 using std::cout;
 using std::cerr;
 using std::vector;
+using std::list;
 using boost::shared_ptr;
 using boost::optional;
 using dcp::raw_convert;
 using namespace dcpomatic;
 
 boost::mutex FFmpeg::_mutex;
+list<FFmpeg::Cache> FFmpeg::_cache;
 
 FFmpeg::FFmpeg (boost::shared_ptr<const FFmpegContent> c)
        : _ffmpeg_content (c)
-       , _avio_buffer (0)
        , _avio_buffer_size (4096)
-       , _avio_context (0)
        , _format_context (0)
        , _frame (0)
 {
@@ -75,7 +75,6 @@ FFmpeg::~FFmpeg ()
        }
 
        av_frame_free (&_frame);
-       avformat_close_input (&_format_context);
 }
 
 static int
@@ -114,33 +113,64 @@ FFmpeg::setup_general ()
        av_log_set_callback (FFmpeg::ffmpeg_log_callback);
 
        _file_group.set_paths (_ffmpeg_content->paths ());
-       _avio_buffer = static_cast<uint8_t*> (wrapped_av_malloc (_avio_buffer_size));
-       _avio_context = avio_alloc_context (_avio_buffer, _avio_buffer_size, 0, this, avio_read_wrapper, 0, avio_seek_wrapper);
-       _format_context = avformat_alloc_context ();
-       _format_context->pb = _avio_context;
-
-       AVDictionary* options = 0;
-       /* These durations are in microseconds, and represent how far into the content file
-          we will look for streams.
-       */
-       av_dict_set (&options, "analyzeduration", raw_convert<string> (5 * 60 * 1000000).c_str(), 0);
-       av_dict_set (&options, "probesize", raw_convert<string> (5 * 60 * 1000000).c_str(), 0);
+
+       optional<Cache> cache;
+       BOOST_FOREACH (Cache i, _cache) {
+               if (i.paths == _ffmpeg_content->paths()
 #ifdef DCPOMATIC_VARIANT_SWAROOP
-       if (_ffmpeg_content->kdm()) {
-               DecryptedECinemaKDM kdm (_ffmpeg_content->kdm().get(), Config::instance()->decryption_chain()->key().get());
-               av_dict_set (&options, "decryption_key", kdm.key().hex().c_str(), 0);
-       }
+                   && i.kdm == _ffmpeg_content->kdm()
 #endif
-
-       int e = avformat_open_input (&_format_context, 0, 0, &options);
-       if (e < 0) {
-               throw OpenFileError (_ffmpeg_content->path(0).string(), e, true);
+                       ) {
+                       cache = i;
+                       break;
+               }
        }
 
-       if (avformat_find_stream_info (_format_context, 0) < 0) {
-               throw DecodeError (_("could not find stream information"));
-       }
+       if (cache) {
+               cout << "cache hit.\n";
+               _format_context = cache->format_context;
+       } else {
+               cout << "cache miss.\n";
+               /* XXX: avio_buffer and the AVIOContext are never freed */
+               uint8_t* avio_buffer = static_cast<uint8_t*> (wrapped_av_malloc(_avio_buffer_size));
+               _format_context = avformat_alloc_context ();
+               _format_context->pb = avio_alloc_context (avio_buffer, _avio_buffer_size, 0, this, avio_read_wrapper, 0, avio_seek_wrapper);
+
+               AVDictionary* options = 0;
+               /* These durations are in microseconds, and represent how far into the content file
+                  we will look for streams.
+               */
+               av_dict_set (&options, "analyzeduration", raw_convert<string>(5 * 60 * 1000000).c_str(), 0);
+               av_dict_set (&options, "probesize", raw_convert<string>(5 * 60 * 1000000).c_str(), 0);
+#ifdef DCPOMATIC_VARIANT_SWAROOP
+               if (_ffmpeg_content->kdm()) {
+                       DecryptedECinemaKDM kdm (_ffmpeg_content->kdm().get(), Config::instance()->decryption_chain()->key().get());
+                       av_dict_set (&options, "decryption_key", kdm.key().hex().c_str(), 0);
+               }
+#endif
+               
+               int e = avformat_open_input (&_format_context, 0, 0, &options);
+               if (e < 0) {
+                       throw OpenFileError (_ffmpeg_content->path(0), e, true);
+               }
+               
+               if (avformat_find_stream_info (_format_context, 0) < 0) {
+                       throw DecodeError (_("could not find stream information"));
+               }
 
+               _cache.push_back (
+                       Cache(
+                               _ffmpeg_content->paths(),
+#ifdef DCPOMATIC_VARIANT_SWAROOP
+                               _ffmpeg_content->kdm(),
+#else
+                               optional<EncryptedECinemaKDM>()
+#endif
+                               _format_context
+                               )
+                       );
+       }
+       
        /* Find video stream */
 
        optional<int> video_stream_undefined_frame_rate;
index 10517055c26cf842619699a901bc561ff00a8fde..a8e639a6fd4160c42e064564e860d7cda47afd04 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "file_group.h"
 #include "ffmpeg_subtitle_period.h"
+#include "encrypted_ecinema_kdm.h"
 extern "C" {
 #include <libavcodec/avcodec.h>
 }
@@ -61,9 +62,7 @@ protected:
 
        boost::shared_ptr<const FFmpegContent> _ffmpeg_content;
 
-       uint8_t* _avio_buffer;
        int _avio_buffer_size;
-       AVIOContext* _avio_context;
        FileGroup _file_group;
 
        AVFormatContext* _format_context;
@@ -85,6 +84,21 @@ private:
 
        static void ffmpeg_log_callback (void* ptr, int level, const char* fmt, va_list vl);
        static boost::weak_ptr<Log> _ffmpeg_log;
+
+       struct Cache
+       {
+               Cache (std::vector<boost::filesystem::path> paths_, boost::optional<EncryptedECinemaKDM> kdm_, AVFormatContext* format_context_)
+                       : paths(paths_)
+                       , kdm(kdm_)
+                       , format_context(format_context_)
+               {}
+               
+               std::vector<boost::filesystem::path> paths;
+               boost::optional<EncryptedECinemaKDM> kdm;
+               AVFormatContext* format_context;
+       };
+       
+       static std::list<Cache> _cache;
 };
 
 #endif