X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2Flib%2Fffmpeg.cc;h=eb131d434b24572c423cd6ada89bb5759b0d6b0f;hb=4a6d23119eceeba42abe0f2615cfaac92e74c83c;hp=0e70d9c6f89350f12e5e1ffba1573f2d3af5aed2;hpb=e7440b69bf0dc486314544b0e1fb5ac2d45a9a8d;p=dcpomatic.git diff --git a/src/lib/ffmpeg.cc b/src/lib/ffmpeg.cc index 0e70d9c6f..eb131d434 100644 --- a/src/lib/ffmpeg.cc +++ b/src/lib/ffmpeg.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2013-2019 Carl Hetherington + Copyright (C) 2013-2021 Carl Hetherington This file is part of DCP-o-matic. @@ -18,6 +18,7 @@ */ + #include "ffmpeg.h" #include "ffmpeg_content.h" #include "film.h" @@ -41,6 +42,7 @@ extern "C" { #include "i18n.h" + using std::string; using std::cout; using std::cerr; @@ -50,20 +52,18 @@ using boost::optional; using dcp::raw_convert; using namespace dcpomatic; + boost::mutex FFmpeg::_mutex; + FFmpeg::FFmpeg (std::shared_ptr c) : _ffmpeg_content (c) - , _avio_buffer (0) - , _avio_buffer_size (4096) - , _avio_context (0) - , _format_context (0) - , _frame (0) { setup_general (); setup_decoders (); } + FFmpeg::~FFmpeg () { boost::mutex::scoped_lock lm (_mutex); @@ -78,18 +78,21 @@ DCPOMATIC_ENABLE_WARNINGS avformat_close_input (&_format_context); } + static int avio_read_wrapper (void* data, uint8_t* buffer, int amount) { return reinterpret_cast(data)->avio_read (buffer, amount); } + static int64_t avio_seek_wrapper (void* data, int64_t offset, int whence) { return reinterpret_cast(data)->avio_seek (offset, whence); } + void FFmpeg::ffmpeg_log_callback (void* ptr, int level, const char* fmt, va_list vl) { @@ -105,6 +108,7 @@ FFmpeg::ffmpeg_log_callback (void* ptr, int level, const char* fmt, va_list vl) dcpomatic_log->log (String::compose ("FFmpeg: %1", str), LogEntry::TYPE_GENERAL); } + void FFmpeg::setup_general () { @@ -114,7 +118,7 @@ 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_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); if (!_avio_context) { throw std::bad_alloc (); @@ -194,6 +198,7 @@ DCPOMATIC_ENABLE_WARNINGS } } + void FFmpeg::setup_decoders () { @@ -203,6 +208,9 @@ DCPOMATIC_DISABLE_WARNINGS for (uint32_t i = 0; i < _format_context->nb_streams; ++i) { 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) { @@ -229,6 +237,7 @@ DCPOMATIC_DISABLE_WARNINGS DCPOMATIC_ENABLE_WARNINGS } + DCPOMATIC_DISABLE_WARNINGS AVCodecContext * FFmpeg::video_codec_context () const @@ -240,10 +249,11 @@ FFmpeg::video_codec_context () const return _format_context->streams[_video_stream.get()]->codec; } + AVCodecContext * FFmpeg::subtitle_codec_context () const { - if (!_ffmpeg_content->subtitle_stream ()) { + if (!_ffmpeg_content->subtitle_stream()) { return nullptr; } @@ -251,12 +261,14 @@ FFmpeg::subtitle_codec_context () const } DCPOMATIC_ENABLE_WARNINGS + int FFmpeg::avio_read (uint8_t* buffer, int const amount) { return _file_group.read (buffer, amount); } + int64_t FFmpeg::avio_seek (int64_t const pos, int whence) { @@ -267,6 +279,7 @@ FFmpeg::avio_seek (int64_t const pos, int whence) return _file_group.seek (pos, whence); } + FFmpegSubtitlePeriod FFmpeg::subtitle_period (AVSubtitle const & sub) { @@ -283,6 +296,7 @@ FFmpeg::subtitle_period (AVSubtitle const & sub) ); } + /** Compute the pts offset to use given a set of audio streams and some video details. * Sometimes these parameters will have just been determined by an Examiner, sometimes * they will have been retrieved from a piece of Content, hence the need for this method