diff -up chromium-67.0.3396.48/content/renderer/media/webrtc/peer_connection_dependency_factory.cc.ffmpeg33 chromium-67.0.3396.48/content/renderer/media/webrtc/peer_connection_dependency_factory.cc --- chromium-67.0.3396.48/content/renderer/media/webrtc/peer_connection_dependency_factory.cc.ffmpeg33 2018-05-21 13:00:57.484186164 +0200 +++ chromium-67.0.3396.48/content/renderer/media/webrtc/peer_connection_dependency_factory.cc 2018-05-21 13:00:10.844131078 +0200 @@ -52,6 +52,7 @@ #include "crypto/openssl_util.h" #include "jingle/glue/thread_wrapper.h" #include "media/base/media_permission.h" +#include "media/filters/ffmpeg_glue.h" #include "media/media_buildflags.h" #include "media/video/gpu_video_accelerator_factories.h" #include "third_party/blink/public/platform/web_media_constraints.h" @@ -158,8 +159,12 @@ void PeerConnectionDependencyFactory::Cr #if BUILDFLAG(RTC_USE_H264) && BUILDFLAG(ENABLE_FFMPEG_VIDEO_DECODERS) // Building /w |rtc_use_h264|, is the corresponding run-time feature enabled? - if (!base::FeatureList::IsEnabled(kWebRtcH264WithOpenH264FFmpeg)) { - // Feature is to be disabled. + if (base::FeatureList::IsEnabled(kWebRtcH264WithOpenH264FFmpeg)) { + // |H264DecoderImpl| may be used which depends on FFmpeg, therefore we need + // to initialize FFmpeg before going further. + media::FFmpegGlue::InitializeFFmpeg(); + } else { + // Feature is to be disabled, no need to make sure FFmpeg is initialized. webrtc::DisableRtcUseH264(); } #else diff -up chromium-67.0.3396.48/media/cdm/library_cdm/clear_key_cdm/clear_key_cdm.cc.ffmpeg33 chromium-67.0.3396.48/media/cdm/library_cdm/clear_key_cdm/clear_key_cdm.cc --- chromium-67.0.3396.48/media/cdm/library_cdm/clear_key_cdm/clear_key_cdm.cc.ffmpeg33 2018-05-21 12:59:42.884097603 +0200 +++ chromium-67.0.3396.48/media/cdm/library_cdm/clear_key_cdm/clear_key_cdm.cc 2018-05-21 13:00:10.844131078 +0200 @@ -38,6 +38,14 @@ #include "media/base/media.h" #include "media/cdm/library_cdm/clear_key_cdm/ffmpeg_cdm_audio_decoder.h" +// Include FFmpeg avformat.h for av_register_all(). +extern "C" { +// Temporarily disable possible loss of data warning. +MSVC_PUSH_DISABLE_WARNING(4244); +#include <libavformat/avformat.h> +MSVC_POP_WARNING(); +} // extern "C" + #if !defined COMPONENT_BUILD static base::AtExitManager g_at_exit_manager; #endif @@ -226,6 +234,7 @@ void INITIALIZE_CDM_MODULE() { DVLOG(1) << __func__; #if defined(CLEAR_KEY_CDM_USE_FFMPEG_DECODER) media::InitializeMediaLibrary(); + av_register_all(); #endif // CLEAR_KEY_CDM_USE_FFMPEG_DECODER g_is_cdm_module_initialized = true; diff -up chromium-67.0.3396.48/media/ffmpeg/ffmpeg_common_unittest.cc.ffmpeg33 chromium-67.0.3396.48/media/ffmpeg/ffmpeg_common_unittest.cc --- chromium-67.0.3396.48/media/ffmpeg/ffmpeg_common_unittest.cc.ffmpeg33 2018-05-21 12:59:42.884097603 +0200 +++ chromium-67.0.3396.48/media/ffmpeg/ffmpeg_common_unittest.cc 2018-05-21 13:00:10.844131078 +0200 @@ -25,7 +25,9 @@ namespace media { class FFmpegCommonTest : public testing::Test { public: - FFmpegCommonTest() {} + FFmpegCommonTest() { + FFmpegGlue::InitializeFFmpeg(); + } ~FFmpegCommonTest() override = default; }; diff -up chromium-67.0.3396.48/media/filters/ffmpeg_audio_decoder.cc.ffmpeg33 chromium-67.0.3396.48/media/filters/ffmpeg_audio_decoder.cc --- chromium-67.0.3396.48/media/filters/ffmpeg_audio_decoder.cc.ffmpeg33 2018-05-21 12:59:42.884097603 +0200 +++ chromium-67.0.3396.48/media/filters/ffmpeg_audio_decoder.cc 2018-05-21 13:00:10.844131078 +0200 @@ -80,6 +80,8 @@ void FFmpegAudioDecoder::Initialize( return; } + FFmpegGlue::InitializeFFmpeg(); + if (!ConfigureDecoder(config)) { av_sample_format_ = 0; bound_init_cb.Run(false); diff -up chromium-67.0.3396.48/media/filters/ffmpeg_glue.cc.ffmpeg33 chromium-67.0.3396.48/media/filters/ffmpeg_glue.cc --- chromium-67.0.3396.48/media/filters/ffmpeg_glue.cc.ffmpeg33 2018-05-21 12:59:42.884097603 +0200 +++ chromium-67.0.3396.48/media/filters/ffmpeg_glue.cc 2018-05-21 13:00:10.844131078 +0200 @@ -63,7 +63,13 @@ static int64_t AVIOSeekOperation(void* o return new_offset; } +void FFmpegGlue::InitializeFFmpeg() { + av_register_all(); +} + FFmpegGlue::FFmpegGlue(FFmpegURLProtocol* protocol) { + InitializeFFmpeg(); + // Initialize an AVIOContext using our custom read and seek operations. Don't // keep pointers to the buffer since FFmpeg may reallocate it on the fly. It // will be cleaned up diff -up chromium-67.0.3396.48/media/filters/ffmpeg_glue.h.ffmpeg33 chromium-67.0.3396.48/media/filters/ffmpeg_glue.h --- chromium-67.0.3396.48/media/filters/ffmpeg_glue.h.ffmpeg33 2018-05-21 12:59:42.884097603 +0200 +++ chromium-67.0.3396.48/media/filters/ffmpeg_glue.h 2018-05-21 13:00:10.844131078 +0200 @@ -17,6 +17,10 @@ // // The glue in turn processes those read and seek requests using the // FFmpegURLProtocol provided during construction. +// +// FFmpegGlue is also responsible for initializing FFmpeg, which is done once +// per process. Initialization includes: turning off log messages, registering +// a lock manager, and finally registering all demuxers and codecs. #ifndef MEDIA_FILTERS_FFMPEG_GLUE_H_ #define MEDIA_FILTERS_FFMPEG_GLUE_H_ @@ -59,6 +63,8 @@ class MEDIA_EXPORT FFmpegURLProtocol { class MEDIA_EXPORT FFmpegGlue { public: + static void InitializeFFmpeg(); + // See file documentation for usage. |protocol| must outlive FFmpegGlue. explicit FFmpegGlue(FFmpegURLProtocol* protocol); ~FFmpegGlue(); diff -up chromium-67.0.3396.48/media/filters/ffmpeg_video_decoder.cc.ffmpeg33 chromium-67.0.3396.48/media/filters/ffmpeg_video_decoder.cc --- chromium-67.0.3396.48/media/filters/ffmpeg_video_decoder.cc.ffmpeg33 2018-05-21 12:59:42.884097603 +0200 +++ chromium-67.0.3396.48/media/filters/ffmpeg_video_decoder.cc 2018-05-21 13:00:10.844131078 +0200 @@ -28,6 +28,7 @@ #include "media/base/video_util.h" #include "media/ffmpeg/ffmpeg_common.h" #include "media/ffmpeg/ffmpeg_decoding_loop.h" +#include "media/filters/ffmpeg_glue.h" namespace media { @@ -110,6 +111,7 @@ static void ReleaseVideoBufferImpl(void* // static bool FFmpegVideoDecoder::IsCodecSupported(VideoCodec codec) { + FFmpegGlue::InitializeFFmpeg(); return avcodec_find_decoder(VideoCodecToCodecID(codec)) != nullptr; } @@ -252,6 +254,8 @@ void FFmpegVideoDecoder::Initialize( return; } + FFmpegGlue::InitializeFFmpeg(); + if (!ConfigureDecoder(config, low_delay)) { bound_init_cb.Run(false); return; diff -up chromium-67.0.3396.48/media/filters/ffmpeg_video_decoder_unittest.cc.ffmpeg33 chromium-67.0.3396.48/media/filters/ffmpeg_video_decoder_unittest.cc --- chromium-67.0.3396.48/media/filters/ffmpeg_video_decoder_unittest.cc.ffmpeg33 2018-05-21 12:59:42.884097603 +0200 +++ chromium-67.0.3396.48/media/filters/ffmpeg_video_decoder_unittest.cc 2018-05-21 13:00:10.844131078 +0200 @@ -29,6 +29,7 @@ #include "media/base/video_frame.h" #include "media/base/video_util.h" #include "media/ffmpeg/ffmpeg_common.h" +#include "media/filters/ffmpeg_glue.h" #include "media/filters/ffmpeg_video_decoder.h" #include "testing/gmock/include/gmock/gmock.h" @@ -62,6 +63,8 @@ class FFmpegVideoDecoderTest : public te : decoder_(new FFmpegVideoDecoder(&media_log_)), decode_cb_(base::Bind(&FFmpegVideoDecoderTest::DecodeDone, base::Unretained(this))) { + FFmpegGlue::InitializeFFmpeg(); + // Initialize various test buffers. frame_buffer_.reset(new uint8_t[kCodedSize.GetArea()]); end_of_stream_buffer_ = DecoderBuffer::CreateEOSBuffer(); diff -up chromium-67.0.3396.48/media/gpu/video_encode_accelerator_unittest.cc.ffmpeg33 chromium-67.0.3396.48/media/gpu/video_encode_accelerator_unittest.cc --- chromium-67.0.3396.48/media/gpu/video_encode_accelerator_unittest.cc.ffmpeg33 2018-05-21 12:59:42.884097603 +0200 +++ chromium-67.0.3396.48/media/gpu/video_encode_accelerator_unittest.cc 2018-05-21 13:00:10.844131078 +0200 @@ -44,6 +44,7 @@ #include "media/base/test_data_util.h" #include "media/base/video_decoder.h" #include "media/base/video_frame.h" +#include "media/filters/ffmpeg_glue.h" #include "media/filters/ffmpeg_video_decoder.h" #include "media/filters/ivf_parser.h" #include "media/gpu/buildflags.h" @@ -784,6 +785,7 @@ VideoFrameQualityValidator::VideoFrameQu void VideoFrameQualityValidator::Initialize(const gfx::Size& coded_size, const gfx::Rect& visible_size) { DCHECK(thread_checker_.CalledOnValidThread()); + FFmpegGlue::InitializeFFmpeg(); gfx::Size natural_size(visible_size.size()); // The default output format of ffmpeg video decoder is YV12.