<entry name="decklink_parameters" type="String">
<label>Default Decklink encoding parameters.</label>
- <default>vcodec=mpeg2video minrate=0 b=12000k acodec=mp2 ab=128k ar=48000 threads=2</default>
+ <default>vcodec=mpeg2video b=12000k minrate=0 pix_fmt=yuv420p g=15 acodec=mp2 ac=2 ab=128k ar=48000 threads=%threads</default>
</entry>
<entry name="decklink_extension" type="String">
#include <QDir>
#include <QString>
#include <QApplication>
+#include <QThread>
#include <cstdlib>
#include <cstdarg>
m_mltConsumer(NULL),
m_mltProducer(NULL),
m_mltProfile(NULL),
+ m_droppedFrames(0),
+ m_livePreview(true),
m_captureDisplayWidget(surface),
m_winid((int) surface->winId()),
m_analyseAudio(KdenliveSettings::monitor_audio())
void MltDeviceCapture::gotCapturedFrame(Mlt::Frame& frame)
{
+ if (m_mltProducer) {
+ int dropped = m_mltProducer->get_int("dropped");
+ if (dropped != m_droppedFrames) {
+ m_droppedFrames = dropped;
+ emit droppedFrames(m_droppedFrames);
+ }
+ }
+ if (!m_livePreview) return;
mlt_image_format format = mlt_image_rgb24a;
int width = 0;
int height = 0;
doCapture = 5;
}
-bool MltDeviceCapture::slotStartCapture(const QString ¶ms, const QString &path, const QString &playlist, bool xmlPlaylist)
+bool MltDeviceCapture::slotStartCapture(const QString ¶ms, const QString &path, const QString &playlist, bool livePreview, bool xmlPlaylist)
{
stop();
+ m_livePreview = livePreview;
+ m_droppedFrames = 0;
if (m_mltProfile) delete m_mltProfile;
char *tmp = qstrdup(m_activeProfile.toUtf8().constData());
m_mltProfile = new Mlt::Profile(tmp);
char *tmp2;
for (int i = 0; i < paramList.count(); i++) {
tmp = qstrdup(paramList.at(i).section("=", 0, 0).toUtf8().constData());
- tmp2 = qstrdup(paramList.at(i).section("=", 1, 1).toUtf8().constData());
+ QString value = paramList.at(i).section("=", 1, 1);
+ if (value == "%threads") value = QString::number(QThread::idealThreadCount());
+ tmp2 = qstrdup(value.toUtf8().constData());
m_mltConsumer->set(tmp, tmp2);
delete[] tmp;
delete[] tmp2;
/** @brief Starts the MLT Video4Linux process.
* @param surface The widget onto which the frame should be painted
*/
- bool slotStartCapture(const QString ¶ms, const QString &path, const QString &playlist, bool xmlPlaylist = true);
+ bool slotStartCapture(const QString ¶ms, const QString &path, const QString &playlist, bool livePreview, bool xmlPlaylist = true);
bool slotStartPreview(const QString &producer, bool xmlFormat = false);
/** @brief A frame arrived from the MLT Video4Linux process. */
void gotCapturedFrame(Mlt::Frame& frame);
Mlt::Producer * m_mltProducer;
Mlt::Profile *m_mltProfile;
QString m_activeProfile;
+ int m_droppedFrames;
+ bool m_livePreview;
/** @brief The surface onto which the captured frames should be painted. */
VideoPreviewContainer *m_captureDisplayWidget;
void audioSamplesSignal(const QVector<int16_t>&, int freq, int num_channels, int num_samples);
void frameSaved(const QString);
+
+ void droppedFrames(int);
public slots:
checkDeviceAvailability();
break;
case BLACKMAGIC:
- //createBlackmagicDevice();
m_recAction->setEnabled(true);
m_stopAction->setEnabled(false);
m_playAction->setEnabled(true);
}
}
-void RecMonitor::createBlackmagicDevice()
-{
- //video_capture->setVisible(true);
- if (m_bmCapture == NULL) {
- QVBoxLayout *lay = new QVBoxLayout;
- m_bmCapture = new BmdCaptureHandler(lay);
- connect(m_bmCapture, SIGNAL(gotTimeCode(ulong)), this, SLOT(slotGotBlackMagicFrameNumber(ulong)));
- connect(m_bmCapture, SIGNAL(gotMessage(const QString &)), this, SLOT(slotGotBlackmagicMessage(const QString &)));
- video_capture->setLayout(lay);
- }
-}
-
void RecMonitor::slotGotBlackmagicFrameNumber(ulong ix)
{
m_dvinfo.setText(QString::number(ix));
}
-void RecMonitor::slotGotBlackmagicMessage(const QString &message)
+void RecMonitor::slotSetInfoMessage(const QString &message)
{
m_logger.insertItem(0, message);
}
m_manager->activateMonitor("record");
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::slotRecord()
{
- /*if (device_selector->currentIndex() == BLACKMAGIC) {
- if (m_blackmagicCapturing) {
- // We are capturing, stop it
- m_bmCapture->stopCapture();
- m_blackmagicCapturing = false;
- } else {
- // Start capture, get capture filename first
- QString path = m_capturePath;
- if (!path.endsWith("/")) path.append("/");
- path.append(KdenliveSettings::hdmifilename());
- m_bmCapture->startCapture(path);
- m_blackmagicCapturing = true;
- }
- return;
- }*/
-
if (m_captureProcess->state() == QProcess::NotRunning && device_selector->currentIndex() == FIREWIRE) {
slotStartCapture();
}
if (m_isCapturing) {
+ // User stopped capture
switch (device_selector->currentIndex()) {
case FIREWIRE:
m_captureProcess->write("\e", 2);
case VIDEO4LINUX:
case BLACKMAGIC:
slotStopCapture();
+ slotSetInfoMessage(i18n("Capture stopped"));
m_isCapturing = false;
m_recAction->setChecked(false);
if (autoaddbox->isChecked() && QFile::exists(m_captureFile.path())) emit addProjectClip(m_captureFile);
playlist.append("</tractor></mlt>");
- if (m_captureDevice->slotStartCapture(KdenliveSettings::v4l_parameters(), m_captureFile.path(), playlist)) {
+ if (m_captureDevice->slotStartCapture(KdenliveSettings::v4l_parameters(), m_captureFile.path(), playlist, enable_preview->isChecked())) {
m_videoBox->setHidden(false);
m_isCapturing = true;
}
profile = ProfilesDialog::getVideoProfile(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();
}
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());
- if (m_captureDevice->slotStartCapture(KdenliveSettings::decklink_parameters(), m_captureFile.path(), QString("decklink:%1").arg(KdenliveSettings::decklink_capturedevice()), false)) {
+ if (m_captureDevice->slotStartCapture(KdenliveSettings::decklink_parameters(), m_captureFile.path(), QString("decklink:%1").arg(KdenliveSettings::decklink_capturedevice()), enable_preview->isChecked(), false)) {
m_videoBox->setHidden(false);
m_isCapturing = true;
+ slotSetInfoMessage(i18n("Capturing to %1", m_captureFile.fileName()));
}
else {
- video_frame->setText(i18n("Failed to start Decklink,\ncheck your parameters..."));
+ video_frame->setText(i18n("Failed to start Decklink,\ncheck your parameters..."));
+ slotSetInfoMessage(i18n("Failed to start capture"));
m_videoBox->setHidden(true);
m_isCapturing = false;
m_recAction->setChecked(false);
if (m_captureDevice) m_captureDevice->sendFrameForAnalysis = analyse;
}
+void RecMonitor::slotDroppedFrames(int dropped)
+{
+ slotSetInfoMessage(i18n("%1 dropped frames", dropped));
+}
#include "recmonitor.moc"
void checkDeviceAvailability();
QPixmap mergeSideBySide(const QPixmap& pix, const QString txt);
void manageCapturedFiles();
- void createBlackmagicDevice();
private slots:
void slotStartCapture(bool play = true);
void slotReadDvgrabInfo();
void slotUpdateFreeSpace();
void slotGotBlackmagicFrameNumber(ulong ix);
- void slotGotBlackmagicMessage(const QString &message);
+ void slotSetInfoMessage(const QString &message);
+ void slotDroppedFrames(int dropped);
public slots:
void refreshRecMonitor(bool visible);
<rect>
<x>0</x>
<y>0</y>
- <width>210</width>
- <height>152</height>
+ <width>371</width>
+ <height>186</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout">
<property name="margin">
<number>0</number>
</property>
- <item row="0" column="0" colspan="3">
+ <item row="0" column="0" colspan="4">
<widget class="QFrame" name="video_capture">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
</widget>
</item>
- <item row="1" column="0" colspan="3">
+ <item row="1" column="0" colspan="4">
<widget class="QLabel" name="video_frame">
<property name="text">
<string>Not connected</string>
</property>
</widget>
</item>
- <item row="2" column="0" colspan="3">
+ <item row="2" column="0" colspan="4">
<widget class="QFrame" name="control_frame_firewire">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
</property>
</widget>
</item>
- <item row="3" column="2">
+ <item row="3" column="3">
<widget class="KComboBox" name="device_selector">
<item>
<property name="text">
</item>
</widget>
</item>
+ <item row="3" column="1">
+ <widget class="QCheckBox" name="enable_preview">
+ <property name="text">
+ <string>Preview while capturing</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="2">
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
</layout>
</widget>
<customwidgets>