From: Carl Hetherington Date: Thu, 25 Jul 2019 14:27:44 +0000 (+0100) Subject: Non-working FFmpeg context cache. X-Git-Url: https://main.carlh.net/gitweb/?p=dcpomatic.git;a=commitdiff_plain;h=c75f8fceec58f2b9ed36f78c8ca02ce1f5f2625f Non-working FFmpeg context cache. --- diff --git a/src/lib/encrypted_ecinema_kdm.cc b/src/lib/encrypted_ecinema_kdm.cc index faea03424..c93a7935e 100644 --- a/src/lib/encrypted_ecinema_kdm.cc +++ b/src/lib/encrypted_ecinema_kdm.cc @@ -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 + diff --git a/src/lib/encrypted_ecinema_kdm.h b/src/lib/encrypted_ecinema_kdm.h index 90e13422a..225114273 100644 --- a/src/lib/encrypted_ecinema_kdm.h +++ b/src/lib/encrypted_ecinema_kdm.h @@ -62,6 +62,8 @@ private: dcp::Data _data; }; +bool operator==(EncryptedECinemaKDM const & a, EncryptedECinemaKDM const & b); + #endif #endif diff --git a/src/lib/ffmpeg.cc b/src/lib/ffmpeg.cc index adc5c224c..d1e071b0a 100644 --- a/src/lib/ffmpeg.cc +++ b/src/lib/ffmpeg.cc @@ -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::FFmpeg (boost::shared_ptr 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 (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 (5 * 60 * 1000000).c_str(), 0); - av_dict_set (&options, "probesize", raw_convert (5 * 60 * 1000000).c_str(), 0); + + optional 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 (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(5 * 60 * 1000000).c_str(), 0); + av_dict_set (&options, "probesize", raw_convert(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() +#endif + _format_context + ) + ); + } + /* Find video stream */ optional video_stream_undefined_frame_rate; diff --git a/src/lib/ffmpeg.h b/src/lib/ffmpeg.h index 10517055c..a8e639a6f 100644 --- a/src/lib/ffmpeg.h +++ b/src/lib/ffmpeg.h @@ -23,6 +23,7 @@ #include "file_group.h" #include "ffmpeg_subtitle_period.h" +#include "encrypted_ecinema_kdm.h" extern "C" { #include } @@ -61,9 +62,7 @@ protected: boost::shared_ptr _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 _ffmpeg_log; + + struct Cache + { + Cache (std::vector paths_, boost::optional kdm_, AVFormatContext* format_context_) + : paths(paths_) + , kdm(kdm_) + , format_context(format_context_) + {} + + std::vector paths; + boost::optional kdm; + AVFormatContext* format_context; + }; + + static std::list _cache; }; #endif