X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Frecmonitor.cpp;h=a2b8906ab09d9e24079a1557720f4059a026b0a0;hb=87e34435cbb42c67c699b0539b5b0d93a4f9ebf9;hp=3a850f2481b8353201bd53604cbb72d181b374d4;hpb=d251786b045680a5b975f72f25daf6f87a57f0d8;p=kdenlive diff --git a/src/recmonitor.cpp b/src/recmonitor.cpp index 3a850f24..a2b8906a 100644 --- a/src/recmonitor.cpp +++ b/src/recmonitor.cpp @@ -20,12 +20,15 @@ #include "recmonitor.h" #include "gentime.h" +#include "mltdevicecapture.h" #include "kdenlivesettings.h" #include "managecapturesdialog.h" +#include "monitormanager.h" +#include "monitor.h" +#include "profilesdialog.h" #include #include -#include #include #include #include @@ -44,13 +47,15 @@ #include -RecMonitor::RecMonitor(QString name, QWidget *parent) : - QWidget(parent), - m_name(name), - m_isActive(false), - m_isCapturing(false), - m_didCapture(false), - m_isPlaying(false) +RecMonitor::RecMonitor(QString name, MonitorManager *manager, QWidget *parent) : + AbstractMonitor(parent), + m_name(name), + m_isCapturing(false), + m_didCapture(false), + m_isPlaying(false), + m_manager(manager), + m_captureDevice(NULL), + m_analyse(false) { setupUi(this); @@ -58,9 +63,17 @@ RecMonitor::RecMonitor(QString name, QWidget *parent) : device_selector->setCurrentIndex(KdenliveSettings::defaultcapture()); connect(device_selector, SIGNAL(currentIndexChanged(int)), this, SLOT(slotVideoDeviceChanged(int))); - - - QToolBar *toolbar = new QToolBar(name, this); + // Video widget holder + 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); + video_frame->setLayout(l); + + QToolBar *toolbar = new QToolBar(this); QHBoxLayout *layout = new QHBoxLayout; layout->setContentsMargins(0, 0, 0, 0); m_playIcon = KIcon("media-playback-start"); @@ -73,7 +86,7 @@ RecMonitor::RecMonitor(QString name, QWidget *parent) : connect(m_rewAction, SIGNAL(triggered()), this, SLOT(slotRewind())); m_playAction = toolbar->addAction(m_playIcon, i18n("Play")); - connect(m_playAction, SIGNAL(triggered()), this, SLOT(slotStartCapture())); + connect(m_playAction, SIGNAL(triggered()), this, SLOT(slotStartPreview())); m_stopAction = toolbar->addAction(KIcon("media-playback-stop"), i18n("Stop")); connect(m_stopAction, SIGNAL(triggered()), this, SLOT(slotStopCapture())); @@ -92,8 +105,12 @@ RecMonitor::RecMonitor(QString name, QWidget *parent) : configAction->setCheckable(false); layout->addWidget(toolbar); - + layout->addWidget(&m_logger); layout->addWidget(&m_dvinfo); + m_logger.setMaxCount(10); + m_logger.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + m_logger.setFrame(false); + //m_logger.setInsertPolicy(QComboBox::InsertAtTop); #if KDE_IS_VERSION(4,2,0) m_freeSpace = new KCapacityBar(KCapacityBar::DrawTextInline, this); @@ -108,37 +125,42 @@ RecMonitor::RecMonitor(QString name, QWidget *parent) : #endif control_frame_firewire->setLayout(layout); - - slotVideoDeviceChanged(device_selector->currentIndex()); m_displayProcess = new QProcess; m_captureProcess = new QProcess; connect(m_captureProcess, SIGNAL(stateChanged(QProcess::ProcessState)), this, SLOT(slotProcessStatus(QProcess::ProcessState))); connect(m_captureProcess, SIGNAL(readyReadStandardError()), this, SLOT(slotReadDvgrabInfo())); + + QString videoDriver = KdenliveSettings::videodrivername(); +#if QT_VERSION >= 0x040600 + QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); + env.insert("SDL_WINDOWID", QString::number(video_frame->winId())); + if (!videoDriver.isEmpty()) { + if (videoDriver == "x11_noaccel") { + env.insert("SDL_VIDEO_YUV_HWACCEL", "0"); + env.insert("SDL_VIDEODRIVER", "x11"); + } else env.insert("SDL_VIDEODRIVER", videoDriver); + } + m_displayProcess->setProcessEnvironment(env); +#else QStringList env = QProcess::systemEnvironment(); env << "SDL_WINDOWID=" + QString::number(video_frame->winId()); - - QString videoDriver = KdenliveSettings::videodrivername(); if (!videoDriver.isEmpty()) { if (videoDriver == "x11_noaccel") { env << "SDL_VIDEO_YUV_HWACCEL=0"; env << "SDL_VIDEODRIVER=x11"; } else env << "SDL_VIDEODRIVER=" + videoDriver; } - setenv("SDL_VIDEO_ALLOW_SCREENSAVER", "1", 1); - m_displayProcess->setEnvironment(env); - - if (KdenliveSettings::video4capture().isEmpty()) { - QString captureCommand; - if (!KdenliveSettings::video4adevice().isEmpty()) captureCommand = "-f " + KdenliveSettings::video4aformat() + " -i " + KdenliveSettings::video4adevice(); - - captureCommand += " -f " + KdenliveSettings::video4vformat() + " -s " + KdenliveSettings::video4size() + " -r " + QString::number(KdenliveSettings::video4rate()) + " -i " + KdenliveSettings::video4vdevice(); - KdenliveSettings::setVideo4capture(captureCommand); - } +#endif + setenv("SDL_VIDEO_ALLOW_SCREENSAVER", "1", 1); kDebug() << "/////// BUILDING MONITOR, ID: " << video_frame->winId(); + slotVideoDeviceChanged(device_selector->currentIndex()); + recording_preview->setToolTip(i18n("Capture preview settings")); + recording_preview->setCurrentIndex(KdenliveSettings::recording_preview()); + connect(recording_preview, SIGNAL(currentIndexChanged(int)), this, SLOT(slotChangeRecordingPreview(int))); } RecMonitor::~RecMonitor() @@ -148,27 +170,38 @@ RecMonitor::~RecMonitor() #endif delete m_captureProcess; delete m_displayProcess; + if (m_captureDevice) delete m_captureDevice; } -QString RecMonitor::name() const +const QString RecMonitor::name() const { return m_name; } +void RecMonitor::stop() +{ + slotStopCapture(); +} + +void RecMonitor::start() +{ +} + void RecMonitor::slotConfigure() { emit showConfigDialog(4, device_selector->currentIndex()); } -void RecMonitor::slotUpdateCaptureFolder() +void RecMonitor::slotUpdateCaptureFolder(const QString ¤tProjectFolder) { - if (m_captureProcess) m_captureProcess->setWorkingDirectory(KdenliveSettings::capturefolder()); + if (KdenliveSettings::capturetoprojectfolder()) m_capturePath = currentProjectFolder; + else m_capturePath = KdenliveSettings::capturefolder(); + if (m_captureProcess) m_captureProcess->setWorkingDirectory(m_capturePath); if (m_captureProcess->state() != QProcess::NotRunning) { if (device_selector->currentIndex() == FIREWIRE) KMessageBox::information(this, i18n("You need to disconnect and reconnect in the capture monitor to apply your changes"), i18n("Capturing")); else KMessageBox::information(this, i18n("You need to stop capture before your changes can be applied"), i18n("Capturing")); } else slotVideoDeviceChanged(device_selector->currentIndex()); - kDebug() << "// UPDATE CAPT FOLD: " << KdenliveSettings::capturefolder(); #if KDE_IS_VERSION(4,2,0) // update free space info @@ -178,12 +211,30 @@ void RecMonitor::slotUpdateCaptureFolder() void RecMonitor::slotVideoDeviceChanged(int ix) { + QString capturefile; + QString capturename; + recording_preview->setHidden(ix != VIDEO4LINUX && ix != BLACKMAGIC); + m_fwdAction->setVisible(ix == FIREWIRE); + m_discAction->setVisible(ix == FIREWIRE); + m_rewAction->setVisible(ix == FIREWIRE); + m_recAction->setEnabled(ix != FIREWIRE); + m_logger.setVisible(ix == BLACKMAGIC); + if (m_captureDevice) { + // MLT capture still running, abort + 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 + m_videoBox->setHidden(ix != VIDEO4LINUX && ix != BLACKMAGIC); + m_videoBox->setHidden(true); switch (ix) { case SCREENGRAB: m_discAction->setEnabled(false); m_rewAction->setEnabled(false); m_fwdAction->setEnabled(false); - m_recAction->setEnabled(true); m_stopAction->setEnabled(false); m_playAction->setEnabled(false); if (KdenliveSettings::rmd_path().isEmpty()) { @@ -191,21 +242,27 @@ void RecMonitor::slotVideoDeviceChanged(int ix) if (rmdpath.isEmpty()) video_frame->setPixmap(mergeSideBySide(KIcon("dialog-warning").pixmap(QSize(50, 50)), i18n("Recordmydesktop utility not found,\n please install it for screen grabs"))); else KdenliveSettings::setRmd_path(rmdpath); } - if (!KdenliveSettings::rmd_path().isEmpty()) video_frame->setPixmap(mergeSideBySide(KIcon("video-display").pixmap(QSize(50, 50)), i18n("Press record button\nto start screen capture\nFiles will be saved in:\n%1", KdenliveSettings::capturefolder()))); + if (!KdenliveSettings::rmd_path().isEmpty()) video_frame->setPixmap(mergeSideBySide(KIcon("video-display").pixmap(QSize(50, 50)), i18n("Press record button\nto start screen capture\nFiles will be saved in:\n%1", m_capturePath))); //video_frame->setText(i18n("Press record button\nto start screen capture")); break; case VIDEO4LINUX: - m_discAction->setEnabled(false); - m_rewAction->setEnabled(false); - m_fwdAction->setEnabled(false); - m_recAction->setEnabled(true); m_stopAction->setEnabled(false); m_playAction->setEnabled(true); checkDeviceAvailability(); break; + case BLACKMAGIC: + m_stopAction->setEnabled(false); + m_playAction->setEnabled(true); + capturefile = m_capturePath; + if (!capturefile.endsWith("/")) capturefile.append("/"); + capturename = KdenliveSettings::decklink_filename(); + capturename.append("xxx."); + capturename.append(KdenliveSettings::decklink_extension()); + capturefile.append(capturename); + video_frame->setPixmap(mergeSideBySide(KIcon("camera-photo").pixmap(QSize(50, 50)), i18n("Plug your camcorder and\npress play button\nto start preview.\nFiles will be saved in:\n%1", capturefile))); + break; default: // FIREWIRE m_discAction->setEnabled(true); - m_recAction->setEnabled(false); m_stopAction->setEnabled(false); m_playAction->setEnabled(false); m_rewAction->setEnabled(false); @@ -218,9 +275,9 @@ void RecMonitor::slotVideoDeviceChanged(int ix) else KdenliveSettings::setDvgrab_path(dvgrabpath); } else { // Show capture info - QString capturefile = KdenliveSettings::capturefolder(); + capturefile = m_capturePath; if (!capturefile.endsWith("/")) capturefile.append("/"); - QString capturename = KdenliveSettings::dvgrabfilename(); + capturename = KdenliveSettings::dvgrabfilename(); if (capturename.isEmpty()) capturename = "capture"; QString extension; switch (KdenliveSettings::firewireformat()) { @@ -243,7 +300,12 @@ void RecMonitor::slotVideoDeviceChanged(int ix) } } -QPixmap RecMonitor::mergeSideBySide(const QPixmap& pix, const QString txt) +void RecMonitor::slotSetInfoMessage(const QString &message) +{ + m_logger.insertItem(0, message); +} + +QPixmap RecMonitor::mergeSideBySide(const QPixmap& pix, const QString &txt) { QPainter p; QRect r = QApplication::fontMetrics().boundingRect(QRect(0, 0, video_frame->width(), video_frame->height()), Qt::AlignLeft, txt); @@ -268,9 +330,9 @@ void RecMonitor::checkDeviceAvailability() m_playAction->setEnabled(false); m_recAction->setEnabled(false); video_frame->setPixmap(mergeSideBySide(KIcon("camera-web").pixmap(QSize(50, 50)), i18n("Cannot read from device %1\nPlease check drivers and access rights.", KdenliveSettings::video4vdevice()))); - //video_frame->setText(i18n("Cannot read from device %1\nPlease check drivers and access rights.", KdenliveSettings::video4vdevice())); - } else //video_frame->setText(i18n("Press play or record button\nto start video capture")); - video_frame->setPixmap(mergeSideBySide(KIcon("camera-web").pixmap(QSize(50, 50)), i18n("Press play or record button\nto start video capture\nFiles will be saved in:\n%1", KdenliveSettings::capturefolder()))); + } else { + video_frame->setPixmap(mergeSideBySide(KIcon("camera-web").pixmap(QSize(50, 50)), i18n("Press play or record button\nto start video capture\nFiles will be saved in:\n%1", m_capturePath))); + } } void RecMonitor::slotDisconnect() @@ -279,7 +341,7 @@ void RecMonitor::slotDisconnect() m_captureTime = KDateTime::currentLocalDateTime(); kDebug() << "CURRENT TIME: " << m_captureTime.toString(); m_didCapture = false; - slotStartCapture(false); + slotStartPreview(false); m_discAction->setIcon(KIcon("network-disconnect")); m_discAction->setText(i18n("Disconnect")); m_recAction->setEnabled(true); @@ -308,27 +370,45 @@ void RecMonitor::slotForward() void RecMonitor::slotStopCapture() { // stop capture + if (!m_isCapturing && !m_isPlaying) return; + m_videoBox->setHidden(true); switch (device_selector->currentIndex()) { case FIREWIRE: m_captureProcess->write("\e", 2); m_playAction->setIcon(m_playIcon); m_isPlaying = false; - break; - case VIDEO4LINUX: - m_captureProcess->write("q\n", 3); - QTimer::singleShot(1000, m_captureProcess, SLOT(kill())); - break; case SCREENGRAB: m_captureProcess->write("q\n", 3); + m_captureProcess->terminate(); + video_frame->setText(i18n("Encoding captured video...")); QTimer::singleShot(1000, m_captureProcess, SLOT(kill())); break; + case VIDEO4LINUX: + case BLACKMAGIC: + if (m_captureDevice) { + m_captureDevice->stop(); + } + recording_preview->setEnabled(true); + m_isCapturing = false; + m_isPlaying = false; + m_playAction->setEnabled(true); + m_stopAction->setEnabled(false); + m_recAction->setEnabled(true); + slotSetInfoMessage(i18n("Capture stopped")); + m_isCapturing = false; + m_recAction->setChecked(false); + if (autoaddbox->isChecked() && !m_captureFile.isEmpty() && QFile::exists(m_captureFile.path())) { + emit addProjectClip(m_captureFile); + m_captureFile.clear(); + } + break; default: break; } } -void RecMonitor::slotStartCapture(bool play) +void RecMonitor::slotStartPreview(bool play) { if (m_captureProcess->state() != QProcess::NotRunning) { if (device_selector->currentIndex() == FIREWIRE) { @@ -349,9 +429,13 @@ void RecMonitor::slotStartCapture(bool play) m_displayArgs.clear(); m_isPlaying = false; QString capturename = KdenliveSettings::dvgrabfilename(); + QString path; + MltVideoProfile profile; + QString producer; QStringList dvargs = KdenliveSettings::dvgrabextra().simplified().split(" ", QString::SkipEmptyParts); - - switch (device_selector->currentIndex()) { + int ix = device_selector->currentIndex(); + m_videoBox->setHidden(ix != VIDEO4LINUX && ix != BLACKMAGIC); + switch (ix) { case FIREWIRE: switch (KdenliveSettings::firewireformat()) { case 0: @@ -387,7 +471,7 @@ void RecMonitor::slotStartCapture(bool play) m_displayArgs << "-x" << QString::number(video_frame->width()) << "-y" << QString::number(video_frame->height()) << "-"; m_captureProcess->setStandardOutputProcess(m_displayProcess); - m_captureProcess->setWorkingDirectory(KdenliveSettings::capturefolder()); + m_captureProcess->setWorkingDirectory(m_capturePath); kDebug() << "Capture: Running dvgrab " << m_captureArgs.join(" "); m_captureProcess->start(KdenliveSettings::dvgrab_path(), m_captureArgs); @@ -395,17 +479,45 @@ void RecMonitor::slotStartCapture(bool play) m_discAction->setEnabled(true); break; case VIDEO4LINUX: - m_captureArgs << KdenliveSettings::video4capture().simplified().split(' ') << KdenliveSettings::video4encoding().simplified().split(' ') << "-f" << "mpegts" << "-vcodec" << "mpeg4" << "-acodec" << "mp2" << "-"; - m_displayArgs << "-f" << "mpegts" << "-x" << QString::number(video_frame->width()) << "-y" << QString::number(video_frame->height()) << "-"; - m_captureProcess->setStandardOutputProcess(m_displayProcess); - kDebug() << "Capture: Running ffmpeg " << m_captureArgs.join(" "); - m_captureProcess->start("ffmpeg", m_captureArgs); + path = KStandardDirs::locateLocal("appdata", "profiles/video4linux"); + m_manager->activateMonitor("record"); + buildMltDevice(path); + profile = ProfilesDialog::getVideoProfile(path); + producer = QString("avformat-novalidate:video4linux2:%1?width:%2&height:%3&frame_rate:%4").arg(KdenliveSettings::video4vdevice()).arg(profile.width).arg(profile.height).arg((double) profile.frame_rate_num / profile.frame_rate_den); + if (!m_captureDevice->slotStartPreview(producer)) { + // v4l capture failed to start + video_frame->setText(i18n("Failed to start Video4Linux,\ncheck your parameters...")); + m_videoBox->setHidden(true); + + } else { + m_playAction->setEnabled(false); + m_stopAction->setEnabled(true); + m_isPlaying = true; + } + + break; + case BLACKMAGIC: + path = KdenliveSettings::current_profile(); + m_manager->activateMonitor("record"); + buildMltDevice(path); + profile = ProfilesDialog::getVideoProfile(path); + producer = QString("decklink:%1").arg(KdenliveSettings::decklink_capturedevice()); + if (!m_captureDevice->slotStartPreview(producer)) { + // v4l capture failed to start + video_frame->setText(i18n("Failed to start Decklink,\ncheck your parameters...")); + m_videoBox->setHidden(true); + + } else { + m_playAction->setEnabled(false); + m_stopAction->setEnabled(true); + m_isPlaying = true; + } break; default: break; } - if (device_selector->currentIndex() != SCREENGRAB) { + if (device_selector->currentIndex() == FIREWIRE) { kDebug() << "Capture: Running ffplay " << m_displayArgs.join(" "); m_displayProcess->start("ffplay", m_displayArgs); video_frame->setText(i18n("Initialising...")); @@ -417,31 +529,11 @@ void RecMonitor::slotStartCapture(bool play) void RecMonitor::slotRecord() { if (m_captureProcess->state() == QProcess::NotRunning && device_selector->currentIndex() == FIREWIRE) { - slotStartCapture(); + slotStartPreview(); } if (m_isCapturing) { - switch (device_selector->currentIndex()) { - case FIREWIRE: - m_captureProcess->write("\e", 2); - m_playAction->setIcon(m_playIcon); - m_isCapturing = false; - m_isPlaying = false; - m_recAction->setChecked(false); - break; - case VIDEO4LINUX: - m_captureProcess->terminate(); - slotStopCapture(); - //m_isCapturing = false; - QTimer::singleShot(1000, this, SLOT(slotStartCapture())); - break; - case SCREENGRAB: - //captureProcess->write("q\n", 3); - m_captureProcess->terminate(); - video_frame->setText(i18n("Encoding captured video...")); - // in case ffmpeg doesn't exit with the 'q' command, kill it one second later - //QTimer::singleShot(1000, captureProcess, SLOT(kill())); - break; - } + // User stopped capture + slotStopCapture(); return; } else if (device_selector->currentIndex() == FIREWIRE) { m_isCapturing = true; @@ -453,14 +545,17 @@ void RecMonitor::slotRecord() return; } if (m_captureProcess->state() == QProcess::NotRunning) { + m_logger.clear(); m_recAction->setChecked(true); - QString extension = "mp4"; + QString extension = "mpg"; if (device_selector->currentIndex() == SCREENGRAB) extension = "ogv"; //KdenliveSettings::screengrabextension(); - QString path = KdenliveSettings::capturefolder() + "/capture0000." + extension; + else if (device_selector->currentIndex() == VIDEO4LINUX) extension = KdenliveSettings::v4l_extension(); + else if (device_selector->currentIndex() == BLACKMAGIC) extension = KdenliveSettings::decklink_extension(); + QString path = KUrl(m_capturePath).path(KUrl::AddTrailingSlash) + "capture0000." + extension; int i = 1; while (QFile::exists(path)) { QString num = QString::number(i).rightJustified(4, '0', false); - path = KdenliveSettings::capturefolder() + "/capture" + num + '.' + extension; + path = KUrl(m_capturePath).path(KUrl::AddTrailingSlash) + "capture" + num + '.' + extension; i++; } m_captureFile = KUrl(path); @@ -468,17 +563,105 @@ void RecMonitor::slotRecord() m_captureArgs.clear(); m_displayArgs.clear(); QString args; + QString playlist; + QString v4lparameters; + MltVideoProfile profile; QString capturename = KdenliveSettings::dvgrabfilename(); if (capturename.isEmpty()) capturename = "capture"; switch (device_selector->currentIndex()) { case VIDEO4LINUX: - m_captureArgs << KdenliveSettings::video4capture().simplified().split(' ') << KdenliveSettings::video4encoding().simplified().split(' ') << "-vcodec" << "mpeg4" << "-acodec" << "mp2" << "-y" << m_captureFile.path() << "-f" << "mpegts" << "-vcodec" << "mpeg4" << "-acodec" << "mp2" << "-"; - m_displayArgs << "-f" << "mpegts" << "-x" << QString::number(video_frame->width()) << "-y" << QString::number(video_frame->height()) << "-"; - m_captureProcess->setStandardOutputProcess(m_displayProcess); - kDebug() << "Capture: Running ffmpeg " << m_captureArgs.join(" "); - m_captureProcess->start("ffmpeg", m_captureArgs); + path = KStandardDirs::locateLocal("appdata", "profiles/video4linux"); + profile = ProfilesDialog::getVideoProfile(path); + m_videoBox->setRatio((double) profile.display_aspect_num / profile.display_aspect_den); + buildMltDevice(path); + playlist = QString("producer100000pausevideo4linux2:%1?width:%2&height:%3&frame_rate:%4avformat-novalidate").arg(KdenliveSettings::video4vdevice()).arg(profile.width).arg(profile.height).arg((double) profile.frame_rate_num / profile.frame_rate_den); + + v4lparameters = KdenliveSettings::v4l_parameters(); + + // Add alsa audio capture + if (KdenliveSettings::v4l_captureaudio()) { + playlist.append(QString("producer100000pausealsa:%50-1avformat").arg(KdenliveSettings::v4l_alsadevicename())); + } + else { + // if we do not want audio, make sure that we don't have audio encoding parameters + // this is required otherwise the MLT avformat consumer will not close properly + if (v4lparameters.contains("acodec")) { + QString endParam = v4lparameters.section("acodec", 1); + int vcodec = endParam.indexOf(" vcodec"); + int format = endParam.indexOf(" f="); + int cutPosition = -1; + if (vcodec > -1) { + if (format > -1) { + cutPosition = qMin(vcodec, format); + } + else cutPosition = vcodec; + } + else if (format > -1) { + cutPosition = format; + } + else { + // nothing interesting in end params + endParam.clear(); + } + if (cutPosition > -1) { + endParam.remove(0, cutPosition); + } + v4lparameters = QString(v4lparameters.section("acodec", 0, 0) + "an=1 " + endParam).simplified(); + } + } + + + playlist.append(""); + + playlist.append(""); + + // Audio mix + if (KdenliveSettings::v4l_captureaudio()) { + playlist.append(""); + playlist.append("01transitionmix"); + } + + playlist.append(""); + + if (m_captureDevice->slotStartCapture(v4lparameters, m_captureFile.path(), playlist, recording_preview->currentIndex())) { + m_videoBox->setHidden(false); + m_isCapturing = true; + m_recAction->setEnabled(false); + m_stopAction->setEnabled(true); + recording_preview->setEnabled(false); + } + else { + video_frame->setText(i18n("Failed to start Video4Linux,\ncheck your parameters...")); + m_videoBox->setHidden(true); + m_isCapturing = false; + } + break; + + case BLACKMAGIC: + path = KdenliveSettings::current_profile(); + profile = ProfilesDialog::getVideoProfile(path); + m_videoBox->setRatio((double) profile.display_aspect_num / profile.display_aspect_den); + buildMltDevice(path); + + playlist = QString("producer100000pause%1decklink").arg(KdenliveSettings::decklink_capturedevice()); + + if (m_captureDevice->slotStartCapture(KdenliveSettings::decklink_parameters(), m_captureFile.path(), QString("decklink:%1").arg(KdenliveSettings::decklink_capturedevice()), recording_preview->currentIndex(), false)) { + m_videoBox->setHidden(false); + m_isCapturing = true; + slotSetInfoMessage(i18n("Capturing to %1", m_captureFile.fileName())); + m_recAction->setEnabled(false); + m_stopAction->setEnabled(true); + recording_preview->setEnabled(false); + } + else { + video_frame->setText(i18n("Failed to start Decklink,\ncheck your parameters...")); + slotSetInfoMessage(i18n("Failed to start capture")); + m_videoBox->setHidden(true); + m_isCapturing = false; + } break; + case SCREENGRAB: switch (KdenliveSettings::rmd_capture_type()) { case 0: @@ -486,7 +669,7 @@ void RecMonitor::slotRecord() break; default: // Region capture - m_captureArgs << "-width" << QString::number(KdenliveSettings::rmd_width()) << "-height" << QString::number(KdenliveSettings::rmd_height()); + m_captureArgs << "--width" << QString::number(KdenliveSettings::rmd_width()) << "--height" << QString::number(KdenliveSettings::rmd_height()); if (!KdenliveSettings::rmd_follow_mouse()) { m_captureArgs << "-x" << QString::number(KdenliveSettings::rmd_offsetx()) << "-y" << QString::number(KdenliveSettings::rmd_offsety()); } else { @@ -495,25 +678,32 @@ void RecMonitor::slotRecord() } break; } + if (KdenliveSettings::rmd_hide_mouse()) m_captureArgs << "--no-cursor"; m_isCapturing = true; if (KdenliveSettings::rmd_capture_audio()) { - m_captureArgs << "-freq" << KdenliveSettings::rmd_freq(); - m_captureArgs << "-channels" << QString::number(KdenliveSettings::rmd_audio_channels()); + m_captureArgs << "--freq" << KdenliveSettings::rmd_freq(); + m_captureArgs << "--channels" << QString::number(KdenliveSettings::rmd_audio_channels()); if (KdenliveSettings::rmd_use_jack()) { - m_captureArgs << "-use-jack" << KdenliveSettings::rmd_jackports(); + m_captureArgs << "--use-jack"; + QStringList ports = KdenliveSettings::rmd_jackports().split(" ", QString::SkipEmptyParts); + for (int i = 0; i < ports.count(); ++i) { + m_captureArgs << ports.at(i); + } if (KdenliveSettings::rmd_jack_buffer() > 0.0) - m_captureArgs << "-ring-buffer-size" << QString::number(KdenliveSettings::rmd_jack_buffer()); + m_captureArgs << "--ring-buffer-size" << QString::number(KdenliveSettings::rmd_jack_buffer()); } else { if (!KdenliveSettings::rmd_alsadevicename().isEmpty()) - m_captureArgs << "-device" << KdenliveSettings::rmd_alsadevicename(); + m_captureArgs << "--device" << KdenliveSettings::rmd_alsadevicename(); if (KdenliveSettings::rmd_alsa_buffer() > 0) - m_captureArgs << "-buffer-size" << QString::number(KdenliveSettings::rmd_alsa_buffer()); + m_captureArgs << "--buffer-size" << QString::number(KdenliveSettings::rmd_alsa_buffer()); } } else m_captureArgs << "--no-sound"; if (KdenliveSettings::rmd_fullshots()) m_captureArgs << "--full-shots"; - m_captureArgs << "-workdir" << KdenliveSettings::currenttmpfolder(); - m_captureArgs << "-fps" << QString::number(KdenliveSettings::rmd_fps()) << "-o" << m_captureFile.path(); + m_captureArgs << "--v_bitrate" << QString::number(KdenliveSettings::rmd_bitrate()); + m_captureArgs << "--v_quality" << QString::number(KdenliveSettings::rmd_quality()); + m_captureArgs << "--workdir" << KdenliveSettings::currenttmpfolder(); + m_captureArgs << "--fps" << QString::number(KdenliveSettings::rmd_fps()) << "-o" << m_captureFile.path(); m_captureProcess->start(KdenliveSettings::rmd_path(), m_captureArgs); kDebug() << "// RecordMyDesktop params: " << m_captureArgs; break; @@ -522,7 +712,7 @@ void RecMonitor::slotRecord() } - if (device_selector->currentIndex() != SCREENGRAB) { + if (device_selector->currentIndex() == FIREWIRE) { m_isCapturing = true; kDebug() << "Capture: Running ffplay " << m_displayArgs.join(" "); m_displayProcess->start("ffplay", m_displayArgs); @@ -570,7 +760,10 @@ void RecMonitor::slotProcessStatus(QProcess::ProcessState status) if (status == QProcess::NotRunning) { m_displayProcess->kill(); if (m_isCapturing && device_selector->currentIndex() != FIREWIRE) - if (autoaddbox->isChecked() && QFile::exists(m_captureFile.path())) emit addProjectClip(m_captureFile); + if (autoaddbox->isChecked() && !m_captureFile.isEmpty() && QFile::exists(m_captureFile.path())) { + emit addProjectClip(m_captureFile); + m_captureFile.clear(); + } if (device_selector->currentIndex() == FIREWIRE) { m_discAction->setIcon(KIcon("network-connect")); m_discAction->setText(i18n("Connect")); @@ -587,8 +780,15 @@ void RecMonitor::slotProcessStatus(QProcess::ProcessState status) if (m_captureProcess && m_captureProcess->exitStatus() == QProcess::CrashExit) { video_frame->setText(i18n("Capture crashed, please check your parameters")); } else { - if (device_selector->currentIndex() != SCREENGRAB) video_frame->setText(i18n("Not connected")); - else video_frame->setPixmap(mergeSideBySide(KIcon("video-display").pixmap(QSize(50, 50)), i18n("Press record button\nto start screen capture\nFiles will be saved in:\n%1", KdenliveSettings::capturefolder()))); + if (device_selector->currentIndex() != SCREENGRAB) { + video_frame->setText(i18n("Not connected")); + } else { + if (m_captureProcess->exitCode() != 0) { + video_frame->setText(i18n("Capture crashed, please check your parameters\nRecordMyDesktop exit code: %1", QString::number(m_captureProcess->exitCode()))); + } else { + video_frame->setPixmap(mergeSideBySide(KIcon("video-display").pixmap(QSize(50, 50)), i18n("Press record button\nto start screen capture\nFiles will be saved in:\n%1", m_capturePath))); + } + } } m_isCapturing = false; @@ -619,18 +819,30 @@ void RecMonitor::manageCapturedFiles() extension = ".m2t"; break; } - QDir dir(KdenliveSettings::capturefolder()); + QDir dir(m_capturePath); QStringList filters; QString capturename = KdenliveSettings::dvgrabfilename(); if (capturename.isEmpty()) capturename = "capture"; filters << capturename + "*" + extension; const QStringList result = dir.entryList(filters, QDir::Files, QDir::Time); KUrl::List capturedFiles; - foreach(const QString &name, result) { + foreach(const QString & name, result) { KUrl url = KUrl(dir.filePath(name)); if (KIO::NetAccess::exists(url, KIO::NetAccess::SourceSide, this)) { KFileItem file(KFileItem::Unknown, KFileItem::Unknown, url, true); - if (file.time(KFileItem::ModificationTime) > m_captureTime) capturedFiles.append(url); + if (file.time(KFileItem::ModificationTime) > m_captureTime) { + // The file was captured in the last batch + if (url.fileName().contains(':')) { + // Several dvgrab options (--timecode,...) use : in the file name, which is + // not supported by MLT, so rename them + QString newUrl = url.directory(KUrl::AppendTrailingSlash) + url.fileName().replace(':', '_'); + if (QFile::rename(url.path(), newUrl)) { + url = KUrl(newUrl); + } + + } + capturedFiles.append(url); + } } } kDebug() << "Found : " << capturedFiles.count() << " new capture files"; @@ -639,10 +851,7 @@ void RecMonitor::manageCapturedFiles() if (capturedFiles.count() > 0) { ManageCapturesDialog *d = new ManageCapturesDialog(capturedFiles, this); if (d->exec() == QDialog::Accepted) { - capturedFiles = d->importFiles(); - foreach(const KUrl &url, capturedFiles) { - emit addProjectClip(url); - } + emit addProjectClipList(d->importFiles()); } delete d; } @@ -659,8 +868,8 @@ void RecMonitor::mousePressEvent(QMouseEvent * /*event*/) void RecMonitor::slotUpdateFreeSpace() { #if KDE_IS_VERSION(4,2,0) - KDiskFreeSpaceInfo info = KDiskFreeSpaceInfo::freeSpaceInfo(KdenliveSettings::capturefolder()); - if (info.isValid()) { + KDiskFreeSpaceInfo info = KDiskFreeSpaceInfo::freeSpaceInfo(m_capturePath); + if (info.isValid() && info.size() > 0) { m_freeSpace->setValue(100 * info.used() / info.size()); m_freeSpace->setText(i18n("Free space: %1", KIO::convertSize(info.available()))); m_freeSpace->update(); @@ -668,23 +877,6 @@ void RecMonitor::slotUpdateFreeSpace() #endif } -void RecMonitor::activateRecMonitor() -{ - //if (!m_isActive) m_monitorManager->activateRecMonitor(m_name); -} - -void RecMonitor::stop() -{ - m_isActive = false; - -} - -void RecMonitor::start() -{ - m_isActive = true; - -} - void RecMonitor::refreshRecMonitor(bool visible) { if (visible) { @@ -708,5 +900,37 @@ void RecMonitor::slotReadDvgrabInfo() m_dvinfo.updateGeometry(); } +AbstractRender *RecMonitor::abstractRender() +{ + return m_captureDevice; +} + + +void RecMonitor::analyseFrames(bool analyse) +{ + m_analyse = analyse; + if (m_captureDevice) m_captureDevice->sendFrameForAnalysis = analyse; +} + +void RecMonitor::slotDroppedFrames(int dropped) +{ + slotSetInfoMessage(i18n("%1 dropped frames", dropped)); +} + +void RecMonitor::buildMltDevice(const QString &path) +{ + if (m_captureDevice == NULL) { + 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(); + } +} + +void RecMonitor::slotChangeRecordingPreview(int ix) +{ + KdenliveSettings::setRecording_preview(ix); +} + #include "recmonitor.moc"