320 lines
13 KiB
Diff
320 lines
13 KiB
Diff
From fcad1884954ec1998f353750dd7332501e204ddb Mon Sep 17 00:00:00 2001
|
|
From: Vasyl Gello <vasek.gello@gmail.com>
|
|
Date: Sat, 15 Oct 2022 16:08:14 +0000
|
|
Subject: [PATCH] Adapt AlwinEsch's ffmpeg5 port patch
|
|
|
|
Signed-off-by: Vasyl Gello <vasek.gello@gmail.com>
|
|
---
|
|
src/stream/FFmpegStream.cpp | 96 ++++++++++++++++++++++++++++++++-----
|
|
src/stream/FFmpegStream.h | 6 ++-
|
|
src/utils/FFmpegCompat.h | 20 ++++++++
|
|
3 files changed, 107 insertions(+), 15 deletions(-)
|
|
create mode 100644 src/utils/FFmpegCompat.h
|
|
|
|
diff --git a/src/stream/FFmpegStream.cpp b/src/stream/FFmpegStream.cpp
|
|
index 73e0963c..f2140a17 100644
|
|
--- a/src/stream/FFmpegStream.cpp
|
|
+++ b/src/stream/FFmpegStream.cpp
|
|
@@ -462,7 +462,14 @@ DEMUX_PACKET* FFmpegStream::DemuxRead()
|
|
// we already check for a valid m_streams[pPacket->iStreamId] above
|
|
else if (stream->type == INPUTSTREAM_TYPE_AUDIO)
|
|
{
|
|
- if (static_cast<DemuxStreamAudio*>(stream)->iChannels != m_pFormatContext->streams[pPacket->iStreamId]->codecpar->channels ||
|
|
+#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \
|
|
+ LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100)
|
|
+ int codecparChannels =
|
|
+ m_pFormatContext->streams[pPacket->iStreamId]->codecpar->ch_layout.nb_channels;
|
|
+#else
|
|
+ int codecparChannels = m_pFormatContext->streams[pPacket->iStreamId]->codecpar->channels;
|
|
+#endif
|
|
+ if (static_cast<DemuxStreamAudio*>(stream)->iChannels != codecparChannels ||
|
|
static_cast<DemuxStreamAudio*>(stream)->iSampleRate != m_pFormatContext->streams[pPacket->iStreamId]->codecpar->sample_rate)
|
|
{
|
|
// content has changed
|
|
@@ -658,7 +665,7 @@ bool FFmpegStream::Aborted()
|
|
|
|
bool FFmpegStream::Open(bool fileinfo)
|
|
{
|
|
- AVInputFormat* iformat = NULL;
|
|
+ FFMPEG_FMT_CONST AVInputFormat* iformat = nullptr;
|
|
std::string strFile;
|
|
m_streaminfo = !m_isRealTimeStream && !m_reopen;;
|
|
m_currentPts = STREAM_NOPTS_VALUE;
|
|
@@ -729,6 +736,8 @@ bool FFmpegStream::Open(bool fileinfo)
|
|
m_streaminfo = true;
|
|
}
|
|
|
|
+ // https://github.com/FFmpeg/FFmpeg/blob/56450a0ee4/doc/APIchanges#L18-L26
|
|
+#if LIBAVFORMAT_BUILD < AV_VERSION_INT(59, 0, 100)
|
|
if (iformat && (strcmp(iformat->name, "mov,mp4,m4a,3gp,3g2,mj2") == 0))
|
|
{
|
|
CURL url(m_streamUrl);
|
|
@@ -736,6 +745,7 @@ bool FFmpegStream::Open(bool fileinfo)
|
|
if (!url.GetProtocol().empty() && !url.IsProtocol("file"))
|
|
m_pFormatContext->iformat->flags |= AVFMT_NOGENSEARCH;
|
|
}
|
|
+#endif
|
|
|
|
// we need to know if this is matroska, avi or sup later
|
|
m_bMatroska = strncmp(m_pFormatContext->iformat->name, "matroska", 8) == 0; // for "matroska.webm"
|
|
@@ -785,8 +795,11 @@ bool FFmpegStream::Open(bool fileinfo)
|
|
// if format can be nonblocking, let's use that
|
|
m_pFormatContext->flags |= AVFMT_FLAG_NONBLOCK;
|
|
|
|
- // deprecated, will be always set in future versions
|
|
+ // https://github.com/FFmpeg/FFmpeg/blob/d682ae70b4/doc/APIchanges#L18-L21
|
|
+#if LIBAVFORMAT_BUILD < AV_VERSION_INT(57, 66, 105) && \
|
|
+ LIBAVCODEC_BUILD < AV_VERSION_INT(57, 83, 101)
|
|
m_pFormatContext->flags |= AVFMT_FLAG_KEEP_SIDE_DATA;
|
|
+#endif
|
|
|
|
UpdateCurrentPTS();
|
|
|
|
@@ -828,12 +841,23 @@ bool FFmpegStream::Open(bool fileinfo)
|
|
{
|
|
int idx = m_pFormatContext->programs[i]->stream_index[j];
|
|
AVStream* st = m_pFormatContext->streams[idx];
|
|
+#if LIBAVFORMAT_BUILD >= AV_VERSION_INT(59, 3, 100)
|
|
+ // Related to https://patchwork.ffmpeg.org/project/ffmpeg/patch/20210429143825.53040-1-jamrial@gmail.com/
|
|
+ // has been replaced with AVSTREAM_EVENT_FLAG_NEW_PACKETS.
|
|
+ if ((st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && (st->event_flags & AVSTREAM_EVENT_FLAG_NEW_PACKETS)) ||
|
|
+ (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->sample_rate > 0))
|
|
+ {
|
|
+ nProgram = i;
|
|
+ break;
|
|
+ }
|
|
+#else
|
|
if ((st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->codec_info_nb_frames > 0) ||
|
|
(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->sample_rate > 0))
|
|
{
|
|
nProgram = i;
|
|
break;
|
|
}
|
|
+#endif
|
|
}
|
|
}
|
|
|
|
@@ -870,7 +894,7 @@ bool FFmpegStream::Open(bool fileinfo)
|
|
return true;
|
|
}
|
|
|
|
-bool FFmpegStream::OpenWithFFmpeg(AVInputFormat* iformat, const AVIOInterruptCB& int_cb)
|
|
+bool FFmpegStream::OpenWithFFmpeg(FFMPEG_FMT_CONST AVInputFormat* iformat, const AVIOInterruptCB& int_cb)
|
|
{
|
|
Log(LOGLEVEL_INFO, "%s - IO handled by FFmpeg's AVFormat", __FUNCTION__);
|
|
|
|
@@ -959,7 +983,7 @@ bool FFmpegStream::OpenWithFFmpeg(AVInputFormat* iformat, const AVIOInterruptCB&
|
|
return true;
|
|
}
|
|
|
|
-bool FFmpegStream::OpenWithCURL(AVInputFormat* iformat)
|
|
+bool FFmpegStream::OpenWithCURL(FFMPEG_FMT_CONST AVInputFormat* iformat)
|
|
{
|
|
Log(LOGLEVEL_INFO, "%s - IO handled by Kodi's cURL", __FUNCTION__);
|
|
|
|
@@ -1039,8 +1063,7 @@ bool FFmpegStream::OpenWithCURL(AVInputFormat* iformat)
|
|
// is present, we assume it is PCM audio.
|
|
// AC3 is always wrapped in iec61937 (ffmpeg "spdif"), while DTS
|
|
// may be just padded.
|
|
- AVInputFormat* iformat2;
|
|
- iformat2 = av_find_input_format("spdif");
|
|
+ FFMPEG_FMT_CONST AVInputFormat* iformat2 = av_find_input_format("spdif");
|
|
|
|
if (iformat2 && iformat2->read_probe(&pd) > AVPROBE_SCORE_MAX / 4)
|
|
{
|
|
@@ -1147,11 +1170,19 @@ void FFmpegStream::UpdateCurrentPTS()
|
|
if (idx >= 0)
|
|
{
|
|
AVStream* stream = m_pFormatContext->streams[idx];
|
|
+#if LIBAVFORMAT_BUILD >= AV_VERSION_INT(59, 3, 100)
|
|
+ if (stream && m_pkt.pkt.dts != (int64_t)AV_NOPTS_VALUE)
|
|
+ {
|
|
+ double ts = ConvertTimestamp(m_pkt.pkt.dts, stream->time_base.den, stream->time_base.num);
|
|
+ m_currentPts = ts;
|
|
+ }
|
|
+#else
|
|
if (stream && stream->cur_dts != (int64_t)AV_NOPTS_VALUE)
|
|
{
|
|
double ts = ConvertTimestamp(stream->cur_dts, stream->time_base.den, stream->time_base.num);
|
|
m_currentPts = ts;
|
|
}
|
|
+#endif
|
|
}
|
|
}
|
|
|
|
@@ -1230,9 +1261,15 @@ bool FFmpegStream::IsProgramChange()
|
|
return true;
|
|
if (m_pFormatContext->streams[idx]->codecpar->codec_id != stream->codec)
|
|
return true;
|
|
+#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \
|
|
+ LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100)
|
|
+ int codecparChannels =
|
|
+ m_pFormatContext->streams[idx]->codecpar->ch_layout.nb_channels;
|
|
+#else
|
|
+ int codecparChannels = m_pFormatContext->streams[idx]->codecpar->channels;
|
|
+#endif
|
|
if (m_pFormatContext->streams[idx]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
|
|
- m_pFormatContext->streams[idx]->codecpar->channels !=
|
|
- static_cast<DemuxStreamAudio*>(stream)->iChannels)
|
|
+ codecparChannels != static_cast<DemuxStreamAudio*>(stream)->iChannels)
|
|
return true;
|
|
if (m_pFormatContext->streams[idx]->codecpar->extradata_size != static_cast<int>(stream->ExtraSize))
|
|
return true;
|
|
@@ -1564,7 +1601,7 @@ void FFmpegStream::ParsePacket(AVPacket* pkt)
|
|
|
|
parser->second->m_parserCtx = av_parser_init(st->codecpar->codec_id);
|
|
|
|
- AVCodec* codec = avcodec_find_decoder(st->codecpar->codec_id);
|
|
+ FFMPEG_FMT_CONST AVCodec* codec = avcodec_find_decoder(st->codecpar->codec_id);
|
|
if (codec == nullptr)
|
|
{
|
|
Log(LOGLEVEL_ERROR, "%s - can't find decoder", __FUNCTION__);
|
|
@@ -1641,7 +1678,11 @@ TRANSPORT_STREAM_STATE FFmpegStream::TransportStreamAudioState()
|
|
{
|
|
if (!m_startTime)
|
|
{
|
|
+#if LIBAVFORMAT_BUILD >= AV_VERSION_INT(59, 3, 100)
|
|
+ m_startTime = av_rescale(m_pkt.pkt.dts, st->time_base.num, st->time_base.den) - 0.000001;
|
|
+#else
|
|
m_startTime = av_rescale(st->cur_dts, st->time_base.num, st->time_base.den) - 0.000001;
|
|
+#endif
|
|
m_seekStream = idx;
|
|
}
|
|
return TRANSPORT_STREAM_STATE::READY;
|
|
@@ -1661,7 +1702,11 @@ TRANSPORT_STREAM_STATE FFmpegStream::TransportStreamAudioState()
|
|
{
|
|
if (!m_startTime)
|
|
{
|
|
+#if LIBAVFORMAT_BUILD >= AV_VERSION_INT(59, 3, 100)
|
|
+ m_startTime = av_rescale(m_pkt.pkt.dts, st->time_base.num, st->time_base.den) - 0.000001;
|
|
+#else
|
|
m_startTime = av_rescale(st->cur_dts, st->time_base.num, st->time_base.den) - 0.000001;
|
|
+#endif
|
|
m_seekStream = i;
|
|
}
|
|
return TRANSPORT_STREAM_STATE::READY;
|
|
@@ -1694,7 +1739,11 @@ TRANSPORT_STREAM_STATE FFmpegStream::TransportStreamVideoState()
|
|
{
|
|
if (!m_startTime)
|
|
{
|
|
+#if LIBAVFORMAT_BUILD >= AV_VERSION_INT(59, 3, 100)
|
|
+ m_startTime = av_rescale(m_pkt.pkt.dts, st->time_base.num, st->time_base.den) - 0.000001;
|
|
+#else
|
|
m_startTime = av_rescale(st->cur_dts, st->time_base.num, st->time_base.den) - 0.000001;
|
|
+#endif
|
|
m_seekStream = idx;
|
|
}
|
|
return TRANSPORT_STREAM_STATE::READY;
|
|
@@ -1714,7 +1763,11 @@ TRANSPORT_STREAM_STATE FFmpegStream::TransportStreamVideoState()
|
|
{
|
|
if (!m_startTime)
|
|
{
|
|
+#if LIBAVFORMAT_BUILD >= AV_VERSION_INT(59, 3, 100)
|
|
+ m_startTime = av_rescale(m_pkt.pkt.dts, st->time_base.num, st->time_base.den) - 0.000001;
|
|
+#else
|
|
m_startTime = av_rescale(st->cur_dts, st->time_base.num, st->time_base.den) - 0.000001;
|
|
+#endif
|
|
m_seekStream = i;
|
|
}
|
|
return TRANSPORT_STREAM_STATE::READY;
|
|
@@ -1824,14 +1877,31 @@ DemuxStream* FFmpegStream::AddStream(int streamIdx)
|
|
{
|
|
DemuxStreamAudioFFmpeg* st = new DemuxStreamAudioFFmpeg(pStream);
|
|
stream = st;
|
|
- st->iChannels = pStream->codecpar->channels;
|
|
+#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \
|
|
+ LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100)
|
|
+ int codecparChannels = pStream->codecpar->ch_layout.nb_channels;
|
|
+ int codecparChannelLayout = pStream->codecpar->ch_layout.u.mask;
|
|
+#else
|
|
+ int codecparChannels = pStream->codecpar->channels;
|
|
+ int codecparChannelLayout = pStream->codecpar->channel_layout;
|
|
+#endif
|
|
+ st->iChannels = codecparChannels;
|
|
+ st->iChannelLayout = codecparChannelLayout;
|
|
st->iSampleRate = pStream->codecpar->sample_rate;
|
|
st->iBlockAlign = pStream->codecpar->block_align;
|
|
st->iBitRate = static_cast<int>(pStream->codecpar->bit_rate);
|
|
st->iBitsPerSample = pStream->codecpar->bits_per_raw_sample;
|
|
- st->iChannelLayout = pStream->codecpar->channel_layout;
|
|
char buf[32] = { 0 };
|
|
+ // https://github.com/FFmpeg/FFmpeg/blob/6ccc3989d15/doc/APIchanges#L50-L53
|
|
+#if LIBAVCODEC_BUILD >= AV_VERSION_INT(59, 37, 100) && \
|
|
+ LIBAVUTIL_BUILD >= AV_VERSION_INT(57, 28, 100)
|
|
+ AVChannelLayout layout = {};
|
|
+ av_channel_layout_from_mask(&layout, st->iChannelLayout);
|
|
+ av_channel_layout_describe(&layout, buf, sizeof(buf));
|
|
+ av_channel_layout_uninit(&layout);
|
|
+#else
|
|
av_get_channel_layout_string(buf, 31, st->iChannels, st->iChannelLayout);
|
|
+#endif
|
|
st->m_channelLayoutName = buf;
|
|
if (st->iBitsPerSample == 0)
|
|
st->iBitsPerSample = pStream->codecpar->bits_per_coded_sample;
|
|
@@ -2070,7 +2140,7 @@ std::string FFmpegStream::GetStreamCodecName(int iStreamId)
|
|
return strName;
|
|
}
|
|
|
|
- AVCodec* codec = avcodec_find_decoder(stream->codec);
|
|
+ FFMPEG_FMT_CONST AVCodec* codec = avcodec_find_decoder(stream->codec);
|
|
if (codec)
|
|
strName = codec->name;
|
|
}
|
|
diff --git a/src/stream/FFmpegStream.h b/src/stream/FFmpegStream.h
|
|
index bf8a50f9..356905dd 100644
|
|
--- a/src/stream/FFmpegStream.h
|
|
+++ b/src/stream/FFmpegStream.h
|
|
@@ -7,6 +7,7 @@
|
|
|
|
#pragma once
|
|
|
|
+#include "../utils/FFmpegCompat.h"
|
|
#include "../utils/HttpProxy.h"
|
|
#include "../utils/Properties.h"
|
|
#include "BaseStream.h"
|
|
@@ -33,6 +34,7 @@ extern "C"
|
|
#include <libavcodec/avcodec.h>
|
|
#include <libavformat/avformat.h>
|
|
#include <libavutil/mastering_display_metadata.h>
|
|
+#include <libavutil/version.h>
|
|
}
|
|
|
|
#ifndef __GNUC__
|
|
@@ -117,8 +119,8 @@ class FFmpegStream
|
|
|
|
private:
|
|
bool Open(bool fileinfo);
|
|
- bool OpenWithFFmpeg(AVInputFormat* iformat, const AVIOInterruptCB& int_cb);
|
|
- bool OpenWithCURL(AVInputFormat* iformat);
|
|
+ bool OpenWithFFmpeg(FFMPEG_FMT_CONST AVInputFormat* iformat, const AVIOInterruptCB& int_cb);
|
|
+ bool OpenWithCURL(FFMPEG_FMT_CONST AVInputFormat* iformat);
|
|
AVDictionary* GetFFMpegOptionsFromInput();
|
|
void ResetVideoStreams();
|
|
double ConvertTimestamp(int64_t pts, int den, int num);
|
|
diff --git a/src/utils/FFmpegCompat.h b/src/utils/FFmpegCompat.h
|
|
new file mode 100644
|
|
index 00000000..46cff53f
|
|
--- /dev/null
|
|
+++ b/src/utils/FFmpegCompat.h
|
|
@@ -0,0 +1,20 @@
|
|
+/*
|
|
+ * Copyright (C) 2005-2022 Team Kodi
|
|
+ * This file is part of Kodi - https://kodi.tv
|
|
+ *
|
|
+ * SPDX-License-Identifier: GPL-2.0-or-later
|
|
+ * See LICENSES/README.md for more information.
|
|
+ */
|
|
+
|
|
+#pragma once
|
|
+
|
|
+extern "C" {
|
|
+#include <libavformat/avformat.h>
|
|
+}
|
|
+
|
|
+// https://github.com/FFmpeg/FFmpeg/blob/56450a0ee4/doc/APIchanges#L18-L26
|
|
+#if LIBAVFORMAT_BUILD >= AV_VERSION_INT(59, 0, 100)
|
|
+#define FFMPEG_FMT_CONST const
|
|
+#else
|
|
+#define FFMPEG_FMT_CONST
|
|
+#endif
|