]> git.sesse.net Git - kdenlive/blob - src/docclipbase.cpp
got first audio frames, but
[kdenlive] / src / docclipbase.cpp
1 /**************************1*************************************************
2                           DocClipBase.cpp  -  description
3                              -------------------
4     begin                : Fri Apr 12 2002
5     copyright            : (C) 2002 by Jason Wood
6     email                : jasonwood@blueyonder.co.uk
7  ***************************************************************************/
8
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  ***************************************************************************/
17
18 #include <KDebug>
19
20 #include "kdenlivesettings.h"
21 #include "docclipbase.h"
22
23 DocClipBase::DocClipBase(QDomElement xml, uint id):
24 m_xml(xml), m_id(id), m_description(""), m_refcount(0), m_projectThumbFrame(0), audioThumbCreated(false), m_duration(GenTime()), m_thumbProd(NULL), m_audioTimer(NULL)
25 {
26   int type = xml.attribute("type").toInt();
27   m_clipType = (CLIPTYPE) type;
28   m_name = xml.attribute("name");
29   m_xml.setAttribute("id", QString::number(id));
30   KUrl url = KUrl(xml.attribute("resource"));
31   int out = xml.attribute("out").toInt();
32   if (out != 0) setDuration(GenTime(out, 25));
33   if (m_name.isEmpty()) m_name = url.fileName();
34         if (!url.isEmpty()){
35     m_thumbProd = new KThumb(url, KdenliveSettings::track_height() * KdenliveSettings::project_display_ratio(), KdenliveSettings::track_height());
36                 connect (m_thumbProd, SIGNAL (audioThumbReady(QMap <int, QMap <int, QByteArray> >)), this , SLOT(updateAudioThumbnail(QMap <int, QMap <int, QByteArray> > )));
37                 connect (this, SIGNAL (getAudioThumbs()), this , SLOT( slotGetAudioThumbs() ) );
38                 
39         }
40         kDebug() << "type is video" << (m_clipType==AV) << " " << m_clipType;
41         
42         if (m_clipType == AV || m_clipType==AUDIO ||m_clipType==UNKNOWN){
43                 m_audioTimer = new QTimer( this );
44                 connect(m_audioTimer, SIGNAL(timeout()), this, SLOT(slotGetAudioThumbs()));
45                 emit getAudioThumbs();
46         }
47 }
48
49 DocClipBase::DocClipBase(const DocClipBase& clip)
50 {
51     m_xml = clip.toXML();
52     m_id = clip.getId();
53     m_clipType = clip.clipType();
54     m_name = clip.name();
55     m_duration = clip.duration();
56 }
57
58 DocClipBase & DocClipBase::operator=(const DocClipBase & clip)
59 {
60     DocClipBase::operator=(clip);
61     m_xml = clip.toXML();
62     m_id = clip.getId();
63     m_clipType = clip.clipType();
64     m_name = clip.name();
65     m_duration = clip.duration();
66     return *this;
67 }
68
69 DocClipBase::~DocClipBase()
70 {
71   //if (m_thumbProd) delete m_thumbProd;
72 }
73
74 KThumb *DocClipBase::thumbProducer()
75 {
76   return m_thumbProd;
77 }
78
79 void DocClipBase::setName(const QString name)
80 {
81     m_name = name;
82 }
83
84 const QString & DocClipBase::name() const
85 {
86   
87     return m_name;
88 }
89
90 uint DocClipBase::getId() const
91 {
92     return m_id;
93 }
94
95 void DocClipBase::setId( const uint &newId)
96 {
97     m_id = newId;
98 }
99
100 const CLIPTYPE & DocClipBase::clipType() const
101 {
102   return m_clipType;
103 }
104
105 void DocClipBase::setClipType(CLIPTYPE type)
106 {
107   m_clipType = type;
108 }
109
110 const KUrl & DocClipBase::fileURL() const
111 {
112   QString res = m_xml.attribute("resource");
113   if (m_clipType != COLOR && !res.isEmpty()) return KUrl(res);
114   return KUrl();
115 }
116
117 void DocClipBase::setProjectThumbFrame( const uint &ix)
118 {
119     m_projectThumbFrame = ix;
120 }
121
122 uint DocClipBase::getProjectThumbFrame() const
123 {
124     return m_projectThumbFrame;
125 }
126
127 void DocClipBase::setDescription(const QString & description)
128 {
129     m_description = description;
130 }
131
132 const QString & DocClipBase::description() const
133 {
134     return m_description;
135 }
136
137 void DocClipBase::setDuration(GenTime dur)
138 {
139     m_duration = dur;
140 }
141
142 const GenTime &DocClipBase::duration() const
143 {
144     return m_duration;
145 }
146
147 bool DocClipBase::hasFileSize() const
148 {
149   return true;
150 }
151
152
153 // virtual
154 QDomElement DocClipBase::toXML() const
155 {
156 /*
157     QDomDocument doc;
158
159     QDomElement clip = doc.createElement("kdenliveclip");
160     QDomText text = doc.createTextNode(description());
161     clip.appendChild(text);
162     doc.appendChild(clip);
163 */
164     return m_xml;
165 }
166
167 DocClipBase *DocClipBase::
168 createClip(KdenliveDoc *doc, const QDomElement & element)
169 {
170     DocClipBase *clip = 0;
171     QString description;
172     QDomNode node = element;
173     node.normalize();
174     if (element.tagName() != "kdenliveclip") {
175         kWarning() <<
176             "DocClipBase::createClip() element has unknown tagName : " <<
177             element.tagName() << endl;
178         return 0;
179     }
180
181     QDomNode n = element.firstChild();
182
183     while (!n.isNull()) {
184         QDomElement e = n.toElement();
185         if (!e.isNull()) {
186             QString tagName = e.tagName();
187             if (e.tagName() == "avfile") {
188                 // clip = DocClipAVFile::createClip(e);
189             } else if (e.tagName() == "DocTrackBaseList") {
190                 // clip = DocClipProject::createClip(doc, e);
191             }
192         } else {
193             QDomText text = n.toText();
194             if (!text.isNull()) {
195                 description = text.nodeValue();
196             }
197         }
198
199         n = n.nextSibling();
200     }
201     if (clip == 0) {
202         kWarning() << "DocClipBase::createClip() unable to create clip" <<
203             endl;
204     } else {
205         // setup DocClipBase specifics of the clip.
206         clip->setDescription(description);
207         clip->setAudioThumbCreated(false);
208     }
209     return clip;
210 }
211
212 void DocClipBase::setAudioThumbCreated(bool isDone)
213 {
214     audioThumbCreated = isDone;
215 }
216
217
218 QDomDocument DocClipBase::generateSceneList(bool, bool) const
219 {
220 }
221
222 void DocClipBase::setThumbnail(const QPixmap & pixmap)
223 {
224     m_thumbnail = pixmap;
225 }
226
227 const QPixmap & DocClipBase::thumbnail() const
228 {
229     return m_thumbnail;
230 }
231
232 void DocClipBase::updateAudioThumbnail(QMap<int,QMap<int,QByteArray> > data)
233 {
234     audioFrameChache = data;
235     audioThumbCreated = true;
236 }
237
238 QList < GenTime > DocClipBase::snapMarkers() const
239 {
240     QList < GenTime > markers;
241
242     for (uint count = 0; count < m_snapMarkers.count(); ++count) {
243         markers.append(m_snapMarkers[count].time());
244     }
245
246     return markers;
247 }
248
249 QList < CommentedTime > DocClipBase::commentedSnapMarkers() const
250 {
251     return m_snapMarkers;
252 }
253
254 void DocClipBase::setSnapMarkers(QList < CommentedTime > markers)
255 {
256     m_snapMarkers = markers;
257 }
258
259 void DocClipBase::addSnapMarker(const GenTime & time, QString comment)
260 {
261     QList < CommentedTime >::Iterator it = m_snapMarkers.begin();
262     for ( it = m_snapMarkers.begin(); it != m_snapMarkers.end(); ++it ) {
263         if ((*it).time() >= time)
264             break;
265     }
266
267     if ((it != m_snapMarkers.end()) && ((*it).time() == time)) {
268         kError() <<
269             "trying to add Snap Marker that already exists, this will cause inconsistancies with undo/redo"
270             << endl;
271     } else {
272         CommentedTime t(time, comment);
273         m_snapMarkers.insert(it, t);
274     }
275
276 }
277
278 void DocClipBase::editSnapMarker(const GenTime & time, QString comment)
279 {
280     QList < CommentedTime >::Iterator it;
281     for ( it = m_snapMarkers.begin(); it != m_snapMarkers.end(); ++it ) {
282         if ((*it).time() == time)
283             break;
284     }
285     if (it != m_snapMarkers.end()) {
286         (*it).setComment(comment);
287     } else {
288         kError() <<
289             "trying to edit Snap Marker that does not already exists"  << endl;
290     }
291 }
292
293 QString DocClipBase::deleteSnapMarker(const GenTime & time)
294 {
295     QString result = i18n("Marker");
296     QList < CommentedTime >::Iterator itt = m_snapMarkers.begin();
297
298     while (itt != m_snapMarkers.end()) {
299         if ((*itt).time() == time)
300             break;
301         ++itt;
302     }
303
304     if ((itt != m_snapMarkers.end()) && ((*itt).time() == time)) {
305         result = (*itt).comment();
306         m_snapMarkers.erase(itt);
307     }
308     return result;
309 }
310
311
312 GenTime DocClipBase::hasSnapMarkers(const GenTime & time)
313 {
314     QList < CommentedTime >::Iterator itt = m_snapMarkers.begin();
315
316     while (itt != m_snapMarkers.end()) {
317         if ((*itt).time() == time)
318             return time;
319         ++itt;
320     }
321
322     return GenTime(0.0);
323 }
324
325 GenTime DocClipBase::findPreviousSnapMarker(const GenTime & currTime)
326 {
327     int it;
328     for ( it = 0; it < m_snapMarkers.count(); it++ ) {
329         if (m_snapMarkers[it].time() >= currTime)
330             break;
331     }
332     if (it == 0) return GenTime();
333     else if (it == m_snapMarkers.count() - 1 && m_snapMarkers[it].time() < currTime)
334         return m_snapMarkers[it].time();
335     else return m_snapMarkers[it-1].time();
336 }
337
338 GenTime DocClipBase::findNextSnapMarker(const GenTime & currTime)
339 {
340     int it;
341     for ( it = 0; it < m_snapMarkers.count(); it++ ) {
342         if (m_snapMarkers[it].time() > currTime)
343             break;
344     }
345     if (it < m_snapMarkers.count() && m_snapMarkers[it].time() > currTime) return m_snapMarkers[it].time();
346     return duration();
347 }
348
349 QString DocClipBase::markerComment(GenTime t)
350 {
351     QList < CommentedTime >::Iterator itt = m_snapMarkers.begin();
352
353     while (itt != m_snapMarkers.end()) {
354         if ((*itt).time() == t)
355             return (*itt).comment();
356         ++itt;
357     }
358     return QString::null;
359 }
360
361 //static
362 QString DocClipBase::getTypeName(CLIPTYPE type)
363 {
364     QString result;
365     switch (type) {
366         case AV:
367             result = i18n("Video Clip");
368             break;
369         case COLOR:
370             result = i18n("Color Clip");
371             break;
372         case PLAYLIST:
373             result = i18n("Playlist Clip");
374             break;
375         case IMAGE:
376             result = i18n("Image Clip");
377             break;
378         case SLIDESHOW:
379             result = i18n("Slideshow Clip");
380             break;
381         case VIRTUAL:
382             result = i18n("Virtual Clip");
383             break;
384         case AUDIO:
385             result = i18n("Audio Clip");
386             break;
387         case VIDEO:
388             result = i18n("Mute Video Clip");
389             break;
390         case TEXT:
391             result = i18n("Text Clip");
392             break;
393         default:
394             result = i18n("None");
395             break;
396     }
397     return result;
398 }
399
400 void DocClipBase::slotGetAudioThumbs(){
401         kDebug() << "getting audio data";
402         if (audioThumbCreated){
403                 if (m_audioTimer!=NULL)
404                         m_audioTimer->stop();
405         }else{
406                 if (m_audioTimer!=NULL)
407                         m_audioTimer->start(5);
408                 double lengthInFrames=duration().frames(/*framesPerSecond()*/25);
409                 m_thumbProd->getAudioThumbs(fileURL(), 1, 0, 10 /*must be number of frames*/, 20);
410                 
411         }
412 }
413