2 ** Copyright (c) 2009 Blackmagic Design
4 ** Permission is hereby granted, free of charge, to any person or organization
5 ** obtaining a copy of the software and accompanying documentation covered by
6 ** this license (the "Software") to use, reproduce, display, distribute,
7 ** execute, and transmit the Software, and to prepare derivative works of the
8 ** Software, and to permit third-parties to whom the Software is furnished to
9 ** do so, all subject to the following:
11 ** The copyright notices in the Software and this entire statement, including
12 ** the above license grant, this restriction and the following disclaimer,
13 ** must be included in all copies of the Software, in whole or in part, and
14 ** all derivative works of the Software, unless such copies or derivative
15 ** works are solely in the form of machine-executable object code generated by
16 ** a source language processor.
18 ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
21 ** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
22 ** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
23 ** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 ** DEALINGS IN THE SOFTWARE.
39 #include <QPaintEvent>
43 #ifndef GL_TEXTURE_RECTANGLE_EXT
44 #define GL_TEXTURE_RECTANGLE_EXT GL_TEXTURE_RECTANGLE_NV
51 #include "kdenlivesettings.h"
53 pthread_mutex_t sleepMutex;
54 pthread_cond_t sleepCond;
55 int videoOutputFile = -1;
56 int audioOutputFile = -1;
58 static BMDTimecodeFormat g_timecodeFormat = 0;
59 static int g_videoModeIndex = -1;
60 static int g_audioChannels = 2;
61 static int g_audioSampleDepth = 16;
62 static int g_maxFrames = -1;
63 static QString doCaptureFrame;
64 static double g_aspect_ratio = 16.0 / 9.0;
66 static unsigned long frameCount = 0;
69 class CDeckLinkGLWidget : public QGLWidget, public IDeckLinkScreenPreviewCallback
74 IDeckLinkInput* deckLinkIn;
75 IDeckLinkGLScreenPreviewHelper* deckLinkScreenPreviewHelper;
76 IDeckLinkVideoFrame* m_frame;
77 QColor m_backgroundColor;
84 bool m_transparentOverlay;
87 CDeckLinkGLWidget(IDeckLinkInput* deckLinkInput, QWidget* parent);
88 // IDeckLinkScreenPreviewCallback
89 virtual HRESULT QueryInterface(REFIID iid, LPVOID *ppv);
90 virtual ULONG AddRef();
91 virtual ULONG Release();
92 virtual HRESULT DrawFrame(IDeckLinkVideoFrame* theFrame);
93 void showOverlay(QImage img, bool transparent);
99 void resizeGL(int width, int height);
100 /*void initializeOverlayGL();
101 void paintOverlayGL();
102 void resizeOverlayGL(int width, int height);*/
105 CDeckLinkGLWidget::CDeckLinkGLWidget(IDeckLinkInput* deckLinkInput, QWidget* parent) : QGLWidget(/*QGLFormat(QGL::HasOverlay | QGL::AlphaChannel),*/ parent)
106 , m_backgroundColor(KdenliveSettings::window_background())
109 , m_transparentOverlay(true)
112 deckLinkIn = deckLinkInput;
113 deckLinkScreenPreviewHelper = CreateOpenGLScreenPreviewHelper();
116 void CDeckLinkGLWidget::showOverlay(QImage img, bool transparent)
118 m_transparentOverlay = transparent;
119 m_img = convertToGLFormat(img);
120 m_zx = (double)m_pictureWidth / m_img.width();
121 m_zy = (double)m_pictureHeight / m_img.height();
122 if (m_transparentOverlay) {
124 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_COLOR);
130 void CDeckLinkGLWidget::hideOverlay()
136 void CDeckLinkGLWidget::initializeGL()
138 if (deckLinkScreenPreviewHelper != NULL) {
140 deckLinkScreenPreviewHelper->InitializeGL();
141 glShadeModel(GL_FLAT);
142 glDisable(GL_DEPTH_TEST);
143 glDisable(GL_CULL_FACE);
144 glDisable(GL_LIGHTING);
145 glDisable(GL_DITHER);
148 //Documents/images/alpha2.png");//
149 //m_texture = bindTexture(convertToGLFormat(img), GL_TEXTURE_RECTANGLE_EXT, GL_RGBA8, QGLContext::LinearFilteringBindOption);
154 /*void CDeckLinkGLWidget::initializeOverlayGL ()
157 glEnable(GL_TEXTURE_RECTANGLE_EXT);
161 void CDeckLinkGLWidget::paintOverlayGL()
163 makeOverlayCurrent();
165 //glClearDepth(0.5f);
166 //glPixelTransferf(GL_ALPHA_SCALE, 10);
167 //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
172 void CDeckLinkGLWidget::paintGL()
176 qglClearColor(m_backgroundColor);
177 //glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
178 glClear(GL_COLOR_BUFFER_BIT);
179 deckLinkScreenPreviewHelper->PaintGL();
180 if (!m_img.isNull()) {
181 glPixelZoom(m_zx, m_zy);
182 glDrawPixels(m_img.width(), m_img.height(), GL_RGBA, GL_UNSIGNED_BYTE, m_img.bits());
187 void CDeckLinkGLWidget::paintEvent(QPaintEvent *event)
191 QRect r = event->rect();
194 m_frame->GetBytes(&frameBytes);
195 QImage img((uchar*)frameBytes, m_frame->GetWidth(), m_frame->GetHeight(), QImage::Format_ARGB32);//m_frame->GetPixelFormat());
196 QRectF re(0, 0, width(), height());
197 p.drawImage(re, img);
202 void CDeckLinkGLWidget::resizeGL(int width, int height)
205 m_pictureHeight = height;
206 m_pictureWidth = width;
207 int calculatedWidth = g_aspect_ratio * height;
208 if (calculatedWidth > width) m_pictureHeight = width / g_aspect_ratio;
210 int calculatedHeight = width / g_aspect_ratio;
211 if (calculatedHeight > height) m_pictureWidth = height * g_aspect_ratio;
213 glViewport((width - m_pictureWidth) / 2, (height - m_pictureHeight) / 2, m_pictureWidth, m_pictureHeight);
214 glMatrixMode(GL_PROJECTION);
216 glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
217 glMatrixMode(GL_MODELVIEW);
218 glRasterPos2i(-1, -1);
219 if (!m_img.isNull()) {
220 m_zx = (double)m_pictureWidth / m_img.width();
221 m_zy = (double)m_pictureHeight / m_img.height();
227 /*void CDeckLinkGLWidget::resizeOverlayGL ( int width, int height )
229 int newwidth = width;
230 int newheight = height;
231 int calculatedWidth = g_aspect_ratio * height;
232 if (calculatedWidth > width) newheight = width / g_aspect_ratio;
234 int calculatedHeight = width / g_aspect_ratio;
235 if (calculatedHeight > height) newwidth = height * g_aspect_ratio;
237 glViewport((width - newwidth) / 2, (height - newheight) / 2, newwidth, newheight);
238 glMatrixMode(GL_PROJECTION);
240 glOrtho(0, width, 0, height, -1.0, 1.0);
241 glMatrixMode(GL_MODELVIEW);
245 HRESULT CDeckLinkGLWidget::QueryInterface(REFIID iid, LPVOID *ppv)
249 return E_NOINTERFACE;
252 ULONG CDeckLinkGLWidget::AddRef()
256 oldValue = refCount.fetchAndAddAcquire(1);
257 return (ULONG)(oldValue + 1);
260 ULONG CDeckLinkGLWidget::Release()
264 oldValue = refCount.fetchAndAddAcquire(-1);
269 return (ULONG)(oldValue - 1);
272 HRESULT CDeckLinkGLWidget::DrawFrame(IDeckLinkVideoFrame* theFrame)
274 if (deckLinkScreenPreviewHelper != NULL && theFrame != NULL) {
278 deckLinkScreenPreviewHelper->SetFrame(theFrame);
285 DeckLinkCaptureDelegate::DeckLinkCaptureDelegate() : m_refCount(0)
287 pthread_mutex_init(&m_mutex, NULL);
290 DeckLinkCaptureDelegate::~DeckLinkCaptureDelegate()
292 pthread_mutex_destroy(&m_mutex);
295 ULONG DeckLinkCaptureDelegate::AddRef(void)
297 pthread_mutex_lock(&m_mutex);
299 pthread_mutex_unlock(&m_mutex);
301 return (ULONG)m_refCount;
304 ULONG DeckLinkCaptureDelegate::Release(void)
306 pthread_mutex_lock(&m_mutex);
308 pthread_mutex_unlock(&m_mutex);
310 if (m_refCount == 0) {
315 return (ULONG)m_refCount;
318 void DeckLinkCaptureDelegate::slotProcessFrame()
320 if (m_framesList.isEmpty()) return;
321 IDeckLinkVideoInputFrame* videoFrame = m_framesList.takeFirst();
322 QString capturePath = m_framePath.takeFirst();
324 videoFrame->GetBytes(&frameBytes);
325 if (capturePath.endsWith("raw")) {
326 // Save as raw uyvy422 imgage
327 videoOutputFile = open(capturePath.toUtf8().constData(), O_WRONLY | O_CREAT/*|O_TRUNC*/, 0664);
328 write(videoOutputFile, frameBytes, videoFrame->GetRowBytes() * videoFrame->GetHeight());
329 close(videoOutputFile);
330 emit frameSaved(capturePath);
332 QImage image(videoFrame->GetWidth(), videoFrame->GetHeight(), QImage::Format_ARGB32_Premultiplied);
333 //convert from uyvy422 to rgba
334 CaptureHandler::uyvy2rgb((uchar *)frameBytes, (uchar *)image.bits(), videoFrame->GetWidth(), videoFrame->GetHeight());
335 image.save(capturePath);
336 emit frameSaved(capturePath);
338 videoFrame->Release();
341 void DeckLinkCaptureDelegate::setAnalyse(bool isOn)
343 m_analyseFrame = isOn;
346 HRESULT DeckLinkCaptureDelegate::VideoInputFrameArrived(IDeckLinkVideoInputFrame* videoFrame, IDeckLinkAudioInputPacket* audioFrame)
348 IDeckLinkVideoFrame* rightEyeFrame = NULL;
349 IDeckLinkVideoFrame3DExtensions* threeDExtensions = NULL;
351 void* audioFrameBytes;
353 // Handle Video Frame
355 // If 3D mode is enabled we retreive the 3D extensions interface which gives.
356 // us access to the right eye frame by calling GetFrameForRightEye() .
357 if ((videoFrame->QueryInterface(IID_IDeckLinkVideoFrame3DExtensions, (void **) &threeDExtensions) != S_OK) ||
358 (threeDExtensions->GetFrameForRightEye(&rightEyeFrame) != S_OK)) {
359 rightEyeFrame = NULL;
362 if (videoFrame->GetFlags() & bmdFrameHasNoInputSource) {
363 emit gotMessage(i18n("Frame (%1) - No input signal", frameCount));
364 fprintf(stderr, "Frame received (#%lu) - No input signal detected\n", frameCount);
366 const char *timecodeString = NULL;
367 if (g_timecodeFormat != 0) {
368 IDeckLinkTimecode *timecode;
369 if (videoFrame->GetTimecode(g_timecodeFormat, &timecode) == S_OK) {
370 timecode->GetString(&timecodeString);
373 // There seems to be No timecode with HDMI... Using frame number
374 emit gotTimeCode(frameCount);
375 /*fprintf(stderr, "Frame received (#%lu) [%s] - %s - Size: %li bytes\n",
377 timecodeString != NULL ? timecodeString : "No timecode",
378 rightEyeFrame != NULL ? "Valid Frame (3D left/right)" : "Valid Frame",
379 videoFrame->GetRowBytes() * videoFrame->GetHeight());*/
382 free((void*)timecodeString);
384 if (!doCaptureFrame.isEmpty()) {
385 videoFrame->AddRef();
386 m_framesList.append(videoFrame);
387 m_framePath.append(doCaptureFrame);
388 doCaptureFrame.clear();
389 QtConcurrent::run(this, &DeckLinkCaptureDelegate::slotProcessFrame);
391 if (m_analyseFrame) {
392 QImage image(videoFrame->GetWidth(), videoFrame->GetHeight(), QImage::Format_ARGB32_Premultiplied);
393 //convert from uyvy422 to rgba
394 CaptureHandler::uyvy2rgb((uchar *)frameBytes, (uchar *)image.bits(), videoFrame->GetWidth(), videoFrame->GetHeight());
395 emit gotFrame(image);
398 if (videoOutputFile != -1) {
399 videoFrame->GetBytes(&frameBytes);
400 write(videoOutputFile, frameBytes, videoFrame->GetRowBytes() * videoFrame->GetHeight());
403 rightEyeFrame->GetBytes(&frameBytes);
404 write(videoOutputFile, frameBytes, videoFrame->GetRowBytes() * videoFrame->GetHeight());
410 if (g_maxFrames > 0 && frameCount >= g_maxFrames) {
411 pthread_cond_signal(&sleepCond);
415 // Handle Audio Frame
417 if (audioOutputFile != -1) {
418 audioFrame->GetBytes(&audioFrameBytes);
419 write(audioOutputFile, audioFrameBytes, audioFrame->GetSampleFrameCount() * g_audioChannels *(g_audioSampleDepth / 8));
425 HRESULT DeckLinkCaptureDelegate::VideoInputFormatChanged(BMDVideoInputFormatChangedEvents events, IDeckLinkDisplayMode *mode, BMDDetectedVideoInputFormatFlags)
432 /*int usage(int status)
435 IDeckLinkDisplayMode *displayMode;
436 int displayModeCount = 0;
439 "Usage: Capture -m <mode id> [OPTIONS]\n"
444 while (displayModeIterator->Next(&displayMode) == S_OK)
446 char * displayModeString = NULL;
448 result = displayMode->GetName((const char **) &displayModeString);
451 BMDTimeValue frameRateDuration, frameRateScale;
452 displayMode->GetFrameRate(&frameRateDuration, &frameRateScale);
454 fprintf(stderr, " %2d: %-20s \t %li x %li \t %g FPS\n",
455 displayModeCount, displayModeString, displayMode->GetWidth(), displayMode->GetHeight(), (double)frameRateScale / (double)frameRateDuration);
457 free(displayModeString);
461 // Release the IDeckLinkDisplayMode object to prevent a leak
462 displayMode->Release();
466 " -p <pixelformat>\n"
467 " 0: 8 bit YUV (4:2:2) (default)\n"
468 " 1: 10 bit YUV (4:2:2)\n"
469 " 2: 10 bit RGB (4:4:4)\n"
470 " -t <format> Print timecode\n"
473 " serial: Serial Timecode\n"
474 " -f <filename> Filename raw video will be written to\n"
475 " -a <filename> Filename raw audio will be written to\n"
476 " -c <channels> Audio Channels (2, 8 or 16 - default is 2)\n"
477 " -s <depth> Audio Sample Depth (16 or 32 - default is 16)\n"
478 " -n <frames> Number of frames to capture (default is unlimited)\n"
479 " -3 Capture Stereoscopic 3D (Requires 3D Hardware support)\n"
481 "Capture video and/or audio to a file. Raw video and/or audio can be viewed with mplayer eg:\n"
483 " Capture -m2 -n 50 -f video.raw -a audio.raw\n"
484 " mplayer video.raw -demuxer rawvideo -rawvideo pal:uyvy -audiofile audio.raw -audio-demuxer 20 -rawaudio rate=48000\n"
494 BmdCaptureHandler::BmdCaptureHandler(QVBoxLayout *lay, QWidget *parent):
495 CaptureHandler(lay, parent),
497 deckLinkIterator(NULL),
502 displayModeIterator(NULL)
506 QStringList BmdCaptureHandler::getDeviceName(QString)
508 return QStringList();
511 void BmdCaptureHandler::startPreview(int deviceId, int captureMode, bool audio)
513 deckLinkIterator = CreateDeckLinkIteratorInstance();
514 BMDVideoInputFlags inputFlags = 0;
515 BMDDisplayMode selectedDisplayMode = bmdModeNTSC;
516 BMDPixelFormat pixelFormat = bmdFormat8BitYUV;
517 int displayModeCount = 0;
520 bool foundDisplayMode = false;
523 /*pthread_mutex_init(&sleepMutex, NULL);
524 pthread_cond_init(&sleepCond, NULL);*/
525 kDebug() << "/// INIT CAPTURE ON DEV: " << deviceId;
527 if (!deckLinkIterator) {
528 emit gotMessage(i18n("This application requires the DeckLink drivers installed."));
529 fprintf(stderr, "This application requires the DeckLink drivers installed.\n");
534 /* Connect to selected DeckLink instance */
535 for (int i = 0; i < deviceId + 1; i++)
536 result = deckLinkIterator->Next(&deckLink);
537 if (result != S_OK) {
538 fprintf(stderr, "No DeckLink PCI cards found.\n");
539 emit gotMessage(i18n("No DeckLink PCI cards found."));
544 if (deckLink->QueryInterface(IID_IDeckLinkInput, (void**)&deckLinkInput) != S_OK) {
549 delegate = new DeckLinkCaptureDelegate();
550 delegate->setAnalyse(m_analyseFrame);
551 connect(delegate, SIGNAL(gotTimeCode(ulong)), this, SIGNAL(gotTimeCode(ulong)));
552 connect(delegate, SIGNAL(gotFrame(QImage)), this, SIGNAL(gotFrame(QImage)));
553 connect(delegate, SIGNAL(gotMessage(const QString &)), this, SIGNAL(gotMessage(const QString &)));
554 connect(delegate, SIGNAL(frameSaved(const QString)), this, SIGNAL(frameSaved(const QString)));
555 deckLinkInput->SetCallback(delegate);
557 previewView = new CDeckLinkGLWidget(deckLinkInput, m_parent);
558 m_layout->addWidget(previewView);
559 //previewView->resize(parent->size());
560 previewView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
561 previewView->DrawFrame(NULL);
563 // Obtain an IDeckLinkDisplayModeIterator to enumerate the display modes supported on output
564 result = deckLinkInput->GetDisplayModeIterator(&displayModeIterator);
565 if (result != S_OK) {
566 emit gotMessage(i18n("Could not obtain the video output display mode iterator - result = ", result));
567 fprintf(stderr, "Could not obtain the video output display mode iterator - result = %08x\n", result);
572 g_videoModeIndex = captureMode;
573 /*g_audioChannels = 2;
574 g_audioSampleDepth = 16;*/
576 // Parse command line options
577 /*while ((ch = getopt(argc, argv, "?h3c:s:f:a:m:n:p:t:")) != -1)
582 g_videoModeIndex = atoi(optarg);
585 g_audioChannels = atoi(optarg);
586 if (g_audioChannels != 2 &&
587 g_audioChannels != 8 &&
588 g_audioChannels != 16)
590 fprintf(stderr, "Invalid argument: Audio Channels must be either 2, 8 or 16\n");
595 g_audioSampleDepth = atoi(optarg);
596 if (g_audioSampleDepth != 16 && g_audioSampleDepth != 32)
598 fprintf(stderr, "Invalid argument: Audio Sample Depth must be either 16 bits or 32 bits\n");
603 g_videoOutputFile = optarg;
606 g_audioOutputFile = optarg;
609 g_maxFrames = atoi(optarg);
612 inputFlags |= bmdVideoInputDualStream3D;
617 case 0: pixelFormat = bmdFormat8BitYUV; break;
618 case 1: pixelFormat = bmdFormat10BitYUV; break;
619 case 2: pixelFormat = bmdFormat10BitRGB; break;
621 fprintf(stderr, "Invalid argument: Pixel format %d is not valid", atoi(optarg));
626 if (!strcmp(optarg, "rp188"))
627 g_timecodeFormat = bmdTimecodeRP188;
628 else if (!strcmp(optarg, "vitc"))
629 g_timecodeFormat = bmdTimecodeVITC;
630 else if (!strcmp(optarg, "serial"))
631 g_timecodeFormat = bmdTimecodeSerial;
634 fprintf(stderr, "Invalid argument: Timecode format \"%s\" is invalid\n", optarg);
644 if (g_videoModeIndex < 0) {
645 emit gotMessage(i18n("No video mode specified"));
646 fprintf(stderr, "No video mode specified\n");
651 /*if (g_videoOutputFile != NULL)
653 videoOutputFile = open(g_videoOutputFile, O_WRONLY|O_CREAT|O_TRUNC, 0664);
654 if (videoOutputFile < 0)
656 emit gotMessage(i18n("Could not open video output file %1", g_videoOutputFile));
657 fprintf(stderr, "Could not open video output file \"%s\"\n", g_videoOutputFile);
661 if (g_audioOutputFile != NULL)
663 audioOutputFile = open(g_audioOutputFile, O_WRONLY|O_CREAT|O_TRUNC, 0664);
664 if (audioOutputFile < 0)
666 emit gotMessage(i18n("Could not open audio output file %1", g_audioOutputFile));
667 fprintf(stderr, "Could not open audio output file \"%s\"\n", g_audioOutputFile);
672 while (displayModeIterator->Next(&displayMode) == S_OK) {
673 if (g_videoModeIndex == displayModeCount) {
674 BMDDisplayModeSupport result;
675 const char *displayModeName;
677 foundDisplayMode = true;
678 displayMode->GetName(&displayModeName);
679 selectedDisplayMode = displayMode->GetDisplayMode();
681 g_aspect_ratio = (double) displayMode->GetWidth() / (double) displayMode->GetHeight();
683 deckLinkInput->DoesSupportVideoMode(selectedDisplayMode, pixelFormat, bmdVideoInputFlagDefault, &result, NULL);
685 if (result == bmdDisplayModeNotSupported) {
686 emit gotMessage(i18n("The display mode %1 is not supported with the selected pixel format", displayModeName));
687 fprintf(stderr, "The display mode %s is not supported with the selected pixel format\n", displayModeName);
692 if (inputFlags & bmdVideoInputDualStream3D) {
693 if (!(displayMode->GetFlags() & bmdDisplayModeSupports3D)) {
694 emit gotMessage(i18n("The display mode %1 is not supported with 3D", displayModeName));
695 fprintf(stderr, "The display mode %s is not supported with 3D\n", displayModeName);
704 displayMode->Release();
707 if (!foundDisplayMode) {
708 emit gotMessage(i18n("Invalid mode %1 specified", g_videoModeIndex));
709 fprintf(stderr, "Invalid mode %d specified\n", g_videoModeIndex);
714 result = deckLinkInput->EnableVideoInput(selectedDisplayMode, pixelFormat, inputFlags);
715 if (result != S_OK) {
716 emit gotMessage(i18n("Failed to enable video input. Is another application using the card?"));
717 fprintf(stderr, "Failed to enable video input. Is another application using the card?\n");
723 result = deckLinkInput->EnableAudioInput(bmdAudioSampleRate48kHz, g_audioSampleDepth, g_audioChannels);
724 if (result != S_OK) {
729 deckLinkInput->SetScreenPreviewCallback(previewView);
730 result = deckLinkInput->StartStreams();
731 if (result != S_OK) {
732 qDebug() << "/// CAPTURE FAILED....";
733 emit gotMessage(i18n("Capture failed"));
739 // Block main thread until signal occurs
740 /* pthread_mutex_lock(&sleepMutex);
741 pthread_cond_wait(&sleepCond, &sleepMutex);
742 pthread_mutex_unlock(&sleepMutex);*/
747 close(videoOutputFile);
749 close(audioOutputFile);
751 if (displayModeIterator != NULL)
753 displayModeIterator->Release();
754 displayModeIterator = NULL;
757 if (deckLinkInput != NULL)
759 deckLinkInput->Release();
760 deckLinkInput = NULL;
763 if (deckLink != NULL)
769 if (deckLinkIterator != NULL)
770 deckLinkIterator->Release();
774 BmdCaptureHandler::~BmdCaptureHandler()
779 void BmdCaptureHandler::startCapture(const QString &path)
782 QString videopath = path + "_video_" + QString::number(i).rightJustified(4, '0', false) + ".raw";
783 QString audiopath = path + "_audio_" + QString::number(i).rightJustified(4, '0', false) + ".raw";
784 while (QFile::exists(videopath) || QFile::exists(audiopath)) {
786 videopath = path + "_video_" + QString::number(i).rightJustified(4, '0', false) + ".raw";
787 audiopath = path + "_audio_" + QString::number(i).rightJustified(4, '0', false) + ".raw";
789 videoOutputFile = open(videopath.toUtf8().constData(), O_WRONLY | O_CREAT | O_TRUNC, 0664);
790 if (videoOutputFile < 0) {
791 emit gotMessage(i18n("Could not open video output file %1", videopath));
792 fprintf(stderr, "Could not open video output file \"%s\"\n", videopath.toUtf8().constData());
795 if (KdenliveSettings::hdmicaptureaudio()) {
796 audioOutputFile = open(audiopath.toUtf8().constData(), O_WRONLY | O_CREAT | O_TRUNC, 0664);
797 if (audioOutputFile < 0) {
798 emit gotMessage(i18n("Could not open audio output file %1", audiopath));
799 fprintf(stderr, "Could not open video output file \"%s\"\n", audiopath.toUtf8().constData());
805 void BmdCaptureHandler::stopCapture()
808 close(videoOutputFile);
810 close(audioOutputFile);
811 videoOutputFile = -1;
812 audioOutputFile = -1;
815 void BmdCaptureHandler::captureFrame(const QString &fname)
817 doCaptureFrame = fname;
820 void BmdCaptureHandler::showOverlay(QImage img, bool transparent)
822 if (previewView) previewView->showOverlay(img, transparent);
825 void BmdCaptureHandler::hideOverlay()
827 if (previewView) previewView->hideOverlay();
830 void BmdCaptureHandler::setDevice(const QString , QString)
834 void BmdCaptureHandler::hidePreview(bool hide)
836 if (previewView) previewView->setHidden(hide);
839 void BmdCaptureHandler::stopPreview()
841 if (!previewView) return;
842 if (deckLinkInput != NULL) deckLinkInput->StopStreams();
844 close(videoOutputFile);
846 close(audioOutputFile);
848 if (displayModeIterator != NULL) {
849 displayModeIterator->Release();
850 displayModeIterator = NULL;
853 if (deckLinkInput != NULL) {
854 deckLinkInput->Release();
855 deckLinkInput = NULL;
858 if (deckLink != NULL) {
863 if (deckLinkIterator != NULL) {
864 deckLinkIterator->Release();
865 deckLinkIterator = NULL;
868 if (previewView != NULL) {
873 /*if (delegate != NULL)