From f302cc139164c3ce665cb210d9056a66e0d348e8 Mon Sep 17 00:00:00 2001 From: trav90 Date: Mon, 16 May 2022 10:58:20 -0500 Subject: Issue #1893 - Part 3: Update audio & video decoders for FFmpeg 5.0 FFmpeg 5.0 removed some deprecated symbols so we need to update our decoding code to account for it. --- dom/media/platforms/ffmpeg/FFmpegAudioDecoder.cpp | 40 +++++++++++++++++++++-- dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp | 16 ++++++--- 2 files changed, 50 insertions(+), 6 deletions(-) diff --git a/dom/media/platforms/ffmpeg/FFmpegAudioDecoder.cpp b/dom/media/platforms/ffmpeg/FFmpegAudioDecoder.cpp index f867ec4942..298bcc8f65 100644 --- a/dom/media/platforms/ffmpeg/FFmpegAudioDecoder.cpp +++ b/dom/media/platforms/ffmpeg/FFmpegAudioDecoder.cpp @@ -7,6 +7,7 @@ #include "mozilla/TaskQueue.h" #include "FFmpegAudioDecoder.h" +#include "FFmpegLog.h" #include "TimeUnits.h" #define MAX_CHANNELS 16 @@ -136,8 +137,10 @@ FFmpegAudioDecoder::DoDecode(MediaRawData* aSample) media::TimeUnit pts = media::TimeUnit::FromMicroseconds(aSample->mTime); while (packet.size > 0) { - int decoded; - int bytesConsumed = + int decoded = false; + int bytesConsumed = -1; +#if LIBAVCODEC_VERSION_MAJOR < 59 + bytesConsumed = mLib->avcodec_decode_audio4(mCodecContext, mFrame, &decoded, &packet); if (bytesConsumed < 0) { @@ -145,6 +148,39 @@ FFmpegAudioDecoder::DoDecode(MediaRawData* aSample) return MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR, RESULT_DETAIL("FFmpeg audio error:%d", bytesConsumed)); } +#else +#define AVRESULT_OK 0 + + int ret = mLib->avcodec_receive_frame(mCodecContext, mFrame); + switch (ret) { + case AVRESULT_OK: + decoded = true; + break; + case AVERROR(EAGAIN): + break; + case AVERROR_EOF: { + FFMPEG_LOG("End of stream."); + return MediaResult(NS_ERROR_DOM_MEDIA_END_OF_STREAM, + RESULT_DETAIL("End of stream")); + } + } + ret = mLib->avcodec_send_packet(mCodecContext, &packet); + switch (ret) { + case AVRESULT_OK: + bytesConsumed = packet.size; + break; + case AVERROR(EAGAIN): + break; + case AVERROR_EOF: + FFMPEG_LOG("End of stream."); + return MediaResult(NS_ERROR_DOM_MEDIA_END_OF_STREAM, + RESULT_DETAIL("End of stream")); + default: + NS_WARNING("FFmpeg audio decoder error."); + return MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR, + RESULT_DETAIL("FFmpeg audio error")); + } +#endif if (decoded) { if (mFrame->format != AV_SAMPLE_FMT_FLT && diff --git a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp index f9e8a2d268..731e7c74cf 100644 --- a/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp +++ b/dom/media/platforms/ffmpeg/FFmpegVideoDecoder.cpp @@ -213,6 +213,14 @@ FFmpegVideoDecoder::DoDecode(MediaRawData* aSample, bool* aGotFrame) return DoDecode(aSample, inputData, inputSize, aGotFrame); } +static int64_t GetFramePts(AVFrame* aFrame) { +#if LIBAVCODEC_VERSION_MAJOR > 58 + return aFrame->pts; +#else + return aFrame->pkt_pts; +#endif +} + MediaResult FFmpegVideoDecoder::DoDecode(MediaRawData* aSample, uint8_t* aData, int aSize, @@ -260,7 +268,7 @@ FFmpegVideoDecoder::DoDecode(MediaRawData* aSample, 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, + MediaResult rv = CreateImage(mFrame->pkt_pos, GetFramePts(mFrame), mFrame->pkt_duration); if (NS_FAILED(rv)) { return rv; @@ -291,9 +299,9 @@ FFmpegVideoDecoder::DoDecode(MediaRawData* aSample, FFMPEG_LOG("DoDecodeFrame:decode_video: rv=%d decoded=%d " "(Input: pts(%lld) dts(%lld) Output: pts(%lld) " - "opaque(%lld) pkt_pts(%lld) pkt_dts(%lld))", + "opaque(%lld) pts(%lld) pkt_dts(%lld))", bytesConsumed, decoded, packet.pts, packet.dts, mFrame->pts, - mFrame->reordered_opaque, mFrame->pkt_pts, mFrame->pkt_dts); + mFrame->reordered_opaque, mFrame->pts, mFrame->pkt_dts); if (bytesConsumed < 0) { return MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR, @@ -308,7 +316,7 @@ FFmpegVideoDecoder::DoDecode(MediaRawData* aSample, } // If we've decoded a frame then we need to output it - int64_t pts = mPtsContext.GuessCorrectPts(mFrame->pkt_pts, mFrame->pkt_dts); + int64_t pts = mPtsContext.GuessCorrectPts(GetFramePts(mFrame), mFrame->pkt_dts); // Retrieve duration from dts. // We use the first entry found matching this dts (this is done to // handle damaged file with multiple frames with the same dts) -- cgit v1.2.3