option(WITH_V4L "Build capture support with Video4Linux" ON)
option(WITH_JogShuttle "Build Jog/Shuttle support" ON)
+option(WITH_BlackMagic "Build Blackmagic Decklinkl support" ON)
if(WITH_V4L)
# This can be changed to support FreeBSD as soon as we move to a newer V4L2
endif(HAVE_LINUX_INPUT_H)
endif(WITH_JogShuttle)
+if(WITH_BlackMagic)
+ set(BUILD_BlackMagic TRUE)
+endif(WITH_BlackMagic)
+
macro_log_feature(QT_QTOPENGL_FOUND
"QtOpenGL"
"Qt bindings for the OpenGL library"
add_subdirectory(audioscopes)
add_subdirectory(beziercurve)
-add_subdirectory(blackmagic)
add_subdirectory(colorcorrection)
add_subdirectory(colorscopes)
add_subdirectory(commands)
add_subdirectory(v4l)
endif(BUILD_V4L)
+if(BUILD_BlackMagic)
+ add_subdirectory(blackmagic)
+endif(BUILD_BlackMagic)
+
list(APPEND kdenlive_SRCS
main.cpp
mainwindow.cpp
add_definitions(-DUSE_V4L)
endif(BUILD_V4L)
+if(BUILD_BlackMagic)
+ add_definitions(-DUSE_BLACKMAGIC)
+endif(BUILD_BlackMagic)
+
if(BUILD_JogShuttle)
add_definitions(-DUSE_JOGSHUTTLE)
endif(BUILD_JogShuttle)
{
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);
#ifndef __DeckLink_API_Verison_h__
#define __DeckLink_API_Version_h__
-#define BLACKMAGIC_DECKLINK_API_VERSION 0x08060100
-#define BLACKMAGIC_DECKLINK_API_VERSION_STRING "8.6.1"
+#define BLACKMAGIC_DECKLINK_API_VERSION 0x09000000
+#define BLACKMAGIC_DECKLINK_API_VERSION_STRING "9.0"
#endif // __DeckLink_API_Version_h__
#ifdef __cplusplus
class IUnknown
{
-public:
- virtual ~IUnknown() = 0;
-
- virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, LPVOID *ppv) = 0;
- virtual ULONG STDMETHODCALLTYPE AddRef(void) = 0;
- virtual ULONG STDMETHODCALLTYPE Release(void) = 0;
+ public:
+ virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, LPVOID *ppv) = 0;
+ virtual ULONG STDMETHODCALLTYPE AddRef(void) = 0;
+ virtual ULONG STDMETHODCALLTYPE Release(void) = 0;
};
#endif
Nepomuk::Resource res( url.path() );
// Check if file has a license
if (res.hasProperty(Nepomuk::Vocabulary::NIE::license())) {
- QGridLayout *l = static_cast<QGridLayout *>(layout());
QString ltype = res.property(Nepomuk::Vocabulary::NIE::licenseType()).toString();
m_view.clip_license->setText(i18n("License: %1", res.property(Nepomuk::Vocabulary::NIE::license()).toString()));
if (ltype.startsWith("http")) {
}
-void CustomTrackView::slotGotFilterJobResults(const QString &id, int startPos, int track, const QString &filter, stringMap filterParams)
+void CustomTrackView::slotGotFilterJobResults(const QString &/*id*/, int startPos, int track, const QString &filter, stringMap filterParams)
{
ClipItem *clip = getClipItemAt(GenTime(startPos, m_document->fps()), track);
if (clip == NULL) {
<default>true</default>
</entry>
- <entry name="recording_preview" type="UInt">
+ <entry name="enable_recording_preview" type="Bool">
<label>Should we display video frames while capturing.</label>
- <default>0</default>
+ <default>true</default>
</entry>
<entry name="add_clip_cut" type="Bool">
#ifdef USE_V4L
#include "v4l/v4lcapture.h"
#endif
+#ifdef USE_BLACKMAGIC
#include "blackmagic/devices.h"
+#endif
#include "encodingprofilesdialog.h"
#include "kdenlivesettings.h"
slotUpdateV4lProfile(-1);
slotUpdateDecklinkProfile(-1);
+#ifdef USE_BLACKMAGIC
BMInterface::getBlackMagicDeviceList(m_configCapture.kcfg_decklink_capturedevice);
if (m_configCapture.kcfg_decklink_capturedevice->count() > 0) {
QStringList modes = m_configCapture.kcfg_decklink_capturedevice->itemData(m_configCapture.kcfg_decklink_capturedevice->currentIndex()).toStringList();
if (BMInterface::getBlackMagicOutputDeviceList(m_configSdl.kcfg_blackmagic_output_device)) {
// Found blackmagic card
} else m_configSdl.kcfg_external_display->setEnabled(false);
+#endif
double dvgrabVersion = 0;
if (!KdenliveSettings::dvgrab_path().isEmpty()) {
#include "mltdevicecapture.h"
#include "kdenlivesettings.h"
#include "definitions.h"
-//#include "recmonitor.h"
-//#include "renderer.h"
-#include "blackmagic/devices.h"
#include <mlt++/Mlt.h>
m_mltProfile(NULL),
m_showFrameEvent(NULL),
m_droppedFrames(0),
- m_livePreview(KdenliveSettings::recording_preview()),
+ m_livePreview(KdenliveSettings::enable_recording_preview()),
m_captureDisplayWidget(surface),
m_winid((int) surface->winId())
{
if (profile.isEmpty()) profile = KdenliveSettings::current_profile();
buildConsumer(profile);
connect(this, SIGNAL(unblockPreview()), this, SLOT(slotPreparePreview()));
+ m_droppedFramesTimer.setSingleShot(false);
+ m_droppedFramesTimer.setInterval(1000);
+ connect(&m_droppedFramesTimer, SIGNAL(timeout()), this, SLOT(slotCheckDroppedFrames()));
}
MltDeviceCapture::~MltDeviceCapture()
}
}
setenv("SDL_VIDEO_ALLOW_SCREENSAVER", "1", 1);
-
+
+
if (m_winid == 0) {
// OpenGL monitor
m_mltConsumer = new Mlt::Consumer(*m_mltProfile, "sdl_audio");
void MltDeviceCapture::stop()
{
+ m_droppedFramesTimer.stop();
bool isPlaylist = false;
disconnect(this, SIGNAL(imageReady(QImage)), this, SIGNAL(frameUpdated(QImage)));
m_captureDisplayWidget->stop();
m_mltConsumer = NULL;
return 0;
}
+ m_droppedFramesTimer.start();
connect(this, SIGNAL(imageReady(QImage)), this, SIGNAL(frameUpdated(QImage)));
return 1;
}
+void MltDeviceCapture::slotCheckDroppedFrames()
+{
+ if (m_mltProducer) {
+ int dropped = m_mltProducer->get_int("dropped");
+ if (dropped > m_droppedFrames) {
+ m_droppedFrames = dropped;
+ emit droppedFrames(m_droppedFrames);
+ }
+ }
+}
+
void MltDeviceCapture::gotCapturedFrame(Mlt::Frame& frame)
{
if (m_mltProducer) {
}
}
m_frameCount++;
- if (m_livePreview == 2) return;
- if (m_livePreview == 0 && (m_frameCount % 10 > 0)) return;
+ if (!m_livePreview) return;
+ //if (m_livePreview == 0 && (m_frameCount % 10 > 0)) return;
mlt_image_format format = mlt_image_rgb24;
int width = 0;
int height = 0;
doCapture = 5;
}
-bool MltDeviceCapture::slotStartCapture(const QString ¶ms, const QString &path, const QString &playlist, int livePreview, bool xmlPlaylist)
+bool MltDeviceCapture::slotStartCapture(const QString ¶ms, const QString &path, const QString &playlist, bool livePreview, bool xmlPlaylist)
{
stop();
m_livePreview = livePreview;
char *tmp = qstrdup(m_activeProfile.toUtf8().constData());
m_mltProfile = new Mlt::Profile(tmp);
delete[] tmp;
- m_mltProfile->get_profile()->is_explicit = 1;
- kDebug()<<"-- CREATING CAP: "<<params<<", PATH: "<<path;
+ //m_mltProfile->get_profile()->is_explicit = 1;
+
+
+ /*kDebug()<<"-- CREATING CAP: "<<params<<", PATH: "<<path;
tmp = qstrdup(QString("avformat:" + path).toUtf8().constData());
m_mltConsumer = new Mlt::Consumer(*m_mltProfile, tmp);
m_mltConsumer->set("real_time", -KdenliveSettings::mltthreads());
- delete[] tmp;
+ delete[] tmp;*/
+
+ m_mltConsumer = new Mlt::Consumer(*m_mltProfile, "multi");
+ if (m_mltConsumer == NULL || !m_mltConsumer->is_valid()) {
+ if (m_mltConsumer) {
+ delete m_mltConsumer;
+ m_mltConsumer = NULL;
+ }
+ return false;
+ }
+
+ m_winid = (int) m_captureDisplayWidget->winId();
+
+ // Create multi consumer setup
+ Mlt::Properties *renderProps = new Mlt::Properties;
+ renderProps->set("mlt_service", "avformat");
+ renderProps->set("target", path.toUtf8().constData());
+ renderProps->set("real_time", -KdenliveSettings::mltthreads());
+ renderProps->set("terminate_on_pause", 0);
+ renderProps->set("mlt_profile", m_activeProfile.toUtf8().constData());
+
QStringList paramList = params.split(" ", QString::SkipEmptyParts);
char *tmp2;
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);
+ renderProps->set(tmp, tmp2);
delete[] tmp;
delete[] tmp2;
}
+ mlt_properties consumerProperties = m_mltConsumer->get_properties();
+ mlt_properties_set_data(consumerProperties, "0", renderProps->get_properties(), 0, (mlt_destructor) mlt_properties_close, NULL);
- if (m_mltConsumer == NULL || !m_mltConsumer->is_valid()) {
- if (m_mltConsumer) {
- delete m_mltConsumer;
- m_mltConsumer = NULL;
+ if (m_livePreview)
+ {
+ // user wants live preview
+ Mlt::Properties *previewProps = new Mlt::Properties;
+ QString videoDriver = KdenliveSettings::videodrivername();
+ if (!videoDriver.isEmpty()) {
+ if (videoDriver == "x11_noaccel") {
+ setenv("SDL_VIDEO_YUV_HWACCEL", "0", 1);
+ videoDriver = "x11";
+ } else {
+ unsetenv("SDL_VIDEO_YUV_HWACCEL");
+ }
}
- return false;
+ setenv("SDL_VIDEO_ALLOW_SCREENSAVER", "1", 1);
+
+ if (m_winid == 0) {
+ // OpenGL monitor
+ previewProps->set("mlt_service", "sdl_audio");
+ previewProps->set("preview_off", 1);
+ previewProps->set("preview_format", mlt_image_rgb24);
+ previewProps->set("terminate_on_pause", 0);
+ m_showFrameEvent = m_mltConsumer->listen("consumer-frame-show", this, (mlt_listener) consumer_gl_frame_show);
+ } else {
+ previewProps->set("mlt_service", "sdl_preview");
+ previewProps->set("window_id", m_winid);
+ previewProps->set("terminate_on_pause", 0);
+ //m_showFrameEvent = m_mltConsumer->listen("consumer-frame-show", this, (mlt_listener) rec_consumer_frame_preview);
+ }
+ //m_mltConsumer->set("resize", 1);
+ previewProps->set("window_background", KdenliveSettings::window_background().name().toUtf8().constData());
+ QString audioDevice = KdenliveSettings::audiodevicename();
+ if (!audioDevice.isEmpty())
+ previewProps->set("audio_device", audioDevice.toUtf8().constData());
+
+ if (!videoDriver.isEmpty())
+ previewProps->set("video_driver", videoDriver.toUtf8().constData());
+
+ QString audioDriver = KdenliveSettings::audiodrivername();
+
+ if (!audioDriver.isEmpty())
+ previewProps->set("audio_driver", audioDriver.toUtf8().constData());
+
+ previewProps->set("real_time", "0");
+ previewProps->set("mlt_profile", m_activeProfile.toUtf8().constData());
+ mlt_properties_set_data(consumerProperties, "1", previewProps->get_properties(), 0, (mlt_destructor) mlt_properties_close, NULL);
+ //m_showFrameEvent = m_mltConsumer->listen("consumer-frame-render", this, (mlt_listener) rec_consumer_frame_show);
+ }
+ else {
+
}
- if (m_livePreview < 2) m_showFrameEvent = m_mltConsumer->listen("consumer-frame-render", this, (mlt_listener) rec_consumer_frame_show);
tmp = qstrdup(playlist.toUtf8().constData());
if (xmlPlaylist) {
// create an xml producer
m_mltConsumer = NULL;
return 0;
}
- m_captureDisplayWidget->start();
+ m_droppedFramesTimer.start();
return 1;
}
/** @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, int livePreview, 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);
QString m_activeProfile;
int m_droppedFrames;
/** @brief When true, images will be displayed on monitor while capturing. */
- int m_livePreview;
+ bool m_livePreview;
/** @brief Count captured frames, used to display only one in ten images while capturing. */
int m_frameCount;
void uyvy2rgb(unsigned char *yuv_buffer, int width, int height);
QString m_capturePath;
+
+ QTimer m_droppedFramesTimer;
/** @brief Build the MLT Consumer object with initial settings.
* @param profileName The MLT profile to use for the consumer */
private slots:
void slotPreparePreview();
void slotAllowPreview();
+ /** @brief When capturing, check every second for dropped frames. */
+ void slotCheckDroppedFrames();
signals:
/** @brief A frame's image has to be shown.
return m_clip->getProperty("duration").toInt();
}
-QStringList ProjectItem::names() const
-{
- QStringList result;
- result.append(text(0));
- result.append(text(1));
- result.append(text(2));
- return result;
-}
-
QDomElement ProjectItem::toXml() const
{
return m_clip->toXML();
*
* The clipId is used both to identify clips and folders (groups) */
const QString &clipId() const;
- QStringList names() const;
const KUrl clipUrl() const;
int clipMaxDuration() const;
CLIPTYPE clipType() const;
} else {
ProjectItem *item = static_cast <ProjectItem *>(selected.at(i));
ids << item->clipId();
- if (item->numReferences() > 0 && KMessageBox::questionYesNo(kapp->activeWindow(), i18np("Delete clip <b>%2</b>?<br />This will also remove the clip in timeline", "Delete clip <b>%2</b>?<br />This will also remove its %1 clips in timeline", item->numReferences(), item->names().at(1)), i18n("Delete Clip"), KStandardGuiItem::yes(), KStandardGuiItem::no(), "DeleteAll") == KMessageBox::No) {
+ if (item->numReferences() > 0 && KMessageBox::questionYesNo(kapp->activeWindow(), i18np("Delete clip <b>%2</b>?<br />This will also remove the clip in timeline", "Delete clip <b>%2</b>?<br />This will also remove its %1 clips in timeline", item->numReferences(), item->text(1)), i18n("Delete Clip"), KStandardGuiItem::yes(), KStandardGuiItem::no(), "DeleteAll") == KMessageBox::No) {
KMessageBox::enableMessage("DeleteAll");
return;
}
rec_audio->setChecked(KdenliveSettings::v4l_captureaudio());
rec_video->setChecked(KdenliveSettings::v4l_capturevideo());
- m_previewSettings = new KSelectAction(i18n("Preview Settings"), this);
- m_previewSettings->addAction(i18n("Quick preview"));
- m_previewSettings->addAction(i18n("Full preview"));
- m_previewSettings->addAction(i18n("No preview"));
+ m_previewSettings = new QAction(i18n("Recording Preview"), this);
+ m_previewSettings->setCheckable(true);
+
+
rec_options->setMenu(menu);
menu->addAction(m_previewSettings);
kDebug() << "/////// BUILDING MONITOR, ID: " << video_frame->winId();
slotVideoDeviceChanged(device_selector->currentIndex());
- m_previewSettings->setCurrentItem(KdenliveSettings::recording_preview());
- connect(m_previewSettings, SIGNAL(triggered(int)), this, SLOT(slotChangeRecordingPreview(int)));
+ m_previewSettings->setChecked(KdenliveSettings::enable_recording_preview());
+ connect(m_previewSettings, SIGNAL(triggered(bool)), this, SLOT(slotChangeRecordingPreview(bool)));
}
RecMonitor::~RecMonitor()
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
switch (device_selector->currentIndex()) {
case VIDEO4LINUX:
+ m_manager->activateMonitor("record");
path = KStandardDirs::locateLocal("appdata", "profiles/video4linux");
profile = ProfilesDialog::getVideoProfile(path);
m_videoBox->setRatio((double) profile.display_aspect_num / profile.display_aspect_den);
}
}
- showPreview = m_previewSettings->currentItem();
- if (!rec_video->isChecked()) showPreview = 2;
+ showPreview = m_previewSettings->isChecked();
+ if (!rec_video->isChecked()) showPreview = false;
if (m_captureDevice->slotStartCapture(v4lparameters, m_captureFile.path(), playlist, showPreview)) {
m_videoBox->setHidden(false);
break;
case BLACKMAGIC:
+ m_manager->activateMonitor("record");
path = KdenliveSettings::current_profile();
profile = ProfilesDialog::getVideoProfile(path);
m_videoBox->setRatio((double) profile.display_aspect_num / profile.display_aspect_den);
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()), m_previewSettings->currentItem(), false)) {
+ if (m_captureDevice->slotStartCapture(KdenliveSettings::decklink_parameters(), m_captureFile.path(), QString("decklink:%1").arg(KdenliveSettings::decklink_capturedevice()), m_previewSettings->isChecked(), false)) {
m_videoBox->setHidden(false);
m_isCapturing = true;
slotSetInfoMessage(i18n("Capturing to %1", m_captureFile.fileName()));
}
}
-void RecMonitor::slotChangeRecordingPreview(int ix)
+void RecMonitor::slotChangeRecordingPreview(bool enable)
{
- KdenliveSettings::setRecording_preview(ix);
+ KdenliveSettings::setEnable_recording_preview(enable);
}
#include "recmonitor.moc"
#include <KIcon>
#include <KAction>
-#include <KSelectAction>
#include <KRestrictedLine>
#include <KDateTime>
#include <kdeversion.h>
MltDeviceCapture *m_captureDevice;
VideoPreviewContainer *m_videoBox;
QAction *m_addCapturedClip;
- KSelectAction *m_previewSettings;
+ QAction *m_previewSettings;
bool m_analyse;
void checkDeviceAvailability();
void slotSetInfoMessage(const QString &message);
void slotDroppedFrames(int dropped);
/** @brief Change setting for preview while recording. */
- void slotChangeRecordingPreview(int ix);
+ void slotChangeRecordingPreview(bool enable);
public slots:
void refreshRecMonitor(bool visible);
#include "definitions.h"
#include "slideshowclip.h"
#include "profilesdialog.h"
+
+#ifdef USE_BLACKMAGIC
#include "blackmagic/devices.h"
+#endif
#include <mlt++/Mlt.h>
m_blackClip->set("mlt_type", "producer");
if (KdenliveSettings::external_display() && m_name != "clip") {
+#ifdef USE_BLACKMAGIC
// Use blackmagic card for video output
QMap< QString, QString > profileProperties = ProfilesDialog::getSettingsFromFile(profileName);
int device = KdenliveSettings::blackmagic_output_device();
if (m_mltConsumer && m_mltConsumer->is_valid()) return;
} else KMessageBox::informationList(qApp->activeWindow(), i18n("Your project's profile %1 is not compatible with the blackmagic output card. Please see supported profiles below. Switching to normal video display.", m_mltProfile->description()), BMInterface::supportedModes(KdenliveSettings::blackmagic_output_device()));
}
+#endif
}
m_externalConsumer = false;
QString videoDriver = KdenliveSettings::videodrivername();
***************************************************************************/
#include "stopmotion.h"
+#ifdef USE_BLACKMAGIC
#include "blackmagic/devices.h"
+#endif
#ifdef USE_V4L
#include "v4l/v4lcapture.h"
#endif
m_videoBox->setLineWidth(4);
layout->addWidget(m_videoBox);
-
+#ifdef USE_BLACKMAGIC
if (BMInterface::getBlackMagicDeviceList(capture_device)) {
// Found a BlackMagic device
}
+#endif
if (QFile::exists(KdenliveSettings::video4vdevice())) {
#ifdef USE_V4L
// Video 4 Linux device detection