Logo Search packages:      
Sourcecode: kdenlive version File versions

docclipavfile.cpp

/***************************************************************************
                          DocClipAVFile.cpp  -  description
                             -------------------
    begin                : Fri Feb 15 2002
    copyright            : (C) 2002 by Jason Wood
    email                : jasonwood@blueyonder.co.uk
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include "docclipavfile.h"

#include <iostream>
#include <assert.h>

#include <qfileinfo.h>

#include <kdebug.h>
#include <klocale.h>
#include <kio/netaccess.h>


#include "clipmanager.h"
#include "kdenlivesettings.h"

#define AUDIO_FRAME_WIDTH 20


DocClipAVFile::DocClipAVFile(const QString & name, const KURL & url,
    uint id):DocClipBase(), m_duration(0.0), m_url(url),
m_durationKnown(false), m_framesPerSecond(0), m_color(QString::null),
m_clipType(NONE), m_alphaTransparency(false), m_loop(false), m_channels(0), m_frequency(0), m_ttl(0), m_hasCrossfade(false), m_audioTimer(0)
{
    thumbCreator = new KThumb();
    m_audioTimer = new QTimer( this );
    connect(m_audioTimer, SIGNAL(timeout()), this, SLOT(getAudioThumbs()));
    setName(name);
    setId(id);
}

/* color clip */
DocClipAVFile::DocClipAVFile(const QString & color, const GenTime & duration, uint id):DocClipBase(),  m_duration(duration),
m_url(QString::null), m_hasCrossfade(false), m_durationKnown(true),m_framesPerSecond(KdenliveSettings::defaultfps()),
m_color(color), m_clipType(COLOR), m_filesize(0), m_alphaTransparency(false), m_loop(false), m_channels(0),m_frequency(0), m_ttl(0), m_videoCodec(NULL), m_audioCodec(NULL), m_audioTimer(0)
{
    setName(i18n("Color Clip"));
    m_width = KdenliveSettings::defaultwidth();
    m_height = KdenliveSettings::defaultheight();
    setId(id);
}

/*  Image clip */
00060 DocClipAVFile::DocClipAVFile(const KURL & url, const GenTime & duration, bool alphaTransparency, uint id):DocClipBase(),
m_duration(duration), m_hasCrossfade(false), m_url(url), m_durationKnown(true),
m_framesPerSecond(KdenliveSettings::defaultfps()), m_color(QString::null), m_clipType(IMAGE), m_alphaTransparency(alphaTransparency), m_loop(false), m_channels(0), m_frequency(0), m_ttl(0), m_videoCodec(NULL), m_audioCodec(NULL), m_audioTimer(0)
{
    setName(url.fileName());
    setId(id);
    QFileInfo fileInfo(m_url.path());
    QPixmap p(m_url.path());
    m_width = p.width();
    m_height = p.height();
    /* Determines the size of the file */
    m_filesize = fileInfo.size();
    
}

/*  Slideshow clip */
00076 DocClipAVFile::DocClipAVFile(const KURL & url, const QString & extension,
    const int &ttl, const GenTime & duration, bool alphaTransparency, bool loop, bool crossfade, const QString &lumaFile, double lumasoftness, uint lumaduration, uint id):DocClipBase(),
m_duration(duration), m_url(url), m_durationKnown(true), m_hasCrossfade(crossfade), m_luma(lumaFile), m_lumasoftness(lumasoftness), m_lumaduration(lumaduration),
m_framesPerSecond(KdenliveSettings::defaultfps()), m_color(QString::null), m_clipType(SLIDESHOW), m_alphaTransparency(alphaTransparency), m_loop(loop), m_channels(0), m_frequency(0), m_ttl(ttl), m_videoCodec(NULL), m_audioCodec(NULL), m_audioTimer(0)
{
    setName(i18n("Slideshow"));
    setId(id);
    QFileInfo fileInfo(m_url.path());
    QPixmap p(m_url.path());
    m_width = p.width();
    m_height = p.height();
    /* Determines the size of the file */
    m_filesize = fileInfo.size();
    
}

