]> git.sesse.net Git - kdenlive/blob - thumbnailer/westleypreview.cpp
Rewrote thumbnail creator
[kdenlive] / thumbnailer / westleypreview.cpp
1 /***************************************************************************
2    Copyright (C) 2006-2008
3    by Marco Gulino <marco@kmobiletools.org>
4
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 2 of the License, or
8    (at your option) any later version.
9
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14
15    You should have received a copy of the GNU General Public License
16    along with this program; if not, write to the
17    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18     Boston, MA 02110-1301, USA.
19  ***************************************************************************/
20
21 #include "westleypreview.h"
22
23 #include <qfile.h>
24 #include <qimage.h>
25 #include <QtCore/QVarLengthArray>
26
27 #include <kstandarddirs.h>
28 #include <krandomsequence.h>
29 #include <qdatetime.h>
30 #include <QColor>
31 #include <kdebug.h>
32 #include <ktempdir.h>
33 #include <kurl.h>
34 #include <qfileinfo.h>
35 #include <KTemporaryFile>
36
37 #include <unistd.h>
38
39
40 #define DBG_AREA
41
42 //#include "config.h"
43 extern "C"
44 {
45     KDE_EXPORT ThumbCreator *new_creator() {
46         return new MltPreview;
47     }
48 }
49
50 MltPreview::MltPreview() :
51         QObject(),
52         ThumbCreator()
53 {
54     Mlt::Factory::init();
55 }
56
57 MltPreview::~MltPreview()
58 {
59     Mlt::Factory::close();
60 }
61
62
63 bool MltPreview::create(const QString &path, int width, int height, QImage &img)
64 {
65     Mlt::Profile *profile = new Mlt::Profile("dv_pal");
66     char *tmp = (char *) qstrdup(path.toUtf8().data());
67     Mlt::Producer *producer = new Mlt::Producer(*profile, tmp);
68     delete[] tmp;
69
70
71     if (producer->is_blank()) {
72         delete producer;
73         return false;
74     }
75     int frame = 75;
76     uint variance = 10;
77     int ct = 1;
78
79     //img = getFrame(producer, frame, width, height);
80
81     while (variance <= 40 && ct < 4) {
82         img = getFrame(producer, frame, width, height);
83         variance = imageVariance(img);
84         frame += 100 * ct;
85         ct++;
86     }
87
88     delete producer;
89     delete profile;
90     return (img.isNull() == false);
91 }
92
93 QImage MltPreview::getFrame(Mlt::Producer *producer, int framepos, int width, int height)
94 {
95     QImage result;
96     if (producer == NULL) {
97         return result;
98     }
99
100     producer->seek(framepos);
101     Mlt::Frame *frame = producer->get_frame();
102     if (frame == NULL) {
103         return result;
104     }
105
106     mlt_image_format format = mlt_image_yuv422;
107     int frame_width = 0;
108     int frame_height = 0;
109     height = 200;
110     double ar = frame->get_double("aspect_ratio");
111     if (ar == 0.0) ar = 1.33;
112     int calculated_width = (int)((double) height * ar);
113     frame->set("normalised_width", calculated_width);
114     frame->set("normalised_height", height);
115     uint8_t *data = frame->get_image(format, frame_width, frame_height, 0);
116     uint8_t *new_image = (uint8_t *)mlt_pool_alloc(frame_width * (frame_height + 1) * 4);
117     mlt_convert_yuv422_to_rgb24a((uint8_t *)data, new_image, frame_width * frame_height);
118     QImage image((uchar *)new_image, frame_width, frame_height, QImage::Format_ARGB32);
119
120     if (!image.isNull()) {
121         result = image.rgbSwapped().convertToFormat(QImage::Format_RGB32);
122     }
123
124     mlt_pool_release(new_image);
125     delete frame;
126     return result;
127 }
128
129
130 uint MltPreview::imageVariance(QImage image)
131 {
132     if (image.isNull()) return 0;
133     uint delta = 0;
134     uint avg = 0;
135     uint bytes = image.numBytes();
136     uint STEPS = bytes / 2;
137     QVarLengthArray<uchar> pivot(STEPS);
138     kDebug(DBG_AREA) << "Using " << STEPS << " steps\n";
139     uchar *bits = image.bits();
140     // First pass: get pivots and taking average
141     for (uint i = 0; i < STEPS ; i++) {
142         pivot[i] = bits[i*(bytes/STEPS)];
143         avg += pivot[i];
144     }
145     avg = avg / STEPS;
146     // Second Step: calculate delta (average?)
147     for (uint i = 0; i < STEPS; i++) {
148         int curdelta = abs(int(avg - pivot[i]));
149         delta += curdelta;
150     }
151     return delta / STEPS;
152 }
153
154 ThumbCreator::Flags MltPreview::flags() const
155 {
156     return None;
157 }
158
159