if (APPLE)
find_package(OpenGL)
set(QT_USE_QTOPENGL TRUE)
+else (APPLE)
+ macro_optional_find_package(OpenGL)
endif (APPLE)
include_directories (
set(kdenlive_SRCS jogshuttle.cpp ${kdenlive_SRCS})
endif(APPLE OR CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" OR NO_JOGSHUTTLE)
-if (APPLE)
+if (APPLE OR OPENGL_FOUND)
+ add_definitions(-DUSE_OPEN_GL)
set(kdenlive_SRCS videoglwidget.cpp ${kdenlive_SRCS})
-endif (APPLE)
+endif (APPLE OR OPENGL_FOUND)
kde4_add_kcfg_files(kdenlive_SRCS kdenlivesettings.kcfgc )
QT4_ADD_DBUS_ADAPTOR(kdenlive_SRCS org.kdenlive.MainWindow.xml mainwindow.h MainWindow)
target_link_libraries(kdenlive ${SDL_LIBRARY})
target_link_libraries(kdenlive ${QT_QTOPENGL_LIBRARY})
target_link_libraries(kdenlive ${OPENGL_LIBRARIES})
+else (APPLE)
+ if (OPENGL_FOUND)
+ target_link_libraries(kdenlive ${QT_QTOPENGL_LIBRARY})
+ target_link_libraries(kdenlive ${OPENGL_LIBRARIES})
+ endif (OPENGL_FOUND)
endif (APPLE)
install(TARGETS kdenlive DESTINATION ${BIN_INSTALL_DIR})
#include <QList>
-AudioSignal::AudioSignal(QWidget *parent):QWidget(parent)
+AudioSignal::AudioSignal(QWidget *parent): QWidget(parent)
{
- //QVBoxLayout *vbox=new QVBoxLayout(this);
- //label=new QLabel();
- //vbox->addWidget(label);
- setMaximumHeight(12);
- col << Qt::green << Qt::green << Qt::green << Qt::green << Qt::green << Qt::green << Qt::green << Qt::green << Qt::green << Qt::green ;
- col << Qt::yellow << Qt::yellow << Qt::yellow << Qt::yellow << Qt::yellow ;
- col << Qt::darkYellow << Qt::darkYellow << Qt::darkYellow;
- col << Qt::red << Qt::red;
+ //QVBoxLayout *vbox=new QVBoxLayout(this);
+ //label=new QLabel();
+ //vbox->addWidget(label);
+ setMinimumHeight(10);
+ col << Qt::green << Qt::green << Qt::green << Qt::green << Qt::green << Qt::green << Qt::green << Qt::green << Qt::green << Qt::green ;
+ col << Qt::yellow << Qt::yellow << Qt::yellow << Qt::yellow << Qt::yellow ;
+ col << Qt::darkYellow << Qt::darkYellow << Qt::darkYellow;
+ col << Qt::red << Qt::red;
}
-void AudioSignal::showAudio(QByteArray arr)
+void AudioSignal::showAudio(const QByteArray arr)
{
- channels=arr;
- update();
+ channels = arr;
+ update();
}
-void AudioSignal::paintEvent(QPaintEvent* e)
+void AudioSignal::paintEvent(QPaintEvent* /*e*/)
{
QPainter p(this);
//p.begin();
- //p.fillRect(0,0,(unsigned char)channels[0]*width()/255,height()/2,QBrush(Qt::SolidPattern));
- //p.fillRect(0,height()/2,(unsigned char)channels[1]*width()/255,height()/2,QBrush(Qt::SolidPattern));
- int numchan=channels.size();
- for (int i=0;i<numchan;i++){
- int maxx=(unsigned char)channels[i]*width()/255;
- int xdelta=width()/20;
- int y1=height()*i/numchan;
- int _h=height()/numchan-1;
- for (int x=0;x<20;x++){
- if (maxx>0){
- p.fillRect(x*xdelta,y1,maxx>xdelta?xdelta-1:maxx-1,_h,QBrush(col.at(x),Qt::SolidPattern));
- maxx-=xdelta;
- }
- }
- }
+ //p.fillRect(0,0,(unsigned char)channels[0]*width()/255,height()/2,QBrush(Qt::SolidPattern));
+ //p.fillRect(0,height()/2,(unsigned char)channels[1]*width()/255,height()/2,QBrush(Qt::SolidPattern));
+ int numchan = channels.size();
+ for (int i = 0; i < numchan; i++) {
+ int maxx = (unsigned char)channels[i] * width() / 255;
+ int xdelta = width() / 20;
+ int y1 = height() * i / numchan;
+ int _h = height() / numchan - 1;
+ for (int x = 0; x < 20; x++) {
+ if (maxx > 0) {
+ p.fillRect(x * xdelta, y1, maxx > xdelta ? xdelta - 1 : maxx - 1, _h, QBrush(col.at(x), Qt::SolidPattern));
+ maxx -= xdelta;
+ }
+ }
+ }
p.end();
}
#include "audiosignal.moc"
class QLabel;
#include <QWidget>
-class AudioSignal : public QWidget
+class AudioSignal : public QWidget
{
- Q_OBJECT
- public:
- AudioSignal (QWidget *parent=0);
- private:
- QLabel* label;
- QByteArray channels;
- QList<QColor> col;
- protected:
- void paintEvent(QPaintEvent* );
- public slots:
- void showAudio(QByteArray);
+ Q_OBJECT
+public:
+ AudioSignal(QWidget *parent = 0);
+private:
+ QLabel* label;
+ QByteArray channels;
+ QList<QColor> col;
+protected:
+ void paintEvent(QPaintEvent*);
+public slots:
+ void showAudio(const QByteArray);
};
</group>
<group name="sdl">
+ <entry name="openglmonitors" type="Bool">
+ <label>Use OpenGL for video display.</label>
+ <default>false</default>
+ </entry>
+
<entry name="video_driver" type="UInt">
<label>Video driver used for output.</label>
<default>0</default>
// Disable drop B frames, see Kdenlive issue #1330
m_configSdl.groupBox->setHidden(true);
+#if not defined(Q_WS_MAC) && not defined(USE_OPEN_GL)
+ m_configSdl.kcfg_openglmonitors->setHidden(true);
+#endif
m_page6 = addPage(p6, i18n("Playback"), "media-playback-start");
Monitor::Monitor(QString name, MonitorManager *manager, QString profile, QWidget *parent) :
QWidget(parent),
render(NULL),
- m_audiosignal(NULL),
+ m_audiosignal(NULL),
m_name(name),
m_monitorManager(manager),
m_currentClip(NULL),
m_scale(1),
m_length(0),
m_dragStarted(false),
+ m_monitorRefresh(NULL),
m_effectScene(NULL),
m_effectView(NULL),
m_selectedClip(NULL),
m_loopClipTransition(true)
+
{
m_ui.setupUi(this);
QVBoxLayout *layout = new QVBoxLayout;
QVBoxLayout *rendererBox = new QVBoxLayout(m_ui.video_frame);
rendererBox->setContentsMargins(0, 0, 0, 0);
+ bool monitorCreated = false;
#ifdef Q_WS_MAC
- m_glWidget = new VideoGLWidget(m_ui.video_frame);
- rendererBox->addWidget(m_glWidget);
- render = new Render(m_name, (int) m_ui.video_frame->winId(), -1, profile, this);
- m_glWidget->setImageAspectRatio(render->dar());
- m_glWidget->setBackgroundColor(KdenliveSettings::window_background());
- m_glWidget->resize(m_ui.video_frame->size());
- connect(render, SIGNAL(showImageSignal(QImage)), m_glWidget, SLOT(showImage(QImage)));
- m_monitorRefresh = 0;
-#else
- m_monitorRefresh = new MonitorRefresh(m_ui.video_frame);
- rendererBox->addWidget(m_monitorRefresh);
- render = new Render(m_name, (int) m_monitorRefresh->winId(), -1, profile, this);
- m_monitorRefresh->setRenderer(render);
+ createOpenGlWidget(rendererBox, profile);
+ monitorCreated = true;
+ //m_glWidget->setFixedSize(width, height);
+#elif defined (USE_OPEN_GL)
+ if (KdenliveSettings::openglmonitors()) {
+ monitorCreated = createOpenGlWidget(rendererBox, profile);
+ }
#endif
- m_audiosignal= new AudioSignal(this);
- rendererBox->addWidget(m_audiosignal);
- connect(render, SIGNAL(showAudioSignal(QByteArray)), m_audiosignal, SLOT(showAudio(QByteArray)));
-
+ if (!monitorCreated) {
+ m_monitorRefresh = new MonitorRefresh(m_ui.video_frame);
+ rendererBox->addWidget(m_monitorRefresh);
+ render = new Render(m_name, (int) m_monitorRefresh->winId(), profile, this);
+ m_monitorRefresh->setRenderer(render);
+ }
+
+ QVBoxLayout *audioBox = new QVBoxLayout;
+ audioBox->setContentsMargins(0, 0, 0, 0);
+ m_audiosignal = new AudioSignal();
+ audioBox->addWidget(m_audiosignal);
+ m_ui.audio_monitor->setLayout(audioBox);
+ connect(render, SIGNAL(showAudioSignal(const QByteArray)), m_audiosignal, SLOT(showAudio(const QByteArray)));
connect(m_ruler, SIGNAL(seekRenderer(int)), this, SLOT(slotSeek(int)));
connect(render, SIGNAL(durationChanged(int)), this, SLOT(adjustRulerSize(int)));
connect(render, SIGNAL(rendererStopped(int)), this, SLOT(rendererStopped(int)));
} else {
connect(m_ruler, SIGNAL(zoneChanged(QPoint)), this, SLOT(setClipZone(QPoint)));
}
-#ifndef Q_WS_MAC
- m_monitorRefresh->show();
-#endif
+
+ if (m_monitorRefresh) m_monitorRefresh->show();
if (name == "project") {
m_effectScene = new MonitorScene(render);
m_effectScene->setUp();
m_effectView->hide();
}
-
- kDebug() << "/////// BUILDING MONITOR, ID: " << m_ui.video_frame->winId();
}
Monitor::~Monitor()
return m_name;
}
+#if defined(Q_WS_MAC) || defined(USE_OPEN_GL)
+bool Monitor::createOpenGlWidget(QVBoxLayout *rendererBox, const QString profile)
+{
+ render = new Render(m_name, 0, profile, this);
+ m_glWidget = new VideoGLWidget(m_ui.video_frame);
+ if (m_glWidget == NULL) {
+ // Creation failed, we are in trouble...
+ return false;
+ }
+ rendererBox->addWidget(m_glWidget);
+ m_glWidget->setImageAspectRatio(render->dar());
+ m_glWidget->setBackgroundColor(KdenliveSettings::window_background());
+ connect(render, SIGNAL(showImageSignal(QImage)), m_glWidget, SLOT(showImage(QImage)));
+ return true;
+}
+#endif
+
void Monitor::setupMenu(QMenu *goMenu, QAction *playZone, QAction *loopZone, QMenu *markerMenu, QAction *loopClip)
{
m_contextMenu = new QMenu(this);
m_contextMenu->addAction(extractFrame);
if (m_name != "clip") {
-#ifndef Q_WS_MAC
+#if defined(Q_WS_MAC) || defined(USE_OPEN_GL)
+ // TODO: why disable in OpenGL?
+ // Don't show split action
+#else
QAction *splitView = m_contextMenu->addAction(KIcon("view-split-left-right"), i18n("Split view"), render, SLOT(slotSplitView(bool)));
splitView->setCheckable(true);
m_configMenu->addAction(splitView);
m_playAction->setIcon(m_playIcon);
}
-void Monitor::initMonitor()
-{
- kDebug() << "/////// INITING MONITOR, ID: " << m_ui.video_frame->winId();
-}
-
-// virtual
-/*void Monitor::resizeEvent(QResizeEvent * event) {
- QWidget::resizeEvent(event);
- adjustRulerSize(-1);
- if (render && m_isActive) render->doRefresh();
- //
-}*/
-
void Monitor::adjustRulerSize(int length)
{
if (length > 0) m_length = length;
KdenliveSettings::setDisplayMonitorInfo(show);
if (show) {
if (m_overlay) return;
-#ifndef Q_WS_MAC
- m_overlay = new Overlay(m_monitorRefresh);
- m_overlay->raise();
- m_overlay->setHidden(true);
-#else
- m_overlay = new Overlay(m_glWidget);
+ if (m_monitorRefresh == NULL) {
+ // Using OpenGL display
+#if defined(Q_WS_MAC) || defined(USE_OPEN_GL)
+ m_overlay = new Overlay(m_glWidget);
#endif
+ } else {
+ m_overlay = new Overlay(m_monitorRefresh);
+ m_overlay->raise();
+ m_overlay->setHidden(true);
+ }
} else {
delete m_overlay;
m_overlay = NULL;
void Monitor::slotSetSelectedClip(ClipItem* item)
{
if (item || (!item && !m_loopClipTransition)) {
- m_loopClipTransition = false;
+ m_loopClipTransition = false;
slotSetSelectedClip((AbstractClipItem*)item);
}
}
void Monitor::slotEffectScene(bool show)
{
if (m_name == "project") {
-#ifdef Q_WS_MAC
- m_glWidget->setVisible(!show);
-#else
- m_monitorRefresh->setVisible(!show);
+ if (m_monitorRefresh) {
+ m_monitorRefresh->setVisible(!show);
+ } else {
+#if defined(Q_WS_MAC) || defined(USE_OPEN_GL)
+ m_glWidget->setVisible(!show);
#endif
+ }
m_effectView->setVisible(show);
emit requestFrameForAnalysis(show);
if (show) {
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
***************************************************************************/
-
#ifndef MONITOR_H
#define MONITOR_H
#include "gentime.h"
#include "ui_monitor_ui.h"
#include "timecodedisplay.h"
-#ifdef Q_WS_MAC
+#if defined(Q_WS_MAC) || defined(USE_OPEN_GL)
#include "videoglwidget.h"
#endif
private:
Ui::Monitor_UI m_ui;
+ AudioSignal *m_audiosignal;
QString m_name;
MonitorManager *m_monitorManager;
DocClipBase *m_currentClip;
/** true if selected clip is transition, false = selected clip is clip.
* Necessary because sometimes we get two signals, e.g. we get a clip and we get selected transition = NULL. */
bool m_loopClipTransition;
-#ifdef Q_WS_MAC
+#if defined(Q_WS_MAC) || defined(USE_OPEN_GL)
VideoGLWidget *m_glWidget;
+ bool createOpenGlWidget(QVBoxLayout *rendererBox, const QString profile);
#endif
- AudioSignal *m_audiosignal;
GenTime getSnapForPos(bool previous);
public slots:
void slotOpenFile(const QString &);
void slotSetXml(DocClipBase *clip, QPoint zone = QPoint(), const int position = -1);
- void initMonitor();
void refreshMonitor(bool visible = true);
void slotSeek(int pos);
void stop();
// detect if the producer has finished playing. Is there a better way to do it?
if (self->m_isBlocked) return;
Mlt::Frame frame(frame_ptr);
-#ifdef Q_WS_MAC
- self->showFrame(frame);
-#endif
- self->showAudio(frame);
+ if (!frame.is_valid()) return;
self->emitFrameNumber(mlt_frame_get_position(frame_ptr));
if (self->sendFrameForAnalysis && frame_ptr->convert_image) {
self->emitFrameUpdated(frame);
}
+ self->showAudio(frame);
if (frame.get_double("_speed") == 0.0) {
self->emitConsumerStopped();
} else if (frame.get_double("_speed") < 0.0 && mlt_frame_get_position(frame_ptr) <= 0) {
}
}
+static void consumer_gl_frame_show(mlt_consumer, Render * self, mlt_frame frame_ptr)
+{
+ // detect if the producer has finished playing. Is there a better way to do it?
+ if (self->m_isBlocked) return;
+ Mlt::Frame frame(frame_ptr);
+ self->showFrame(frame);
+ if (frame.get_double("_speed") == 0.0) {
+ self->emitConsumerStopped();
+ } else if (frame.get_double("_speed") < 0.0 && mlt_frame_get_position(frame_ptr) <= 0) {
+ self->pause();
+ self->emitConsumerStopped();
+ }
+}
-Render::Render(const QString & rendererName, int winid, int /* extid */, QString profile, QWidget *parent) :
- QObject(parent),
- m_isBlocked(0),
- sendFrameForAnalysis(false),
- m_name(rendererName),
- m_mltConsumer(NULL),
- m_mltProducer(NULL),
- m_mltProfile(NULL),
- m_framePosition(0),
- m_isZoneMode(false),
- m_isLoopMode(false),
- m_isSplitView(false),
- m_blackClip(NULL),
- m_winid(winid)
-#ifdef Q_WS_MAC
- , m_glWidget(0)
-#endif
+Render::Render(const QString & rendererName, int winid, QString profile, QWidget *parent) :
+ QObject(parent),
+ m_isBlocked(0),
+ sendFrameForAnalysis(false),
+ m_name(rendererName),
+ m_mltConsumer(NULL),
+ m_mltProducer(NULL),
+ m_mltProfile(NULL),
+ m_framePosition(0),
+ m_isZoneMode(false),
+ m_isLoopMode(false),
+ m_isSplitView(false),
+ m_blackClip(NULL),
+ m_winid(winid)
{
/*if (rendererName == "project") m_monitorId = 10000;
else m_monitorId = 10001;*/
setenv("SDL_VIDEO_ALLOW_SCREENSAVER", "1", 1);
//m_mltConsumer->set("fullscreen", 1);
-#ifdef Q_WS_MAC
- m_mltConsumer = new Mlt::Consumer(*m_mltProfile, "sdl_audio");
- m_mltConsumer->set("preview_off", 1);
- m_mltConsumer->set("preview_format", mlt_image_rgb24a);
-#else
- m_mltConsumer = new Mlt::Consumer(*m_mltProfile, "sdl_preview");
-#endif
+ if (m_winid == 0) {
+ // OpenGL monitor
+ m_mltConsumer = new Mlt::Consumer(*m_mltProfile, "sdl_audio");
+ m_mltConsumer->set("preview_off", 1);
+ m_mltConsumer->set("preview_format", mlt_image_rgb24a);
+ m_mltConsumer->listen("consumer-frame-show", this, (mlt_listener) consumer_gl_frame_show);
+ } else {
+ m_mltConsumer = new Mlt::Consumer(*m_mltProfile, "sdl_preview");
+ // FIXME: the event object returned by the listen gets leaked...
+ m_mltConsumer->listen("consumer-frame-show", this, (mlt_listener) consumer_frame_show);
+ m_mltConsumer->set("window_id", m_winid);
+ }
m_mltConsumer->set("resize", 1);
- m_mltConsumer->set("window_id", m_winid);
m_mltConsumer->set("terminate_on_pause", 1);
m_mltConsumer->set("window_background", KdenliveSettings::window_background().name().toUtf8().constData());
-
- // FIXME: the event object returned by the listen gets leaked...
- m_mltConsumer->listen("consumer-frame-show", this, (mlt_listener) consumer_frame_show);
m_mltConsumer->set("rescale", "nearest");
mlt_log_set_callback(kdenlive_callback);
m_blackClip = new Mlt::Producer(*m_mltProfile, "colour", "black");
m_blackClip->set("id", "black");
m_blackClip->set("mlt_type", "producer");
-
}
Mlt::Producer *Render::invalidProducer(const QString &id)
delete m_mltProducer;
}
m_mltProducer = NULL;
-
buildConsumer(profileName);
double new_fps = m_mltProfile->fps();
if (current_fps != new_fps) {
//pixmap = im.scaled(width, height);
return pixmap;
}
-/*
-//static
-QPixmap Render::getVideoThumbnail(char *profile, QString file, int frame_position, int width, int height) {
- QPixmap pix(width, height);
- Mlt::Profile *prof = new Mlt::Profile(profile);
- Mlt::Producer m_producer(*prof, file.toUtf8().constData());
- if (m_producer.is_blank()) {
- pix.fill(Qt::black);
- return pix;
- }
-
- Mlt::Filter m_convert(*prof, "avcolour_space");
- m_convert.set("forced", mlt_image_rgb24a);
- m_producer.attach(m_convert);
- m_producer.seek(frame_position);
- Mlt::Frame * frame = m_producer.get_frame();
- if (frame) {
- pix = frameThumbnail(frame, width, height, true);
- delete frame;
- }
- if (prof) delete prof;
- return pix;
-}
-*/
-/*
-void Render::getImage(KUrl url, int frame_position, QPoint size)
-{
- Mlt::Producer m_producer(url.path().toUtf8().constData());
- if (m_producer.is_blank()) {
- return;
- }
- Mlt::Filter m_convert("avcolour_space");
- m_convert.set("forced", mlt_image_rgb24a);
- m_producer.attach(m_convert);
- m_producer.seek(frame_position);
-
- Mlt::Frame * frame = m_producer.get_frame();
-
- if (frame) {
- QPixmap pix = frameThumbnail(frame, size.x(), size.y(), true);
- delete frame;
- emit replyGetImage(url, frame_position, pix, size.x(), size.y());
- }
-}*/
-
-/* Create thumbnail for color */
-/*void Render::getImage(int id, QString color, QPoint size)
-{
- QPixmap pixmap(size.x() - 2, size.y() - 2);
- color = color.replace(0, 2, "#");
- color = color.left(7);
- pixmap.fill(QColor(color));
- QPixmap result(size.x(), size.y());
- result.fill(Qt::black);
- //copyBlt(&result, 1, 1, &pixmap, 0, 0, size.x() - 2, size.y() - 2);
- emit replyGetImage(id, result, size.x(), size.y());
-
-}*/
-
-/* Create thumbnail for image */
-/*void Render::getImage(KUrl url, QPoint size)
-{
- QImage im;
- QPixmap pixmap;
- if (url.fileName().startsWith(".all.")) { // check for slideshow
- QString fileType = url.fileName().right(3);
- QStringList more;
- QStringList::Iterator it;
-
- QDir dir( url.directory() );
- more = dir.entryList( QDir::Files );
- for ( it = more.begin() ; it != more.end() ; ++it ) {
- if ((*it).endsWith("."+fileType, Qt::CaseInsensitive)) {
- if (!im.load(url.directory() + '/' + *it))
- kDebug()<<"++ ERROR LOADIN IMAGE: "<<url.directory() + '/' + *it;
- break;
- }
- }
- }
- else im.load(url.path());
-
- //pixmap = im.smoothScale(size.x() - 2, size.y() - 2);
- QPixmap result(size.x(), size.y());
- result.fill(Qt::black);
- //copyBlt(&result, 1, 1, &pixmap, 0, 0, size.x() - 2, size.y() - 2);
- emit replyGetImage(url, 1, result, size.x(), size.y());
-}*/
-
double Render::consumerRatio() const
{
return m_mltProfile->dar();
}
+
void Render::slotSplitView(bool doit)
{
m_isSplitView = doit;
int dropFrames = 1;
if (show == false) dropFrames = 0;
m_mltConsumer->stop();
-#ifdef Q_WS_MAC
- m_mltConsumer->set("real_time", dropFrames);
-#else
- m_mltConsumer->set("play.real_time", dropFrames);
-#endif
+ if (m_winid == 0)
+ m_mltConsumer->set("real_time", dropFrames);
+ else
+ m_mltConsumer->set("play.real_time", dropFrames);
+
if (m_mltConsumer->start() == -1) {
kDebug(QtWarningMsg) << "ERROR, Cannot start monitor";
}
//if (notify) QApplication::postEvent(qApp->activeWindow(), new UrlEvent(url, 10003));
}
-#ifdef Q_WS_MAC
+
void Render::showFrame(Mlt::Frame& frame)
{
+ m_framePosition = qMax(frame.get_int("_position"), 0);
+ emit rendererPosition((int) m_framePosition);
mlt_image_format format = mlt_image_rgb24a;
int width = 0;
int height = 0;
QImage qimage(width, height, QImage::Format_ARGB32_Premultiplied);
memcpy(qimage.scanLine(0), image, width * height * 4);
emit showImageSignal(qimage);
+ showAudio(frame);
+ if (sendFrameForAnalysis && frame.get_frame()->convert_image) {
+ emit frameUpdated(qimage.rgbSwapped());
+ }
}
-#endif
void Render::showAudio(Mlt::Frame& frame)
{
- mlt_audio_format audio_format=mlt_audio_pcm;
- int freq,num_channels,samples;
- uint8_t* data=(uint8_t*)frame.get_audio(audio_format,freq,num_channels,samples);
- if (!data)
- return;
- int value=0;
- QByteArray channels;
-
- for (int i=0;i<num_channels;i++){
- /* switch (audio_format)
- {
- case 0:
- value=( ( (uint8_t*)data) [i] );
- break;
- case 1:
- value=( ( (uint16_t*)data) [i] >> 8 );
- break;
- case 2:
- value=( ((uint32_t*)data) [i] >> 16 );
- break;
- case 3:
- value=( ((float*)data) [i]*255);
- break;
- default:
- value=0;
- }
- */
- long val=0;
- int num_samples=20;
- for (int s=0;s<samples;s+=samples/num_samples){
- val+=(data[i+s*num_channels]- 127);
- }
- channels.append(val/num_samples);
- }
-
-
- if (samples>0)
- emit showAudioSignal(channels);
+ if (!frame.is_valid() || frame.get_int("test_audio") != 0) return;
+ mlt_audio_format audio_format = mlt_audio_pcm;
+ int freq = 0;
+ int num_channels = 0;
+ int samples = 0;
+ uint8_t* data = (uint8_t*)frame.get_audio(audio_format, freq, num_channels, samples);
+ if (!data)
+ return;
+ int value = 0;
+ QByteArray channels;
+ for (int i = 0; i < num_channels; i++) {
+ /* switch (audio_format)
+ {
+ case 0:
+ value=( ( (uint8_t*)data) [i] );
+ break;
+ case 1:
+ value=( ( (uint16_t*)data) [i] >> 8 );
+ break;
+ case 2:
+ value=( ((uint32_t*)data) [i] >> 16 );
+ break;
+ case 3:
+ value=( ((float*)data) [i]*255);
+ break;
+ default:
+ value=0;
+ }
+ */
+ long val = 0;
+ int num_samples = 20;
+ for (int s = 0; s < samples; s += samples / num_samples) {
+ val += (data[i+s*num_channels] - 127);
+ }
+ channels.append(val / num_samples);
+ }
+
+
+ if (samples > 0)
+ emit showAudioSignal(channels);
}
/*
krender.h - description
-------------------
begin : Fri Nov 22 2002
- copyright : (C) 2002 by Jason Wood
- email : jasonwood@blueyonder.co.uk
+ copyright : (C) 2002 by Jason Wood (jasonwood@blueyonder.co.uk)
+ copyright : (C) 2010 by Jean-Baptiste Mardelle (jb@kdenlive.org)
+
***************************************************************************/
/***************************************************************************
/**
* @class Render
- * @author Jason Wood
* @brief Client side of the interface to a renderer.
*
* From Kdenlive's point of view, you treat the Render object as the renderer,
#include <QList>
#include <QEvent>
-#ifdef Q_WS_MAC
-#include "videoglwidget.h"
-#endif
class Render;
enum FailStates { OK = 0,
APP_NOEXIST
};
+ /** @brief Build a MLT Renderer
+ * @param rendererName A unique identifier for this renderer
+ * @param winid The parent widget identifier (required for SDL display). Set to 0 for OpenGL rendering
+ * @param profile The MLT profile used for the renderer (default one will be used if empty). */
+ Render(const QString & rendererName, int winid, QString profile = QString(), QWidget *parent = 0);
- Render(const QString & rendererName, int winid, int extid, QString profile = QString(), QWidget *parent = 0);
+ /** @brief Destroy the MLT Renderer. */
~Render();
/** @brief Seeks the renderer clip to the given time. */
void seekToFrameDiff(int diff);
int m_isBlocked;
- //static QPixmap getVideoThumbnail(char *profile, QString file, int frame, int width, int height);
QPixmap getImageThumbnail(KUrl url, int width, int height);
- /* Return thumbnail for color clip
- void getImage(int id, QString color, QPoint size);*/
-
- // static QPixmap frameThumbnail(Mlt::Frame *frame, int width, int height, bool border = false);
-
- /* Return thumbnail for image clip
- void getImage(KUrl url, QPoint size);*/
-
- /* Requests a particular frame from the given file.
- *
- * The pixmap will be returned by emitting the replyGetImage() signal.
- void getImage(KUrl url, int frame, QPoint size);*/
-
+ /** @brief Sets the current MLT producer playlist.
+ * @param list The xml describing the playlist
+ * @param position (optional) time to seek to */
int setSceneList(QDomDocument list, int position = 0);
- /** @brief Sets the current scene list.
- * @param list new scene list
+ /** @brief Sets the current MLT producer playlist.
+ * @param list new playlist
* @param position (optional) time to seek to
* @return 0 when it has success, different from 0 otherwise
*
- * Creates the producer from the MLT XML QDomDocument. Wraps the VEML
- * command of the same name. */
+ * Creates the producer from the text playlist. */
int setSceneList(QString playlist, int position = 0);
int setProducer(Mlt::Producer *producer, int position);
+
+ /** @brief Get the current MLT producer playlist.
+ * @return A string describing the playlist */
const QString sceneList();
bool saveSceneList(QString path, QDomElement kdenliveData = QDomElement());
* @param speed speed to play the scene to
*
* The speed is relative to normal playback, e.g. 1.0 is normal speed, 0.0
- * is paused, -1.0 means play backwards. It does not specify start/stop
- * times for playback. Wraps the VEML command of the same name. */
+ * is paused, -1.0 means play backwards. It does not specify start/stop */
void play(double speed);
void switchPlay();
void pause();
QImage extractFrame(int frame_position, int width = -1, int height = -1);
/** @brief Plays the scene starting from a specific time.
- * @param startTime time to start playing the scene from
- *
- * Wraps the VEML command of the same name. */
+ * @param startTime time to start playing the scene from */
void play(const GenTime & startTime);
void playZone(const GenTime & startTime, const GenTime & stopTime);
void loopZone(const GenTime & startTime, const GenTime & stopTime);
void updatePreviewSettings();
void setDropFrames(bool show);
QString updateSceneListFps(double current_fps, double new_fps, QString scene);
-#ifdef Q_WS_MAC
void showFrame(Mlt::Frame&);
-#endif
- void showAudio(Mlt::Frame&);
+
+ void showAudio(Mlt::Frame&);
/** @brief This property is used to decide if the renderer should convert it's frames to QImage for use in other Kdenlive widgets. */
bool sendFrameForAnalysis;
QList <int> checkTrackSequence(int);
/** @brief A human-readable description of this renderer. */
int m_winid;
-#ifdef Q_WS_MAC
- VideoGLWidget *m_glWidget;
-#endif
void closeMlt();
void mltCheckLength(Mlt::Tractor *tractor);
void mltPasteEffects(Mlt::Producer *source, Mlt::Producer *dest);
QMap<QString, QString> mltGetTransitionParamsFromXml(QDomElement xml);
QMap<QString, Mlt::Producer *> m_slowmotionProducers;
+
+ /** @brief Build the MLT Consumer object with initial settings.
+ * @param profileName The MLT profile to use for the consumer */
void buildConsumer(const QString profileName);
void resetZoneMode();
void fillSlowMotionProducers();
*
* Used in Mac OS X. */
void showImageSignal(QImage);
- void showAudioSignal(QByteArray);
+ void showAudioSignal(const QByteArray);
/** @brief The renderer refreshed the current frame, but no seeking was done. */
void frameUpdated(QImage);
<rect>
<x>0</x>
<y>0</y>
- <width>352</width>
- <height>239</height>
+ <width>353</width>
+ <height>247</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_2">
</property>
</widget>
</item>
- <item row="1" column="0">
+ <item row="2" column="0">
<widget class="QLabel" name="textLabel1_2_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
</property>
</widget>
</item>
- <item row="1" column="1" colspan="2">
+ <item row="2" column="1" colspan="2">
<widget class="KComboBox" name="kcfg_video_driver"/>
</item>
- <item row="2" column="0">
+ <item row="3" column="0">
<widget class="QLabel" name="textLabel1_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
</property>
</widget>
</item>
- <item row="2" column="1" colspan="2">
+ <item row="3" column="1" colspan="2">
<widget class="KComboBox" name="kcfg_audio_driver"/>
</item>
- <item row="3" column="0">
+ <item row="4" column="0">
<widget class="QLabel" name="textLabel1">
<property name="text">
<string>Audio device:</string>
</property>
</widget>
</item>
- <item row="3" column="1" colspan="2">
+ <item row="4" column="1" colspan="2">
<widget class="KComboBox" name="kcfg_audio_device"/>
</item>
- <item row="5" column="2">
+ <item row="6" column="2">
<widget class="KColorButton" name="kcfg_window_background">
<property name="defaultColor">
<color>
</property>
</widget>
</item>
- <item row="8" column="1" colspan="2">
+ <item row="9" column="1" colspan="2">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</spacer>
</item>
- <item row="7" column="0" colspan="3">
+ <item row="8" column="0" colspan="3">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Monitor Preview Speedup Settings</string>
</layout>
</widget>
</item>
- <item row="5" column="0" colspan="2">
+ <item row="6" column="0" colspan="2">
<widget class="QLabel" name="label">
<property name="text">
<string>Monitor background color:</string>
</property>
</widget>
</item>
- <item row="4" column="0" colspan="2">
+ <item row="5" column="0" colspan="2">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Preview volume:</string>
</property>
</widget>
</item>
- <item row="4" column="2">
+ <item row="5" column="2">
<widget class="QSpinBox" name="kcfg_volume">
<property name="suffix">
<string>%</string>
</property>
</widget>
</item>
+ <item row="1" column="0" colspan="3">
+ <widget class="QCheckBox" name="kcfg_openglmonitors">
+ <property name="text">
+ <string>Use OpenGL for video display (restart Kdenlive to apply)</string>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
<customwidgets>
<rect>
<x>0</x>
<y>0</y>
- <width>237</width>
- <height>177</height>
+ <width>391</width>
+ <height>242</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="spacing">
<number>0</number>
</property>
- <item row="0" column="0" colspan="2">
+ <item row="0" column="0">
+ <widget class="QFrame" name="audio_monitor">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Maximum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Plain</enum>
+ </property>
+ <property name="lineWidth">
+ <number>0</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
<widget class="QFrame" name="video_frame">
<property name="font">
<font>
</property>
</widget>
</item>
- <item row="1" column="0" colspan="2">
+ <item row="2" column="0">
<widget class="QFrame" name="ruler_frame">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
</property>
</widget>
</item>
- <item row="2" column="0" colspan="2">
+ <item row="3" column="0">
<widget class="QFrame" name="button_frame">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">