From 1258bc5bfee68a48c1de140285b7a0b207c0af2e Mon Sep 17 00:00:00 2001 From: trav90 Date: Tue, 27 Dec 2016 01:54:24 -0600 Subject: [PATCH] Add support for libavcodec 57 At this point only the original FFmpeg project is supported. --- .../platforms/ffmpeg/FFmpegAudioDecoder.cpp | 4 +-- .../platforms/ffmpeg/FFmpegDataDecoder.cpp | 1 - .../platforms/ffmpeg/FFmpegFunctionList.h | 8 ++--- .../platforms/ffmpeg/FFmpegH264Decoder.cpp | 18 ++++++++--- .../platforms/ffmpeg/FFmpegRuntimeLinker.cpp | 31 ++++++++++++++----- .../platforms/ffmpeg/FFmpegRuntimeLinker.h | 8 +++-- dom/media/platforms/moz.build | 1 + 7 files changed, 49 insertions(+), 22 deletions(-) diff --git a/dom/media/platforms/ffmpeg/FFmpegAudioDecoder.cpp b/dom/media/platforms/ffmpeg/FFmpegAudioDecoder.cpp index a0de21915d..104951ea3e 100644 --- a/dom/media/platforms/ffmpeg/FFmpegAudioDecoder.cpp +++ b/dom/media/platforms/ffmpeg/FFmpegAudioDecoder.cpp @@ -44,8 +44,8 @@ FFmpegAudioDecoder::InitCodecContext() // isn't implemented. mCodecContext->thread_count = 1; // FFmpeg takes this as a suggestion for what format to use for audio samples. - uint32_t major, minor; - FFmpegRuntimeLinker::GetVersion(major, minor); + uint32_t major, minor, micro; + FFmpegRuntimeLinker::GetVersion(major, minor, micro); // LibAV 0.8 produces rubbish float interleaved samples, request 16 bits audio. mCodecContext->request_sample_fmt = (major == 53) ? AV_SAMPLE_FMT_S16 : AV_SAMPLE_FMT_FLT; diff --git a/dom/media/platforms/ffmpeg/FFmpegDataDecoder.cpp b/dom/media/platforms/ffmpeg/FFmpegDataDecoder.cpp index ad794c02fb..12cae1e91d 100644 --- a/dom/media/platforms/ffmpeg/FFmpegDataDecoder.cpp +++ b/dom/media/platforms/ffmpeg/FFmpegDataDecoder.cpp @@ -8,7 +8,6 @@ #include #include "MediaTaskQueue.h" -#include "FFmpegLibs.h" #include "FFmpegLog.h" #include "FFmpegDataDecoder.h" #include "prsystem.h" diff --git a/dom/media/platforms/ffmpeg/FFmpegFunctionList.h b/dom/media/platforms/ffmpeg/FFmpegFunctionList.h index c2f1ece2ba..a97e04240c 100644 --- a/dom/media/platforms/ffmpeg/FFmpegFunctionList.h +++ b/dom/media/platforms/ffmpeg/FFmpegFunctionList.h @@ -31,9 +31,9 @@ AV_FUNC(avcodec_alloc_frame, AV_FUNC_AVUTIL_54) AV_FUNC(avcodec_free_frame, AV_FUNC_AVUTIL_54) #endif #if LIBAVCODEC_VERSION_MAJOR >= 55 || defined(LIBAVCODEC_ALLVERSION) -/* libavutil v55 only */ -AV_FUNC(av_frame_alloc, AV_FUNC_AVUTIL_55) -AV_FUNC(av_frame_free, AV_FUNC_AVUTIL_55) -AV_FUNC(av_frame_unref, AV_FUNC_AVUTIL_55) +/* libavutil v55 and later only */ +AV_FUNC(av_frame_alloc, (AV_FUNC_AVUTIL_55 | AV_FUNC_AVUTIL_56 | AV_FUNC_AVUTIL_57)) +AV_FUNC(av_frame_free, (AV_FUNC_AVUTIL_55 | AV_FUNC_AVUTIL_56 | AV_FUNC_AVUTIL_57)) +AV_FUNC(av_frame_unref, (AV_FUNC_AVUTIL_55 | AV_FUNC_AVUTIL_56 | AV_FUNC_AVUTIL_57)) #endif #endif diff --git a/dom/media/platforms/ffmpeg/FFmpegH264Decoder.cpp b/dom/media/platforms/ffmpeg/FFmpegH264Decoder.cpp index 9ee8a7b4c7..d07150bcfa 100644 --- a/dom/media/platforms/ffmpeg/FFmpegH264Decoder.cpp +++ b/dom/media/platforms/ffmpeg/FFmpegH264Decoder.cpp @@ -15,6 +15,14 @@ #include "FFmpegLog.h" #include "mozilla/PodOperations.h" +#include "libavutil/pixfmt.h" +#if LIBAVCODEC_VERSION_MAJOR < 54 +#define AVPixelFormat PixelFormat +#define AV_PIX_FMT_YUV420P PIX_FMT_YUV420P +#define AV_PIX_FMT_YUVJ420P PIX_FMT_YUVJ420P +#define AV_PIX_FMT_NONE PIX_FMT_NONE +#endif + typedef mozilla::layers::Image Image; typedef mozilla::layers::PlanarYCbCrImage PlanarYCbCrImage; @@ -27,19 +35,19 @@ namespace mozilla * For now, we just look for YUV420P as it is the only non-HW accelerated format * supported by FFmpeg's H264 decoder. */ -static PixelFormat -ChoosePixelFormat(AVCodecContext* aCodecContext, const PixelFormat* aFormats) +static AVPixelFormat +ChoosePixelFormat(AVCodecContext* aCodecContext, const AVPixelFormat* aFormats) { FFMPEG_LOG("Choosing FFmpeg pixel format for video decoding."); for (; *aFormats > -1; aFormats++) { - if (*aFormats == PIX_FMT_YUV420P || *aFormats == PIX_FMT_YUVJ420P) { + if (*aFormats == AV_PIX_FMT_YUV420P || *aFormats == AV_PIX_FMT_YUVJ420P) { FFMPEG_LOG("Requesting pixel format YUV420P."); - return PIX_FMT_YUV420P; + return AV_PIX_FMT_YUV420P; } } NS_WARNING("FFmpeg does not share any supported pixel formats."); - return PIX_FMT_NONE; + return AV_PIX_FMT_NONE; } FFmpegH264Decoder::PtsCorrectionContext::PtsCorrectionContext() diff --git a/dom/media/platforms/ffmpeg/FFmpegRuntimeLinker.cpp b/dom/media/platforms/ffmpeg/FFmpegRuntimeLinker.cpp index ce340ef78f..b1ba07bec2 100644 --- a/dom/media/platforms/ffmpeg/FFmpegRuntimeLinker.cpp +++ b/dom/media/platforms/ffmpeg/FFmpegRuntimeLinker.cpp @@ -23,12 +23,15 @@ public: static const char* sLibs[] = { #if defined(XP_DARWIN) + "libavcodec.57.dylib", "libavcodec.56.dylib", "libavcodec.55.dylib", "libavcodec.54.dylib", "libavcodec.53.dylib", #else + "libavcodec-ffmpeg.so.57", "libavcodec-ffmpeg.so.56", + "libavcodec.so.57", "libavcodec.so.56", "libavcodec.so.55", "libavcodec.so.54", @@ -89,8 +92,8 @@ FFmpegRuntimeLinker::Bind(const char* aLibName) { avcodec_version = (typeof(avcodec_version))PR_FindSymbol(sLinkedLib, "avcodec_version"); - uint32_t major, minor; - if (!GetVersion(major, minor)) { + uint32_t major, minor, micro; + if (!GetVersion(major, minor, micro)) { return false; } @@ -102,10 +105,20 @@ FFmpegRuntimeLinker::Bind(const char* aLibName) case 54: version = AV_FUNC_54; break; - case 55: case 56: + // We use libavcodec 55 code instead. Fallback. + case 55: version = AV_FUNC_55; break; + case 57: + if (micro != 100) { + // A micro version of 100 indicates that it's FFmpeg (as opposed to LibAV). + // Due to current AVCodecContext binary incompatibility we can only + // support FFmpeg at this point. + return false; + } + version = AV_FUNC_57; + break; default: // Not supported at this stage. return false; @@ -133,8 +146,8 @@ FFmpegRuntimeLinker::CreateDecoderModule() if (!Link()) { return nullptr; } - uint32_t major, minor; - if (!GetVersion(major, minor)) { + uint32_t major, minor, micro; + if (!GetVersion(major, minor, micro)) { return nullptr; } @@ -142,7 +155,10 @@ FFmpegRuntimeLinker::CreateDecoderModule() switch (major) { case 53: module = FFmpegDecoderModule<53>::Create(); break; case 54: module = FFmpegDecoderModule<54>::Create(); break; - default: module = FFmpegDecoderModule<55>::Create(); break; + case 55: + case 56: module = FFmpegDecoderModule<55>::Create(); break; + case 57: module = FFmpegDecoderModule<57>::Create(); break; + default: module = nullptr; } return module.forget(); } @@ -160,7 +176,7 @@ FFmpegRuntimeLinker::Unlink() } /* static */ bool -FFmpegRuntimeLinker::GetVersion(uint32_t& aMajor, uint32_t& aMinor) +FFmpegRuntimeLinker::GetVersion(uint32_t& aMajor, uint32_t& aMinor, uint32_t& aMicro) { if (!avcodec_version) { return false; @@ -168,6 +184,7 @@ FFmpegRuntimeLinker::GetVersion(uint32_t& aMajor, uint32_t& aMinor) uint32_t version = avcodec_version(); aMajor = (version >> 16) & 0xff; aMinor = (version >> 8) & 0xff; + aMicro = version & 0xff; return true; } diff --git a/dom/media/platforms/ffmpeg/FFmpegRuntimeLinker.h b/dom/media/platforms/ffmpeg/FFmpegRuntimeLinker.h index 456be437ea..9d4ee395d0 100644 --- a/dom/media/platforms/ffmpeg/FFmpegRuntimeLinker.h +++ b/dom/media/platforms/ffmpeg/FFmpegRuntimeLinker.h @@ -21,12 +21,14 @@ enum { AV_FUNC_54 = 1 << 1, AV_FUNC_55 = 1 << 2, AV_FUNC_56 = 1 << 3, + AV_FUNC_57 = 1 << 4, AV_FUNC_AVUTIL_53 = AV_FUNC_53 | AV_FUNC_AVUTIL_MASK, AV_FUNC_AVUTIL_54 = AV_FUNC_54 | AV_FUNC_AVUTIL_MASK, AV_FUNC_AVUTIL_55 = AV_FUNC_55 | AV_FUNC_AVUTIL_MASK, AV_FUNC_AVUTIL_56 = AV_FUNC_56 | AV_FUNC_AVUTIL_MASK, - AV_FUNC_AVCODEC_ALL = AV_FUNC_53 | AV_FUNC_54 | AV_FUNC_55 | AV_FUNC_56, - AV_FUNC_AVUTIL_ALL = AV_FUNC_AVUTIL_53 | AV_FUNC_AVUTIL_54 | AV_FUNC_AVUTIL_55 | AV_FUNC_AVUTIL_56 + AV_FUNC_AVUTIL_57 = AV_FUNC_57 | AV_FUNC_AVUTIL_MASK, + AV_FUNC_AVCODEC_ALL = AV_FUNC_53 | AV_FUNC_54 | AV_FUNC_55 | AV_FUNC_56 | AV_FUNC_57, + AV_FUNC_AVUTIL_ALL = AV_FUNC_AVCODEC_ALL | AV_FUNC_AVUTIL_MASK }; class FFmpegRuntimeLinker @@ -35,7 +37,7 @@ public: static bool Link(); static void Unlink(); static already_AddRefed CreateDecoderModule(); - static bool GetVersion(uint32_t& aMajor, uint32_t& aMinor); + static bool GetVersion(uint32_t& aMajor, uint32_t& aMinor, uint32_t& aMicro); private: static PRLibrary* sLinkedLib; diff --git a/dom/media/platforms/moz.build b/dom/media/platforms/moz.build index 058e6b27ac..bd125a58ff 100644 --- a/dom/media/platforms/moz.build +++ b/dom/media/platforms/moz.build @@ -34,6 +34,7 @@ if CONFIG['MOZ_FFMPEG']: 'ffmpeg/libav53', 'ffmpeg/libav54', 'ffmpeg/libav55', + 'ffmpeg/ffmpeg57', ] LOCAL_INCLUDES += [ 'ffmpeg',