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::yuv2rgb((uchar *)frameBytes, (uchar *)image.bits(), videoFrame->GetWidth(), videoFrame->GetHeight());
335 image.save(capturePath);
336 emit frameSaved(capturePath);
338 videoFrame->Release();
341 HRESULT DeckLinkCaptureDelegate::VideoInputFrameArrived(IDeckLinkVideoInputFrame* videoFrame, IDeckLinkAudioInputPacket* audioFrame)
343 IDeckLinkVideoFrame* rightEyeFrame = NULL;
344 IDeckLinkVideoFrame3DExtensions* threeDExtensions = NULL;
346 void* audioFrameBytes;
348 // Handle Video Frame
350 // If 3D mode is enabled we retreive the 3D extensions interface which gives.
351 // us access to the right eye frame by calling GetFrameForRightEye() .
352 if ((videoFrame->QueryInterface(IID_IDeckLinkVideoFrame3DExtensions, (void **) &threeDExtensions) != S_OK) ||
353 (threeDExtensions->GetFrameForRightEye(&rightEyeFrame) != S_OK)) {
354 rightEyeFrame = NULL;
357 if (videoFrame->GetFlags() & bmdFrameHasNoInputSource) {
358 emit gotMessage(i18n("Frame (%1) - No input signal", frameCount));
359 fprintf(stderr, "Frame received (#%lu) - No input signal detected\n", frameCount);
361 const char *timecodeString = NULL;
362 if (g_timecodeFormat != 0) {
363 IDeckLinkTimecode *timecode;
364 if (videoFrame->GetTimecode(g_timecodeFormat, &timecode) == S_OK) {
365 timecode->GetString(&timecodeString);
368 // There seems to be No timecode with HDMI... Using frame number
369 emit gotTimeCode(frameCount);
370 /*fprintf(stderr, "Frame received (#%lu) [%s] - %s - Size: %li bytes\n",
372 timecodeString != NULL ? timecodeString : "No timecode",
373 rightEyeFrame != NULL ? "Valid Frame (3D left/right)" : "Valid Frame",
374 videoFrame->GetRowBytes() * videoFrame->GetHeight());*/
377 free((void*)timecodeString);
379 if (!doCaptureFrame.isEmpty()) {
380 videoFrame->AddRef();
381 m_framesList.append(videoFrame);
382 m_framePath.append(doCaptureFrame);
383 doCaptureFrame.clear();
384 QtConcurrent::run(this, &DeckLinkCaptureDelegate::slotProcessFrame);
387 if (videoOutputFile != -1) {
388 videoFrame->GetBytes(&frameBytes);
389 write(videoOutputFile, frameBytes, videoFrame->GetRowBytes() * videoFrame->GetHeight());
392 rightEyeFrame->GetBytes(&frameBytes);
393 write(videoOutputFile, frameBytes, videoFrame->GetRowBytes() * videoFrame->GetHeight());
399 if (g_maxFrames > 0 && frameCount >= g_maxFrames) {
400 pthread_cond_signal(&sleepCond);
404 // Handle Audio Frame
406 if (audioOutputFile != -1) {
407 audioFrame->GetBytes(&audioFrameBytes);
408 write(audioOutputFile, audioFrameBytes, audioFrame->GetSampleFrameCount() * g_audioChannels *(g_audioSampleDepth / 8));
414 HRESULT DeckLinkCaptureDelegate::VideoInputFormatChanged(BMDVideoInputFormatChangedEvents events, IDeckLinkDisplayMode *mode, BMDDetectedVideoInputFormatFlags)
421 /*int usage(int status)
424 IDeckLinkDisplayMode *displayMode;
425 int displayModeCount = 0;
428 "Usage: Capture -m <mode id> [OPTIONS]\n"
433 while (displayModeIterator->Next(&displayMode) == S_OK)
435 char * displayModeString = NULL;
437 result = displayMode->GetName((const char **) &displayModeString);
440 BMDTimeValue frameRateDuration, frameRateScale;
441 displayMode->GetFrameRate(&frameRateDuration, &frameRateScale);
443 fprintf(stderr, " %2d: %-20s \t %li x %li \t %g FPS\n",
444 displayModeCount, displayModeString, displayMode->GetWidth(), displayMode->GetHeight(), (double)frameRateScale / (double)frameRateDuration);
446 free(displayModeString);
450 // Release the IDeckLinkDisplayMode object to prevent a leak
451 displayMode->Release();
455 " -p <pixelformat>\n"
456 " 0: 8 bit YUV (4:2:2) (default)\n"
457 " 1: 10 bit YUV (4:2:2)\n"
458 " 2: 10 bit RGB (4:4:4)\n"
459 " -t <format> Print timecode\n"
462 " serial: Serial Timecode\n"
463 " -f <filename> Filename raw video will be written to\n"
464 " -a <filename> Filename raw audio will be written to\n"
465 " -c <channels> Audio Channels (2, 8 or 16 - default is 2)\n"
466 " -s <depth> Audio Sample Depth (16 or 32 - default is 16)\n"
467 " -n <frames> Number of frames to capture (default is unlimited)\n"
468 " -3 Capture Stereoscopic 3D (Requires 3D Hardware support)\n"
470 "Capture video and/or audio to a file. Raw video and/or audio can be viewed with mplayer eg:\n"
472 " Capture -m2 -n 50 -f video.raw -a audio.raw\n"
473 " mplayer video.raw -demuxer rawvideo -rawvideo pal:uyvy -audiofile audio.raw -audio-demuxer 20 -rawaudio rate=48000\n"
483 BmdCaptureHandler::BmdCaptureHandler(QVBoxLayout *lay, QWidget *parent):
484 CaptureHandler(lay, parent),
486 deckLinkIterator(NULL),
491 displayModeIterator(NULL)
495 QString BmdCaptureHandler::getDeviceName(QString)
500 void BmdCaptureHandler::startPreview(int deviceId, int captureMode, bool audio)
502 deckLinkIterator = CreateDeckLinkIteratorInstance();
503 BMDVideoInputFlags inputFlags = 0;
504 BMDDisplayMode selectedDisplayMode = bmdModeNTSC;
505 BMDPixelFormat pixelFormat = bmdFormat8BitYUV;
506 int displayModeCount = 0;
509 bool foundDisplayMode = false;
512 /*pthread_mutex_init(&sleepMutex, NULL);
513 pthread_cond_init(&sleepCond, NULL);*/
514 kDebug() << "/// INIT CAPTURE ON DEV: " << deviceId;
516 if (!deckLinkIterator) {
517 emit gotMessage(i18n("This application requires the DeckLink drivers installed."));
518 fprintf(stderr, "This application requires the DeckLink drivers installed.\n");
523 /* Connect to selected DeckLink instance */
524 for (int i = 0; i < deviceId + 1; i++)
525 result = deckLinkIterator->Next(&deckLink);
526 if (result != S_OK) {
527 fprintf(stderr, "No DeckLink PCI cards found.\n");
528 emit gotMessage(i18n("No DeckLink PCI cards found."));
533 if (deckLink->QueryInterface(IID_IDeckLinkInput, (void**)&deckLinkInput) != S_OK) {
538 delegate = new DeckLinkCaptureDelegate();
539 connect(delegate, SIGNAL(gotTimeCode(ulong)), this, SIGNAL(gotTimeCode(ulong)));
540 connect(delegate, SIGNAL(gotMessage(const QString &)), this, SIGNAL(gotMessage(const QString &)));
541 connect(delegate, SIGNAL(frameSaved(const QString)), this, SIGNAL(frameSaved(const QString)));
542 deckLinkInput->SetCallback(delegate);
544 previewView = new CDeckLinkGLWidget(deckLinkInput, m_parent);
545 m_layout->addWidget(previewView);
546 //previewView->resize(parent->size());
547 previewView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
548 previewView->DrawFrame(NULL);
550 // Obtain an IDeckLinkDisplayModeIterator to enumerate the display modes supported on output
551 result = deckLinkInput->GetDisplayModeIterator(&displayModeIterator);
552 if (result != S_OK) {
553 emit gotMessage(i18n("Could not obtain the video output display mode iterator - result = ", result));
554 fprintf(stderr, "Could not obtain the video output display mode iterator - result = %08x\n", result);
559 g_videoModeIndex = captureMode;
560 /*g_audioChannels = 2;
561 g_audioSampleDepth = 16;*/
563 // Parse command line options
564 /*while ((ch = getopt(argc, argv, "?h3c:s:f:a:m:n:p:t:")) != -1)
569 g_videoModeIndex = atoi(optarg);
572 g_audioChannels = atoi(optarg);
573 if (g_audioChannels != 2 &&
574 g_audioChannels != 8 &&
575 g_audioChannels != 16)
577 fprintf(stderr, "Invalid argument: Audio Channels must be either 2, 8 or 16\n");
582 g_audioSampleDepth = atoi(optarg);
583 if (g_audioSampleDepth != 16 && g_audioSampleDepth != 32)
585 fprintf(stderr, "Invalid argument: Audio Sample Depth must be either 16 bits or 32 bits\n");
590 g_videoOutputFile = optarg;
593 g_audioOutputFile = optarg;
596 g_maxFrames = atoi(optarg);
599 inputFlags |= bmdVideoInputDualStream3D;
604 case 0: pixelFormat = bmdFormat8BitYUV; break;
605 case 1: pixelFormat = bmdFormat10BitYUV; break;
606 case 2: pixelFormat = bmdFormat10BitRGB; break;
608 fprintf(stderr, "Invalid argument: Pixel format %d is not valid", atoi(optarg));
613 if (!strcmp(optarg, "rp188"))
614 g_timecodeFormat = bmdTimecodeRP188;
615 else if (!strcmp(optarg, "vitc"))
616 g_timecodeFormat = bmdTimecodeVITC;
617 else if (!strcmp(optarg, "serial"))
618 g_timecodeFormat = bmdTimecodeSerial;
621 fprintf(stderr, "Invalid argument: Timecode format \"%s\" is invalid\n", optarg);
631 if (g_videoModeIndex < 0) {
632 emit gotMessage(i18n("No video mode specified"));
633 fprintf(stderr, "No video mode specified\n");
638 /*if (g_videoOutputFile != NULL)
640 videoOutputFile = open(g_videoOutputFile, O_WRONLY|O_CREAT|O_TRUNC, 0664);
641 if (videoOutputFile < 0)
643 emit gotMessage(i18n("Could not open video output file %1", g_videoOutputFile));
644 fprintf(stderr, "Could not open video output file \"%s\"\n", g_videoOutputFile);
648 if (g_audioOutputFile != NULL)
650 audioOutputFile = open(g_audioOutputFile, O_WRONLY|O_CREAT|O_TRUNC, 0664);
651 if (audioOutputFile < 0)
653 emit gotMessage(i18n("Could not open audio output file %1", g_audioOutputFile));
654 fprintf(stderr, "Could not open audio output file \"%s\"\n", g_audioOutputFile);
659 while (displayModeIterator->Next(&displayMode) == S_OK) {
660 if (g_videoModeIndex == displayModeCount) {
661 BMDDisplayModeSupport result;
662 const char *displayModeName;
664 foundDisplayMode = true;
665 displayMode->GetName(&displayModeName);
666 selectedDisplayMode = displayMode->GetDisplayMode();
668 g_aspect_ratio = (double) displayMode->GetWidth() / (double) displayMode->GetHeight();
670 deckLinkInput->DoesSupportVideoMode(selectedDisplayMode, pixelFormat, bmdVideoInputFlagDefault, &result, NULL);
672 if (result == bmdDisplayModeNotSupported) {
673 emit gotMessage(i18n("The display mode %1 is not supported with the selected pixel format", displayModeName));
674 fprintf(stderr, "The display mode %s is not supported with the selected pixel format\n", displayModeName);
679 if (inputFlags & bmdVideoInputDualStream3D) {
680 if (!(displayMode->GetFlags() & bmdDisplayModeSupports3D)) {
681 emit gotMessage(i18n("The display mode %1 is not supported with 3D", displayModeName));
682 fprintf(stderr, "The display mode %s is not supported with 3D\n", displayModeName);
691 displayMode->Release();
694 if (!foundDisplayMode) {
695 emit gotMessage(i18n("Invalid mode %1 specified", g_videoModeIndex));
696 fprintf(stderr, "Invalid mode %d specified\n", g_videoModeIndex);
701 result = deckLinkInput->EnableVideoInput(selectedDisplayMode, pixelFormat, inputFlags);
702 if (result != S_OK) {
703 emit gotMessage(i18n("Failed to enable video input. Is another application using the card?"));
704 fprintf(stderr, "Failed to enable video input. Is another application using the card?\n");
710 result = deckLinkInput->EnableAudioInput(bmdAudioSampleRate48kHz, g_audioSampleDepth, g_audioChannels);
711 if (result != S_OK) {
716 deckLinkInput->SetScreenPreviewCallback(previewView);
717 result = deckLinkInput->StartStreams();
718 if (result != S_OK) {
719 qDebug() << "/// CAPTURE FAILED....";
720 emit gotMessage(i18n("Capture failed"));
726 // Block main thread until signal occurs
727 /* pthread_mutex_lock(&sleepMutex);
728 pthread_cond_wait(&sleepCond, &sleepMutex);
729 pthread_mutex_unlock(&sleepMutex);*/
734 close(videoOutputFile);
736 close(audioOutputFile);
738 if (displayModeIterator != NULL)
740 displayModeIterator->Release();
741 displayModeIterator = NULL;
744 if (deckLinkInput != NULL)
746 deckLinkInput->Release();
747 deckLinkInput = NULL;
750 if (deckLink != NULL)
756 if (deckLinkIterator != NULL)
757 deckLinkIterator->Release();
761 BmdCaptureHandler::~BmdCaptureHandler()
766 void BmdCaptureHandler::startCapture(const QString &path)
769 QString videopath = path + "_video_" + QString::number(i).rightJustified(4, '0', false) + ".raw";
770 QString audiopath = path + "_audio_" + QString::number(i).rightJustified(4, '0', false) + ".raw";
771 while (QFile::exists(videopath) || QFile::exists(audiopath)) {
773 videopath = path + "_video_" + QString::number(i).rightJustified(4, '0', false) + ".raw";
774 audiopath = path + "_audio_" + QString::number(i).rightJustified(4, '0', false) + ".raw";
776 videoOutputFile = open(videopath.toUtf8().constData(), O_WRONLY | O_CREAT | O_TRUNC, 0664);
777 if (videoOutputFile < 0) {
778 emit gotMessage(i18n("Could not open video output file %1", videopath));
779 fprintf(stderr, "Could not open video output file \"%s\"\n", videopath.toUtf8().constData());
782 if (KdenliveSettings::hdmicaptureaudio()) {
783 audioOutputFile = open(audiopath.toUtf8().constData(), O_WRONLY | O_CREAT | O_TRUNC, 0664);
784 if (audioOutputFile < 0) {
785 emit gotMessage(i18n("Could not open audio output file %1", audiopath));
786 fprintf(stderr, "Could not open video output file \"%s\"\n", audiopath.toUtf8().constData());
792 void BmdCaptureHandler::stopCapture()
795 close(videoOutputFile);
797 close(audioOutputFile);
798 videoOutputFile = -1;
799 audioOutputFile = -1;
802 void BmdCaptureHandler::captureFrame(const QString &fname)
804 doCaptureFrame = fname;
807 void BmdCaptureHandler::showOverlay(QImage img, bool transparent)
809 if (previewView) previewView->showOverlay(img, transparent);
812 void BmdCaptureHandler::hideOverlay()
814 if (previewView) previewView->hideOverlay();
817 void BmdCaptureHandler::hidePreview(bool hide)
819 if (previewView) previewView->setHidden(hide);
822 void BmdCaptureHandler::stopPreview()
824 if (!previewView) return;
825 if (deckLinkInput != NULL) deckLinkInput->StopStreams();
827 close(videoOutputFile);
829 close(audioOutputFile);
831 if (displayModeIterator != NULL) {
832 displayModeIterator->Release();
833 displayModeIterator = NULL;
836 if (deckLinkInput != NULL) {
837 deckLinkInput->Release();
838 deckLinkInput = NULL;
841 if (deckLink != NULL) {
846 if (deckLinkIterator != NULL) {
847 deckLinkIterator->Release();
848 deckLinkIterator = NULL;
851 if (previewView != NULL) {
856 /*if (delegate != NULL)