]> git.sesse.net Git - kdenlive/blobdiff - src/blackmagic/capture.cpp
Second part of the capture rewrite. Decklink capture now seems to work with latest MLT
[kdenlive] / src / blackmagic / capture.cpp
index 2989cacfbb3da89abb028c49a8641d52eddcacc8..f57a48c65bfd1b3492d392cecb43989f812a970b 100644 (file)
@@ -244,7 +244,7 @@ void    CDeckLinkGLWidget::resizeGL(int width, int height)
 
 HRESULT     CDeckLinkGLWidget::QueryInterface(REFIID iid, LPVOID *ppv)
 {
-    Q_UNUSED(iid);
+    Q_UNUSED(iid)
     *ppv = NULL;
     return E_NOINTERFACE;
 }
@@ -315,6 +315,18 @@ ULONG DeckLinkCaptureDelegate::Release(void)
     return (ULONG)m_refCount;
 }
 
+
+inline bool safe_write(int fd, const void* bytes, size_t length) {
+  int rc = 0;
+  size_t written = 0;
+  const char* buf = static_cast<const char*>(bytes);
+  while (rc != -1 && written < length) {
+    rc = write(fd, &(buf[written]), length - written);
+    written += (rc >= 0 ? rc : 0);
+  }
+  return rc != -1;
+}
+
 void DeckLinkCaptureDelegate::slotProcessFrame()
 {
     if (m_framesList.isEmpty()) return;
@@ -325,7 +337,7 @@ void DeckLinkCaptureDelegate::slotProcessFrame()
     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());
+        safe_write(videoOutputFile, frameBytes, videoFrame->GetRowBytes() * videoFrame->GetHeight());
         close(videoOutputFile);
         emit frameSaved(capturePath);
     } else {
@@ -338,6 +350,11 @@ void DeckLinkCaptureDelegate::slotProcessFrame()
     videoFrame->Release();
 }
 
+void DeckLinkCaptureDelegate::setAnalyse(bool isOn)
+{
+    m_analyseFrame = isOn;
+}
+
 HRESULT DeckLinkCaptureDelegate::VideoInputFrameArrived(IDeckLinkVideoInputFrame* videoFrame, IDeckLinkAudioInputPacket* audioFrame)
 {
     IDeckLinkVideoFrame*                    rightEyeFrame = NULL;
@@ -383,20 +400,27 @@ HRESULT DeckLinkCaptureDelegate::VideoInputFrameArrived(IDeckLinkVideoInputFrame
                 doCaptureFrame.clear();
                 QtConcurrent::run(this, &DeckLinkCaptureDelegate::slotProcessFrame);
             }
+            if (m_analyseFrame) {
+               QImage image(videoFrame->GetWidth(), videoFrame->GetHeight(), QImage::Format_ARGB32_Premultiplied);
+               //convert from uyvy422 to rgba
+                videoFrame->GetBytes(&frameBytes);
+               CaptureHandler::uyvy2rgb((uchar *)frameBytes, (uchar *)image.bits(), videoFrame->GetWidth(), videoFrame->GetHeight());
+               emit gotFrame(image);
+           }
 
             if (videoOutputFile != -1) {
-                videoFrame->GetBytes(&frameBytes);
-                write(videoOutputFile, frameBytes, videoFrame->GetRowBytes() * videoFrame->GetHeight());
+                if (!m_analyseFrame) videoFrame->GetBytes(&frameBytes);
+                safe_write(videoOutputFile, frameBytes, videoFrame->GetRowBytes() * videoFrame->GetHeight());
 
                 if (rightEyeFrame) {
                     rightEyeFrame->GetBytes(&frameBytes);
-                    write(videoOutputFile, frameBytes, videoFrame->GetRowBytes() * videoFrame->GetHeight());
+                    safe_write(videoOutputFile, frameBytes, videoFrame->GetRowBytes() * videoFrame->GetHeight());
                 }
             }
         }
         frameCount++;
 
-        if (g_maxFrames > 0 && frameCount >= g_maxFrames) {
+        if (g_maxFrames > 0 && frameCount >= (uint) g_maxFrames) {
             pthread_cond_signal(&sleepCond);
         }
     }
@@ -405,7 +429,7 @@ HRESULT DeckLinkCaptureDelegate::VideoInputFrameArrived(IDeckLinkVideoInputFrame
     if (audioFrame) {
         if (audioOutputFile != -1) {
             audioFrame->GetBytes(&audioFrameBytes);
-            write(audioOutputFile, audioFrameBytes, audioFrame->GetSampleFrameCount() * g_audioChannels *(g_audioSampleDepth / 8));
+            safe_write(audioOutputFile, audioFrameBytes, audioFrame->GetSampleFrameCount() * g_audioChannels *(g_audioSampleDepth / 8));
         }
     }
     return S_OK;
@@ -413,8 +437,8 @@ HRESULT DeckLinkCaptureDelegate::VideoInputFrameArrived(IDeckLinkVideoInputFrame
 
 HRESULT DeckLinkCaptureDelegate::VideoInputFormatChanged(BMDVideoInputFormatChangedEvents events, IDeckLinkDisplayMode *mode, BMDDetectedVideoInputFormatFlags)
 {
-    Q_UNUSED(events);
-    Q_UNUSED(mode);
+    Q_UNUSED(events)
+    Q_UNUSED(mode)
     return S_OK;
 }
 
@@ -536,7 +560,9 @@ void BmdCaptureHandler::startPreview(int deviceId, int captureMode, bool audio)
     }
 
     delegate = new DeckLinkCaptureDelegate();
+    delegate->setAnalyse(m_analyseFrame);
     connect(delegate, SIGNAL(gotTimeCode(ulong)), this, SIGNAL(gotTimeCode(ulong)));
+    connect(delegate, SIGNAL(gotFrame(QImage)), this, SIGNAL(gotFrame(QImage)));
     connect(delegate, SIGNAL(gotMessage(const QString &)), this, SIGNAL(gotMessage(const QString &)));
     connect(delegate, SIGNAL(frameSaved(const QString)), this, SIGNAL(frameSaved(const QString)));
     deckLinkInput->SetCallback(delegate);
@@ -779,14 +805,14 @@ void BmdCaptureHandler::startCapture(const QString &path)
         fprintf(stderr, "Could not open video output file \"%s\"\n", videopath.toUtf8().constData());
         return;
     }
-    if (KdenliveSettings::hdmicaptureaudio()) {
+    /*if (KdenliveSettings::hdmicaptureaudio()) {
         audioOutputFile = open(audiopath.toUtf8().constData(), O_WRONLY | O_CREAT | O_TRUNC, 0664);
         if (audioOutputFile < 0) {
             emit gotMessage(i18n("Could not open audio output file %1", audiopath));
             fprintf(stderr, "Could not open video output file \"%s\"\n", audiopath.toUtf8().constData());
             return;
         }
-    }
+    }*/
 }
 
 void BmdCaptureHandler::stopCapture()