DocClipAVFile::DocClipAVFile(const KURL & url):DocClipBase(),
m_duration(0.0),
m_url(url), m_hasCrossfade(false), 
m_durationKnown(false), 
m_framesPerSecond(0), m_color(QString::null), m_clipType(NONE), m_alphaTransparency(false), m_loop(false), m_channels(0), m_frequency(0),  m_ttl(0), m_videoCodec(NULL), m_audioCodec(NULL), m_audioTimer(0)
{
    setName(url.fileName());
    thumbCreator = new KThumb();
    m_audioTimer = new QTimer( this );
    connect(m_audioTimer, SIGNAL(timeout()), this, SLOT(getAudioThumbs()));
    // #TODO: What about the id of these clips ?
}

DocClipAVFile::DocClipAVFile(QDomDocument node):DocClipBase()
{
QDomElement element = node.documentElement(); 
 if (element.tagName() != "kdenliveclip") {
      kdWarning() <<
          "DocClipRef::createClip() element has unknown tagName : " <<
          element.tagName() << endl;
      return;
    }

    QDomNode n = element.firstChild();

    while (!n.isNull()) {
      QDomElement e = n.toElement();
      if (!e.isNull()) {
          //kdWarning() << "DocClipRef::createClip() tag = " << e.tagName() << endl;
          if (e.tagName() == "avfile") {
            m_url.setPath(e.attribute("url", QString::null));
            uint clipType = e.attribute("type", QString::null).toInt();
                setId(e.attribute("id", "-1").toInt());
                m_filesize = e.attribute("filesize", "0").toInt();
            m_alphaTransparency = e.attribute("transparency", "0").toInt();
            if (clipType == DocClipBase::SLIDESHOW) {
                m_hasCrossfade = e.attribute("crossfade", "0").toInt();
                m_loop = e.attribute("loop", "0").toInt();
                m_ttl = e.attribute("ttl", "0").toInt();
                m_luma = e.attribute("lumafile", QString::null);
                m_lumasoftness = e.attribute("lumasoftness", "0").toDouble();
                m_lumaduration = e.attribute("lumaduration", "0").toInt();
            }
            m_width = e.attribute("width", "0").toInt();
            m_height = e.attribute("height", "0").toInt();
            m_channels = e.attribute("channels", "0").toInt();
            m_frequency = e.attribute("frequency", "0").toInt();
            m_videoCodec = e.attribute("videocodec", QString::null);
            m_audioCodec = e.attribute("audiocodec", QString::null);
            m_durationKnown = e.attribute("durationknown", "0" ).toInt();
            if (clipType == DocClipBase::COLOR) m_color = e.attribute("color", QString::null);
            m_duration = GenTime(e.attribute("duration", "0").toInt(), KdenliveSettings::defaultfps());
            setName(e.attribute("name", QString::null));
            setDescription(e.attribute("description", QString::null));
            m_audioTimer = 0;
            switch (clipType) {
                case DocClipBase::NONE:
                  thumbCreator = new KThumb();
                  m_audioTimer = new QTimer( this );
                  connect(m_audioTimer, SIGNAL(timeout()), this, SLOT(getAudioThumbs()));
                  m_clipType = DocClipBase::NONE;
                  break;
                case DocClipBase::AUDIO:
                  thumbCreator = new KThumb();
                  m_audioTimer = new QTimer( this );
                  connect(m_audioTimer, SIGNAL(timeout()), this, SLOT(getAudioThumbs()));
                  m_clipType = DocClipBase::AUDIO;
                  break;
                case DocClipBase::VIDEO:
                  thumbCreator = new KThumb();
                  m_clipType = DocClipBase::VIDEO;
                  break;
                case DocClipBase::PLAYLIST:
                  thumbCreator = new KThumb();
                  m_audioTimer = new QTimer( this );
                  connect(m_audioTimer, SIGNAL(timeout()), this, SLOT(getAudioThumbs()));
                  m_clipType = DocClipBase::PLAYLIST;
                  break;
                case DocClipBase::AV:
                  thumbCreator = new KThumb();
                  m_audioTimer = new QTimer( this );
                  connect(m_audioTimer, SIGNAL(timeout()), this, SLOT(getAudioThumbs()));
                  m_clipType = DocClipBase::AV;
                  break;
                case DocClipBase::COLOR:
                  m_clipType = DocClipBase::COLOR;
                  break;
                case DocClipBase::IMAGE:
                  m_clipType = DocClipBase::IMAGE;
                  break;
                case DocClipBase::TEXT:
                  m_clipType = DocClipBase::TEXT;
                  break;
                case DocClipBase::SLIDESHOW:
                  m_clipType = DocClipBase::SLIDESHOW;
                  break;
            }
          }
      }
      n = n.nextSibling();
    }

}


