Commit 36ed5af2 authored by Jean-Baptiste Mardelle's avatar Jean-Baptiste Mardelle
Browse files

Correctly handle audio stream changes

parent 511ff37c
......@@ -30,6 +30,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "jobs/jobmanager.h"
#include "jobs/loadjob.hpp"
#include "jobs/thumbjob.hpp"
#include "jobs/audiothumbjob.hpp"
#include "kdenlivesettings.h"
#include "lib/audio/audioStreamInfo.h"
#include "mltcontroller/clipcontroller.h"
......@@ -299,7 +300,7 @@ size_t ProjectClip::frameDuration() const
return (size_t)d.frames(pCore->getCurrentFps());
}
void ProjectClip::reloadProducer(bool refreshOnly)
void ProjectClip::reloadProducer(bool refreshOnly, bool audioStreamChanged)
{
// we find if there are some loading job on that clip
int loadjobId = -1;
......@@ -313,6 +314,10 @@ void ProjectClip::reloadProducer(bool refreshOnly)
pCore->jobManager()->discardJobs(clipId(), AbstractClipJob::THUMBJOB);
m_thumbsProducer.reset();
pCore->jobManager()->startJob<ThumbJob>({clipId()}, loadjobId, QString(), 150, -1, true, true);
if (audioStreamChanged) {
discardAudioThumb();
pCore->jobManager()->startJob<AudioThumbJob>({clipId()}, loadjobId, QString());
}
} else {
// If another load job is running?
......@@ -925,7 +930,7 @@ void ProjectClip::setProperties(const QMap<QString, QString> &properties, bool r
QStringList timelineProperties{QStringLiteral("force_aspect_ratio"), QStringLiteral("video_index"), QStringLiteral("audio_index"),
QStringLiteral("set.force_full_luma"), QStringLiteral("full_luma"), QStringLiteral("threads"),
QStringLiteral("force_colorspace"), QStringLiteral("force_tff"), QStringLiteral("force_progressive"),
QStringLiteral("video_index"), QStringLiteral("audio_index")};
};
QStringList forceReloadProperties{QStringLiteral("autorotate"), QStringLiteral("templatetext"), QStringLiteral("resource"),
QStringLiteral("force_fps"), QStringLiteral("set.test_image"), QStringLiteral("set.test_audio")};
QStringList keys{QStringLiteral("luma_duration"), QStringLiteral("luma_file"), QStringLiteral("fade"), QStringLiteral("ttl"),
......@@ -1016,7 +1021,7 @@ void ProjectClip::setProperties(const QMap<QString, QString> &properties, bool r
setProducerProperty(QStringLiteral("_overwriteproxy"), 1);
pCore->jobManager()->startJob<ProxyJob>({clipId()}, -1, QString());
} else {
reloadProducer(refreshOnly);
reloadProducer(refreshOnly, properties.contains(QStringLiteral("audio_index")));
}
if (refreshOnly) {
if (auto ptr = m_model.lock()) {
......@@ -1205,6 +1210,7 @@ void ProjectClip::discardAudioThumb()
audioFrameCache.clear();
qCDebug(KDENLIVE_LOG) << "//////////////////// DISCARD AUIIO THUMBNS";
m_audioThumbCreated = false;
refreshAudioInfo();
pCore->jobManager()->discardJobs(clipId(), AbstractClipJob::AUDIOTHUMBJOB);
}
......
......@@ -85,7 +85,7 @@ protected:
public:
~ProjectClip() override;
void reloadProducer(bool refreshOnly = false);
void reloadProducer(bool refreshOnly = false, bool audioStreamChanged = false);
/** @brief Returns a unique hash identifier used to store clip thumbnails. */
// virtual void hash() = 0;
......
......@@ -35,18 +35,7 @@ AudioStreamInfo::AudioStreamInfo(const std::shared_ptr<Mlt::Producer> &producer,
key = QStringLiteral("meta.media.%1.codec.channels").arg(audioStreamIndex).toLocal8Bit();
m_channels = producer->get_int(key.data());
int streams = producer->get_int("meta.media.nb_streams");
QList<int> audioStreams;
for (int i = 0; i < streams; ++i) {
QByteArray propertyName = QStringLiteral("meta.media.%1.stream.type").arg(i).toLocal8Bit();
QString type = producer->get(propertyName.data());
if (type == QLatin1String("audio")) {
audioStreams << i;
}
}
if (audioStreams.count() > 1) {
m_ffmpegAudioIndex = audioStreams.indexOf(m_audioStreamIndex);
}
setAudioIndex(producer, m_audioStreamIndex);
}
}
......@@ -82,3 +71,22 @@ void AudioStreamInfo::dumpInfo() const
qCDebug(KDENLIVE_LOG) << "Info for audio stream " << m_audioStreamIndex << "\n\tChannels: " << m_channels << "\n\tSampling rate: " << m_samplingRate
<< "\n\tBit rate: " << m_bitRate;
}
void AudioStreamInfo::setAudioIndex(const std::shared_ptr<Mlt::Producer> &producer, int ix)
{
m_audioStreamIndex = ix;
if (ix > -1) {
int streams = producer->get_int("meta.media.nb_streams");
QList<int> audioStreams;
for (int i = 0; i < streams; ++i) {
QByteArray propertyName = QStringLiteral("meta.media.%1.stream.type").arg(i).toLocal8Bit();
QString type = producer->get(propertyName.data());
if (type == QLatin1String("audio")) {
audioStreams << i;
}
}
if (audioStreams.count() > 1 && m_audioStreamIndex < audioStreams.count()) {
m_ffmpegAudioIndex = audioStreams.indexOf(m_audioStreamIndex);
}
}
}
......@@ -32,6 +32,7 @@ public:
int audio_index() const;
int ffmpeg_audio_index() const;
void dumpInfo() const;
void setAudioIndex(const std::shared_ptr<Mlt::Producer> &producer, int ix);
private:
int m_audioStreamIndex;
......
......@@ -44,7 +44,6 @@ ClipController::ClipController(const QString &clipId, const std::shared_ptr<Mlt:
, m_properties(producer ? new Mlt::Properties(producer->get_properties()) : nullptr)
, m_usesProxy(false)
, m_audioInfo(nullptr)
, m_audioIndex(0)
, m_videoIndex(0)
, m_clipType(ClipType::Unknown)
, m_hasLimitedDuration(true)
......@@ -178,15 +177,15 @@ void ClipController::getProducerXML(QDomDocument &document, bool includeMeta)
void ClipController::getInfoForProducer()
{
date = QFileInfo(m_path).lastModified();
m_audioIndex = -1;
m_videoIndex = -1;
int audioIndex = -1;
// special case: playlist with a proxy clip have to be detected separately
if (m_usesProxy && m_path.endsWith(QStringLiteral(".mlt"))) {
m_clipType = ClipType::Playlist;
} else if (m_service == QLatin1String("avformat") || m_service == QLatin1String("avformat-novalidate")) {
m_audioIndex = getProducerIntProperty(QStringLiteral("audio_index"));
audioIndex = getProducerIntProperty(QStringLiteral("audio_index"));
m_videoIndex = getProducerIntProperty(QStringLiteral("video_index"));
if (m_audioIndex == -1) {
if (audioIndex == -1) {
m_clipType = ClipType::Video;
} else if (m_videoIndex == -1) {
m_clipType = ClipType::Audio;
......@@ -224,8 +223,8 @@ void ClipController::getInfoForProducer()
} else {
m_clipType = ClipType::Unknown;
}
if (m_audioIndex > -1 || m_clipType == ClipType::Playlist) {
m_audioInfo = std::make_unique<AudioStreamInfo>(m_masterProducer, m_audioIndex);
if (audioIndex > -1 || m_clipType == ClipType::Playlist) {
m_audioInfo = std::make_unique<AudioStreamInfo>(m_masterProducer, audioIndex);
}
if (!m_hasLimitedDuration) {
......@@ -471,7 +470,7 @@ const QString ClipController::codec(bool audioCodec) const
if ((m_properties == nullptr) || (m_clipType != ClipType::AV && m_clipType != ClipType::Video && m_clipType != ClipType::Audio)) {
return QString();
}
QString propertyName = QStringLiteral("meta.media.%1.codec.name").arg(audioCodec ? m_audioIndex : m_videoIndex);
QString propertyName = QStringLiteral("meta.media.%1.codec.name").arg(audioCodec ? m_properties->get_int("audio_index") : m_videoIndex);
return m_properties->get(propertyName.toUtf8().constData());
}
......@@ -876,3 +875,10 @@ std::shared_ptr<MarkerListModel> ClipController::getMarkerModel() const
{
return m_markerModel;
}
void ClipController::refreshAudioInfo()
{
if (m_audioInfo && m_masterProducer) {
m_audioInfo->setAudioIndex(m_masterProducer, m_properties->get_int("audio_index"));
}
}
......@@ -207,6 +207,8 @@ protected:
// This is the helper function that checks if the clip has audio and video and stores the result
void checkAudioVideo();
// Update audio stream info
void refreshAudioInfo();
std::shared_ptr<Mlt::Producer> m_masterProducer;
Mlt::Properties *m_properties;
......@@ -214,7 +216,6 @@ protected:
std::unique_ptr<AudioStreamInfo> m_audioInfo;
QString m_service;
QString m_path;
int m_audioIndex;
int m_videoIndex;
ClipType::ProducerType m_clipType;
bool m_hasLimitedDuration;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment