diff --git a/app/audio/audioprocessor.cpp b/app/audio/audioprocessor.cpp index cddf5aed9..6cc04d171 100644 --- a/app/audio/audioprocessor.cpp +++ b/app/audio/audioprocessor.cpp @@ -116,7 +116,9 @@ bool AudioProcessor::Open(const AudioParams &from, const AudioParams &to, double } // Create conversion filter - if (from.sample_rate() != to.sample_rate() || from.channel_layout() != to.channel_layout() || from.format() != to.format() + auto ch1=from.channel_layout(); + auto ch2=to.channel_layout(); + if (from.sample_rate() != to.sample_rate() || av_channel_layout_compare(&ch1, &ch2) || from.format() != to.format() || (to.format().is_planar() && create_tempo)) { // Tempo processor automatically converts to packed, // so if the desired output is planar, it'll need // to be converted @@ -169,8 +171,7 @@ bool AudioProcessor::Open(const AudioParams &from, const AudioParams &to, double if (in_frame_) { in_frame_->sample_rate = from.sample_rate(); in_frame_->format = from_fmt_; - in_frame_->channel_layout = from.channel_layout(); - in_frame_->channels = from.channel_count(); + in_frame_->ch_layout = from.channel_layout(); in_frame_->pts = 0; } else { qCritical() << "Failed to allocate input frame"; diff --git a/app/codec/conformmanager.cpp b/app/codec/conformmanager.cpp index 70d012a94..8f3acfa33 100644 --- a/app/codec/conformmanager.cpp +++ b/app/codec/conformmanager.cpp @@ -66,7 +66,7 @@ QVector ConformManager::GetConformedFilename(const QString &cache_path, QString::number(stream.stream()), QString::number(params.sample_rate()), QString::number(params.format()), - QString::number(params.channel_layout()), + QString::number(params.channel_layout().u.mask), QString::number(i)); filenames[i] = QDir(cache_path).filePath(index_fn); diff --git a/app/codec/encoder.cpp b/app/codec/encoder.cpp index 810cdcd1b..e405e5323 100644 --- a/app/codec/encoder.cpp +++ b/app/codec/encoder.cpp @@ -256,7 +256,9 @@ void EncodingParams::Save(QXmlStreamWriter *writer) const if (audio_enabled_) { writer->writeTextElement(QStringLiteral("codec"), QString::number(audio_codec_)); writer->writeTextElement(QStringLiteral("samplerate"), QString::number(audio_params_.sample_rate())); - writer->writeTextElement(QStringLiteral("channellayout"), QString::number(audio_params_.channel_layout())); + + writer->writeTextElement(QStringLiteral("channellayout"), + QString::number(audio_params().channel_layout().u.mask)); writer->writeTextElement(QStringLiteral("format"), QString::fromStdString(audio_params_.format().to_string())); writer->writeTextElement(QStringLiteral("bitrate"), QString::number(audio_bit_rate_)); } @@ -469,7 +471,10 @@ bool EncodingParams::LoadV1(QXmlStreamReader *reader) } else if (reader->name() == QStringLiteral("samplerate")) { audio_params_.set_sample_rate(reader->readElementText().toInt()); } else if (reader->name() == QStringLiteral("channellayout")) { - audio_params_.set_channel_layout(reader->readElementText().toULongLong()); + AVChannelLayout av_channel_layout; + av_channel_layout_from_mask(&av_channel_layout, reader->readElementText().toLongLong()); + audio_params_.set_channel_layout(av_channel_layout); + av_channel_layout_uninit(&av_channel_layout); } else if (reader->name() == QStringLiteral("format")) { audio_params_.set_format(SampleFormat::from_string(reader->readElementText().toStdString())); } else if (reader->name() == QStringLiteral("bitrate")) { diff --git a/app/codec/encoder.h b/app/codec/encoder.h index 65702a36f..ea66ed562 100644 --- a/app/codec/encoder.h +++ b/app/codec/encoder.h @@ -33,7 +33,7 @@ #include "render/colortransform.h" #include "render/subtitleparams.h" #include "render/videoparams.h" - +//这个代码也许是导出编码视频用的? namespace olive { class Encoder; diff --git a/app/codec/ffmpeg/ffmpegdecoder.cpp b/app/codec/ffmpeg/ffmpegdecoder.cpp index 938ff3f22..14f61abf6 100644 --- a/app/codec/ffmpeg/ffmpegdecoder.cpp +++ b/app/codec/ffmpeg/ffmpegdecoder.cpp @@ -439,9 +439,9 @@ FootageDescription FFmpegDecoder::Probe(const QString &filename, CancelAtom *can } else if (avstream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { // Create an audio stream object - uint64_t channel_layout = avstream->codecpar->channel_layout; - if (!channel_layout) { - channel_layout = static_cast(av_get_default_channel_layout(avstream->codecpar->channels)); + AVChannelLayout &channel_layout = avstream->codecpar->ch_layout; + if (!av_channel_layout_check(&channel_layout)) { + av_channel_layout_default(&channel_layout,avstream->codecpar->ch_layout.nb_channels); } if (avstream->duration == AV_NOPTS_VALUE || duration_guessed_from_bitrate) { @@ -551,22 +551,23 @@ bool FFmpegDecoder::ConformAudioInternal(const QVector &filenames, cons instance_.Seek(0); // Handle NULL channel layout - uint64_t channel_layout = ValidateChannelLayout(instance_.avstream()); - if (!channel_layout) { + AVChannelLayout channel_layout = ValidateChannelLayout(instance_.avstream()); + if (!av_channel_layout_check(&channel_layout)) { qCritical() << "Failed to determine channel layout of audio file, could not conform"; return false; } - // Create resampling context - SwrContext* resampler = swr_alloc_set_opts(nullptr, - params.channel_layout(), - FFmpegUtils::GetFFmpegSampleFormat(params.format()), - params.sample_rate(), - channel_layout, - static_cast(instance_.avstream()->codecpar->format), - instance_.avstream()->codecpar->sample_rate, - 0, - nullptr); + std::shared_ptr layout=params.channel_layout(); + SwrContext* resampler; + swr_alloc_set_opts2(&resampler, + layout.get(), + FFmpegUtils::GetFFmpegSampleFormat(params.format()), + params.sample_rate(), + &channel_layout, + static_cast(instance_.avstream()->codecpar->format), + instance_.avstream()->codecpar->sample_rate, + 0, + nullptr); swr_init(resampler); @@ -689,13 +690,14 @@ int FFmpegDecoder::GetNativeChannelCount(AVPixelFormat pix_fmt) } } -uint64_t FFmpegDecoder::ValidateChannelLayout(AVStream* stream) +AVChannelLayout FFmpegDecoder::ValidateChannelLayout(AVStream* stream) { - if (stream->codecpar->channel_layout) { - return stream->codecpar->channel_layout; + if (av_channel_layout_check(&stream->codecpar->ch_layout)) { + return stream->codecpar->ch_layout; } - - return av_get_default_channel_layout(stream->codecpar->channels); + AVChannelLayout layout; + av_channel_layout_default(&layout,stream->codecpar->ch_layout.nb_channels); + return layout; } const char *FFmpegDecoder::GetInterlacingModeInFFmpeg(VideoParams::Interlacing interlacing) diff --git a/app/codec/ffmpeg/ffmpegencoder.cpp b/app/codec/ffmpeg/ffmpegencoder.cpp index f5ca225a4..36879513a 100644 --- a/app/codec/ffmpeg/ffmpegencoder.cpp +++ b/app/codec/ffmpeg/ffmpegencoder.cpp @@ -334,7 +334,7 @@ bool FFmpegEncoder::WriteAudioData(const AudioParams &audio_params, const uint8_ 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; - av_samples_alloc_array_and_samples(&output_data, &output_linesize, audio_stream_->codecpar->channels, + av_samples_alloc_array_and_samples(&output_data, &output_linesize, audio_stream_->codecpar->ch_layout.nb_channels, output_sample_count, static_cast(audio_stream_->codecpar->format), 0); // Perform conversion diff --git a/app/codec/oiio/oiiodecoder.cpp b/app/codec/oiio/oiiodecoder.cpp index e3efc4108..5ba005558 100644 --- a/app/codec/oiio/oiiodecoder.cpp +++ b/app/codec/oiio/oiiodecoder.cpp @@ -134,10 +134,10 @@ TexturePtr OIIODecoder::RetrieveVideoInternal(const RetrieveVideoParams &p) if (p.divider == 1) { // Just upload straight to the buffer - image_->read_image(oiio_pix_fmt_, buffer_.data(), OIIO::AutoStride, buffer_.linesize_bytes()); + image_->read_image(0, 0, 0, -1, oiio_pix_fmt_, buffer_.data()); } else { OIIO::ImageBuf buf(image_->spec()); - image_->read_image(image_->spec().format, buf.localpixels(), buf.pixel_stride(), buf.scanline_stride(), buf.z_stride()); + image_->read_image(0,0,0,-1,image_->spec().format, buf.localpixels(), buf.pixel_stride(), buf.scanline_stride(), buf.z_stride()); // Roughly downsample image for divider (for some reason OIIO::ImageBufAlgo::resample failed here) int px_sz = vp.GetBytesPerPixel(); diff --git a/app/dialog/export/export.cpp b/app/dialog/export/export.cpp index c5cfa2a17..552a9d0a1 100644 --- a/app/dialog/export/export.cpp +++ b/app/dialog/export/export.cpp @@ -749,7 +749,7 @@ void ExportDialog::SetParams(const EncodingParams &e) audio_enabled_->setChecked(e.audio_enabled()); if (e.audio_enabled()) { audio_tab_->sample_rate_combobox()->SetSampleRate(e.audio_params().sample_rate()); - audio_tab_->channel_layout_combobox()->SetChannelLayout(e.audio_params().channel_layout()); + audio_tab_->channel_layout_combobox()->SetChannelLayout(e.audio_params().channel_layout().u.mask()); audio_tab_->sample_format_combobox()->SetSampleFormat(e.audio_params().format()); audio_tab_->SetCodec(e.audio_codec()); diff --git a/app/dialog/sequence/sequencedialogparametertab.cpp b/app/dialog/sequence/sequencedialogparametertab.cpp index 9022c3543..aab63923b 100644 --- a/app/dialog/sequence/sequencedialogparametertab.cpp +++ b/app/dialog/sequence/sequencedialogparametertab.cpp @@ -124,7 +124,7 @@ void SequenceDialogParameterTab::PresetChanged(const SequencePreset &preset) void SequenceDialogParameterTab::SavePresetClicked() { - emit SaveParametersAsPreset({QString(), + emit SaveParametersAsPreset(SequencePreset(QString(), GetSelectedVideoWidth(), GetSelectedVideoHeight(), GetSelectedVideoFrameRate(), @@ -134,7 +134,7 @@ void SequenceDialogParameterTab::SavePresetClicked() GetSelectedAudioChannelLayout(), GetSelectedPreviewResolution(), GetSelectedPreviewFormat(), - GetSelectedPreviewAutoCache()}); + GetSelectedPreviewAutoCache())); } void SequenceDialogParameterTab::UpdatePreviewResolutionLabel() diff --git a/app/dialog/sequence/sequencedialogparametertab.h b/app/dialog/sequence/sequencedialogparametertab.h index 0efef7e7c..7880344ca 100644 --- a/app/dialog/sequence/sequencedialogparametertab.h +++ b/app/dialog/sequence/sequencedialogparametertab.h @@ -44,12 +44,9 @@ public: return interlacing_combo_->GetInterlaceMode(); } - int GetSelectedAudioSampleRate() const - { - return audio_sample_rate_field_->GetSampleRate(); - } + int GetSelectedAudioSampleRate() const { return audio_sample_rate_field_->GetSampleRate(); } - uint64_t GetSelectedAudioChannelLayout() const + [[nodiscard]] AVChannelLayout GetSelectedAudioChannelLayout() const { return audio_channels_field_->GetChannelLayout(); } diff --git a/app/dialog/sequence/sequencepreset.h b/app/dialog/sequence/sequencepreset.h index 2a2f5699b..84c0cbab5 100644 --- a/app/dialog/sequence/sequencepreset.h +++ b/app/dialog/sequence/sequencepreset.h @@ -41,7 +41,7 @@ public: const rational& pixel_aspect, VideoParams::Interlacing interlacing, int sample_rate, - uint64_t channel_layout, + AVChannelLayout &channel_layout, int preview_divider, PixelFormat preview_format, bool preview_autocache) : @@ -77,7 +77,7 @@ public: } else if (reader->name() == QStringLiteral("samplerate")) { sample_rate_ = reader->readElementText().toInt(); } else if (reader->name() == QStringLiteral("chlayout")) { - channel_layout_ = reader->readElementText().toULongLong(); + channel_layout_.u.mask = reader->readElementText().toULongLong(); } else if (reader->name() == QStringLiteral("divider")) { preview_divider_ = reader->readElementText().toInt(); } else if (reader->name() == QStringLiteral("format")) { @@ -99,7 +99,7 @@ public: writer->writeTextElement(QStringLiteral("pixelaspect"), QString::fromStdString(pixel_aspect_.toString())); writer->writeTextElement(QStringLiteral("interlacing_"), QString::number(interlacing_)); writer->writeTextElement(QStringLiteral("samplerate"), QString::number(sample_rate_)); - writer->writeTextElement(QStringLiteral("chlayout"), QString::number(channel_layout_)); + writer->writeTextElement(QStringLiteral("chlayout"), QString::number(channel_layout_.u.mask)); writer->writeTextElement(QStringLiteral("divider"), QString::number(preview_divider_)); writer->writeTextElement(QStringLiteral("format"), QString::number(preview_format_)); writer->writeTextElement(QStringLiteral("autocache"), QString::number(preview_autocache_)); @@ -135,7 +135,7 @@ public: return sample_rate_; } - uint64_t channel_layout() const + AVChannelLayout channel_layout() const { return channel_layout_; } @@ -162,7 +162,7 @@ private: rational pixel_aspect_; VideoParams::Interlacing interlacing_; int sample_rate_; - uint64_t channel_layout_; + AVChannelLayout channel_layout_; int preview_divider_; PixelFormat preview_format_; bool preview_autocache_; diff --git a/app/widget/standardcombos/channellayoutcombobox.h b/app/widget/standardcombos/channellayoutcombobox.h index 0cdf7a503..575ae12d9 100644 --- a/app/widget/standardcombos/channellayoutcombobox.h +++ b/app/widget/standardcombos/channellayoutcombobox.h @@ -23,7 +23,9 @@ #include #include - +extern "C"{ +#include +} #include "ui/humanstrings.h" namespace olive { @@ -42,22 +44,24 @@ public: QVariant::fromValue(ch_layout)); } } - - uint64_t GetChannelLayout() const + [[nodiscard]] AVChannelLayout GetChannelLayout() const { - return this->currentData().toULongLong(); + AVChannelLayout audio_channel_layout_; + av_channel_layout_from_mask(&audio_channel_layout_, this->currentData().toULongLong()); + return audio_channel_layout_; } - void SetChannelLayout(uint64_t ch) + void SetChannelLayout(std::shared_ptr &ch) { for (int i=0; icount(); i++) { - if (this->itemData(i).toULongLong() == ch) { + if (this->itemData(i).toULongLong() == ch->u.mask) { this->setCurrentIndex(i); break; } } } - +public slots: +private: }; } diff --git a/ext/core b/ext/core index 277792824..25e4152bb 160000 --- a/ext/core +++ b/ext/core @@ -1 +1 @@ -Subproject commit 277792824801495e868580ca86f6e7a1b53e4779 +Subproject commit 25e4152bb70a0f4e30b9249e4f4b31e7936dc84a