DocClipAVFile::~DocClipAVFile()
{
    if (m_audioTimer) delete m_audioTimer;
}

void DocClipAVFile::removeTmpFile() const
{
    if (thumbCreator) thumbCreator->removeAudioThumb();
}

void DocClipAVFile::prepareThumbs() const
{
    if (m_audioTimer) m_audioTimer->start(1000, true);
}

bool DocClipAVFile::isTransparent() const
{
    return m_alphaTransparency;
}

bool DocClipAVFile::loop() const
{
    return m_loop;
}

void DocClipAVFile::setLoop(bool isOn)
{
    m_loop = isOn;
}

bool DocClipAVFile::hasCrossfade() const
{
    return m_hasCrossfade;
}

void DocClipAVFile::setCrossfade( bool cross)
{
    m_hasCrossfade = cross;
}

void DocClipAVFile::setAlpha(bool transp)
{
    m_alphaTransparency = transp;
}

00242 const GenTime & DocClipAVFile::duration() const
{
    return m_duration;
}

00247 const DocClipBase::CLIPTYPE & DocClipAVFile::clipType() const
{
    return m_clipType;
}


00253 const KURL & DocClipAVFile::fileURL() const
{
    return m_url;
}

00258 DocClipAVFile *DocClipAVFile::createClip(const QDomElement element)
{
      DocClipAVFile *file = 0;
      if(element.tagName() == "avfile") {
            KURL url;
            url.setPath(element.attribute("url"));
            if (KIO::NetAccess::exists(url, true, 0))
                  file = new DocClipAVFile(url);
      } else {
            kdWarning() << "DocClipAVFile::createClip failed to generate clip" << endl;
      }

      return file;
}

00273 void DocClipAVFile::setFileURL(const KURL & url)
{
    m_url = url;
    setName(url.fileName());
    QFileInfo fileInfo(m_url.path());
    m_durationKnown = false;
    /* Determines the size of the file */
    m_filesize = fileInfo.size();
}

00283 void DocClipAVFile::setDuration(const GenTime & duration)
{
    m_durationKnown = true;
    m_duration = duration;
}

00289 void DocClipAVFile::setColor(const QString color)
{
    m_color = color;
}

00294 const QString & DocClipAVFile::color() const
{
    return m_color;
}

00299 bool DocClipAVFile::durationKnown() const
{
    return m_durationKnown;
}

// virtual
double DocClipAVFile::framesPerSecond() const
{
    return m_framesPerSecond;
}

//returns clip video properties -reh
uint DocClipAVFile::clipHeight() const
{
    return m_height;
}

uint DocClipAVFile::clipWidth() const
{
    return m_width;
}

//returns slideshow time for each image (in frames)
int DocClipAVFile::clipTtl() const
{
    return m_ttl;
}

void DocClipAVFile::setClipTtl(const int &ttl)
{
    m_ttl = ttl;
}

void DocClipAVFile::setLumaFile(const QString & luma)
{
    m_luma = luma;
}

const QString & DocClipAVFile::lumaFile() const
{
    return m_luma;
}

void DocClipAVFile::setLumaSoftness(const double & softness)
{
    m_lumasoftness = softness;
}

const double & DocClipAVFile::lumaSoftness() const
{
    return m_lumasoftness;
}

void DocClipAVFile::setLumaDuration(const uint & duration)
{
    m_lumaduration = duration;
}

const uint & DocClipAVFile::lumaDuration() const
{
    return m_lumaduration;
}

