multimedia/olive: Unbreak

This commit is contained in:
Yuri Victorovich
2026-02-28 18:27:06 -08:00
parent c84c76682b
commit bf7ece95e3
6 changed files with 291 additions and 2 deletions
-2
View File
@@ -13,8 +13,6 @@ COMMENT= Non-linear video editor
WWW= https://olivevideoeditor.org/ \
https://github.com/olive-editor/olive
BROKEN= Does not build with ffmpeg > 6
LICENSE= GPLv3
LICENSE_FILE= ${WRKSRC}/LICENSE
@@ -0,0 +1,15 @@
--- app/audio/audioprocessor.cpp.orig 2026-02-28 23:14:00 UTC
+++ app/audio/audioprocessor.cpp
@@ -169,8 +169,12 @@ bool AudioProcessor::Open(const AudioParams &from, con
if (in_frame_) {
in_frame_->sample_rate = from.sample_rate();
in_frame_->format = from_fmt_;
+#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(57, 28, 100)
+ av_channel_layout_from_mask(&in_frame_->ch_layout, from.channel_layout());
+#else
in_frame_->channel_layout = from.channel_layout();
in_frame_->channels = from.channel_count();
+#endif
in_frame_->pts = 0;
} else {
qCritical() << "Failed to allocate input frame";
@@ -0,0 +1,123 @@
--- 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)
@@ -0,0 +1,108 @@
--- app/codec/ffmpeg/ffmpegencoder.cpp.orig 2024-12-04 17:13:33 UTC
+++ app/codec/ffmpeg/ffmpegencoder.cpp
@@ -334,7 +334,11 @@ bool FFmpegEncoder::WriteAudioData(const AudioParams &
int output_sample_count = input_sample_count ? swr_get_out_samples(audio_resample_ctx_, input_sample_count) : 102400;
uint8_t** output_data = nullptr;
int output_linesize;
+#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(57, 28, 100)
+ av_samples_alloc_array_and_samples(&output_data, &output_linesize, audio_stream_->codecpar->ch_layout.nb_channels,
+#else
av_samples_alloc_array_and_samples(&output_data, &output_linesize, audio_stream_->codecpar->channels,
+#endif
output_sample_count, static_cast<AVSampleFormat>(audio_stream_->codecpar->format), 0);
// Perform conversion
@@ -349,7 +353,11 @@ bool FFmpegEncoder::WriteAudioData(const AudioParams &
av_samples_copy(audio_frame_->data, output_data, audio_frame_offset_, i,
copy_length,
+#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(57, 28, 100)
+ audio_frame_->ch_layout.nb_channels, static_cast<AVSampleFormat>(audio_frame_->format));
+#else
audio_frame_->channels, static_cast<AVSampleFormat>(audio_frame_->format));
+#endif
audio_frame_offset_ += copy_length;
i += copy_length;
@@ -690,8 +698,12 @@ bool FFmpegEncoder::InitializeStream(AVMediaType type,
// Assume audio stream
codec_ctx->sample_rate = params().audio_params().sample_rate();
+#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(57, 28, 100)
+ av_channel_layout_from_mask(&codec_ctx->ch_layout, params().audio_params().channel_layout());
+#else
codec_ctx->channel_layout = params().audio_params().channel_layout();
codec_ctx->channels = av_get_channel_layout_nb_channels(codec_ctx->channel_layout);
+#endif
codec_ctx->sample_fmt = FFmpegUtils::GetFFmpegSampleFormat(params().audio_params().format());
codec_ctx->time_base = {1, codec_ctx->sample_rate};
@@ -787,12 +799,19 @@ void FFmpegEncoder::FlushEncoders()
}
if (fmt_ctx_) {
+#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(59, 0, 100)
+ // AVFMT_ALLOW_FLUSH removed in ffmpeg 7+, always allow flush now
+ int r = av_interleaved_write_frame(fmt_ctx_, nullptr);
+#else
if (fmt_ctx_->oformat->flags & AVFMT_ALLOW_FLUSH) {
int r = av_interleaved_write_frame(fmt_ctx_, nullptr);
+#endif
if (r < 0) {
FFmpegError(tr("Failed to write interleaved packet"), r);
}
+#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(59, 0, 100)
}
+#endif
}
}
@@ -829,6 +848,28 @@ bool FFmpegEncoder::InitializeResampleContext(const Au
}
// Create resample 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, audio_codec_ctx_->ch_layout.u.mask ? audio_codec_ctx_->ch_layout.u.mask : AV_CH_LAYOUT_STEREO);
+ av_channel_layout_from_mask(&in_ch_layout, audio.channel_layout());
+
+ int ret = swr_alloc_set_opts2(&audio_resample_ctx_,
+ &out_ch_layout,
+ audio_codec_ctx_->sample_fmt,
+ audio_codec_ctx_->sample_rate,
+ &in_ch_layout,
+ FFmpegUtils::GetFFmpegSampleFormat(audio.format()),
+ audio.sample_rate(),
+ 0,
+ nullptr);
+ av_channel_layout_uninit(&out_ch_layout);
+ av_channel_layout_uninit(&in_ch_layout);
+
+ if (ret < 0) {
+ return false;
+ }
+#else
audio_resample_ctx_ = swr_alloc_set_opts(nullptr,
static_cast<int64_t>(audio_codec_ctx_->channel_layout),
audio_codec_ctx_->sample_fmt,
@@ -838,6 +879,7 @@ bool FFmpegEncoder::InitializeResampleContext(const Au
audio.sample_rate(),
0,
nullptr);
+#endif
if (!audio_resample_ctx_) {
return false;
}
@@ -865,7 +907,11 @@ bool FFmpegEncoder::InitializeResampleContext(const Au
return false;
}
+#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(57, 28, 100)
+ av_channel_layout_copy(&audio_frame_->ch_layout, &audio_codec_ctx_->ch_layout);
+#else
audio_frame_->channel_layout = audio_codec_ctx_->channel_layout;
+#endif
audio_frame_->format = audio_codec_ctx_->sample_fmt;
audio_frame_->nb_samples = audio_max_samples_;
@@ -0,0 +1,23 @@
--- app/codec/oiio/oiiodecoder.cpp.orig 2026-02-28 23:20:04 UTC
+++ app/codec/oiio/oiiodecoder.cpp
@@ -134,10 +134,20 @@ TexturePtr OIIODecoder::RetrieveVideoInternal(const Re
if (p.divider == 1) {
// Just upload straight to the buffer
+#if OIIO_VERSION >= OIIO_MAKE_VERSION(3, 0, 0)
+ // OpenImageIO 3.0+ requires subimage, miplevel, chbegin, chend parameters
+ image_->read_image(0, 0, 0, image_->spec().nchannels, oiio_pix_fmt_, buffer_.data(), OIIO::AutoStride, buffer_.linesize_bytes());
+#else
image_->read_image(oiio_pix_fmt_, buffer_.data(), OIIO::AutoStride, buffer_.linesize_bytes());
+#endif
} else {
OIIO::ImageBuf buf(image_->spec());
+#if OIIO_VERSION >= OIIO_MAKE_VERSION(3, 0, 0)
+ // OpenImageIO 3.0+ requires subimage, miplevel, chbegin, chend parameters
+ image_->read_image(0, 0, 0, image_->spec().nchannels, image_->spec().format, buf.localpixels(), buf.pixel_stride(), buf.scanline_stride(), buf.z_stride());
+#else
image_->read_image(image_->spec().format, buf.localpixels(), buf.pixel_stride(), buf.scanline_stride(), buf.z_stride());
+#endif
// Roughly downsample image for divider (for some reason OIIO::ImageBufAlgo::resample failed here)
int px_sz = vp.GetBytesPerPixel();
@@ -0,0 +1,22 @@
--- ext/core/src/render/audioparams.cpp.orig 2026-02-28 23:05:00 UTC
+++ ext/core/src/render/audioparams.cpp
@@ -159,7 +159,19 @@ void AudioParams::calculate_channel_count()
void AudioParams::calculate_channel_count()
{
+#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(57, 28, 100)
+ // ffmpeg 5.1+ uses new channel layout API
+ AVChannelLayout ch_layout = AV_CHANNEL_LAYOUT_MASK(0, 0);
+ if (channel_layout() > 0) {
+ av_channel_layout_from_mask(&ch_layout, channel_layout());
+ channel_count_ = ch_layout.nb_channels;
+ av_channel_layout_uninit(&ch_layout);
+ } else {
+ channel_count_ = 0;
+ }
+#else
channel_count_ = av_get_channel_layout_nb_channels(channel_layout());
+#endif
}
}