+ return QString();
+}
+
+void DocClipBase::clearProducers()
+{
+ m_baseTrackProducers.clear();
+}
+
+void DocClipBase::deleteProducers()
+{
+ kDebug() << "// CLIP KILL PRODS ct: " << m_baseTrackProducers.count();
+ if (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;
+
+ qDeleteAll(m_baseTrackProducers);
+ m_baseTrackProducers.clear();
+ qDeleteAll(m_audioTrackProducers);
+ m_audioTrackProducers.clear();
+}
+
+void DocClipBase::setProducer(Mlt::Producer *producer, bool reset)
+{
+ if (producer == NULL) return;
+ if (reset) {
+ // Clear all previous producers
+ kDebug() << "/+++++++++++++++ DELETE ALL PRODS " << producer->get("id");
+ deleteProducers();
+ }
+ QString id = producer->get("id");
+ if (id.contains('_')) {
+ // this is a subtrack producer, insert it at correct place
+ id = id.section('_', 1);
+ if (id.endsWith("audio")) {
+ int pos = id.section('_', 0, 0).toInt();
+ if (pos >= m_audioTrackProducers.count()) {
+ while (m_audioTrackProducers.count() - 1 < pos) {
+ m_audioTrackProducers.append(NULL);
+ }
+ }
+ if (m_audioTrackProducers.at(pos) == NULL) m_audioTrackProducers[pos] = producer;
+ return;
+ } else if (id.endsWith("video")) {
+ m_videoOnlyProducer = producer;
+ return;
+ }
+ int pos = id.toInt();
+ if (pos >= m_baseTrackProducers.count()) {
+ while (m_baseTrackProducers.count() - 1 < pos) {
+ m_baseTrackProducers.append(NULL);
+ }
+ }
+ if (m_baseTrackProducers.at(pos) == NULL) m_baseTrackProducers[pos] = producer;
+ } else {
+ if (m_baseTrackProducers.isEmpty()) m_baseTrackProducers.append(producer);
+ else if (m_baseTrackProducers.at(0) == NULL) m_baseTrackProducers[0] = producer;
+ }
+ //m_clipProducer = producer;
+ //m_clipProducer->set("transparency", m_properties.value("transparency").toInt());
+ if (m_thumbProd && (reset || !m_thumbProd->hasProducer())) m_thumbProd->setProducer(producer);
+}
+
+Mlt::Producer *DocClipBase::audioProducer(int track)
+{
+ if (m_audioTrackProducers.count() <= track) {
+ while (m_audioTrackProducers.count() - 1 < track) {
+ m_audioTrackProducers.append(NULL);
+ }
+ }
+ if (m_audioTrackProducers.at(track) == NULL) {
+ Mlt::Producer *base = producer();
+ m_audioTrackProducers[track] = new Mlt::Producer(*(base->profile()), base->get("resource"));
+ if (m_properties.contains("force_aspect_ratio")) m_audioTrackProducers.at(track)->set("force_aspect_ratio", m_properties.value("force_aspect_ratio").toDouble());
+ 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());
+ char *tmp = (char *) qstrdup(QString(getId() + '_' + QString::number(track) + "_audio").toUtf8().data());
+ m_audioTrackProducers.at(track)->set("id", tmp);
+ delete[] tmp;
+ }
+ return m_audioTrackProducers.at(track);
+}
+
+Mlt::Producer *DocClipBase::videoProducer()
+{
+ 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_ratio")) m_videoOnlyProducer->set("force_aspect_ratio", m_properties.value("force_aspect_ratio").toDouble());
+ 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());
+ char *tmp = (char *) qstrdup(QString(getId() + "_video").toUtf8().data());
+ m_videoOnlyProducer->set("id", tmp);
+ delete[] tmp;
+ }
+ 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");
+ }*/
+ if (track == -1 || (m_clipType != AUDIO && m_clipType != AV)) {
+ if (m_baseTrackProducers.count() == 0) return NULL;
+ for (int i = 0; i < m_baseTrackProducers.count(); i++) {
+ if (m_baseTrackProducers.at(i) != NULL)
+ return m_baseTrackProducers.at(i);
+ }
+ return NULL;
+ }
+ if (track >= m_baseTrackProducers.count()) {
+ while (m_baseTrackProducers.count() - 1 < track) {
+ m_baseTrackProducers.append(NULL);
+ }
+ }
+ if (m_baseTrackProducers.at(track) == 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;
+
+ 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;
+ }
+
+ if (m_properties.contains("force_aspect_ratio")) m_baseTrackProducers[track]->set("force_aspect_ratio", m_properties.value("force_aspect_ratio").toDouble());
+ 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());
+ char *tmp = (char *) qstrdup(QString(getId() + '_' + QString::number(track)).toUtf8().data());
+ m_baseTrackProducers[track]->set("id", tmp);
+ delete[] tmp;
+ if (KdenliveSettings::dropbframes() && m_baseTrackProducers.at(i)->get("skip_loop_filter") && strcmp(m_baseTrackProducers.at(i)->get("skip_loop_filter"), "all") == 0) {
+ m_baseTrackProducers[track]->set("skip_loop_filter", "all");
+ m_baseTrackProducers[track]->set("skip_frame", "bidir");
+ }
+ }
+ return m_baseTrackProducers.at(track);
+}
+
+void DocClipBase::setProducerProperty(const char *name, int data)
+{
+ for (int i = 0; i < m_baseTrackProducers.count(); i++) {
+ if (m_baseTrackProducers.at(i) != NULL)
+ m_baseTrackProducers[i]->set(name, data);
+ }
+}
+
+void DocClipBase::setProducerProperty(const char *name, double data)
+{
+ for (int i = 0; i < m_baseTrackProducers.count(); i++) {
+ if (m_baseTrackProducers.at(i) != NULL)
+ m_baseTrackProducers[i]->set(name, data);
+ }
+}
+
+void DocClipBase::setProducerProperty(const char *name, const char *data)
+{
+ for (int i = 0; i < m_baseTrackProducers.count(); i++) {
+ if (m_baseTrackProducers.at(i) != NULL)
+ m_baseTrackProducers[i]->set(name, data);
+ }
+}
+
+const char *DocClipBase::producerProperty(const char *name) const
+{
+ for (int i = 0; i < m_baseTrackProducers.count(); i++) {
+ if (m_baseTrackProducers.at(i) != NULL) {
+ return m_baseTrackProducers.at(i)->get(name);
+ }
+ }
+ return NULL;
+}
+
+
+void DocClipBase::slotRefreshProducer()
+{
+ if (m_baseTrackProducers.count() == 0) return;
+ kDebug() << "//////////// REFRESH CLIP !!!!!!!!!!!!!!!!";
+ if (m_clipType == SLIDESHOW) {
+ /*char *tmp = (char *) qstrdup(getProperty("resource").toUtf8().data());
+ Mlt::Producer producer(*(m_clipProducer->profile()), tmp);
+ delete[] tmp;
+ delete m_clipProducer;
+ m_clipProducer = new Mlt::Producer(producer.get_producer());
+ if (!getProperty("out").isEmpty()) m_clipProducer->set_in_and_out(getProperty("in").toInt(), getProperty("out").toInt());*/
+ setProducerProperty("ttl", getProperty("ttl").toInt());
+ //m_clipProducer->set("id", getProperty("id"));
+ if (getProperty("fade") == "1") {
+ // we want a fade filter effect
+ kDebug() << "//////////// FADE WANTED";
+ Mlt::Service clipService(m_baseTrackProducers.at(0)->get_service());
+ int ct = 0;
+ Mlt::Filter *filter = clipService.filter(ct);
+ while (filter) {
+ if (strcmp(filter->get("mlt_service"), "luma") == 0) {
+ break;
+ }
+ ct++;
+ filter = clipService.filter(ct);
+ }
+
+ if (filter && strcmp(filter->get("mlt_service"), "luma") == 0) {
+ filter->set("period", getProperty("ttl").toInt() - 1);
+ filter->set("luma.out", getProperty("luma_duration").toInt());
+ QString resource = getProperty("luma_file");
+ char *tmp = (char *) qstrdup(resource.toUtf8().data());
+ filter->set("luma.resource", tmp);
+ delete[] tmp;
+ if (!getProperty("softness").isEmpty()) {
+ int soft = getProperty("softness").toInt();
+ filter->set("luma.softness", (double) soft / 100.0);
+ }
+ } else {
+ // filter does not exist, create it...
+ Mlt::Filter *filter = new Mlt::Filter(*(m_baseTrackProducers.at(0)->profile()), "luma");
+ filter->set("period", getProperty("ttl").toInt() - 1);
+ filter->set("luma.out", getProperty("luma_duration").toInt());
+ QString resource = getProperty("luma_file");
+ char *tmp = (char *) qstrdup(resource.toUtf8().data());
+ filter->set("luma.resource", tmp);
+ delete[] tmp;
+ if (!getProperty("softness").isEmpty()) {
+ int soft = getProperty("softness").toInt();
+ filter->set("luma.softness", (double) soft / 100.0);
+ }
+ clipService.attach(*filter);
+ }
+ } else {
+ kDebug() << "//////////// FADE NOT WANTED!!!";
+ Mlt::Service clipService(m_baseTrackProducers.at(0)->get_service());
+ int ct = 0;
+ Mlt::Filter *filter = clipService.filter(0);
+ while (filter) {
+ if (strcmp(filter->get("mlt_service"), "luma") == 0) {
+ clipService.detach(*filter);
+ } else ct++;
+ filter = clipService.filter(ct);
+ }
+ }
+ }