QString DocClipAVFile::avDecompressor()
{
    return m_decompressor;
}

QString DocClipAVFile::avSystem()
{
    return m_system;
}

//returns clip audio properties -reh
uint DocClipAVFile::audioChannels() const
{
    return m_channels;
}

QString DocClipAVFile::audioFormat()
{
    return m_format;
}

uint DocClipAVFile::audioBits() const
{
    return m_bitspersample;
}

uint DocClipAVFile::audioFrequency() const
{
    return m_frequency;
}

void DocClipAVFile::getAudioThumbs()
{
    double lengthInFrames=duration().frames(framesPerSecond());
    thumbCreator->getAudioThumbs(fileURL(), m_channels, 0, lengthInFrames,AUDIO_FRAME_WIDTH);
}

void DocClipAVFile::stopAudioThumbs()
{
    thumbCreator->stopAudioThumbs();
}

double DocClipAVFile::aspectRatio() const
{
    return KdenliveSettings::aspectratio();
    double ratio = ((double) KdenliveSettings::defaultwidth()/KdenliveSettings::defaultheight())/((double)clipWidth()/clipHeight()) * KdenliveSettings::aspectratio();
    return ratio;
}

/*
// virtual
QDomDocument DocClipAVFile::generateSceneList() const
{
      static QString str_inpoint="clipBegin";
      static QString str_outpoint="clipEnd";
      static QString str_file="src";

      QDomDocument scenelist;
      scenelist.appendChild(scenelist.createElement("scenelist"));

      // generate the next scene.
      QDomElement scene = scenelist.createElement("seq");

      QDomElement sceneClip;
      sceneClip = scenelist.createElement("video");
      sceneClip.setAttribute(str_file, fileURL().path());
      sceneClip.setAttribute(str_inpoint, "0.0");
      sceneClip.setAttribute(str_outpoint, QString::number(duration().seconds()));
      scene.appendChild(sceneClip);
      scenelist.documentElement().appendChild(scene);

      return scenelist;
}
*/

// virtual
QDomDocument DocClipAVFile::sceneToXML(const GenTime & startTime,
    const GenTime & endTime) const
{
}

// virtual
QDomDocument DocClipAVFile::generateSceneList(bool, bool) const
{
    QDomDocument sceneList;
    QDomElement westley = sceneList.createElement("westley");
    sceneList.appendChild(westley);

    if (clipType() == IMAGE || clipType() == SLIDESHOW ) {

            QDomElement producer = sceneList.createElement("producer");
        producer.setAttribute("id", 0);
        producer.setAttribute("resource", fileURL().path());
        if (KdenliveSettings::distortimages()) producer.setAttribute("aspect_ratio", QString::number(aspectRatio()));
      // else producer.setAttribute("aspect_ratio", QString::number(KdenliveSettings::aspectratio()));
      
        producer.setAttribute("in", "0");
        producer.setAttribute("out",
        QString::number(duration().frames(KdenliveSettings::defaultfps()) - 1));

      if (clipType() == SLIDESHOW) {
          producer.setAttribute("ttl", clipTtl());
          if (hasCrossfade()) {
            QDomElement clipFilter =
            sceneList.createElement("filter");
            clipFilter.setAttribute("mlt_service", "luma");
            clipFilter.setAttribute("period", QString::number(clipTtl()));
            clipFilter.setAttribute("resource", lumaFile());
            clipFilter.setAttribute("luma.softness", QString::number(lumaSoftness()));
            //clipFilter.setAttribute("luma.out", QString::number(lumaDuration()));
            producer.appendChild(clipFilter);
            }
      }
      westley.appendChild(producer);
    }

    else if (clipType() == COLOR) {
      QDomElement producer = sceneList.createElement("producer");
      producer.setAttribute("id", getId());
      producer.setAttribute("mlt_service", "colour");
      producer.setAttribute("colour", color());
      westley.appendChild(producer);
      producer.setAttribute("in", "0");
      producer.setAttribute("out",
          QString::number(duration().frames(KdenliveSettings::defaultfps()) - 1));
      westley.appendChild(producer);
    }
    else {
      // AUDIO OR VIDEO CLIP
      QDomElement producer = sceneList.createElement("producer");
      producer.setAttribute("id", getId());
      producer.setAttribute("resource", fileURL().path());
      westley.appendChild(producer);
    }

    //kdDebug()<<"++++++++++++CLIP SCENE:\n"<<sceneList.toString()<<endl;


    return sceneList;
}

