diff options
author | wolfbeast <mcwerewolf@wolfbeast.com> | 2019-11-10 11:39:27 +0100 |
---|---|---|
committer | wolfbeast <mcwerewolf@wolfbeast.com> | 2019-11-10 11:39:27 +0100 |
commit | 974a481d12bf430891725bd3662876358e57e11a (patch) | |
tree | cad011151456251fef2f1b8d02ef4b4e45fad61a /dom/media/platforms/ffmpeg | |
parent | 6bd66b1728eeddb058066edda740aaeb2ceaec23 (diff) | |
parent | 736d25cbec4541186ed46c935c117ce4d1c7f3bb (diff) | |
download | UXP-974a481d12bf430891725bd3662876358e57e11a.tar UXP-974a481d12bf430891725bd3662876358e57e11a.tar.gz UXP-974a481d12bf430891725bd3662876358e57e11a.tar.lz UXP-974a481d12bf430891725bd3662876358e57e11a.tar.xz UXP-974a481d12bf430891725bd3662876358e57e11a.zip |
Merge branch 'master' into js-modules
# Conflicts:
# modules/libpref/init/all.js
Diffstat (limited to 'dom/media/platforms/ffmpeg')
-rw-r--r-- | dom/media/platforms/ffmpeg/FFmpegDataDecoder.cpp | 18 | ||||
-rw-r--r-- | dom/media/platforms/ffmpeg/FFmpegLibWrapper.cpp | 3 | ||||
-rw-r--r-- | dom/media/platforms/ffmpeg/FFmpegLibWrapper.h | 7 | ||||
-rw-r--r-- | dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp | 75 | ||||
-rw-r--r-- | dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h | 1 | ||||
-rw-r--r-- | dom/media/platforms/ffmpeg/ffvpx/moz.build | 2 |
6 files changed, 91 insertions, 15 deletions
diff --git a/dom/media/platforms/ffmpeg/FFmpegDataDecoder.cpp b/dom/media/platforms/ffmpeg/FFmpegDataDecoder.cpp index 8cb5c8578..8655ce25f 100644 --- a/dom/media/platforms/ffmpeg/FFmpegDataDecoder.cpp +++ b/dom/media/platforms/ffmpeg/FFmpegDataDecoder.cpp @@ -69,12 +69,21 @@ FFmpegDataDecoder<LIBAV_VER>::InitDecoder() mCodecContext->extradata_size = mExtraData->Length(); // FFmpeg may use SIMD instructions to access the data which reads the // data in 32 bytes block. Must ensure we have enough data to read. + uint32_t padding_size = #if LIBAVCODEC_VERSION_MAJOR >= 58 - mExtraData->AppendElements(AV_INPUT_BUFFER_PADDING_SIZE); + AV_INPUT_BUFFER_PADDING_SIZE; #else - mExtraData->AppendElements(FF_INPUT_BUFFER_PADDING_SIZE); + FF_INPUT_BUFFER_PADDING_SIZE; #endif - mCodecContext->extradata = mExtraData->Elements(); + mCodecContext->extradata = static_cast<uint8_t*>( + mLib->av_malloc(mExtraData->Length() + padding_size)); + if (!mCodecContext->extradata) { + return MediaResult(NS_ERROR_OUT_OF_MEMORY, + RESULT_DETAIL("Couldn't init ffmpeg extradata")); + } + memcpy(mCodecContext->extradata, + mExtraData->Elements(), + mExtraData->Length()); } else { mCodecContext->extradata_size = 0; } @@ -165,6 +174,9 @@ FFmpegDataDecoder<LIBAV_VER>::ProcessShutdown() StaticMutexAutoLock mon(sMonitor); if (mCodecContext) { + if (mCodecContext->extradata) { + mLib->av_freep(&mCodecContext->extradata); + } mLib->avcodec_close(mCodecContext); mLib->av_freep(&mCodecContext); #if LIBAVCODEC_VERSION_MAJOR >= 55 diff --git a/dom/media/platforms/ffmpeg/FFmpegLibWrapper.cpp b/dom/media/platforms/ffmpeg/FFmpegLibWrapper.cpp index 6302882a6..426e9f74b 100644 --- a/dom/media/platforms/ffmpeg/FFmpegLibWrapper.cpp +++ b/dom/media/platforms/ffmpeg/FFmpegLibWrapper.cpp @@ -7,6 +7,7 @@ #include "MediaPrefs.h" #include "mozilla/PodOperations.h" #include "mozilla/Types.h" +#include "PlatformDecoderModule.h" #include "prlink.h" #define AV_LOG_DEBUG 48 @@ -144,6 +145,8 @@ FFmpegLibWrapper::Link() AV_FUNC(avcodec_alloc_frame, (AV_FUNC_53 | AV_FUNC_54)) AV_FUNC(avcodec_get_frame_defaults, (AV_FUNC_53 | AV_FUNC_54)) AV_FUNC(avcodec_free_frame, AV_FUNC_54) + AV_FUNC(avcodec_send_packet, AV_FUNC_58) + AV_FUNC(avcodec_receive_frame, AV_FUNC_58) AV_FUNC(av_log_set_level, AV_FUNC_AVUTIL_ALL) AV_FUNC(av_malloc, AV_FUNC_AVUTIL_ALL) AV_FUNC(av_freep, AV_FUNC_AVUTIL_ALL) diff --git a/dom/media/platforms/ffmpeg/FFmpegLibWrapper.h b/dom/media/platforms/ffmpeg/FFmpegLibWrapper.h index d6944a1d8..b968edd32 100644 --- a/dom/media/platforms/ffmpeg/FFmpegLibWrapper.h +++ b/dom/media/platforms/ffmpeg/FFmpegLibWrapper.h @@ -5,6 +5,7 @@ #ifndef __FFmpegLibWrapper_h__ #define __FFmpegLibWrapper_h__ +#include "mozilla/Attributes.h" #include "mozilla/Types.h" struct AVCodec; @@ -70,6 +71,10 @@ struct FFmpegLibWrapper // libavcodec v54 only void (*avcodec_free_frame)(AVFrame** frame); + // libavcodec v58 and later only + int (*avcodec_send_packet)(AVCodecContext* avctx, const AVPacket* avpkt); + int (*avcodec_receive_frame)(AVCodecContext* avctx, AVFrame* frame); + // libavutil void (*av_log_set_level)(int level); void* (*av_malloc)(size_t size); @@ -91,4 +96,4 @@ private: } // namespace mozilla -#endif // FFmpegLibWrapper
\ No newline at end of file +#endif // FFmpegLibWrapper diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp index aec1e9136..f3101e44c 100644 --- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp +++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp @@ -174,12 +174,15 @@ FFmpegVideoDecoder<LIBAV_VER>::DoDecode(MediaRawData* aSample, bool* aGotFrame) uint8_t* inputData = const_cast<uint8_t*>(aSample->Data()); size_t inputSize = aSample->Size(); -#if LIBAVCODEC_VERSION_MAJOR >= 54 +#if LIBAVCODEC_VERSION_MAJOR >= 54 && LIBAVCODEC_VERSION_MAJOR < 58 if (inputSize && mCodecParser && (mCodecID == AV_CODEC_ID_VP8 -#if LIBAVCODEC_VERSION_MAJOR >= 55 +#if LIBAVCODEC_VERSION_MAJOR >= 55 && LIBAVCODEC_VERSION_MAJOR < 58 || mCodecID == AV_CODEC_ID_VP9 #endif - )) { + )) +#endif +#if LIBAVCODEC_VERSION_MAJOR >= 54 + { while (inputSize) { uint8_t* data = inputData; int size = inputSize; @@ -224,6 +227,48 @@ FFmpegVideoDecoder<LIBAV_VER>::DoDecode(MediaRawData* aSample, packet.flags = aSample->mKeyframe ? AV_PKT_FLAG_KEY : 0; packet.pos = aSample->mOffset; +#if LIBAVCODEC_VERSION_MAJOR >= 58 + packet.duration = aSample->mDuration; + int res = mLib->avcodec_send_packet(mCodecContext, &packet); + if (res < 0) { + // In theory, avcodec_send_packet could sent -EAGAIN should its internal + // buffers be full. In practice this can't happen as we only feed one frame + // at a time, and we immediately call avcodec_receive_frame right after. + FFMPEG_LOG("avcodec_send_packet error: %d", res); + return MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR, + RESULT_DETAIL("avcodec_send_packet error: %d", res)); + } + + if (aGotFrame) { + *aGotFrame = false; + } + do { + if (!PrepareFrame()) { + NS_WARNING("FFmpeg h264 decoder failed to allocate frame."); + return MediaResult(NS_ERROR_OUT_OF_MEMORY, __func__); + } + res = mLib->avcodec_receive_frame(mCodecContext, mFrame); + if (res == int(AVERROR_EOF)) { + return NS_ERROR_DOM_MEDIA_END_OF_STREAM; + } + if (res == AVERROR(EAGAIN)) { + return NS_OK; + } + if (res < 0) { + FFMPEG_LOG("avcodec_receive_frame error: %d", res); + return MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR, + RESULT_DETAIL("avcodec_receive_frame error: %d", res)); + } + MediaResult rv = CreateImage(mFrame->pkt_pos, mFrame->pkt_pts, + mFrame->pkt_duration); + if (NS_FAILED(rv)) { + return rv; + } + if (aGotFrame) { + *aGotFrame = true; + } + } while (true); +#else // LibAV provides no API to retrieve the decoded sample's duration. // (FFmpeg >= 1.0 provides av_frame_get_pkt_duration) // As such we instead use a map using the dts as key that we will retrieve @@ -276,8 +321,21 @@ FFmpegVideoDecoder<LIBAV_VER>::DoDecode(MediaRawData* aSample, // against the map becoming extremely big. mDurationMap.Clear(); } + + MediaResult rv = CreateImage(aSample->mOffset, pts, duration); + if (NS_SUCCEEDED(rv) && aGotFrame) { + *aGotFrame = true; + } + return rv; +#endif +} + +MediaResult +FFmpegVideoDecoder<LIBAV_VER>::CreateImage(int64_t aOffset, int64_t aPts, + int64_t aDuration) +{ FFMPEG_LOG("Got one frame output with pts=%lld dts=%lld duration=%lld opaque=%lld", - pts, mFrame->pkt_dts, duration, mCodecContext->reordered_opaque); + aPts, mFrame->pkt_dts, aDuration, mCodecContext->reordered_opaque); VideoData::YCbCrBuffer b; b.mPlanes[0].mData = mFrame->data[0]; @@ -317,9 +375,9 @@ FFmpegVideoDecoder<LIBAV_VER>::DoDecode(MediaRawData* aSample, RefPtr<VideoData> v = VideoData::CreateAndCopyData(mInfo, mImageContainer, - aSample->mOffset, - pts, - duration, + aOffset, + aPts, + aDuration, b, !!mFrame->key_frame, -1, @@ -331,9 +389,6 @@ FFmpegVideoDecoder<LIBAV_VER>::DoDecode(MediaRawData* aSample, RESULT_DETAIL("image allocation error")); } mCallback->Output(v); - if (aGotFrame) { - *aGotFrame = true; - } return NS_OK; } diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h index 786df0da1..49a55e8a6 100644 --- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h +++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.h @@ -49,6 +49,7 @@ private: MediaResult DoDecode(MediaRawData* aSample) override; MediaResult DoDecode(MediaRawData* aSample, bool* aGotFrame); MediaResult DoDecode(MediaRawData* aSample, uint8_t* aData, int aSize, bool* aGotFrame); + MediaResult CreateImage(int64_t aOffset, int64_t aPts, int64_t aDuration); void ProcessDrain() override; void ProcessFlush() override; void OutputDelayedFrames(); diff --git a/dom/media/platforms/ffmpeg/ffvpx/moz.build b/dom/media/platforms/ffmpeg/ffvpx/moz.build index aee58b5b0..c0041a4d4 100644 --- a/dom/media/platforms/ffmpeg/ffvpx/moz.build +++ b/dom/media/platforms/ffmpeg/ffvpx/moz.build @@ -20,7 +20,7 @@ SOURCES += [ ] LOCAL_INCLUDES += [ '..', - '../ffmpeg57/include', + '../ffmpeg58/include', ] if CONFIG['OS_ARCH'] == 'WINNT': |