#include "abstractmonitor.h"
#include "kdenlivesettings.h"
+#include "monitormanager.h"
#include <KDebug>
#include <QPaintEvent>
+#include <QDesktopWidget>
-VideoPreviewContainer::VideoPreviewContainer(QWidget *parent) :
- QFrame(parent),
- m_dar(1.0),
- m_refresh(false)
-{
- setFrameShape(QFrame::NoFrame);
- setFocusPolicy(Qt::ClickFocus);
- setAttribute(Qt::WA_PaintOnScreen);
- setAttribute(Qt::WA_OpaquePaintEvent);
- setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
- connect(&m_refreshTimer, SIGNAL(timeout()), this, SLOT(update()));
- m_refreshTimer.setSingleShot(false);
- m_refreshTimer.setInterval(200);
-}
-VideoPreviewContainer::~VideoPreviewContainer()
+AbstractMonitor::AbstractMonitor(Kdenlive::MONITORID id, MonitorManager *manager, QWidget *parent):
+ QWidget(parent),
+ m_id(id),
+ m_monitorManager(manager)
+{}
+
+bool AbstractMonitor::isActive() const
{
- qDeleteAll(m_imageQueue);
+ return m_monitorManager->isActive(m_id);
}
-//virtual
-void VideoPreviewContainer::resizeEvent( QResizeEvent * /*event*/ )
+bool AbstractMonitor::slotActivateMonitor()
{
- updateDisplayZone();
+ return m_monitorManager->activateMonitor(m_id);
}
-void VideoPreviewContainer::setRatio(double ratio)
+VideoContainer::VideoContainer(AbstractMonitor* monitor, QWidget *parent) :
+ QFrame(parent)
+ , m_monitor(monitor)
{
- m_dar = ratio;
- updateDisplayZone();
+ setFrameShape(QFrame::NoFrame);
+ setFocusPolicy(Qt::ClickFocus);
+ setAttribute(Qt::WA_PaintOnScreen);
+ setAttribute(Qt::WA_OpaquePaintEvent);
+ //setEnabled(false);
+ setContentsMargins(0, 0, 0, 0);
+ setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
}
-
-void VideoPreviewContainer::updateDisplayZone()
+// virtual
+void VideoContainer::mouseReleaseEvent(QMouseEvent * event)
{
- QRect rect = this->frameRect();
- int paintW = rect.height() * m_dar + 0.5;
- if (paintW > rect.width()) {
- int paintH = rect.width() / m_dar + 0.5;
- int diff = (rect.height() - paintH) / 2;
- rect.adjust(0, diff, 0, 0);
- rect.setHeight(paintH);
- }
- else {
- int diff = (rect.width() - paintW) / 2;
- rect.adjust(diff, 0, 0, 0);
- rect.setWidth(paintW);
+ if (event->button() != Qt::RightButton) {
+ if (m_monitor->isActive()) {
+ m_monitor->slotPlay();
+ }
}
- m_displayRect = rect;
- m_refresh = true;
}
-void VideoPreviewContainer::setImage(QImage img)
+// virtual
+void VideoContainer::keyPressEvent(QKeyEvent *event)
{
- if (m_imageQueue.count() > 2) {
- delete m_imageQueue.takeLast();
- }
- m_imageQueue.prepend(new QImage(img));
- update();
+ // Exit fullscreen with Esc key
+ if (event->key() == Qt::Key_Escape && isFullScreen()) {
+ switchFullScreen();
+ event->setAccepted(true);
+ } else event->setAccepted(false);
}
-void VideoPreviewContainer::stop()
+// virtual
+void VideoContainer::wheelEvent(QWheelEvent * event)
{
- //m_refreshTimer.stop();
- qDeleteAll(m_imageQueue);
- m_imageQueue.clear();
+ m_monitor->slotMouseSeek(event->delta(), event->modifiers() == Qt::ControlModifier);
+ event->accept();
}
-void VideoPreviewContainer::start()
+void VideoContainer::mouseDoubleClickEvent(QMouseEvent * event)
{
- //m_refreshTimer.start();
+ if (!KdenliveSettings::openglmonitors())
+ switchFullScreen();
+ event->accept();
}
-// virtual
-void VideoPreviewContainer::paintEvent(QPaintEvent *event)
+void VideoContainer::switchFullScreen()
{
- if (m_imageQueue.isEmpty()) return;
- QImage *img = m_imageQueue.takeFirst();
- QPainter painter(this);
- if (m_refresh) {
- painter.fillRect(event->rect(), QColor(KdenliveSettings::window_background()));
- m_refresh = false;
+ // TODO: disable screensaver?
+ m_monitor->pause();
+ Qt::WindowFlags flags = windowFlags();
+ if (!isFullScreen()) {
+ // Check if we ahave a multiple monitor setup
+ setUpdatesEnabled(false);
+#if QT_VERSION >= 0x040600
+ int monitors = QApplication::desktop()->screenCount();
+#else
+ int monitors = QApplication::desktop()->numScreens();
+#endif
+ if (monitors > 1) {
+ QRect screenres;
+ // Move monitor widget to the second screen (one screen for Kdenlive, the other one for the Monitor widget
+ int currentScreen = QApplication::desktop()->screenNumber(this);
+ if (currentScreen < monitors - 1)
+ screenres = QApplication::desktop()->screenGeometry(currentScreen + 1);
+ else
+ screenres = QApplication::desktop()->screenGeometry(currentScreen - 1);
+ move(QPoint(screenres.x(), screenres.y()));
+ resize(screenres.width(), screenres.height());
+ }
+
+ m_baseFlags = flags & (Qt::Window | Qt::SubWindow);
+ flags |= Qt::Window;
+ flags ^= Qt::SubWindow;
+ setWindowFlags(flags);
+#ifdef Q_WS_X11
+ // This works around a bug with Compiz
+ // as the window must be visible before we can set the state
+ show();
+ raise();
+ setWindowState(windowState() | Qt::WindowFullScreen); // set
+#else
+ setWindowState(windowState() | Qt::WindowFullScreen); // set
+ setUpdatesEnabled(true);
+ show();
+#endif
+ setEnabled(true);
+ } else {
+ setUpdatesEnabled(false);
+ flags ^= (Qt::Window | Qt::SubWindow); //clear the flags...
+ flags |= m_baseFlags; //then we reset the flags (window and subwindow)
+ setWindowFlags(flags);
+ setWindowState(windowState() ^ Qt::WindowFullScreen); // reset
+ setUpdatesEnabled(true);
+ setEnabled(false);
+ show();
}
- painter.drawImage(m_displayRect, *img);
- delete img;
+ m_monitor->unpause();
}
-
-
#include <stdint.h>
-class VideoPreviewContainer : public QFrame
-{
- Q_OBJECT
-public:
- VideoPreviewContainer(QWidget *parent = 0);
- ~VideoPreviewContainer();
- /** @brief Set the image to be displayed, will be put in the queue. */
- void setImage(QImage img);
- /** @brief Start the display refresh timer. */
- void start();
- /** @brief Stop the display refresh timer. */
- void stop();
- /** @brief Set the display ratio for this display. */
- void setRatio(double ratio);
-
-protected:
- virtual void paintEvent(QPaintEvent */*event*/);
- virtual void resizeEvent(QResizeEvent * event);
-
-private:
- /** @brief The display aspect ratio for profile. */
- double m_dar;
- /** @brief When true, the whole widget surface will be repainted, useful when resizing widget. */
- bool m_refresh;
- /** @brief The rectangle defining the area for painting our image. */
- QRect m_displayRect;
- /** @brief The queue of images to be displayed. */
- QList <QImage *> m_imageQueue;
- /** @brief We refresh the image with a timer, since this widget is only for preview during capture. */
- QTimer m_refreshTimer;
- /** @brief Re-calculate the display zone after a resize or aspect ratio change. */
- void updateDisplayZone();
-};
-
+class MonitorManager;
class AbstractRender: public QObject
{
Q_OBJECT
public:
- AbstractMonitor(Kdenlive::MONITORID id, QWidget *parent = 0): QWidget(parent) {m_id = id;};
+ AbstractMonitor(Kdenlive::MONITORID id, MonitorManager *manager, QWidget *parent = 0);
Kdenlive::MONITORID id() {return m_id;};
virtual ~AbstractMonitor() {};
virtual AbstractRender *abstractRender() = 0;
-
+ virtual void pause() = 0;
+ virtual void unpause() = 0;
+ bool isActive() const;
+
public slots:
virtual void stop() = 0;
virtual void start() = 0;
+ virtual void slotPlay() = 0;
+ virtual void slotMouseSeek(int eventDelta, bool fast) = 0;
+ bool slotActivateMonitor();
+ virtual void slotSwitchFullScreen() = 0;
protected:
Kdenlive::MONITORID m_id;
+ MonitorManager *m_monitorManager;
};
+class VideoContainer : public QFrame
+{
+ Q_OBJECT
+public:
+ VideoContainer(AbstractMonitor *monitor, QWidget *parent = 0);
+ void switchFullScreen();
+
+protected:
+ virtual void mouseDoubleClickEvent(QMouseEvent * event);
+ virtual void mouseReleaseEvent(QMouseEvent *event);
+ void keyPressEvent(QKeyEvent *event);
+ virtual void wheelEvent(QWheelEvent * event);
+
+private:
+ Qt::WindowFlags m_baseFlags;
+ AbstractMonitor *m_monitor;
+};
+
+
#endif
geom->insert(item2);
}
}
-
emit parameterChanged();
}
// Connect the project list
connect(m_projectList, SIGNAL(clipSelected(DocClipBase *, QPoint, bool)), m_clipMonitor, SLOT(slotSetClipProducer(DocClipBase *, QPoint, bool)));
- connect(m_projectList, SIGNAL(raiseClipMonitor()), m_clipMonitor, SLOT(activateMonitor()));
+ connect(m_projectList, SIGNAL(raiseClipMonitor()), m_clipMonitor, SLOT(slotActivateMonitor()));
connect(m_projectList, SIGNAL(loadingIsOver()), this, SLOT(slotElapsedTime()));
connect(m_projectList, SIGNAL(displayMessage(const QString&, int)), this, SLOT(slotGotProgressInfo(const QString&, int)));
connect(m_projectList, SIGNAL(updateRenderStatus()), this, SLOT(slotCheckRenderStatus()));
connect(m_projectMonitorDock, SIGNAL(visibilityChanged(bool)), m_projectMonitor, SLOT(refreshMonitor(bool)));
connect(m_clipMonitorDock, SIGNAL(visibilityChanged(bool)), m_clipMonitor, SLOT(refreshMonitor(bool)));
- //connect(m_monitorManager, SIGNAL(checkColorScopes()), this, SLOT(slotUpdateColorScopes()));
- //connect(m_monitorManager, SIGNAL(clearScopes()), this, SLOT(slotClearColorScopes()));
connect(m_effectList, SIGNAL(addEffect(const QDomElement)), this, SLOT(slotAddEffect(const QDomElement)));
connect(m_effectList, SIGNAL(reloadEffects()), this, SLOT(slotReloadEffects()));
KAction *fullMon = collection.addAction("monitor_fullscreen");
fullMon->setText(i18n("Switch monitor fullscreen"));
fullMon->setIcon(KIcon("view-fullscreen"));
- connect(fullMon, SIGNAL(triggered(bool)), this, SLOT(slotSwitchFullscreen()));
+ connect(fullMon, SIGNAL(triggered(bool)), m_monitorManager, SLOT(slotSwitchFullscreen()));
KAction *insertTree = collection.addAction("insert_project_tree");
insertTree->setText(i18n("Insert zone in project tree"));
disconnect(m_activeTimeline->projectView(), SIGNAL(showClipFrame(DocClipBase *, QPoint, bool, const int)), m_clipMonitor, SLOT(slotSetClipProducer(DocClipBase *, QPoint, bool, const int)));
disconnect(m_projectList, SIGNAL(gotFilterJobResults(const QString &, int, int, const QString &, stringMap)), m_activeTimeline->projectView(), SLOT(slotGotFilterJobResults(const QString &, int, int, const QString &, stringMap)));
- disconnect(m_activeTimeline, SIGNAL(cursorMoved()), m_projectMonitor, SLOT(activateMonitor()));
+ disconnect(m_activeTimeline, SIGNAL(cursorMoved()), m_projectMonitor, SLOT(slotActivateMonitor()));
disconnect(m_activeTimeline, SIGNAL(configTrack(int)), this, SLOT(slotConfigTrack(int)));
disconnect(m_activeDocument, SIGNAL(docModified(bool)), this, SLOT(slotUpdateDocumentState(bool)));
disconnect(m_effectStack, SIGNAL(updateEffect(ClipItem*, int, QDomElement, QDomElement, int)), m_activeTimeline->projectView(), SLOT(slotUpdateClipEffect(ClipItem*, int, QDomElement, QDomElement, int)));
disconnect(m_effectStack, SIGNAL(displayMessage(const QString&, int)), this, SLOT(slotGotProgressInfo(const QString&, int)));
disconnect(m_transitionConfig, SIGNAL(transitionUpdated(Transition *, QDomElement)), m_activeTimeline->projectView() , SLOT(slotTransitionUpdated(Transition *, QDomElement)));
disconnect(m_transitionConfig, SIGNAL(seekTimeline(int)), m_activeTimeline->projectView() , SLOT(setCursorPos(int)));
- disconnect(m_activeTimeline->projectView(), SIGNAL(activateDocumentMonitor()), m_projectMonitor, SLOT(activateMonitor()));
+ disconnect(m_activeTimeline->projectView(), SIGNAL(activateDocumentMonitor()), m_projectMonitor, SLOT(slotActivateMonitor()));
disconnect(m_activeTimeline, SIGNAL(zoneMoved(int, int)), this, SLOT(slotZoneMoved(int, int)));
disconnect(m_projectList, SIGNAL(loadingIsOver()), m_activeTimeline->projectView(), SLOT(slotUpdateAllThumbs()));
disconnect(m_projectList, SIGNAL(refreshClip(const QString &)), m_activeTimeline->projectView(), SLOT(slotRefreshThumbs(const QString &)));
connect(m_effectStack, SIGNAL(reloadEffects()), this, SLOT(slotReloadEffects()));
connect(m_effectStack, SIGNAL(displayMessage(const QString&, int)), this, SLOT(slotGotProgressInfo(const QString&, int)));
- connect(trackView->projectView(), SIGNAL(activateDocumentMonitor()), m_projectMonitor, SLOT(activateMonitor()));
+ connect(trackView->projectView(), SIGNAL(activateDocumentMonitor()), m_projectMonitor, SLOT(slotActivateMonitor()));
connect(trackView, SIGNAL(zoneMoved(int, int)), this, SLOT(slotZoneMoved(int, int)));
connect(m_projectList, SIGNAL(loadingIsOver()), trackView->projectView(), SLOT(slotUpdateAllThumbs()));
trackView->projectView()->setContextMenu(m_timelineContextMenu, m_timelineContextClipMenu, m_timelineContextTransitionMenu, m_clipTypeGroup, static_cast<QMenu*>(factory()->container("marker_menu", this)));
void MainWindow::slotInsertTrack(int ix)
{
- m_projectMonitor->activateMonitor();
+ m_projectMonitor->slotActivateMonitor();
if (m_activeTimeline) {
if (ix == -1) ix = m_activeTimeline->projectView()->selectedTrack();
m_activeTimeline->projectView()->slotInsertTrack(ix);
void MainWindow::slotDeleteTrack(int ix)
{
- m_projectMonitor->activateMonitor();
+ m_projectMonitor->slotActivateMonitor();
if (m_activeTimeline) {
if (ix == -1) ix = m_activeTimeline->projectView()->selectedTrack();
m_activeTimeline->projectView()->slotDeleteTrack(ix);
void MainWindow::slotConfigTrack(int ix)
{
- m_projectMonitor->activateMonitor();
+ m_projectMonitor->slotActivateMonitor();
if (m_activeTimeline)
m_activeTimeline->projectView()->slotConfigTracks(ix);
if (m_activeDocument)
void MainWindow::slotSelectTrack()
{
- m_projectMonitor->activateMonitor();
+ m_projectMonitor->slotActivateMonitor();
if (m_activeTimeline) {
m_activeTimeline->projectView()->slotSelectClipsInTrack();
}
void MainWindow::slotSelectAllTracks()
{
- m_projectMonitor->activateMonitor();
+ m_projectMonitor->slotActivateMonitor();
if (m_activeTimeline)
m_activeTimeline->projectView()->slotSelectAllClips();
}
else m_projectList->focusTree();
}
-void MainWindow::slotSwitchFullscreen()
-{
- if (m_projectMonitor->isActive()) m_projectMonitor->slotSwitchFullScreen();
- else m_clipMonitor->slotSwitchFullScreen();
-}
-
void MainWindow::slotInsertZoneToTree()
{
if (!m_clipMonitor->isActive() || m_clipMonitor->activeClip() == NULL) return;
/** @brief The monitor informs that it needs (or not) to have frames sent by the renderer. */
void slotMonitorRequestRenderFrame(bool request);
- /** @brief Switch current monitor to fullscreen. */
- void slotSwitchFullscreen();
/** @brief Open the stopmotion dialog. */
void slotOpenStopmotion();
/** @brief Implements all the actions that are int he ActionsCollection. */
}
-MltDeviceCapture::MltDeviceCapture(QString profile, VideoPreviewContainer *surface, QWidget *parent) :
+MltDeviceCapture::MltDeviceCapture(QString profile, VideoContainer *surface, QWidget *parent) :
AbstractRender(Kdenlive::recordMonitor, parent),
doCapture(0),
sendFrameForAnalysis(false),
m_showFrameEvent(NULL),
m_droppedFrames(0),
m_livePreview(KdenliveSettings::enable_recording_preview()),
- m_captureDisplayWidget(surface),
m_winid((int) surface->winId())
{
+ m_captureDisplayWidget = surface;
analyseAudio = KdenliveSettings::monitor_audio();
if (profile.isEmpty()) profile = KdenliveSettings::current_profile();
buildConsumer(profile);
//m_mltConsumer->set("real_time", 0);
}
+void MltDeviceCapture::pause()
+{
+ if (m_mltConsumer) {
+ m_mltConsumer->set("refresh", 0);
+ //m_mltProducer->set_speed(0.0);
+ m_mltConsumer->purge();
+ }
+}
+
void MltDeviceCapture::stop()
{
m_droppedFramesTimer.stop();
bool isPlaylist = false;
- disconnect(this, SIGNAL(imageReady(QImage)), this, SIGNAL(frameUpdated(QImage)));
- m_captureDisplayWidget->stop();
+ //disconnect(this, SIGNAL(imageReady(QImage)), this, SIGNAL(frameUpdated(QImage)));
+ //m_captureDisplayWidget->stop();
if (m_showFrameEvent) delete m_showFrameEvent;
m_showFrameEvent = NULL;
}
-void MltDeviceCapture::doRefresh()
+void MltDeviceCapture::slotDoRefresh()
{
- if (m_mltConsumer) m_mltConsumer->set("refresh", 1);
+ QMutexLocker locker(&m_mutex);
+ if (!m_mltProducer)
+ return;
+ if (m_mltConsumer) {
+ if (m_mltConsumer->is_stopped()) m_mltConsumer->start();
+ m_mltConsumer->purge();
+ m_mltConsumer->set("refresh", 1);
+ }
}
return 0;
}
m_droppedFramesTimer.start();
- connect(this, SIGNAL(imageReady(QImage)), this, SIGNAL(frameUpdated(QImage)));
+ //connect(this, SIGNAL(imageReady(QImage)), this, SIGNAL(frameUpdated(QImage)));
return 1;
}
//memcpy(image.bits(), data, width * height * 3);
QImage image((uchar *)data, width, height, QImage::Format_RGB888);
- m_captureDisplayWidget->setImage(image);
+ //m_captureDisplayWidget->setImage(image);
//TEST: is it better to process frame conversion ouside MLT???
/*
rgb_ptr += 3;
}
//emit imageReady(image);
- m_captureDisplayWidget->setImage(image);
+ //m_captureDisplayWidget->setImage(image);
emit unblockPreview();
//processingImage = false;
}
/** @brief Build a MLT 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 capture (default one will be used if empty). */
- MltDeviceCapture(QString profile, VideoPreviewContainer *surface, QWidget *parent = 0);
+ MltDeviceCapture(QString profile, VideoContainer *surface, QWidget *parent = 0);
/** @brief Destroy the MLT Renderer. */
~MltDeviceCapture();
void gotCapturedFrame(Mlt::Frame& frame);
/** @brief Save current frame to file. */
void captureFrame(const QString &path);
- void doRefresh();
+
/** @brief This will add the video clip from path and add it in the overlay track. */
void setOverlay(const QString &path);
/** @brief True if we are processing an image (yuv > rgb) when recording. */
bool processingImage;
+
+ void pause();
private:
Mlt::Consumer * m_mltConsumer;
int m_frameCount;
/** @brief The surface onto which the captured frames should be painted. */
- VideoPreviewContainer *m_captureDisplayWidget;
+ VideoContainer *m_captureDisplayWidget;
/** @brief A human-readable description of this renderer. */
int m_winid;
QString m_capturePath;
QTimer m_droppedFramesTimer;
+
+ QMutex m_mutex;
/** @brief Build the MLT Consumer object with initial settings.
* @param profileName The MLT profile to use for the consumer */
/** @brief Stops the consumer. */
void stop();
+ void slotDoRefresh();
};
#endif
Monitor::Monitor(Kdenlive::MONITORID id, MonitorManager *manager, QString profile, QWidget *parent) :
- AbstractMonitor(id, parent),
+ AbstractMonitor(id, manager, parent),
render(NULL),
- m_monitorManager(manager),
m_currentClip(NULL),
m_ruler(new SmallRuler(m_monitorManager)),
m_overlay(NULL),
// Video widget holder
m_videoBox = new VideoContainer(this);
- m_videoBox->setContentsMargins(0, 0, 0, 0);
- m_videoBox->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
layout->addWidget(m_videoBox, 10);
layout->addStretch();
if (m_dragStarted && event->button() != Qt::RightButton) {
if (m_videoBox->geometry().contains(event->pos()) && (!m_effectWidget || !m_effectWidget->isVisible())) {
if (isActive()) slotPlay();
- else activateMonitor();
+ else slotActivateMonitor();
} //else event->ignore(); //QWidget::mouseReleaseEvent(event);
m_dragStarted = false;
}
}
}
-bool Monitor::isActive() const
-{
- return m_monitorManager->isActive(m_id);
-}
-
-bool Monitor::activateMonitor()
-{
- return m_monitorManager->activateMonitor(m_id);
-}
-
void Monitor::setTimePos(const QString &pos)
{
m_timePos->setValue(pos);
void Monitor::slotSeek(int pos)
{
if (render == NULL) return;
- activateMonitor();
+ slotActivateMonitor();
render->seekToFrame(pos);
}
void Monitor::slotStart()
{
- activateMonitor();
+ slotActivateMonitor();
render->play(0);
render->seekToFrame(0);
}
void Monitor::slotEnd()
{
- activateMonitor();
+ slotActivateMonitor();
render->play(0);
render->seekToFrame(render->getLength());
}
void Monitor::slotZoneStart()
{
- activateMonitor();
+ slotActivateMonitor();
render->play(0);
render->seekToFrame(m_ruler->zone().x());
}
void Monitor::slotZoneEnd()
{
- activateMonitor();
+ slotActivateMonitor();
render->play(0);
render->seekToFrame(m_ruler->zone().y());
}
void Monitor::slotRewind(double speed)
{
- activateMonitor();
+ slotActivateMonitor();
if (speed == 0) {
double currentspeed = render->playSpeed();
if (currentspeed >= 0) render->play(-2);
void Monitor::slotForward(double speed)
{
- activateMonitor();
+ slotActivateMonitor();
if (speed == 0) {
double currentspeed = render->playSpeed();
if (currentspeed <= 1) render->play(2);
void Monitor::slotRewindOneFrame(int diff)
{
- activateMonitor();
+ slotActivateMonitor();
render->play(0);
render->seekToFrameDiff(-diff);
}
void Monitor::slotForwardOneFrame(int diff)
{
- activateMonitor();
+ slotActivateMonitor();
render->play(0);
render->seekToFrameDiff(diff);
}
void Monitor::seekCursor(int pos)
{
- //activateMonitor();
+ //slotActivateMonitor();
if (m_ruler->slotNewValue(pos)) {
checkOverlay();
m_timePos->setValue(pos);
void Monitor::refreshMonitor(bool visible)
{
if (visible && render) {
- if (!activateMonitor()) {
+ if (!slotActivateMonitor()) {
// the monitor was already active, simply refreshClipThumbnail
render->doRefresh();
}
void Monitor::pause()
{
if (render == NULL) return;
- activateMonitor();
+ slotActivateMonitor();
render->pause();
//m_playAction->setChecked(true);
m_playAction->setIcon(m_playIcon);
}
+void Monitor::unpause()
+{
+}
+
void Monitor::slotPlay()
{
if (render == NULL) return;
- activateMonitor();
+ slotActivateMonitor();
if (render->playSpeed() == 0.0) {
m_playAction->setIcon(m_pauseIcon);
render->switchPlay(true);
void Monitor::slotPlayZone()
{
if (render == NULL) return;
- activateMonitor();
+ slotActivateMonitor();
QPoint p = m_ruler->zone();
render->playZone(GenTime(p.x(), m_monitorManager->timecode().fps()), GenTime(p.y(), m_monitorManager->timecode().fps()));
//m_playAction->setChecked(true);
void Monitor::slotLoopZone()
{
if (render == NULL) return;
- activateMonitor();
+ slotActivateMonitor();
QPoint p = m_ruler->zone();
render->loopZone(GenTime(p.x(), m_monitorManager->timecode().fps()), GenTime(p.y(), m_monitorManager->timecode().fps()));
//m_playAction->setChecked(true);
{
if (render == NULL || m_selectedClip == NULL)
return;
- activateMonitor();
+ slotActivateMonitor();
render->loopZone(m_selectedClip->startPos(), m_selectedClip->endPos());
//m_playAction->setChecked(true);
m_playAction->setIcon(m_pauseIcon);
if (clip != m_currentClip || forceUpdate) {
m_currentClip = clip;
- if (m_currentClip) activateMonitor();
+ if (m_currentClip) slotActivateMonitor();
updateMarkers(clip);
Mlt::Producer *prod = NULL;
if (clip) prod = clip->getCloneProducer();
}
} else {
if (m_currentClip) {
- activateMonitor();
+ slotActivateMonitor();
if (position == -1) position = render->seekFramePosition();
render->seek(position);
}
void Monitor::slotOpenFile(const QString &file)
{
if (render == NULL) return;
- activateMonitor();
+ slotActivateMonitor();
QDomDocument doc;
QDomElement mlt = doc.createElement("mlt");
doc.appendChild(mlt);
m_timePos->updateTimeCode(m_monitorManager->timecode());
if (render == NULL) return;
if (!render->hasProfile(profile)) {
- activateMonitor();
+ slotActivateMonitor();
render->resetProfile(profile);
}
if (m_effectWidget)
update();
}
-VideoContainer::VideoContainer(Monitor* parent) :
- QFrame()
- , m_monitor(parent)
-{
- setFrameShape(QFrame::NoFrame);
- setFocusPolicy(Qt::ClickFocus);
- setEnabled(false);
- setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
-}
-
-// virtual
-void VideoContainer::mouseReleaseEvent(QMouseEvent * event)
-{
- if (event->button() != Qt::RightButton) {
- if (m_monitor->isActive()) {
- m_monitor->slotPlay();
- }
- }
-}
-
-
-// virtual
-void VideoContainer::keyPressEvent(QKeyEvent *event)
-{
- // Exit fullscreen with Esc key
- if (event->key() == Qt::Key_Escape && isFullScreen()) {
- switchFullScreen();
- event->setAccepted(true);
- } else event->setAccepted(false);
-}
-
-// virtual
-void VideoContainer::wheelEvent(QWheelEvent * event)
-{
- m_monitor->slotMouseSeek(event->delta(), event->modifiers() == Qt::ControlModifier);
- event->accept();
-}
-
-void VideoContainer::mouseDoubleClickEvent(QMouseEvent * event)
-{
- if (!KdenliveSettings::openglmonitors())
- switchFullScreen();
- event->accept();
-}
-
-void VideoContainer::switchFullScreen()
-{
- // TODO: disable screensaver?
- Qt::WindowFlags flags = windowFlags();
- if (!isFullScreen()) {
- // Check if we ahave a multiple monitor setup
- setUpdatesEnabled(false);
-#if QT_VERSION >= 0x040600
- int monitors = QApplication::desktop()->screenCount();
-#else
- int monitors = QApplication::desktop()->numScreens();
-#endif
- if (monitors > 1) {
- QRect screenres;
- // Move monitor widget to the second screen (one screen for Kdenlive, the other one for the Monitor widget
- int currentScreen = QApplication::desktop()->screenNumber(this);
- if (currentScreen < monitors - 1)
- screenres = QApplication::desktop()->screenGeometry(currentScreen + 1);
- else
- screenres = QApplication::desktop()->screenGeometry(currentScreen - 1);
- move(QPoint(screenres.x(), screenres.y()));
- resize(screenres.width(), screenres.height());
- }
-
- m_baseFlags = flags & (Qt::Window | Qt::SubWindow);
- flags |= Qt::Window;
- flags ^= Qt::SubWindow;
- setWindowFlags(flags);
-#ifdef Q_WS_X11
- // This works around a bug with Compiz
- // as the window must be visible before we can set the state
- show();
- raise();
- setWindowState(windowState() | Qt::WindowFullScreen); // set
-#else
- setWindowState(windowState() | Qt::WindowFullScreen); // set
- setUpdatesEnabled(true);
- show();
-#endif
- setEnabled(true);
- } else {
- setUpdatesEnabled(false);
- flags ^= (Qt::Window | Qt::SubWindow); //clear the flags...
- flags |= m_baseFlags; //then we reset the flags (window and subwindow)
- setWindowFlags(flags);
- setWindowState(windowState() ^ Qt::WindowFullScreen); // reset
- setUpdatesEnabled(true);
- setEnabled(false);
- show();
- }
- m_monitor->pause();
-}
-
#include "monitor.moc"
class Monitor;
class MonitorManager;
-class VideoContainer : public QFrame
-{
- Q_OBJECT
-public:
- VideoContainer(Monitor *parent = 0);
- void switchFullScreen();
-
-protected:
- virtual void mouseDoubleClickEvent(QMouseEvent * event);
- virtual void mouseReleaseEvent(QMouseEvent *event);
- void keyPressEvent(QKeyEvent *event);
- virtual void wheelEvent(QWheelEvent * event);
-
-private:
- Qt::WindowFlags m_baseFlags;
- Monitor *m_monitor;
-};
class MonitorRefresh : public QWidget
{
AbstractRender *abstractRender();
void resetProfile(const QString &profile);
void resetSize();
- bool isActive() const;
void pause();
+ void unpause();
void setupMenu(QMenu *goMenu, QAction *playZone, QAction *loopZone, QMenu *markerMenu = NULL, QAction *loopClip = NULL);
const QString sceneList();
DocClipBase *activeClip();
private:
Kdenlive::MONITORID m_name;
- MonitorManager *m_monitorManager;
DocClipBase *m_currentClip;
SmallRuler *m_ruler;
Overlay *m_overlay;
void slotSeek(int pos);
void stop();
void start();
- bool activateMonitor();
void slotPlay();
void slotPlayZone();
void slotLoopZone();
MonitorEditWidget::MonitorEditWidget(Render* renderer, QWidget* parent) :
QWidget(parent)
{
+ setAutoFillBackground(true);
+ setAttribute(Qt::WA_PaintOnScreen, false);
+ setAttribute(Qt::WA_OpaquePaintEvent, false);
+ setContentsMargins(0, 0, 0, 0);
+ setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
m_ui.setupUi(this);
-
m_scene = new MonitorScene(renderer);
m_view = new QGraphicsView(m_scene, m_ui.frameVideo);
+ m_view->setFrameShape(QFrame::NoFrame);
m_view->setRenderHints(QFlags<QPainter::RenderHint>());
m_view->scale(((double) renderer->renderWidth()) / renderer->frameRenderWidth(), 1.0);
m_view->setMouseTracking(true);
private slots:
/** @brief Sets the KdenliveSetting directupdate with true = update parameters (rerender frame) during mouse move (before mouse button is released) */
void slotSetDirectUpdate(bool directUpdate);
-
+
private:
Ui::MonitorEditWidget_UI m_ui;
MonitorScene *m_scene;
void MonitorManager::stopActiveMonitor()
{
if (m_activeMonitor == m_clipMonitor) m_clipMonitor->pause();
- else m_projectMonitor->pause();
+ else if (m_activeMonitor == m_projectMonitor) m_projectMonitor->pause();
}
void MonitorManager::slotPlay()
{
- if (m_activeMonitor == m_clipMonitor) m_clipMonitor->slotPlay();
- else m_projectMonitor->slotPlay();
+ if (m_activeMonitor) m_activeMonitor->slotPlay();
}
void MonitorManager::slotPause()
void MonitorManager::slotPlayZone()
{
if (m_activeMonitor == m_clipMonitor) m_clipMonitor->slotPlayZone();
- else m_projectMonitor->slotPlayZone();
+ else if (m_activeMonitor == m_projectMonitor) m_projectMonitor->slotPlayZone();
}
void MonitorManager::slotLoopZone()
void MonitorManager::slotRewind(double speed)
{
if (m_activeMonitor == m_clipMonitor) m_clipMonitor->slotRewind(speed);
- else m_projectMonitor->slotRewind(speed);
+ else if (m_activeMonitor == m_projectMonitor) m_projectMonitor->slotRewind(speed);
}
void MonitorManager::slotForward(double speed)
{
if (m_activeMonitor == m_clipMonitor) m_clipMonitor->slotForward(speed);
- else m_projectMonitor->slotForward(speed);
+ else if (m_activeMonitor == m_projectMonitor) m_projectMonitor->slotForward(speed);
}
void MonitorManager::slotRewindOneFrame()
{
if (m_activeMonitor == m_clipMonitor) m_clipMonitor->slotRewindOneFrame();
- else m_projectMonitor->slotRewindOneFrame();
+ else if (m_activeMonitor == m_projectMonitor) m_projectMonitor->slotRewindOneFrame();
}
void MonitorManager::slotForwardOneFrame()
{
if (m_activeMonitor == m_clipMonitor) m_clipMonitor->slotForwardOneFrame();
- else m_projectMonitor->slotForwardOneFrame();
+ else if (m_activeMonitor == m_projectMonitor) m_projectMonitor->slotForwardOneFrame();
}
void MonitorManager::slotRewindOneSecond()
{
if (m_activeMonitor == m_clipMonitor) m_clipMonitor->slotRewindOneFrame(m_timecode.fps());
- else m_projectMonitor->slotRewindOneFrame(m_timecode.fps());
+ else if (m_activeMonitor == m_projectMonitor) m_projectMonitor->slotRewindOneFrame(m_timecode.fps());
}
void MonitorManager::slotForwardOneSecond()
{
if (m_activeMonitor == m_clipMonitor) m_clipMonitor->slotForwardOneFrame(m_timecode.fps());
- else m_projectMonitor->slotForwardOneFrame(m_timecode.fps());
+ else if (m_activeMonitor == m_projectMonitor) m_projectMonitor->slotForwardOneFrame(m_timecode.fps());
}
void MonitorManager::slotStart()
{
if (m_activeMonitor == m_clipMonitor) m_clipMonitor->slotStart();
- else m_projectMonitor->slotStart();
+ else if (m_activeMonitor == m_projectMonitor) m_projectMonitor->slotStart();
}
void MonitorManager::slotEnd()
{
if (m_activeMonitor == m_clipMonitor) m_clipMonitor->slotEnd();
- else m_projectMonitor->slotEnd();
+ else if (m_activeMonitor == m_projectMonitor) m_projectMonitor->slotEnd();
}
void MonitorManager::resetProfiles(Timecode tc)
return NULL;
}
+void MonitorManager::slotSwitchFullscreen()
+{
+ if (m_activeMonitor) m_activeMonitor->slotSwitchFullScreen();
+}
+
#include "monitormanager.moc"
void slotStart();
void slotEnd();
void slotResetProfiles();
+
+ /** @brief Switch current monitor to fullscreen. */
+ void slotSwitchFullscreen();
/** @brief Switches between project and clip monitor.
* @ref activateMonitor
RecMonitor::RecMonitor(Kdenlive::MONITORID name, MonitorManager *manager, QWidget *parent) :
- AbstractMonitor(name, parent),
+ AbstractMonitor(name, manager, parent),
m_isCapturing(false),
m_didCapture(false),
m_isPlaying(false),
- m_manager(manager),
m_captureDevice(NULL),
m_analyse(false)
{
setupUi(this);
- video_frame->setAttribute(Qt::WA_PaintOnScreen);
+ //video_frame->setAttribute(Qt::WA_PaintOnScreen);
device_selector->setCurrentIndex(KdenliveSettings::defaultcapture());
connect(device_selector, SIGNAL(currentIndexChanged(int)), this, SLOT(slotVideoDeviceChanged(int)));
QVBoxLayout *l = new QVBoxLayout;
l->setContentsMargins(0, 0, 0, 0);
l->setSpacing(0);
- m_videoBox = new VideoPreviewContainer();
- m_videoBox->setContentsMargins(0, 0, 0, 0);
- m_videoBox->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
- l->addWidget(m_videoBox);
+ m_videoBox = new VideoContainer(this);
+ l->addWidget(m_videoBox, 10);
video_frame->setLayout(l);
QToolBar *toolbar = new QToolBar(this);
QString videoDriver = KdenliveSettings::videodrivername();
#if QT_VERSION >= 0x040600
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
- env.insert("SDL_WINDOWID", QString::number(video_frame->winId()));
+ env.insert("SDL_WINDOWID", QString::number(m_videoBox->winId()));
if (!videoDriver.isEmpty()) {
if (videoDriver == "x11_noaccel") {
env.insert("SDL_VIDEO_YUV_HWACCEL", "0");
m_displayProcess->setProcessEnvironment(env);
#else
QStringList env = QProcess::systemEnvironment();
- env << "SDL_WINDOWID=" + QString::number(video_frame->winId());
+ env << "SDL_WINDOWID=" + QString::number(m_videoBox->winId());
if (!videoDriver.isEmpty()) {
if (videoDriver == "x11_noaccel") {
env << "SDL_VIDEO_YUV_HWACCEL=0";
#endif
setenv("SDL_VIDEO_ALLOW_SCREENSAVER", "1", 1);
- kDebug() << "/////// BUILDING MONITOR, ID: " << video_frame->winId();
+ kDebug() << "/////// BUILDING MONITOR, ID: " << m_videoBox->winId();
slotVideoDeviceChanged(device_selector->currentIndex());
m_previewSettings->setChecked(KdenliveSettings::enable_recording_preview());
connect(m_previewSettings, SIGNAL(triggered(bool)), this, SLOT(slotChangeRecordingPreview(bool)));
if (m_captureDevice) delete m_captureDevice;
}
+void RecMonitor::mouseDoubleClickEvent(QMouseEvent * event)
+{
+ if (!KdenliveSettings::openglmonitors() && m_videoBox && m_videoBox->isVisible()) {
+ m_videoBox->switchFullScreen();
+ event->accept();
+ }
+}
+
+void RecMonitor::slotSwitchFullScreen()
+{
+ m_videoBox->switchFullScreen();
+}
void RecMonitor::stop()
{
void RecMonitor::start()
{
+ //slotStartPreview(true);
}
void RecMonitor::slotConfigure()
m_logger.setVisible(ix == BLACKMAGIC);
if (m_captureDevice) {
// MLT capture still running, abort
+ m_monitorManager->clearScopeSource();
m_captureDevice->stop();
delete m_captureDevice;
m_captureDevice = NULL;
- m_manager->clearScopeSource();
}
// The m_videoBox container has to be shown once before the MLT consumer is build, or preview will fail
}
return;
}
+ if (m_isPlaying) return;
m_captureArgs.clear();
m_displayArgs.clear();
m_isPlaying = false;
break;
case VIDEO4LINUX:
path = KStandardDirs::locateLocal("appdata", "profiles/video4linux");
- m_manager->activateMonitor(Kdenlive::recordMonitor);
+ slotActivateMonitor();
buildMltDevice(path);
profile = ProfilesDialog::getVideoProfile(path);
producer = getV4lXmlPlaylist(profile);
break;
case BLACKMAGIC:
path = KdenliveSettings::current_profile();
- m_manager->activateMonitor(Kdenlive::recordMonitor);
+ slotActivateMonitor();
buildMltDevice(path);
producer = QString("decklink:%1").arg(KdenliveSettings::decklink_capturedevice());
if (!m_captureDevice->slotStartPreview(producer)) {
switch (device_selector->currentIndex()) {
case VIDEO4LINUX:
- m_manager->activateMonitor(Kdenlive::recordMonitor);
+ slotActivateMonitor();
path = KStandardDirs::locateLocal("appdata", "profiles/video4linux");
profile = ProfilesDialog::getVideoProfile(path);
- m_videoBox->setRatio((double) profile.display_aspect_num / profile.display_aspect_den);
+ //m_videoBox->setRatio((double) profile.display_aspect_num / profile.display_aspect_den);
buildMltDevice(path);
playlist = getV4lXmlPlaylist(profile);
break;
case BLACKMAGIC:
- m_manager->activateMonitor(Kdenlive::recordMonitor);
+ slotActivateMonitor();
path = KdenliveSettings::current_profile();
profile = ProfilesDialog::getVideoProfile(path);
- m_videoBox->setRatio((double) profile.display_aspect_num / profile.display_aspect_den);
+ //m_videoBox->setRatio((double) profile.display_aspect_num / profile.display_aspect_den);
buildMltDevice(path);
playlist = QString("<producer id=\"producer0\" in=\"0\" out=\"99999\"><property name=\"mlt_type\">producer</property><property name=\"length\">100000</property><property name=\"eof\">pause</property><property name=\"resource\">%1</property><property name=\"mlt_service\">decklink</property></producer>").arg(KdenliveSettings::decklink_capturedevice());
}
// virtual
-void RecMonitor::mousePressEvent(QMouseEvent * /*event*/)
+void RecMonitor::mousePressEvent(QMouseEvent *event)
{
if (m_freeSpace->underMouse()) slotUpdateFreeSpace();
+ else QWidget::mousePressEvent(event);//m_videoBox->mousePressEvent(event);
}
void RecMonitor::slotUpdateFreeSpace()
void RecMonitor::refreshRecMonitor(bool visible)
{
if (visible) {
- //if (!m_isActive) m_monitorManager->activateRecMonitor(m_name);
+ //if (!m_isActive) activateMonitor();
}
}
void RecMonitor::slotPlay()
{
-
- //if (!m_isActive) m_monitorManager->activateRecMonitor(m_name);
-
+ if (m_isPlaying) slotStopCapture();
+ else slotStartPreview(true);
}
void RecMonitor::slotReadDvgrabInfo()
void RecMonitor::buildMltDevice(const QString &path)
{
if (m_captureDevice == NULL) {
+ m_monitorManager->updateScopeSource();
m_captureDevice = new MltDeviceCapture(path, m_videoBox, this);
connect(m_captureDevice, SIGNAL(droppedFrames(int)), this, SLOT(slotDroppedFrames(int)));
m_captureDevice->sendFrameForAnalysis = m_analyse;
- m_manager->updateScopeSource();
+ m_monitorManager->updateScopeSource();
}
}
KdenliveSettings::setEnable_recording_preview(enable);
}
+void RecMonitor::pause()
+{
+ if (m_isCapturing) return;
+ slotStopCapture();
+ if (m_captureDevice) {
+ m_monitorManager->clearScopeSource();
+ delete m_captureDevice;
+ m_captureDevice = NULL;
+ }
+}
+
+void RecMonitor::unpause()
+{
+ if (m_isCapturing) return;
+ slotStartPreview(true);
+}
+
+void RecMonitor::slotMouseSeek(int /*eventDelta*/, bool /*fast*/)
+{
+}
+
+
#include "recmonitor.moc"
AbstractRender *abstractRender();
void analyseFrames(bool analyse);
+ void pause();
+ void unpause();
enum CAPTUREDEVICE {FIREWIRE = 0, VIDEO4LINUX = 1, SCREENGRAB = 2, BLACKMAGIC = 3};
protected:
virtual void mousePressEvent(QMouseEvent * event);
+ virtual void mouseDoubleClickEvent(QMouseEvent * event);
private:
KDateTime m_captureTime;
MonitorManager *m_manager;
MltDeviceCapture *m_captureDevice;
- VideoPreviewContainer *m_videoBox;
+ VideoContainer *m_videoBox;
QAction *m_addCapturedClip;
QAction *m_previewSettings;
void start();
void slotStopCapture();
void slotUpdateCaptureFolder(const QString ¤tProjectFolder);
+ void slotMouseSeek(int eventDelta, bool fast);
+ void slotSwitchFullScreen();
signals:
void renderPosition(int);
}
-StopmotionMonitor::StopmotionMonitor(QWidget *parent) :
- AbstractMonitor(Kdenlive::stopmotionMonitor, parent),
+StopmotionMonitor::StopmotionMonitor(MonitorManager *manager, QWidget *parent) :
+ AbstractMonitor(Kdenlive::stopmotionMonitor, manager, parent),
m_captureDevice(NULL)
{
}
{
}
+void StopmotionMonitor::slotSwitchFullScreen()
+{
+}
+
void StopmotionMonitor::setRender(MltDeviceCapture *render)
{
m_captureDevice = render;
{
}
+void StopmotionMonitor::pause()
+{
+}
+
+void StopmotionMonitor::unpause()
+{
+}
+
+void StopmotionMonitor::slotPlay()
+{
+}
+
+void StopmotionMonitor::slotMouseSeek(int /*eventDelta*/, bool /*fast*/)
+{
+}
+
StopmotionWidget::StopmotionWidget(MonitorManager *manager, KUrl projectFolder, QList< QAction* > actions, QWidget* parent) :
QDialog(parent)
, Ui::Stopmotion_UI()
, m_animatedIndex(-1)
, m_animate(false)
, m_manager(manager)
- , m_monitor(new StopmotionMonitor(this))
+ , m_monitor(new StopmotionMonitor(manager, this))
{
//setAttribute(Qt::WA_DeleteOnClose);
//HACK: the monitor widget is hidden, it is just used to control the capturedevice from monitormanager
QVBoxLayout *layout = new QVBoxLayout;
layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
- m_videoBox = new VideoPreviewContainer();
- m_videoBox->setContentsMargins(0, 0, 0, 0);
- m_videoBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
- //m_videoBox->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
+ m_videoBox = new VideoContainer(m_monitor);
m_videoBox->setLineWidth(4);
layout->addWidget(m_videoBox);
if (m_captureDevice) m_captureDevice->mirror(isOn);
}
+
const QString StopmotionWidget::createProducer(MltVideoProfile profile, const QString &service, const QString &resource)
{
Q_UNUSED(profile)
{
Q_OBJECT
public:
- StopmotionMonitor(QWidget *parent);
+ StopmotionMonitor(MonitorManager *manager, QWidget *parent);
~StopmotionMonitor();
AbstractRender *abstractRender();
Kdenlive::MONITORID id() const;
void setRender(MltDeviceCapture *render);
+ void pause();
+ void unpause();
private:
MltDeviceCapture *m_captureDevice;
public slots:
- virtual void stop();
- virtual void start();
+ void stop();
+ void start();
+ void slotPlay();
+ void slotMouseSeek(int eventDelta, bool fast);
+ void slotSwitchFullScreen();
signals:
void stopCapture();
/** @brief Capture holder that will handle all video operation. */
MltDeviceCapture *m_captureDevice;
- VideoPreviewContainer *m_videoBox;
+ VideoContainer *m_videoBox;
/** @brief Holds the name of the current sequence.
* Files will be saved in project folder with name: sequence001.png */