Пример #1
0
bool EffectManager::editEffect(EffectsParameterList params, int duration, bool replaceEffect)
{
    int index = params.paramValue(QStringLiteral("kdenlive_ix")).toInt();
    QString tag =  params.paramValue(QStringLiteral("tag"));

    if (!params.paramValue(QStringLiteral("keyframes")).isEmpty() || replaceEffect || tag.startsWith(QLatin1String("ladspa")) || tag == QLatin1String("sox") || tag == QLatin1String("autotrack_rectangle")) {
        // This is a keyframe effect, to edit it, we remove it and re-add it.
        if (removeEffect(index, false)) {
            return addEffect(params, duration);
        }
    }

    // find filter
    int ct = 0;
    Mlt::Filter *filter = m_producer.filter(ct);
    while (filter) {
        if (filter->get_int("kdenlive_ix") == index) {
            break;
        }
        delete filter;
        ct++;
        filter = m_producer.filter(ct);
    }

    if (!filter) {
        qDebug() << "WARINIG, FILTER FOR EDITING NOT FOUND, ADDING IT! " << index << ", " << tag;
        // filter was not found, it was probably a disabled filter, so add it to the correct place...

        bool success = addEffect(params, duration);
        return success;
    }
    ct = 0;
    QString ser = filter->get("mlt_service");
    QList <Mlt::Filter *> filtersList;
    m_producer.lock();
    if (ser != tag) {
        // Effect service changes, delete effect and re-add it
        m_producer.detach(*filter);
        delete filter;
        // Delete all effects after deleted one
        filter = m_producer.filter(ct);
        while (filter) {
            if (filter->get_int("kdenlive_ix") > index) {
                filtersList.append(filter);
                m_producer.detach(*filter);
            }
            else ct++;
            delete filter;
            filter = m_producer.filter(ct);
        }

        // re-add filter
        doAddFilter(params, duration);
        m_producer.unlock();
        return true;
    }
    if (params.hasParam(QStringLiteral("kdenlive:sync_in_out"))) {
        if (params.paramValue(QStringLiteral("kdenlive:sync_in_out")) == QLatin1String("1")) {
            // This effect must sync in / out with parent clip
            //params.removeParam(QStringLiteral("sync_in_out"));
            Mlt::Producer prod(m_producer);
            filter->set_in_and_out(prod.get_in(), prod.get_out());
        } else {
            // Reset in/out properties
            filter->set("in", (char*)NULL);
            filter->set("out", (char*)NULL);
        }
    }

    for (int j = 0; j < params.count(); ++j) {
        filter->set(params.at(j).name().toUtf8().constData(), params.at(j).value().toUtf8().constData());
    }

    for (int j = 0; j < filtersList.count(); ++j) {
        m_producer.attach(*(filtersList.at(j)));
    }
    qDeleteAll(filtersList);
    m_producer.unlock();
    delete filter;
    return true;
}
Пример #2
0
bool EffectManager::doAddFilter(EffectsParameterList params, int duration)
{
    // create filter
    QString tag =  params.paramValue(QStringLiteral("tag"));
    QLocale locale;
    ////qDebug() << " / / INSERTING EFFECT: " << tag << ", REGI: " << region;
    QString kfr = params.paramValue(QStringLiteral("keyframes"));
    if (!kfr.isEmpty()) {
        QStringList keyFrames = kfr.split(';', QString::SkipEmptyParts);
        char *starttag = qstrdup(params.paramValue(QStringLiteral("starttag"), QStringLiteral("start")).toUtf8().constData());
        char *endtag = qstrdup(params.paramValue(QStringLiteral("endtag"), QStringLiteral("end")).toUtf8().constData());
        ////qDebug() << "// ADDING KEYFRAME TAGS: " << starttag << ", " << endtag;
        //double max = params.paramValue("max").toDouble();
        double min = params.paramValue(QStringLiteral("min")).toDouble();
        double factor = params.paramValue(QStringLiteral("factor"), QStringLiteral("1")).toDouble();
        double paramOffset = params.paramValue(QStringLiteral("offset"), QStringLiteral("0")).toDouble();
        params.removeParam(QStringLiteral("starttag"));
        params.removeParam(QStringLiteral("endtag"));
        params.removeParam(QStringLiteral("keyframes"));
        params.removeParam(QStringLiteral("min"));
        params.removeParam(QStringLiteral("max"));
        params.removeParam(QStringLiteral("factor"));
        params.removeParam(QStringLiteral("offset"));
        // Special case, only one keyframe, means we want a constant value
        if (keyFrames.count() == 1) {
            Mlt::Filter *filter = new Mlt::Filter(*m_producer.profile(), qstrdup(tag.toUtf8().constData()));
            if (filter && filter->is_valid()) {
                filter->set("kdenlive_id", qstrdup(params.paramValue(QStringLiteral("id")).toUtf8().constData()));
                int x1 = keyFrames.at(0).section('=', 0, 0).toInt();
                double y1 = keyFrames.at(0).section('=', 1, 1).toDouble();
                for (int j = 0; j < params.count(); ++j) {
                    filter->set(params.at(j).name().toUtf8().constData(), params.at(j).value().toUtf8().constData());
                }
                filter->set("in", x1);
                ////qDebug() << "// ADDING KEYFRAME vals: " << min<<" / "<<max<<", "<<y1<<", factor: "<<factor;
                filter->set(starttag, locale.toString(((min + y1) - paramOffset) / factor).toUtf8().data());
                m_producer.attach(*filter);
                delete filter;
            } else {
                delete[] starttag;
                delete[] endtag;
                //qDebug() << "filter is NULL";
                m_producer.unlock();
                return false;
            }
        } else for (int i = 0; i < keyFrames.size() - 1; ++i) {
            Mlt::Filter *filter = new Mlt::Filter(*m_producer.profile(), qstrdup(tag.toUtf8().constData()));
            if (filter && filter->is_valid()) {
                filter->set("kdenlive_id", qstrdup(params.paramValue(QStringLiteral("id")).toUtf8().constData()));
                int x1 = keyFrames.at(i).section('=', 0, 0).toInt();
                double y1 = keyFrames.at(i).section('=', 1, 1).toDouble();
                int x2 = keyFrames.at(i + 1).section('=', 0, 0).toInt();
                double y2 = keyFrames.at(i + 1).section('=', 1, 1).toDouble();
                if (x2 == -1) x2 = duration;
                // non-overlapping sections
                if (i > 0) {
                    y1 += (y2 - y1) / (x2 - x1);
                    ++x1;
                }

                for (int j = 0; j < params.count(); ++j) {
                    filter->set(params.at(j).name().toUtf8().constData(), params.at(j).value().toUtf8().constData());
                }

                filter->set("in", x1);
                filter->set("out", x2);
                ////qDebug() << "// ADDING KEYFRAME vals: " << min<<" / "<<max<<", "<<y1<<", factor: "<<factor;
                filter->set(starttag, locale.toString(((min + y1) - paramOffset) / factor).toUtf8().data());
                filter->set(endtag, locale.toString(((min + y2) - paramOffset) / factor).toUtf8().data());
                m_producer.attach(*filter);
                delete filter;
            } else {
                delete[] starttag;
                delete[] endtag;
                //qDebug() << "filter is NULL";
                m_producer.unlock();
                return false;
            }
        }
        delete[] starttag;
        delete[] endtag;
    } else {
        Mlt::Filter *filter;
        QString prefix;
        filter = new Mlt::Filter(*m_producer.profile(), qstrdup(tag.toUtf8().constData()));
        if (filter && filter->is_valid()) {
            filter->set("kdenlive_id", qstrdup(params.paramValue(QStringLiteral("id")).toUtf8().constData()));
        } else {
            //qDebug() << "filter is NULL";
            m_producer.unlock();
            return false;
        }
        params.removeParam(QStringLiteral("kdenlive_id"));
        if (params.paramValue(QStringLiteral("kdenlive:sync_in_out")) == QLatin1String("1")) {
            // This effect must sync in / out with parent clip
            //params.removeParam(QStringLiteral("_sync_in_out"));
            filter->set_in_and_out(m_producer.get_int("in"), m_producer.get_int("out"));
        }

        for (int j = 0; j < params.count(); ++j) {
            filter->set((prefix + params.at(j).name()).toUtf8().constData(), params.at(j).value().toUtf8().constData());
        }

        if (tag == QLatin1String("sox")) {
            QString effectArgs = params.paramValue(QStringLiteral("id")).section('_', 1);

            params.removeParam(QStringLiteral("id"));
            params.removeParam(QStringLiteral("kdenlive_ix"));
            params.removeParam(QStringLiteral("tag"));
            params.removeParam(QStringLiteral("disable"));
            params.removeParam(QStringLiteral("region"));

            for (int j = 0; j < params.count(); ++j) {
                effectArgs.append(' ' + params.at(j).value());
            }
            ////qDebug() << "SOX EFFECTS: " << effectArgs.simplified();
            filter->set("effect", effectArgs.simplified().toUtf8().constData());
        }
        // attach filter to the clip
        m_producer.attach(*filter);
        delete filter;
    }
    return true;
}