diff --git a/dom/media/platforms/ffmpeg/FFmpegDataDecoder.cpp b/dom/media/platforms/ffmpeg/FFmpegDataDecoder.cpp index 8e8262317..06547ae4c 100644 --- a/dom/media/platforms/ffmpeg/FFmpegDataDecoder.cpp +++ b/dom/media/platforms/ffmpeg/FFmpegDataDecoder.cpp @@ -8,6 +8,7 @@ #include #include +#include #include "FFmpegLog.h" #include "FFmpegDataDecoder.h" @@ -41,6 +42,7 @@ FFmpegDataDecoder::FFmpegDataDecoder(FlushableTaskQueue* aTaskQueue, , mMonitor("FFMpegaDataDecoder") , mIsFlushing(false) , mCodecParser(nullptr) + , mHQ(false) { MOZ_COUNT_CTOR(FFmpegDataDecoder); } @@ -108,10 +110,27 @@ FFmpegDataDecoder::InitDecoder() // FFmpeg will call back to this to negotiate a video pixel format. mCodecContext->get_format = ChoosePixelFormat; - mCodecContext->thread_count = PR_GetNumberOfProcessors(); + //mCodecContext->thread_count = PR_GetNumberOfProcessors(); + // PR_GetNumberOfProcessors() lies on TenFourFox. Get from sysctl(). + // TenFourFox issue 599. + int mib[2] = { CTL_HW, HW_NCPU }; + size_t len = sizeof(mCodecContext->thread_count); + if (sysctl(mib, 2, &(mCodecContext->thread_count), &len, NULL, 0) == -1) + mCodecContext->thread_count = 1; +#if DEBUG + fprintf(stderr, "FFmpeg using %d CPUs.\n", mCodecContext->thread_count); +#endif mCodecContext->thread_type = FF_THREAD_SLICE | FF_THREAD_FRAME; mCodecContext->thread_safe_callbacks = false; + if (!mHQ) { + // Enable skipping the loop filter and FFmpeg's lightly documented + // non-spec-compliant mode. TenFourFox issue 599. This is pushed here + // because this is not on the main thread, so we assert. + mCodecContext->flags2 |= CODEC_FLAG2_FAST; + mCodecContext->skip_loop_filter = AVDISCARD_ALL; + } + if (mExtraData) { mCodecContext->extradata_size = mExtraData->Length(); // FFmpeg may use SIMD instructions to access the data which reads the diff --git a/dom/media/platforms/ffmpeg/FFmpegDataDecoder.h b/dom/media/platforms/ffmpeg/FFmpegDataDecoder.h index a64e716f4..cd0a04149 100644 --- a/dom/media/platforms/ffmpeg/FFmpegDataDecoder.h +++ b/dom/media/platforms/ffmpeg/FFmpegDataDecoder.h @@ -38,6 +38,7 @@ public: static AVCodec* FindAVCodec(AVCodecID aCodec); + bool mHQ; // TenFourFox high quality mode (issue 599) protected: // Flush and Drain operation, always run virtual void ProcessFlush(); diff --git a/dom/media/platforms/ffmpeg/FFmpegDecoderModule.h b/dom/media/platforms/ffmpeg/FFmpegDecoderModule.h index f81f150e5..958a93712 100644 --- a/dom/media/platforms/ffmpeg/FFmpegDecoderModule.h +++ b/dom/media/platforms/ffmpeg/FFmpegDecoderModule.h @@ -19,14 +19,14 @@ class FFmpegDecoderModule : public PlatformDecoderModule { public: static already_AddRefed - Create() + Create(bool hq) { - RefPtr pdm = new FFmpegDecoderModule(); + RefPtr pdm = new FFmpegDecoderModule(hq); return pdm.forget(); } - FFmpegDecoderModule() {} + FFmpegDecoderModule(bool hq) : mHQ(hq) {} virtual ~FFmpegDecoderModule() {} already_AddRefed @@ -75,6 +75,7 @@ public: } } + bool mHQ; // TenFourFox high quality mode (issue 599). }; } // namespace mozilla diff --git a/dom/media/platforms/ffmpeg/FFmpegH264Decoder.cpp b/dom/media/platforms/ffmpeg/FFmpegH264Decoder.cpp index c27ed3899..4b2df08ea 100644 --- a/dom/media/platforms/ffmpeg/FFmpegH264Decoder.cpp +++ b/dom/media/platforms/ffmpeg/FFmpegH264Decoder.cpp @@ -99,7 +99,7 @@ FFmpegH264Decoder::DecodeResult FFmpegH264Decoder::DoDecodeFrame(MediaRawData* aSample) { MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn()); - if (PR_Now() < sLockOutDueToOOM) { + if (MOZ_UNLIKELY(PR_Now() < sLockOutDueToOOM)) { // Halt further allocations. NS_WARNING("** FFMPEG LOCKED OUT DUE TO OUT OF MEMORY **"); mCallback->Error(); @@ -152,7 +152,7 @@ FFmpegH264Decoder::DoDecodeFrame(MediaRawData* aSample, uint8_t* aData, int aSize) { MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn()); - if (PR_Now() < sLockOutDueToOOM) { + if (MOZ_UNLIKELY(PR_Now() < sLockOutDueToOOM)) { // Halt further allocations. NS_WARNING("** FFMPEG LOCKED OUT DUE TO OUT OF MEMORY **"); mCallback->Error(); diff --git a/dom/media/platforms/ffmpeg/FFmpegRuntimeLinker.cpp b/dom/media/platforms/ffmpeg/FFmpegRuntimeLinker.cpp index e84cb5bee..b503d7191 100644 --- a/dom/media/platforms/ffmpeg/FFmpegRuntimeLinker.cpp +++ b/dom/media/platforms/ffmpeg/FFmpegRuntimeLinker.cpp @@ -17,6 +17,9 @@ #include #endif /* XP_DARWIN */ +/* TenFourFox issue 599 */ +static bool sHQ = false; + namespace mozilla { @@ -26,7 +29,7 @@ FFmpegRuntimeLinker::LinkStatus FFmpegRuntimeLinker::sLinkStatus = template class FFmpegDecoderModule { public: - static already_AddRefed Create(); + static already_AddRefed Create(bool hq); }; static const char* sLibs[] = { @@ -175,6 +178,9 @@ FFmpegRuntimeLinker::Bind(const char* aLibName) return false; } + /* This is the only safe place to get preferences. TenFourFox issue 599. */ + sHQ = Preferences::GetBool("tenfourfox.mp4.high_quality", false); + int version; switch (major) { case 53: @@ -243,11 +249,11 @@ FFmpegRuntimeLinker::CreateDecoderModule() RefPtr module; switch (major) { - case 53: module = FFmpegDecoderModule<53>::Create(); break; - case 54: module = FFmpegDecoderModule<54>::Create(); break; + case 53: module = FFmpegDecoderModule<53>::Create(sHQ); break; + case 54: module = FFmpegDecoderModule<54>::Create(sHQ); break; case 55: - case 56: module = FFmpegDecoderModule<55>::Create(); break; - case 57: module = FFmpegDecoderModule<57>::Create(); break; + case 56: module = FFmpegDecoderModule<55>::Create(sHQ); break; + case 57: module = FFmpegDecoderModule<57>::Create(sHQ); break; default: module = nullptr; } return module.forget();