Slight hack to reduce the chance of config files looking different
[dcpomatic.git] / src / lib / ffmpeg.cc
index 0668f9f37b381707b726cee11086ec4511845bca..f8398763e8185c59b096a7c9484844dedc5400a0 100644 (file)
@@ -27,7 +27,6 @@
 #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"
@@ -38,7 +37,6 @@ extern "C" {
 #include <libswscale/swscale.h>
 }
 #include <boost/algorithm/string.hpp>
-#include <boost/foreach.hpp>
 #include <iostream>
 
 #include "i18n.h"
@@ -47,14 +45,14 @@ using std::string;
 using std::cout;
 using std::cerr;
 using std::vector;
-using boost::shared_ptr;
+using std::shared_ptr;
 using boost::optional;
 using dcp::raw_convert;
 using namespace dcpomatic;
 
 boost::mutex FFmpeg::_mutex;
 
-FFmpeg::FFmpeg (boost::shared_ptr<const FFmpegContent> c)
+FFmpeg::FFmpeg (std::shared_ptr<const FFmpegContent> c)
        : _ffmpeg_content (c)
        , _avio_buffer (0)
        , _avio_buffer_size (4096)
@@ -70,9 +68,11 @@ FFmpeg::~FFmpeg ()
 {
        boost::mutex::scoped_lock lm (_mutex);
 
+DCPOMATIC_DISABLE_WARNINGS
        for (uint32_t i = 0; i < _format_context->nb_streams; ++i) {
                avcodec_close (_format_context->streams[i]->codec);
        }
+DCPOMATIC_ENABLE_WARNINGS
 
        av_frame_free (&_frame);
        avformat_close_input (&_format_context);
@@ -116,22 +116,16 @@ FFmpeg::setup_general ()
        _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);
+       if (!_avio_context) {
+               throw std::bad_alloc ();
+       }
        _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);
-#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);
+       if (!_format_context) {
+               throw std::bad_alloc ();
        }
-#endif
+       _format_context->pb = _avio_context;
 
+       AVDictionary* options = nullptr;
        int e = avformat_open_input (&_format_context, 0, 0, &options);
        if (e < 0) {
                throw OpenFileError (_ffmpeg_content->path(0).string(), e, OpenFileError::READ);
@@ -145,8 +139,9 @@ FFmpeg::setup_general ()
 
        optional<int> video_stream_undefined_frame_rate;
 
+DCPOMATIC_DISABLE_WARNINGS
        for (uint32_t i = 0; i < _format_context->nb_streams; ++i) {
-               AVStream* s = _format_context->streams[i];
+               auto s = _format_context->streams[i];
                if (s->codec->codec_type == AVMEDIA_TYPE_VIDEO && avcodec_find_decoder(s->codec->codec_id)) {
                        if (s->avg_frame_rate.num > 0 && s->avg_frame_rate.den > 0) {
                                /* This is definitely our video stream */
@@ -157,6 +152,7 @@ FFmpeg::setup_general ()
                        }
                }
        }
+DCPOMATIC_ENABLE_WARNINGS
 
        /* Files from iTunes sometimes have two video streams, one with the avg_frame_rate.num and .den set
           to zero.  Only use such a stream if there is no alternative.
@@ -203,13 +199,17 @@ FFmpeg::setup_decoders ()
 {
        boost::mutex::scoped_lock lm (_mutex);
 
+DCPOMATIC_DISABLE_WARNINGS
        for (uint32_t i = 0; i < _format_context->nb_streams; ++i) {
-               AVCodecContext* context = _format_context->streams[i]->codec;
+               auto context = _format_context->streams[i]->codec;
+
+               context->thread_count = 8;
+               context->thread_type = FF_THREAD_FRAME | FF_THREAD_SLICE;
 
                AVCodec* codec = avcodec_find_decoder (context->codec_id);
                if (codec) {
 
-                       AVDictionary* options = 0;
+                       AVDictionary* options = nullptr;
                        /* This option disables decoding of DCA frame footers in our patched version
                           of FFmpeg.  I believe these footers are of no use to us, and they can cause
                           problems when FFmpeg fails to decode them (mantis #352).
@@ -229,13 +229,15 @@ FFmpeg::setup_decoders ()
                        dcpomatic_log->log (String::compose ("No codec found for stream %1", i), LogEntry::TYPE_WARNING);
                }
        }
+DCPOMATIC_ENABLE_WARNINGS
 }
 
+DCPOMATIC_DISABLE_WARNINGS
 AVCodecContext *
 FFmpeg::video_codec_context () const
 {
        if (!_video_stream) {
-               return 0;
+               return nullptr;
        }
 
        return _format_context->streams[_video_stream.get()]->codec;
@@ -245,11 +247,12 @@ AVCodecContext *
 FFmpeg::subtitle_codec_context () const
 {
        if (!_ffmpeg_content->subtitle_stream ()) {
-               return 0;
+               return nullptr;
        }
 
        return _ffmpeg_content->subtitle_stream()->stream(_format_context)->codec;
 }
+DCPOMATIC_ENABLE_WARNINGS
 
 int
 FFmpeg::avio_read (uint8_t* buffer, int const amount)
@@ -270,7 +273,7 @@ FFmpeg::avio_seek (int64_t const pos, int whence)
 FFmpegSubtitlePeriod
 FFmpeg::subtitle_period (AVSubtitle const & sub)
 {
-       ContentTime const packet_time = ContentTime::from_seconds (static_cast<double> (sub.pts) / AV_TIME_BASE);
+       auto const packet_time = ContentTime::from_seconds (static_cast<double> (sub.pts) / AV_TIME_BASE);
 
        if (sub.end_display_time == static_cast<uint32_t> (-1)) {
                /* End time is not known */
@@ -289,7 +292,7 @@ FFmpeg::subtitle_period (AVSubtitle const & sub)
  *  in FFmpeg.
  */
 ContentTime
-FFmpeg::pts_offset (vector<shared_ptr<FFmpegAudioStream> > audio_streams, optional<ContentTime> first_video, double video_frame_rate) const
+FFmpeg::pts_offset (vector<shared_ptr<FFmpegAudioStream>> audio_streams, optional<ContentTime> first_video, double video_frame_rate) const
 {
        /* Audio and video frame PTS values may not start with 0.  We want
           to fiddle them so that:
@@ -307,13 +310,13 @@ FFmpeg::pts_offset (vector<shared_ptr<FFmpegAudioStream> > audio_streams, option
 
        /* First, make one of them start at 0 */
 
-       ContentTime po = ContentTime::min ();
+       auto po = ContentTime::min ();
 
        if (first_video) {
                po = - first_video.get ();
        }
 
-       BOOST_FOREACH (shared_ptr<FFmpegAudioStream> i, audio_streams) {
+       for (auto i: audio_streams) {
                if (i->first_audio) {
                        po = max (po, - i->first_audio.get ());
                }
@@ -329,7 +332,7 @@ FFmpeg::pts_offset (vector<shared_ptr<FFmpegAudioStream> > audio_streams, option
 
        /* Now adjust so that the video pts starts on a frame */
        if (first_video) {
-               ContentTime const fvc = first_video.get() + po;
+               auto const fvc = first_video.get() + po;
                po += fvc.ceil (video_frame_rate) - fvc;
        }