void DocClipAVFile::populateSceneTimes(QValueVector < GenTime >
    &toPopulate) const
{
    toPopulate.append(GenTime(0));
    toPopulate.append(duration());
}

00510 uint DocClipAVFile::fileSize() const
{
    return m_filesize;
}

QString DocClipAVFile::videoCodec() const
{
    return m_videoCodec;
}

QString DocClipAVFile::audioCodec() const
{
    return m_audioCodec;
}

// virtual
00526 bool DocClipAVFile::referencesClip(DocClipBase * clip) const
{
    return this == clip;
}

// virtual
QDomDocument DocClipAVFile::toXML() const
{

    QDomDocument doc = DocClipBase::toXML();
    QDomNode node = doc.firstChild();

    while (!node.isNull()) {
      QDomElement element = node.toElement();
      if (!element.isNull()) {
          if (element.tagName() == "kdenliveclip") {
            QDomElement avfile = doc.createElement("avfile");
            avfile.setAttribute("url", fileURL().path());
            avfile.setAttribute("type", m_clipType);
                avfile.setAttribute("id", getId());
            avfile.setAttribute("durationknown", m_durationKnown );
            avfile.setAttribute("duration", m_duration.frames(KdenliveSettings::defaultfps()));
                avfile.setAttribute("filesize", m_filesize);
            avfile.setAttribute("transparency", m_alphaTransparency);

            if (m_clipType == DocClipBase::SLIDESHOW) {
                avfile.setAttribute("crossfade", m_hasCrossfade);
                avfile.setAttribute("loop", m_loop);
                avfile.setAttribute("ttl", m_ttl);
                avfile.setAttribute("lumafile", m_luma);
                avfile.setAttribute("lumasoftness", m_lumasoftness);
                avfile.setAttribute("lumaduration", m_lumaduration);
            }

            avfile.setAttribute("channels", m_channels);
            avfile.setAttribute("frequency", m_frequency);
            if (m_clipType == DocClipBase::COLOR) avfile.setAttribute("color", m_color);
            avfile.setAttribute("description", description());
            avfile.setAttribute("name", name());
            avfile.setAttribute("width", m_width);
            avfile.setAttribute("height", m_height);

            element.appendChild(avfile);
            return doc;
          }
      }
      node = node.nextSibling();
    }


    assert(node.isNull());

    /* This final return should never be reached, it is here to remove compiler warning. */
    return doc;
}

// virtual
00583 bool DocClipAVFile::matchesXML(const QDomElement & element) const
{
    bool result = false;

    if (element.tagName() == "kdenliveclip") {
      bool found = false;
      QDomNode n = element.firstChild();
      while (!n.isNull()) {
          QDomElement avElement = n.toElement();      // try to convert the node to an element.

          if (!avElement.isNull()) {
            if (avElement.tagName() == "avfile") {
                if (found) {
                  kdWarning() <<
                      "Clip contains multiple avclip definitions, only matching XML of the first one,"
                      << endl;
                  break;
                } else {
                  found = true;
                  //if(avElement.attribute("url") == fileURL().url()) {
                  if (avElement.attribute("id") ==
                      QString::number(getId())) {
                      result = true;
                  }
                }
            }
          }

          n = n.nextSibling();
      }
    }

    return result;
}

QString DocClipAVFile::formattedMetaData() 
{
      QString result;
      QMap<QString, QString>::Iterator it;
        for ( it = m_metadata.begin(); it != m_metadata.end(); ++it ) {
                    result+="<b>" + it.key() + "</b>: " + it.data() + "<br>";
        }
      return result;
}


