Don't say we're encoding at 0fps when we're waiting for the timing history to stablise.
[dcpomatic.git] / src / lib / ffmpeg.cc
index 3bd08e84a6ea7c1be2f27426e1755171dce484d4..0668f9f37b381707b726cee11086ec4511845bca 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2013-2016 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2013-2019 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
 #include "exceptions.h"
 #include "util.h"
 #include "log.h"
+#include "dcpomatic_log.h"
 #include "ffmpeg_subtitle_stream.h"
 #include "ffmpeg_audio_stream.h"
+#include "decrypted_ecinema_kdm.h"
 #include "digester.h"
 #include "compose.hpp"
+#include "config.h"
 #include <dcp/raw_convert.h>
 extern "C" {
 #include <libavcodec/avcodec.h>
@@ -47,9 +50,9 @@ using std::vector;
 using boost::shared_ptr;
 using boost::optional;
 using dcp::raw_convert;
+using namespace dcpomatic;
 
 boost::mutex FFmpeg::_mutex;
-boost::weak_ptr<Log> FFmpeg::_ffmpeg_log;
 
 FFmpeg::FFmpeg (boost::shared_ptr<const FFmpegContent> c)
        : _ffmpeg_content (c)
@@ -97,14 +100,9 @@ FFmpeg::ffmpeg_log_callback (void* ptr, int level, const char* fmt, va_list vl)
        char line[1024];
        static int prefix = 0;
        av_log_format_line (ptr, level, fmt, vl, line, sizeof (line), &prefix);
-       shared_ptr<Log> log = _ffmpeg_log.lock ();
-       if (log) {
-               string str (line);
-               boost::algorithm::trim (str);
-               log->log (String::compose ("FFmpeg: %1", str), LogEntry::TYPE_GENERAL);
-       } else {
-               cerr << line;
-       }
+       string str (line);
+       boost::algorithm::trim (str);
+       dcpomatic_log->log (String::compose ("FFmpeg: %1", str), LogEntry::TYPE_GENERAL);
 }
 
 void
@@ -127,13 +125,16 @@ FFmpeg::setup_general ()
        */
        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);
-       if (_ffmpeg_content->decryption_key()) {
-               av_dict_set (&options, "decryption_key", _ffmpeg_content->decryption_key()->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).string(), e, true);
+               throw OpenFileError (_ffmpeg_content->path(0).string(), e, OpenFileError::READ);
        }
 
        if (avformat_find_stream_info (_format_context, 0) < 0) {
@@ -164,6 +165,11 @@ FFmpeg::setup_general ()
                _video_stream = video_stream_undefined_frame_rate.get();
        }
 
+       /* Ignore video streams with crazy frame rates.  These are usually things like album art on MP3s. */
+       if (_video_stream && av_q2d(av_guess_frame_rate(_format_context, _format_context->streams[_video_stream.get()], 0)) > 1000) {
+               _video_stream = optional<int>();
+       }
+
        /* Hack: if the AVStreams have duplicate IDs, replace them with our
           own.  We use the IDs so that we can cope with VOBs, in which streams
           move about in index but remain with the same ID in different
@@ -213,6 +219,8 @@ FFmpeg::setup_decoders ()
                           https://trac.ffmpeg.org/ticket/5681
                        */
                        av_dict_set_int (&options, "strict", FF_COMPLIANCE_EXPERIMENTAL, 0);
+                       /* Enable following of links in files */
+                       av_dict_set_int (&options, "enable_drefs", 1, 0);
 
                        if (avcodec_open2 (context, codec, &options) < 0) {
                                throw DecodeError (N_("could not open decoder"));