return (ULONG)m_refCount;
}
+void DeckLinkCaptureDelegate::slotProcessFrame()
+{
+ if (m_framesList.isEmpty()) return;
+ IDeckLinkVideoInputFrame* videoFrame = m_framesList.takeFirst();
+ QString capturePath = m_framePath.takeFirst();
+ void *frameBytes;
+ videoFrame->GetBytes(&frameBytes);
+ if (capturePath.endsWith("raw")) {
+ // Save as raw uyvy422 imgage
+ videoOutputFile = open(capturePath.toUtf8().constData(), O_WRONLY | O_CREAT/*|O_TRUNC*/, 0664);
+ write(videoOutputFile, frameBytes, videoFrame->GetRowBytes() * videoFrame->GetHeight());
+ close(videoOutputFile);
+ emit frameSaved(capturePath);
+ } else {
+ QImage image(videoFrame->GetWidth(), videoFrame->GetHeight(), QImage::Format_ARGB32_Premultiplied);
+ //convert from uyvy422 to rgba
+ CaptureHandler::yuv2rgb((uchar *)frameBytes, (uchar *)image.bits(), videoFrame->GetWidth(), videoFrame->GetHeight());
+ image.save(capturePath);
+ emit frameSaved(capturePath);
+ }
+ videoFrame->Release();
+}
+
HRESULT DeckLinkCaptureDelegate::VideoInputFrameArrived(IDeckLinkVideoInputFrame* videoFrame, IDeckLinkAudioInputPacket* audioFrame)
{
IDeckLinkVideoFrame* rightEyeFrame = NULL;
free((void*)timecodeString);
if (!doCaptureFrame.isEmpty()) {
- videoFrame->GetBytes(&frameBytes);
- if (doCaptureFrame.endsWith("raw")) {
- // Save as raw uyvy422 imgage
- videoOutputFile = open(doCaptureFrame.toUtf8().constData(), O_WRONLY | O_CREAT/*|O_TRUNC*/, 0664);
- write(videoOutputFile, frameBytes, videoFrame->GetRowBytes() * videoFrame->GetHeight());
- close(videoOutputFile);
- emit frameSaved(doCaptureFrame);
- } else {
- QImage image(videoFrame->GetWidth(), videoFrame->GetHeight(), QImage::Format_ARGB32_Premultiplied);
- //convert from uyvy422 to rgba
- CaptureHandler::yuv2rgb((uchar *)frameBytes, (uchar *)image.bits(), videoFrame->GetWidth(), videoFrame->GetHeight());
- image.save(doCaptureFrame);
- emit frameSaved(doCaptureFrame);
- }
+ videoFrame->AddRef();
+ m_framesList.append(videoFrame);
+ m_framePath.append(doCaptureFrame);
doCaptureFrame.clear();
+ QtConcurrent::run(this, &DeckLinkCaptureDelegate::slotProcessFrame);
}
if (videoOutputFile != -1) {
return QString();
}
-void BmdCaptureHandler::startPreview(int deviceId, int captureMode)
+void BmdCaptureHandler::startPreview(int deviceId, int captureMode, bool audio)
{
deckLinkIterator = CreateDeckLinkIteratorInstance();
BMDVideoInputFlags inputFlags = 0;
return;
}
- result = deckLinkInput->EnableAudioInput(bmdAudioSampleRate48kHz, g_audioSampleDepth, g_audioChannels);
- if (result != S_OK) {
- stopCapture();
- return;
+ if (audio) {
+ result = deckLinkInput->EnableAudioInput(bmdAudioSampleRate48kHz, g_audioSampleDepth, g_audioChannels);
+ if (result != S_OK) {
+ stopCapture();
+ return;
+ }
}
deckLinkInput->SetScreenPreviewCallback(previewView);
result = deckLinkInput->StartStreams();
private:
ULONG m_refCount;
pthread_mutex_t m_mutex;
+ QList <IDeckLinkVideoInputFrame*> m_framesList;
+ QStringList m_framePath;
+
+private slots:
+ void slotProcessFrame();
+
signals:
void gotTimeCode(ulong);
void gotMessage(const QString &);
BmdCaptureHandler(QVBoxLayout *lay, QWidget *parent = 0);
~BmdCaptureHandler();
CDeckLinkGLWidget *previewView;
- void startPreview(int deviceId, int captureMode);
+ void startPreview(int deviceId, int captureMode, bool audio = true);
void stopPreview();
void startCapture(const QString &path);
void stopCapture();
public:
CaptureHandler(QVBoxLayout *lay, QWidget *parent = 0);
~CaptureHandler();
- virtual void startPreview(int deviceId, int captureMode) = 0;
+ virtual void startPreview(int deviceId, int captureMode, bool audio = true) = 0;
virtual void stopPreview() = 0;
virtual void startCapture(const QString &path) = 0;
virtual void stopCapture();
else emit seek(false);
}
+//virtual
+void MyLabel::mousePressEvent(QMouseEvent *)
+{
+ emit switchToLive();
+}
+
//virtual
void MyLabel::paintEvent(QPaintEvent * event)
{
connect(showThumbs, SIGNAL(triggered(bool)), this, SLOT(slotShowThumbs(bool)));
QAction *removeCurrent = new QAction(KIcon("edit-delete"), i18n("Delete current frame"), this);
- //TODO: implement frame deletion
- //connect(removeCurrent, SIGNAL(triggered()), this, SLOT(slotRemoveFrame()));
+ removeCurrent->setShortcut(Qt::Key_Delete);
+ connect(removeCurrent, SIGNAL(triggered()), this, SLOT(slotRemoveFrame()));
QAction *capInterval = new QAction(KIcon(), i18n("Set capture interval"), this);
connect(capInterval, SIGNAL(triggered()), this, SLOT(slotSetCaptureInterval()));
capture_button->setMenu(capMenu);
connect(sequence_name, SIGNAL(textChanged(const QString &)), this, SLOT(sequenceNameChanged(const QString &)));
+ connect(sequence_name, SIGNAL(currentIndexChanged(int)), live_button, SLOT(setFocus()));
+
m_layout = new QVBoxLayout;
if (BMInterface::getBlackMagicDeviceList(capture_device, NULL)) {
// Found a BlackMagic device
connect(capture_device, SIGNAL(currentIndexChanged(int)), this, SLOT(slotUpdateHandler()));
m_frame_preview = new MyLabel(this);
connect(m_frame_preview, SIGNAL(seek(bool)), this, SLOT(slotSeekFrame(bool)));
+ connect(m_frame_preview, SIGNAL(switchToLive()), this, SLOT(slotSwitchLive()));
m_layout->addWidget(m_frame_preview);
m_frame_preview->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
video_preview->setLayout(m_layout);
connect(button_addsequence, SIGNAL(clicked(bool)), this, SLOT(slotAddSequence()));
connect(preview_button, SIGNAL(clicked(bool)), this, SLOT(slotPlayPreview(bool)));
connect(frame_list, SIGNAL(currentRowChanged(int)), this, SLOT(slotShowSelectedFrame()));
+ connect(frame_list, SIGNAL(itemClicked(QListWidgetItem *)), this, SLOT(slotShowSelectedFrame()));
connect(this, SIGNAL(doCreateThumbs(QImage, int)), this, SLOT(slotCreateThumbs(QImage, int)));
+ frame_list->addAction(removeCurrent);
+ frame_list->setContextMenuPolicy(Qt::ActionsContextMenu);
frame_list->setHidden(!KdenliveSettings::showstopmotionthumbs());
parseExistingSequences();
}
if (isOn) {
//m_frame_preview->setImage(QImage());
m_frame_preview->setHidden(true);
- m_bmCapture->startPreview(KdenliveSettings::hdmi_capturedevice(), KdenliveSettings::hdmi_capturemode());
+ m_bmCapture->startPreview(KdenliveSettings::hdmi_capturedevice(), KdenliveSettings::hdmi_capturemode(), false);
capture_button->setEnabled(true);
} else {
m_bmCapture->stopPreview();
}
//capture_button->setEnabled(false);
QString currentPath = getPathForFrame(m_sequenceFrame);
- kDebug() << "Capture FRame NB: " << m_sequenceFrame;
m_bmCapture->captureFrame(currentPath);
KNotification::event("FrameCaptured");
m_sequenceFrame++;
QListWidgetItem *item = new QListWidgetItem(icon, QString(), frame_list);
item->setToolTip(getPathForFrame(ix, sequence_name->currentText()));
item->setData(Qt::UserRole, ix);
+ frame_list->blockSignals(true);
+ frame_list->setCurrentItem(item);
+ frame_list->blockSignals(false);
m_future = QtConcurrent::run(this, &StopmotionWidget::slotPrepareThumbs);
}
//TODO: loop
if (frame_list->currentRow() < (frame_list->count() - 1)) {
frame_list->setCurrentRow(frame_list->currentRow() + 1);
- QTimer::singleShot(200, this, SLOT(slotAnimate()));
+ QTimer::singleShot(100, this, SLOT(slotAnimate()));
} else preview_button->setChecked(false);
} else if (!m_animationList.isEmpty()) {
slotShowFrame(m_animationList.takeFirst());
- QTimer::singleShot(200, this, SLOT(slotAnimate()));
+ QTimer::singleShot(100, this, SLOT(slotAnimate()));
} else preview_button->setChecked(false);
}
} else if (ix > 0) frame_list->setCurrentRow(ix - 1);
}
-
+void StopmotionWidget::slotRemoveFrame()
+{
+ if (frame_list->currentItem() == NULL) return;
+ QString path = frame_list->currentItem()->toolTip();
+ if (KMessageBox::questionYesNo(this, i18n("Delete frame %1 from disk?", path), i18n("Delete Frame")) != KMessageBox::Yes) return;
+ QFile f(path);
+ if (f.remove()) {
+ QListWidgetItem *item = frame_list->takeItem(frame_list->currentRow());
+ delete item;
+ }
+}
protected:
virtual void paintEvent(QPaintEvent * event);
virtual void wheelEvent(QWheelEvent * event);
+ virtual void mousePressEvent(QMouseEvent *);
private:
QImage m_img;
/** @brief Seek to next or previous frame.
* @param forward set to true to go to next frame, fals to go to previous frame */
void seek(bool forward);
+
+ /** @brief Switch to live view. */
+ void switchToLive();
};
class StopmotionWidget : public QDialog , public Ui::Stopmotion_UI
/** @brief Set the effect to be applied to overlay frame. */
void slotUpdateOverlayEffect(QAction *act);
- /** @brief Switch between live view / currently selected fram. */
+ /** @brief Switch between live view / currently selected frame. */
void slotSwitchLive();
+
+ /** @brief Delete current frame from disk. */
+ void slotRemoveFrame();
+
signals:
/** @brief Ask to add sequence to current project. */
void addOrUpdateSequence(const QString);
return deviceName.isEmpty() ? input : deviceName;
}
-void V4lCaptureHandler::startPreview(int /*deviceId*/, int /*captureMode*/)
+void V4lCaptureHandler::startPreview(int /*deviceId*/, int /*captureMode*/, bool)
{
m_display->setHidden(false);
fswebcam_config_t *config;
public:
V4lCaptureHandler(QVBoxLayout *lay, QWidget *parent = 0);
~V4lCaptureHandler();
- void startPreview(int deviceId, int captureMode);
+ void startPreview(int deviceId, int captureMode, bool audio = true);
void stopPreview();
void startCapture(const QString &path);
void stopCapture();