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;
319 inline bool safe_write(int fd, const void* bytes, size_t length) {
322 const char* buf = static_cast<const char*>(bytes);
323 while (rc != -1 && written < length) {
324 rc = write(fd, &(buf[written]), length - written);
325 written += (rc >= 0 ? rc : 0);
330 void DeckLinkCaptureDelegate::slotProcessFrame()
332 if (m_framesList.isEmpty()) return;
333 IDeckLinkVideoInputFrame* videoFrame = m_framesList.takeFirst();
334 QString capturePath = m_framePath.takeFirst();
336 videoFrame->GetBytes(&frameBytes);
337 if (capturePath.endsWith("raw")) {
338 // Save as raw uyvy422 imgage
339 videoOutputFile = open(capturePath.toUtf8().constData(), O_WRONLY | O_CREAT/*|O_TRUNC*/, 0664);
340 safe_write(videoOutputFile, frameBytes, videoFrame->GetRowBytes() * videoFrame->GetHeight());
341 close(videoOutputFile);
342 emit frameSaved(capturePath);
344 QImage image(videoFrame->GetWidth(), videoFrame->GetHeight(), QImage::Format_ARGB32_Premultiplied);
345 //convert from uyvy422 to rgba
346 CaptureHandler::uyvy2rgb((uchar *)frameBytes, (uchar *)image.bits(), videoFrame->GetWidth(), videoFrame->GetHeight());
347 image.save(capturePath);
348 emit frameSaved(capturePath);
350 videoFrame->Release();
353 void DeckLinkCaptureDelegate::setAnalyse(bool isOn)
355 m_analyseFrame = isOn;
358 HRESULT DeckLinkCaptureDelegate::VideoInputFrameArrived(IDeckLinkVideoInputFrame* videoFrame, IDeckLinkAudioInputPacket* audioFrame)
360 IDeckLinkVideoFrame* rightEyeFrame = NULL;
361 IDeckLinkVideoFrame3DExtensions* threeDExtensions = NULL;
363 void* audioFrameBytes;
365 // Handle Video Frame
367 // If 3D mode is enabled we retreive the 3D extensions interface which gives.
368 // us access to the right eye frame by calling GetFrameForRightEye() .
369 if ((videoFrame->QueryInterface(IID_IDeckLinkVideoFrame3DExtensions, (void **) &threeDExtensions) != S_OK) ||
370 (threeDExtensions->GetFrameForRightEye(&rightEyeFrame) != S_OK)) {
371 rightEyeFrame = NULL;
374 if (videoFrame->GetFlags() & bmdFrameHasNoInputSource) {
375 emit gotMessage(i18n("Frame (%1) - No input signal", frameCount));
376 fprintf(stderr, "Frame received (#%lu) - No input signal detected\n", frameCount);
378 const char *timecodeString = NULL;
379 if (g_timecodeFormat != 0) {
380 IDeckLinkTimecode *timecode;
381 if (videoFrame->GetTimecode(g_timecodeFormat, &timecode) == S_OK) {
382 timecode->GetString(&timecodeString);
385 // There seems to be No timecode with HDMI... Using frame number
386 emit gotTimeCode(frameCount);
387 /*fprintf(stderr, "Frame received (#%lu) [%s] - %s - Size: %li bytes\n",
389 timecodeString != NULL ? timecodeString : "No timecode",
390 rightEyeFrame != NULL ? "Valid Frame (3D left/right)" : "Valid Frame",
391 videoFrame->GetRowBytes() * videoFrame->GetHeight());*/
394 free((void*)timecodeString);
396 if (!doCaptureFrame.isEmpty()) {
397 videoFrame->AddRef();
398 m_framesList.append(videoFrame);
399 m_framePath.append(doCaptureFrame);
400 doCaptureFrame.clear();
401 QtConcurrent::run(this, &DeckLinkCaptureDelegate::slotProcessFrame);
403 if (m_analyseFrame) {
404 QImage image(videoFrame->GetWidth(), videoFrame->GetHeight(), QImage::Format_ARGB32_Premultiplied);
405 //convert from uyvy422 to rgba
406 videoFrame->GetBytes(&frameBytes);
407 CaptureHandler::uyvy2rgb((uchar *)frameBytes, (uchar *)image.bits(), videoFrame->GetWidth(), videoFrame->GetHeight());
408 emit gotFrame(image);
411 if (videoOutputFile != -1) {
412 if (!m_analyseFrame) videoFrame->GetBytes(&frameBytes);
413 safe_write(videoOutputFile, frameBytes, videoFrame->GetRowBytes() * videoFrame->GetHeight());
416 rightEyeFrame->GetBytes(&frameBytes);
417 safe_write(videoOutputFile, frameBytes, videoFrame->GetRowBytes() * videoFrame->GetHeight());
423 if (g_maxFrames > 0 && frameCount >= (uint) g_maxFrames) {
424 pthread_cond_signal(&sleepCond);
428 // Handle Audio Frame
430 if (audioOutputFile != -1) {
431 audioFrame->GetBytes(&audioFrameBytes);
432 safe_write(audioOutputFile, audioFrameBytes, audioFrame->GetSampleFrameCount() * g_audioChannels *(g_audioSampleDepth / 8));
438 HRESULT DeckLinkCaptureDelegate::VideoInputFormatChanged(BMDVideoInputFormatChangedEvents events, IDeckLinkDisplayMode *mode, BMDDetectedVideoInputFormatFlags)
445 /*int usage(int status)
448 IDeckLinkDisplayMode *displayMode;
449 int displayModeCount = 0;
452 "Usage: Capture -m <mode id> [OPTIONS]\n"
457 while (displayModeIterator->Next(&displayMode) == S_OK)
459 char * displayModeString = NULL;
461 result = displayMode->GetName((const char **) &displayModeString);
464 BMDTimeValue frameRateDuration, frameRateScale;
465 displayMode->GetFrameRate(&frameRateDuration, &frameRateScale);
467 fprintf(stderr, " %2d: %-20s \t %li x %li \t %g FPS\n",
468 displayModeCount, displayModeString, displayMode->GetWidth(), displayMode->GetHeight(), (double)frameRateScale / (double)frameRateDuration);
470 free(displayModeString);
474 // Release the IDeckLinkDisplayMode object to prevent a leak
475 displayMode->Release();
479 " -p <pixelformat>\n"
480 " 0: 8 bit YUV (4:2:2) (default)\n"
481 " 1: 10 bit YUV (4:2:2)\n"
482 " 2: 10 bit RGB (4:4:4)\n"
483 " -t <format> Print timecode\n"
486 " serial: Serial Timecode\n"
487 " -f <filename> Filename raw video will be written to\n"
488 " -a <filename> Filename raw audio will be written to\n"
489 " -c <channels> Audio Channels (2, 8 or 16 - default is 2)\n"
490 " -s <depth> Audio Sample Depth (16 or 32 - default is 16)\n"
491 " -n <frames> Number of frames to capture (default is unlimited)\n"
492 " -3 Capture Stereoscopic 3D (Requires 3D Hardware support)\n"
494 "Capture video and/or audio to a file. Raw video and/or audio can be viewed with mplayer eg:\n"
496 " Capture -m2 -n 50 -f video.raw -a audio.raw\n"
497 " mplayer video.raw -demuxer rawvideo -rawvideo pal:uyvy -audiofile audio.raw -audio-demuxer 20 -rawaudio rate=48000\n"
507 BmdCaptureHandler::BmdCaptureHandler(QVBoxLayout *lay, QWidget *parent):
508 CaptureHandler(lay, parent),
510 deckLinkIterator(NULL),
515 displayModeIterator(NULL)
519 QStringList BmdCaptureHandler::getDeviceName(QString)
521 return QStringList();
524 void BmdCaptureHandler::startPreview(int deviceId, int captureMode, bool audio)
526 deckLinkIterator = CreateDeckLinkIteratorInstance();
527 BMDVideoInputFlags inputFlags = 0;
528 BMDDisplayMode selectedDisplayMode = bmdModeNTSC;
529 BMDPixelFormat pixelFormat = bmdFormat8BitYUV;
530 int displayModeCount = 0;
533 bool foundDisplayMode = false;
536 /*pthread_mutex_init(&sleepMutex, NULL);
537 pthread_cond_init(&sleepCond, NULL);*/
538 kDebug() << "/// INIT CAPTURE ON DEV: " << deviceId;
540 if (!deckLinkIterator) {
541 emit gotMessage(i18n("This application requires the DeckLink drivers installed."));
542 fprintf(stderr, "This application requires the DeckLink drivers installed.\n");
547 /* Connect to selected DeckLink instance */
548 for (int i = 0; i < deviceId + 1; i++)
549 result = deckLinkIterator->Next(&deckLink);
550 if (result != S_OK) {
551 fprintf(stderr, "No DeckLink PCI cards found.\n");
552 emit gotMessage(i18n("No DeckLink PCI cards found."));
557 if (deckLink->QueryInterface(IID_IDeckLinkInput, (void**)&deckLinkInput) != S_OK) {
562 delegate = new DeckLinkCaptureDelegate();
563 delegate->setAnalyse(m_analyseFrame);
564 connect(delegate, SIGNAL(gotTimeCode(ulong)), this, SIGNAL(gotTimeCode(ulong)));
565 connect(delegate, SIGNAL(gotFrame(QImage)), this, SIGNAL(gotFrame(QImage)));
566 connect(delegate, SIGNAL(gotMessage(const QString &)), this, SIGNAL(gotMessage(const QString &)));
567 connect(delegate, SIGNAL(frameSaved(const QString)), this, SIGNAL(frameSaved(const QString)));
568 deckLinkInput->SetCallback(delegate);
570 previewView = new CDeckLinkGLWidget(deckLinkInput, m_parent);
571 m_layout->addWidget(previewView);
572 //previewView->resize(parent->size());
573 previewView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
574 previewView->DrawFrame(NULL);
576 // Obtain an IDeckLinkDisplayModeIterator to enumerate the display modes supported on output
577 result = deckLinkInput->GetDisplayModeIterator(&displayModeIterator);
578 if (result != S_OK) {
579 emit gotMessage(i18n("Could not obtain the video output display mode iterator - result = ", result));
580 fprintf(stderr, "Could not obtain the video output display mode iterator - result = %08x\n", result);
585 g_videoModeIndex = captureMode;
586 /*g_audioChannels = 2;
587 g_audioSampleDepth = 16;*/
589 // Parse command line options
590 /*while ((ch = getopt(argc, argv, "?h3c:s:f:a:m:n:p:t:")) != -1)
595 g_videoModeIndex = atoi(optarg);
598 g_audioChannels = atoi(optarg);
599 if (g_audioChannels != 2 &&
600 g_audioChannels != 8 &&
601 g_audioChannels != 16)
603 fprintf(stderr, "Invalid argument: Audio Channels must be either 2, 8 or 16\n");
608 g_audioSampleDepth = atoi(optarg);
609 if (g_audioSampleDepth != 16 && g_audioSampleDepth != 32)
611 fprintf(stderr, "Invalid argument: Audio Sample Depth must be either 16 bits or 32 bits\n");
616 g_videoOutputFile = optarg;
619 g_audioOutputFile = optarg;
622 g_maxFrames = atoi(optarg);
625 inputFlags |= bmdVideoInputDualStream3D;
630 case 0: pixelFormat = bmdFormat8BitYUV; break;
631 case 1: pixelFormat = bmdFormat10BitYUV; break;
632 case 2: pixelFormat = bmdFormat10BitRGB; break;
634 fprintf(stderr, "Invalid argument: Pixel format %d is not valid", atoi(optarg));
639 if (!strcmp(optarg, "rp188"))
640 g_timecodeFormat = bmdTimecodeRP188;
641 else if (!strcmp(optarg, "vitc"))
642 g_timecodeFormat = bmdTimecodeVITC;
643 else if (!strcmp(optarg, "serial"))
644 g_timecodeFormat = bmdTimecodeSerial;
647 fprintf(stderr, "Invalid argument: Timecode format \"%s\" is invalid\n", optarg);
657 if (g_videoModeIndex < 0) {
658 emit gotMessage(i18n("No video mode specified"));
659 fprintf(stderr, "No video mode specified\n");
664 /*if (g_videoOutputFile != NULL)
666 videoOutputFile = open(g_videoOutputFile, O_WRONLY|O_CREAT|O_TRUNC, 0664);
667 if (videoOutputFile < 0)
669 emit gotMessage(i18n("Could not open video output file %1", g_videoOutputFile));
670 fprintf(stderr, "Could not open video output file \"%s\"\n", g_videoOutputFile);
674 if (g_audioOutputFile != NULL)
676 audioOutputFile = open(g_audioOutputFile, O_WRONLY|O_CREAT|O_TRUNC, 0664);
677 if (audioOutputFile < 0)
679 emit gotMessage(i18n("Could not open audio output file %1", g_audioOutputFile));
680 fprintf(stderr, "Could not open audio output file \"%s\"\n", g_audioOutputFile);
685 while (displayModeIterator->Next(&displayMode) == S_OK) {
686 if (g_videoModeIndex == displayModeCount) {
687 BMDDisplayModeSupport result;
688 const char *displayModeName;
690 foundDisplayMode = true;
691 displayMode->GetName(&displayModeName);
692 selectedDisplayMode = displayMode->GetDisplayMode();
694 g_aspect_ratio = (double) displayMode->GetWidth() / (double) displayMode->GetHeight();
696 deckLinkInput->DoesSupportVideoMode(selectedDisplayMode, pixelFormat, bmdVideoInputFlagDefault, &result, NULL);
698 if (result == bmdDisplayModeNotSupported) {
699 emit gotMessage(i18n("The display mode %1 is not supported with the selected pixel format", displayModeName));
700 fprintf(stderr, "The display mode %s is not supported with the selected pixel format\n", displayModeName);
705 if (inputFlags & bmdVideoInputDualStream3D) {
706 if (!(displayMode->GetFlags() & bmdDisplayModeSupports3D)) {
707 emit gotMessage(i18n("The display mode %1 is not supported with 3D", displayModeName));
708 fprintf(stderr, "The display mode %s is not supported with 3D\n", displayModeName);
717 displayMode->Release();
720 if (!foundDisplayMode) {
721 emit gotMessage(i18n("Invalid mode %1 specified", g_videoModeIndex));
722 fprintf(stderr, "Invalid mode %d specified\n", g_videoModeIndex);
727 result = deckLinkInput->EnableVideoInput(selectedDisplayMode, pixelFormat, inputFlags);
728 if (result != S_OK) {
729 emit gotMessage(i18n("Failed to enable video input. Is another application using the card?"));
730 fprintf(stderr, "Failed to enable video input. Is another application using the card?\n");
736 result = deckLinkInput->EnableAudioInput(bmdAudioSampleRate48kHz, g_audioSampleDepth, g_audioChannels);
737 if (result != S_OK) {
742 deckLinkInput->SetScreenPreviewCallback(previewView);
743 result = deckLinkInput->StartStreams();
744 if (result != S_OK) {
745 qDebug() << "/// CAPTURE FAILED....";
746 emit gotMessage(i18n("Capture failed"));
752 // Block main thread until signal occurs
753 /* pthread_mutex_lock(&sleepMutex);
754 pthread_cond_wait(&sleepCond, &sleepMutex);
755 pthread_mutex_unlock(&sleepMutex);*/
760 close(videoOutputFile);
762 close(audioOutputFile);
764 if (displayModeIterator != NULL)
766 displayModeIterator->Release();
767 displayModeIterator = NULL;
770 if (deckLinkInput != NULL)
772 deckLinkInput->Release();
773 deckLinkInput = NULL;
776 if (deckLink != NULL)
782 if (deckLinkIterator != NULL)
783 deckLinkIterator->Release();
787 BmdCaptureHandler::~BmdCaptureHandler()
792 void BmdCaptureHandler::startCapture(const QString &path)
795 QString videopath = path + "_video_" + QString::number(i).rightJustified(4, '0', false) + ".raw";
796 QString audiopath = path + "_audio_" + QString::number(i).rightJustified(4, '0', false) + ".raw";
797 while (QFile::exists(videopath) || QFile::exists(audiopath)) {
799 videopath = path + "_video_" + QString::number(i).rightJustified(4, '0', false) + ".raw";
800 audiopath = path + "_audio_" + QString::number(i).rightJustified(4, '0', false) + ".raw";
802 videoOutputFile = open(videopath.toUtf8().constData(), O_WRONLY | O_CREAT | O_TRUNC, 0664);
803 if (videoOutputFile < 0) {
804 emit gotMessage(i18n("Could not open video output file %1", videopath));
805 fprintf(stderr, "Could not open video output file \"%s\"\n", videopath.toUtf8().constData());
808 /*if (KdenliveSettings::hdmicaptureaudio()) {
809 audioOutputFile = open(audiopath.toUtf8().constData(), O_WRONLY | O_CREAT | O_TRUNC, 0664);
810 if (audioOutputFile < 0) {
811 emit gotMessage(i18n("Could not open audio output file %1", audiopath));
812 fprintf(stderr, "Could not open video output file \"%s\"\n", audiopath.toUtf8().constData());
818 void BmdCaptureHandler::stopCapture()
821 close(videoOutputFile);
823 close(audioOutputFile);
824 videoOutputFile = -1;
825 audioOutputFile = -1;
828 void BmdCaptureHandler::captureFrame(const QString &fname)
830 doCaptureFrame = fname;
833 void BmdCaptureHandler::showOverlay(QImage img, bool transparent)
835 if (previewView) previewView->showOverlay(img, transparent);
838 void BmdCaptureHandler::hideOverlay()
840 if (previewView) previewView->hideOverlay();
843 void BmdCaptureHandler::setDevice(const QString , QString)
847 void BmdCaptureHandler::hidePreview(bool hide)
849 if (previewView) previewView->setHidden(hide);
852 void BmdCaptureHandler::stopPreview()
854 if (!previewView) return;
855 if (deckLinkInput != NULL) deckLinkInput->StopStreams();
857 close(videoOutputFile);
859 close(audioOutputFile);
861 if (displayModeIterator != NULL) {
862 displayModeIterator->Release();
863 displayModeIterator = NULL;
866 if (deckLinkInput != NULL) {
867 deckLinkInput->Release();
868 deckLinkInput = NULL;
871 if (deckLink != NULL) {
876 if (deckLinkIterator != NULL) {
877 deckLinkIterator->Release();
878 deckLinkIterator = NULL;
881 if (previewView != NULL) {
886 /*if (delegate != NULL)