if (!m_properties.contains("name")) m_properties.insert("name", url.fileName());
- //if (!url.isEmpty() && QFile::exists(url.path()))
- {
- m_thumbProd = new KThumb(clipManager, url, m_id, m_properties.value("file_hash"));
- if (m_clipType == AV || m_clipType == AUDIO || m_clipType == PLAYLIST) slotCreateAudioTimer();
- }
- //kDebug() << "type is video" << (m_clipType == AV) << " " << m_clipType;
-}
-
-/*DocClipBase & DocClipBase::operator=(const DocClipBase & clip) {
- DocClipBase::operator=(clip);
- m_id = clip.getId();
- m_clipType = clip.clipType();
- m_name = clip.name();
- m_duration = clip.duration();
- m_audioThumbCreated = clip.audioThumbCreated();
- m_properties = clip.properties();
- return *this;
-}*/
+ m_thumbProd = new KThumb(clipManager, url, m_id, m_properties.value("file_hash"));
+ if (m_clipType == AV || m_clipType == AUDIO || m_clipType == PLAYLIST) slotCreateAudioTimer();
+}
DocClipBase::~DocClipBase()
{
- kDebug() << "CLIP " << m_id << " DELETED******************************";
delete m_thumbProd;
if (m_audioTimer) {
m_audioTimer->stop();
delete m_audioTimer;
}
- /*kDebug() <<" * * *CNT "<<m_baseTrackProducers.count();
- if (m_baseTrackProducers.count() > 0) kDebug()<<"YOYO: "<<m_baseTrackProducers.at(0)->get_out()<<", CUT: "<<m_baseTrackProducers.at(0)->is_cut();*/
qDeleteAll(m_baseTrackProducers);
m_baseTrackProducers.clear();
qDeleteAll(m_audioTrackProducers);
void DocClipBase::deleteProducers(bool clearThumbCreator)
{
if (clearThumbCreator && m_thumbProd) m_thumbProd->clearProducer();
- /*kDebug()<<"// CLIP KILL PRODS ct: "<<m_baseTrackProducers.count();
- int max = m_baseTrackProducers.count();
- for (int i = 0; i < max; i++) {
- kDebug()<<"// CLIP KILL PROD "<<i;
- Mlt::Producer *p = m_baseTrackProducers.takeAt(i);
- if (p != NULL) {
- delete p;
- p = NULL;
- }
- m_baseTrackProducers.insert(i, NULL);
- }*/
delete m_videoOnlyProducer;
m_videoOnlyProducer = NULL;
void DocClipBase::setProducer(Mlt::Producer *producer, bool reset, bool readPropertiesFromProducer)
{
- if (producer == NULL || (m_placeHolder && !reset)) return;
- if (m_thumbProd && (reset || !m_thumbProd->hasProducer())) m_thumbProd->setProducer(producer);
+ if (producer == NULL || !producer->is_valid()) return;
+ if (reset) QMutexLocker locker(&m_producerMutex);
+ if (m_placeHolder) {
+ char *tmp = qstrdup(i18n("Missing clip").toUtf8().constData());
+ producer->set("markup", tmp);
+ producer->set("bgcolour", "0xff0000ff");
+ producer->set("pad", "10");
+ delete[] tmp;
+ }
+ QString id = producer->get("id");
+ if (m_thumbProd) {
+ if (reset) m_thumbProd->setProducer(NULL);
+ if (!m_thumbProd->hasProducer()) {
+ if (m_clipType != AUDIO) {
+ if (!id.endsWith("_audio"))
+ m_thumbProd->setProducer(producer);
+ }
+ else m_thumbProd->setProducer(producer);
+ }
+ }
if (reset) {
// Clear all previous producers
kDebug() << "/+++++++++++++++ DELETE ALL PRODS " << producer->get("id");
deleteProducers(false);
}
- QString id = producer->get("id");
bool updated = false;
if (id.contains('_')) {
// this is a subtrack producer, insert it at correct place
}
if (updated && readPropertiesFromProducer && (m_clipType != COLOR && m_clipType != IMAGE && m_clipType != TEXT))
setDuration(GenTime(producer->get_length(), KdenliveSettings::project_fps()));
- //m_clipProducer = producer;
- //m_clipProducer->set("transparency", m_properties.value("transparency").toInt());
}
static double getPixelAspect(QMap<QString, QString>& props) {
Mlt::Producer *DocClipBase::audioProducer(int track)
{
+ QMutexLocker locker(&m_producerMutex);
if (m_audioTrackProducers.count() <= track) {
while (m_audioTrackProducers.count() - 1 < track) {
m_audioTrackProducers.append(NULL);
int i;
for (i = 0; i < m_audioTrackProducers.count(); i++)
if (m_audioTrackProducers.at(i) != NULL) break;
- if (i < m_audioTrackProducers.count()) {
- // Could not find a valid producer for that clip, check in
- return m_audioTrackProducers.at(i);
+ Mlt::Producer *base;
+ if (i >= m_audioTrackProducers.count()) {
+ // Could not find a valid producer for that clip
+ locker.unlock();
+ base = producer();
+ if (base == NULL) {
+ return NULL;
+ }
+ locker.relock();
}
-
- Mlt::Producer *base = producer();
- m_audioTrackProducers[track] = new Mlt::Producer(*(base->profile()), base->get("resource"));
- if (m_properties.contains("force_aspect_num") && m_properties.contains("force_aspect_den") && m_properties.contains("frame_size"))
- m_audioTrackProducers.at(track)->set("force_aspect_ratio", getPixelAspect(m_properties));
- if (m_properties.contains("force_fps")) m_audioTrackProducers.at(track)->set("force_fps", m_properties.value("force_fps").toDouble());
- if (m_properties.contains("force_progressive")) m_audioTrackProducers.at(track)->set("force_progressive", m_properties.value("force_progressive").toInt());
- if (m_properties.contains("force_tff")) m_audioTrackProducers.at(track)->set("force_tff", m_properties.value("force_tff").toInt());
- if (m_properties.contains("threads")) m_audioTrackProducers.at(track)->set("threads", m_properties.value("threads").toInt());
- m_audioTrackProducers.at(track)->set("video_index", -1);
- if (m_properties.contains("audio_index")) m_audioTrackProducers.at(track)->set("audio_index", m_properties.value("audio_index").toInt());
- m_audioTrackProducers.at(track)->set("id", QString(getId() + '_' + QString::number(track) + "_audio").toUtf8().data());
- if (m_properties.contains("force_colorspace")) m_audioTrackProducers.at(track)->set("force_colorspace", m_properties.value("force_colorspace").toInt());
- if (m_properties.contains("full_luma")) m_audioTrackProducers.at(track)->set("set.force_full_luma", m_properties.value("full_luma").toInt());
+ else base = m_audioTrackProducers.at(i);
+ m_audioTrackProducers[track] = cloneProducer(base);
+ adjustProducerProperties(m_audioTrackProducers.at(track), QString(getId() + '_' + QString::number(track) + "_audio"), false, true);
}
return m_audioTrackProducers.at(track);
}
+
+void DocClipBase::adjustProducerProperties(Mlt::Producer *prod, const QString &id, bool mute, bool blind)
+{
+ if (m_properties.contains("force_aspect_num") && m_properties.contains("force_aspect_den") && m_properties.contains("frame_size"))
+ prod->set("force_aspect_ratio", getPixelAspect(m_properties));
+ if (m_properties.contains("force_fps")) prod->set("force_fps", m_properties.value("force_fps").toDouble());
+ if (m_properties.contains("force_progressive")) prod->set("force_progressive", m_properties.value("force_progressive").toInt());
+ if (m_properties.contains("force_tff")) prod->set("force_tff", m_properties.value("force_tff").toInt());
+ if (m_properties.contains("threads")) prod->set("threads", m_properties.value("threads").toInt());
+ if (mute) prod->set("audio_index", -1);
+ else if (m_properties.contains("audio_index")) prod->set("audio_index", m_properties.value("audio_index").toInt());
+ if (blind) prod->set("video_index", -1);
+ else if (m_properties.contains("video_index")) prod->set("video_index", m_properties.value("video_index").toInt());
+ prod->set("id", id.toUtf8().data());
+ if (m_properties.contains("force_colorspace")) prod->set("force_colorspace", m_properties.value("force_colorspace").toInt());
+ if (m_properties.contains("full_luma")) prod->set("set.force_full_luma", m_properties.value("full_luma").toInt());
+ if (m_properties.contains("proxy_out")) {
+ // We have a proxy clip, make sure the proxy has same duration as original
+ prod->set("length", m_properties.value("duration").toInt());
+ prod->set("out", m_properties.value("proxy_out").toInt());
+ }
+
+}
+
Mlt::Producer *DocClipBase::videoProducer()
{
+ QMutexLocker locker(&m_producerMutex);
if (m_videoOnlyProducer == NULL) {
int i;
for (i = 0; i < m_baseTrackProducers.count(); i++)
if (m_baseTrackProducers.at(i) != NULL) break;
if (i >= m_baseTrackProducers.count()) return NULL;
- m_videoOnlyProducer = new Mlt::Producer(*m_baseTrackProducers.at(i)->profile(), m_baseTrackProducers.at(i)->get("resource"));
- if (m_properties.contains("force_aspect_num") && m_properties.contains("force_aspect_den") && m_properties.contains("frame_size"))
- m_videoOnlyProducer->set("force_aspect_ratio", getPixelAspect(m_properties));
- if (m_properties.contains("force_fps")) m_videoOnlyProducer->set("force_fps", m_properties.value("force_fps").toDouble());
- if (m_properties.contains("force_progressive")) m_videoOnlyProducer->set("force_progressive", m_properties.value("force_progressive").toInt());
- if (m_properties.contains("force_tff")) m_videoOnlyProducer->set("force_tff", m_properties.value("force_tff").toInt());
- if (m_properties.contains("threads")) m_videoOnlyProducer->set("threads", m_properties.value("threads").toInt());
- m_videoOnlyProducer->set("audio_index", -1);
- if (m_properties.contains("video_index")) m_videoOnlyProducer->set("video_index", m_properties.value("video_index").toInt());
- m_videoOnlyProducer->set("id", QString(getId() + "_video").toUtf8().data());
- if (m_properties.contains("force_colorspace")) m_videoOnlyProducer->set("force_colorspace", m_properties.value("force_colorspace").toInt());
- if (m_properties.contains("full_luma")) m_videoOnlyProducer->set("set.force_full_luma", m_properties.value("full_luma").toInt());
+ m_videoOnlyProducer = cloneProducer(m_baseTrackProducers.at(i));
+ adjustProducerProperties(m_videoOnlyProducer, QString(getId() + "_video"), true, false);
}
return m_videoOnlyProducer;
}
Mlt::Producer *DocClipBase::producer(int track)
{
- /*for (int i = 0; i < m_baseTrackProducers.count(); i++) {
- if (m_baseTrackProducers.at(i)) kDebug() << "// PROD: " << i << ", ID: " << m_baseTrackProducers.at(i)->get("id");
- }*/
+ QMutexLocker locker(&m_producerMutex);
if (track == -1 || (m_clipType != AUDIO && m_clipType != AV && m_clipType != PLAYLIST)) {
- if (m_baseTrackProducers.count() == 0) return NULL;
+ if (m_baseTrackProducers.count() == 0) {
+ return NULL;
+ }
for (int i = 0; i < m_baseTrackProducers.count(); i++) {
- if (m_baseTrackProducers.at(i) != NULL)
+ if (m_baseTrackProducers.at(i) != NULL) {
return m_baseTrackProducers.at(i);
+ }
}
return NULL;
}
// Could not find a valid producer for that clip, check in
return NULL;
}
+ m_baseTrackProducers[track] = cloneProducer(m_baseTrackProducers.at(i));
+ adjustProducerProperties(m_baseTrackProducers.at(track), QString(getId() + '_' + QString::number(track)), false, false);
+ }
+ return m_baseTrackProducers.at(track);
+}
- if (KIO::NetAccess::exists(KUrl(m_baseTrackProducers.at(i)->get("resource")), KIO::NetAccess::SourceSide, 0))
- m_baseTrackProducers[track] = new Mlt::Producer(*m_baseTrackProducers.at(i)->profile(), m_baseTrackProducers.at(i)->get("resource"));
- else { // special case for placeholder clips
- m_baseTrackProducers[track] = NULL;
- return NULL;
+
+Mlt::Producer *DocClipBase::cloneProducer(Mlt::Producer *source)
+{
+ Mlt::Producer *result = NULL;
+ QString url = source->get("resource");
+ if (KIO::NetAccess::exists(KUrl(url), KIO::NetAccess::SourceSide, 0)) {
+ char *tmp = qstrdup(url.toUtf8().constData());
+ result = new Mlt::Producer(*source->profile(), tmp);
+ delete[] tmp;
+ }
+ if (result == NULL || !result->is_valid()) {
+ // placeholder clip
+ QString txt = "+" + i18n("Missing clip") + ".txt";
+ char *tmp = qstrdup(txt.toUtf8().constData());
+ result = new Mlt::Producer(*source->profile(), tmp);
+ delete[] tmp;
+ if (result == NULL || !result->is_valid())
+ result = new Mlt::Producer(*source->profile(), "colour:red");
+ else {
+ result->set("bgcolour", "0xff0000ff");
+ result->set("pad", "10");
}
- if (m_properties.contains("force_aspect_num") && m_properties.contains("force_aspect_den") && m_properties.contains("frame_size"))
- m_baseTrackProducers[track]->set("force_aspect_ratio", getPixelAspect(m_properties));
- if (m_properties.contains("force_fps")) m_baseTrackProducers[track]->set("force_fps", m_properties.value("force_fps").toDouble());
- if (m_properties.contains("force_progressive")) m_baseTrackProducers[track]->set("force_progressive", m_properties.value("force_progressive").toInt());
- if (m_properties.contains("force_tff")) m_baseTrackProducers[track]->set("force_tff", m_properties.value("force_tff").toInt());
- if (m_properties.contains("threads")) m_baseTrackProducers[track]->set("threads", m_properties.value("threads").toInt());
- if (m_properties.contains("video_index")) m_baseTrackProducers[track]->set("video_index", m_properties.value("video_index").toInt());
- if (m_properties.contains("audio_index")) m_baseTrackProducers[track]->set("audio_index", m_properties.value("audio_index").toInt());
- m_baseTrackProducers[track]->set("id", QString(getId() + '_' + QString::number(track)).toUtf8().data());
-
- if (m_properties.contains("force_colorspace")) m_baseTrackProducers[track]->set("force_colorspace", m_properties.value("force_colorspace").toInt());
- if (m_properties.contains("full_luma")) m_baseTrackProducers[track]->set("set.force_full_luma", m_properties.value("full_luma").toInt());
}
- return m_baseTrackProducers.at(track);
+ Mlt::Properties props(result->get_properties());
+ Mlt::Properties src_props(source->get_properties());
+ props.inherit(src_props);
+ return result;
}
void DocClipBase::setProducerProperty(const char *name, int data)
bool refreshProducer = false;
QStringList keys;
keys << "luma_duration" << "luma_file" << "fade" << "ttl" << "softness" << "crop" << "animation";
+ QString oldProxy = m_properties.value("proxy");
while (i.hasNext()) {
i.next();
setProperty(i.key(), i.value());
if (m_clipType == SLIDESHOW && keys.contains(i.key())) refreshProducer = true;
}
+ if (properties.contains("proxy")) {
+ QString value = properties.value("proxy");
+ // If value is "-", that means user manually disabled proxy on this clip
+ if (value.isEmpty() || value == "-") {
+ // reset proxy
+ emit abortProxy(m_id, oldProxy);
+ }
+ else {
+ emit createProxy(m_id);
+ }
+ }
if (refreshProducer) slotRefreshProducer();
}
else if (m_clipType == TEXT) hash = QCryptographicHash::hash(QString("title" + getId() + m_properties.value("xmldata")).toUtf8().data(), QCryptographicHash::Md5).toHex();
else {
if (m_properties.contains("file_hash")) hash = m_properties.value("file_hash");
- else hash = getHash(fileURL().path());
+ if (hash.isEmpty()) hash = getHash(fileURL().path());
}
return hash;
resetProducerProperty("set.force_full_luma");
} else setProducerProperty("set.force_full_luma", value.toInt());
}
- else if (key == "proxy") {
- // If value is "-", that means user manually disabled proxy on this clip
- if (value.isEmpty() || value == "-") {
- // reset proxy
- emit abortProxy(m_id);
- }
- else {
- emit createProxy(m_id);
- }
- }
}
QMap <QString, QString> DocClipBase::properties() const
}
+void DocClipBase::slotExtractImage(int frame, int frame2)
+{
+ if (m_thumbProd == NULL) return;
+ m_thumbProd->extractImage(frame, frame2);
+}
+
+QPixmap DocClipBase::extractImage(int frame, int width, int height)
+{
+ if (m_thumbProd == NULL) return QPixmap(width, height);
+ QMutexLocker locker(&m_producerMutex);
+ QPixmap p = m_thumbProd->extractImage(frame, width, height);
+ return p;
+}
+