/** Calculates properties for this file that will be useful for the rest of the program. */
00630 void DocClipAVFile::calculateFileProperties(const QMap < QString,
    QString > &attributes, const QMap < QString,
    QString > &metadata)
{
    if (m_url.isLocalFile()) {
      QFileInfo fileInfo(m_url.path());

      /* Determines the size of the file */
      m_filesize = fileInfo.size();

      if (attributes.contains("duration")) {
          m_duration = GenTime(attributes["duration"].toInt(), KdenliveSettings::defaultfps());
          m_durationKnown = true;
      } else {
          // No duration known, use an arbitrary one until it is.
          m_duration = GenTime(0.0);
          m_durationKnown = false;
      }
      //extend attributes -reh
      if (attributes.contains("type")) {
          if (attributes["type"] == "audio")
            m_clipType = AUDIO;
          else if (attributes["type"] == "video")
            m_clipType = VIDEO;
          else if (attributes["type"] == "av")
            m_clipType = AV;
          else if (attributes["type"] == "playlist")
            m_clipType = PLAYLIST;
      } else {
          m_clipType = AV;
      }
      if (attributes.contains("height")) {
          m_height = attributes["height"].toInt();
      } else {
          m_height = 0;
      }
      if (attributes.contains("width")) {
          m_width = attributes["width"].toInt();
      } else {
          m_width = 0;
      }
      //decoder name
      if (attributes.contains("name")) {
          m_decompressor = attributes["name"];
      } else {
          m_decompressor = "n/a";
      }
      //video type ntsc/pal
      if (attributes.contains("system")) {
          m_system = attributes["system"];
      } else {
          m_system = "n/a";
      }
      if (attributes.contains("fps")) {
          m_framesPerSecond = attributes["fps"].toInt();
      } else {
          // No frame rate known.
          m_framesPerSecond = 0;
      }
      //audio attributes -reh
      if (attributes.contains("channels")) {
          m_channels = attributes["channels"].toInt();
      } else {
          m_channels = 0;
      }
      if (attributes.contains("format")) {
          m_format = attributes["format"];
      } else {
          m_format = "n/a";
      }
      if (attributes.contains("frequency")) {
          m_frequency = attributes["frequency"].toInt();
      } else {
          m_frequency = 0;
      }
      if (attributes.contains("videocodec")) {
          m_videoCodec = attributes["videocodec"];
      }
      if (attributes.contains("audiocodec")) {
          m_audioCodec = attributes["audiocodec"];
      }

      m_metadata = metadata;

      if (m_metadata.contains("description")) {
          setDescription (m_metadata["description"]);
      }
      else if (m_metadata.contains("comment")) {
          setDescription (m_metadata["comment"]);
      } 

    } else {
            /** If the file is not local, then no file properties are currently returned */
      m_duration = GenTime(0.0);
      m_durationKnown = false;
      m_framesPerSecond = 0;
      m_filesize = 0;
    }
}

00730 QStringList DocClipAVFile::brokenPlayList()
{
    if (clipType() != PLAYLIST) return QStringList();
    QStringList missingClips;
    QDomDocument doc;
    doc.setContent(&QFile(m_url.path()), false);
    QDomElement documentElement = doc.documentElement();
    if (documentElement.tagName() != "westley") {
      kdWarning() << "KdenliveDoc::loadFromXML() document element has unknown tagName : " << documentElement.tagName() << endl;
    }

    QDomNode kdenlivedoc = documentElement.elementsByTagName("kdenlivedoc").item(0);
    QDomNode n;
    if (!kdenlivedoc.isNull()) n = kdenlivedoc.firstChild();
    else n = documentElement.firstChild();
    QDomElement e;
    bool missingFiles = false;

    while (!n.isNull()) {
      e = n.toElement();
      if (!e.isNull() && e.tagName() == "producer") {
          QString prodUrl = e.attribute("resource", QString::null);
          if (!prodUrl.isEmpty() && !KIO::NetAccess::exists(KURL(prodUrl), false)) 
            missingClips.append(prodUrl);
      }
        n = n.nextSibling();
    }
    return missingClips;
}

Generated by  Doxygen 1.6.0   Back to index