Files
ports/multimedia/olive/files/patch-app_codec_ffmpeg_ffmpegdecoder.cpp
T
2026-02-28 18:27:28 -08:00

124 lines
5.6 KiB
C++

--- app/codec/ffmpeg/ffmpegdecoder.cpp.orig 2024-12-04 17:13:33 UTC
+++ app/codec/ffmpeg/ffmpegdecoder.cpp
@@ -355,8 +355,15 @@ FootageDescription FFmpegDecoder::Probe(const QString
// Read first frame and retrieve some metadata
if (instance.GetFrame(pkt, frame) >= 0) {
// Check if video is interlaced and what field dominance it has if so
+#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(58, 0, 100)
+ int interlaced = (frame->flags & AV_FRAME_FLAG_INTERLACED);
+ int top_field_first = (frame->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST);
+ if (interlaced) {
+ if (top_field_first) {
+#else
if (frame->interlaced_frame) {
if (frame->top_field_first) {
+#endif
interlacing = VideoParams::kInterlacedTopFirst;
} else {
interlacing = VideoParams::kInterlacedBottomFirst;
@@ -439,10 +446,30 @@ FootageDescription FFmpegDecoder::Probe(const QString
} else if (avstream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
// Create an audio stream object
+#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(57, 28, 100)
+ uint64_t channel_layout;
+ if (avstream->codecpar->ch_layout.order != AV_CHANNEL_ORDER_UNSPEC) {
+ AVChannelLayout ch_layout = AV_CHANNEL_LAYOUT_MASK(0, 0);
+ av_channel_layout_copy(&ch_layout, &avstream->codecpar->ch_layout);
+ if (ch_layout.order == AV_CHANNEL_ORDER_NATIVE && ch_layout.u.mask) {
+ channel_layout = ch_layout.u.mask;
+ } else {
+ av_channel_layout_default(&ch_layout, avstream->codecpar->ch_layout.nb_channels);
+ channel_layout = ch_layout.u.mask;
+ }
+ av_channel_layout_uninit(&ch_layout);
+ } else {
+ AVChannelLayout ch_layout = AV_CHANNEL_LAYOUT_MASK(0, 0);
+ av_channel_layout_default(&ch_layout, avstream->codecpar->ch_layout.nb_channels);
+ channel_layout = ch_layout.u.mask;
+ av_channel_layout_uninit(&ch_layout);
+ }
+#else
uint64_t channel_layout = avstream->codecpar->channel_layout;
if (!channel_layout) {
channel_layout = static_cast<uint64_t>(av_get_default_channel_layout(avstream->codecpar->channels));
}
+#endif
if (avstream->duration == AV_NOPTS_VALUE || duration_guessed_from_bitrate) {
// Loop through stream until we get the whole duration
@@ -558,6 +585,29 @@ bool FFmpegDecoder::ConformAudioInternal(const QVector
}
// Create resampling context
+#if LIBSWRESAMPLE_VERSION_INT >= AV_VERSION_INT(4, 5, 100)
+ AVChannelLayout out_ch_layout = AV_CHANNEL_LAYOUT_MASK(0, 0);
+ AVChannelLayout in_ch_layout = AV_CHANNEL_LAYOUT_MASK(0, 0);
+ av_channel_layout_from_mask(&out_ch_layout, params.channel_layout());
+ av_channel_layout_from_mask(&in_ch_layout, channel_layout);
+
+ SwrContext* resampler = nullptr;
+ int swr_ret = swr_alloc_set_opts2(&resampler,
+ &out_ch_layout,
+ FFmpegUtils::GetFFmpegSampleFormat(params.format()),
+ params.sample_rate(),
+ &in_ch_layout,
+ static_cast<AVSampleFormat>(instance_.avstream()->codecpar->format),
+ instance_.avstream()->codecpar->sample_rate,
+ 0,
+ nullptr);
+ av_channel_layout_uninit(&out_ch_layout);
+ av_channel_layout_uninit(&in_ch_layout);
+
+ if (swr_ret < 0) {
+ return false;
+ }
+#else
SwrContext* resampler = swr_alloc_set_opts(nullptr,
params.channel_layout(),
FFmpegUtils::GetFFmpegSampleFormat(params.format()),
@@ -567,6 +617,7 @@ bool FFmpegDecoder::ConformAudioInternal(const QVector
instance_.avstream()->codecpar->sample_rate,
0,
nullptr);
+#endif
swr_init(resampler);
@@ -691,11 +742,35 @@ uint64_t FFmpegDecoder::ValidateChannelLayout(AVStream
uint64_t FFmpegDecoder::ValidateChannelLayout(AVStream* stream)
{
+#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(57, 28, 100)
+ if (stream->codecpar->ch_layout.order != AV_CHANNEL_ORDER_UNSPEC) {
+ AVChannelLayout ch_layout = AV_CHANNEL_LAYOUT_MASK(0, 0);
+ av_channel_layout_copy(&ch_layout, &stream->codecpar->ch_layout);
+ uint64_t mask = 0;
+ if (ch_layout.order == AV_CHANNEL_ORDER_NATIVE && ch_layout.u.mask) {
+ mask = ch_layout.u.mask;
+ } else {
+ AVChannelLayout default_layout = AV_CHANNEL_LAYOUT_MASK(0, 0);
+ av_channel_layout_default(&default_layout, stream->codecpar->ch_layout.nb_channels);
+ mask = default_layout.u.mask;
+ av_channel_layout_uninit(&default_layout);
+ }
+ av_channel_layout_uninit(&ch_layout);
+ return mask;
+ }
+
+ AVChannelLayout ch_layout = AV_CHANNEL_LAYOUT_MASK(0, 0);
+ av_channel_layout_default(&ch_layout, stream->codecpar->ch_layout.nb_channels);
+ uint64_t mask = ch_layout.u.mask;
+ av_channel_layout_uninit(&ch_layout);
+ return mask;
+#else
if (stream->codecpar->channel_layout) {
return stream->codecpar->channel_layout;
}
return av_get_default_channel_layout(stream->codecpar->channels);
+#endif
}
const char *FFmpegDecoder::GetInterlacingModeInFFmpeg(VideoParams::Interlacing interlacing)