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;
68 void yuv2rgb_int(unsigned char *yuv_buffer, unsigned char *rgb_buffer, int width, int height)
73 int rgb_ptr, y_ptr, t;
75 len = width * height / 2;
80 for(t = 0; t < len; t++) { /* process 2 pixels at a time */
81 /* Compute parts of the UV components */
83 U = yuv_buffer[y_ptr];
84 Y = yuv_buffer[y_ptr+1];
85 V = yuv_buffer[y_ptr+2];
86 Y2 = yuv_buffer[y_ptr+3];
90 /*r = 1.164*(Y-16) + 1.596*(V-128);
91 g = 1.164*(Y-16) - 0.813*(V-128) - 0.391*(U-128);
92 b = 1.164*(Y-16) + 2.018*(U-128);*/
95 r = ((298 * (Y - 16) + 409 * (V - 128) + 128) >> 8);
97 g = ((298 * (Y - 16) - 100 * (U - 128) - 208 * (V - 128) + 128) >> 8);
99 b = ((298 * (Y - 16) + 516 * (U - 128) + 128) >> 8);
109 rgb_buffer[rgb_ptr] = b;
110 rgb_buffer[rgb_ptr+1] = g;
111 rgb_buffer[rgb_ptr+2] = r;
112 rgb_buffer[rgb_ptr+3] = 255;
115 /*r = 1.164*(Y2-16) + 1.596*(V-128);
116 g = 1.164*(Y2-16) - 0.813*(V-128) - 0.391*(U-128);
117 b = 1.164*(Y2-16) + 2.018*(U-128);*/
120 r = ((298 * (Y2 - 16) + 409 * (V - 128) + 128) >> 8);
122 g = ((298 * (Y2 - 16) - 100 * (U - 128) - 208 * (V - 128) + 128) >> 8);
124 b = ((298 * (Y2 - 16) + 516 * (U - 128) + 128) >> 8);
134 rgb_buffer[rgb_ptr] = b;
135 rgb_buffer[rgb_ptr+1] = g;
136 rgb_buffer[rgb_ptr+2] = r;
137 rgb_buffer[rgb_ptr+3] = 255;
143 class CDeckLinkGLWidget : public QGLWidget, public IDeckLinkScreenPreviewCallback
148 IDeckLinkInput* deckLinkIn;
149 IDeckLinkGLScreenPreviewHelper* deckLinkScreenPreviewHelper;
150 IDeckLinkVideoFrame* m_frame;
151 QColor m_backgroundColor;
158 bool m_transparentOverlay;
161 CDeckLinkGLWidget(IDeckLinkInput* deckLinkInput, QWidget* parent);
162 // IDeckLinkScreenPreviewCallback
163 virtual HRESULT QueryInterface(REFIID iid, LPVOID *ppv);
164 virtual ULONG AddRef();
165 virtual ULONG Release();
166 virtual HRESULT DrawFrame(IDeckLinkVideoFrame* theFrame);
167 void showOverlay(QImage img, bool transparent);
173 void resizeGL(int width, int height);
174 /*void initializeOverlayGL();
175 void paintOverlayGL();
176 void resizeOverlayGL(int width, int height);*/
179 CDeckLinkGLWidget::CDeckLinkGLWidget(IDeckLinkInput* deckLinkInput, QWidget* parent) : QGLWidget(/*QGLFormat(QGL::HasOverlay | QGL::AlphaChannel),*/ parent)
180 , m_backgroundColor(KdenliveSettings::window_background())
183 , m_transparentOverlay(true)
186 deckLinkIn = deckLinkInput;
187 deckLinkScreenPreviewHelper = CreateOpenGLScreenPreviewHelper();
190 void CDeckLinkGLWidget::showOverlay(QImage img, bool transparent)
192 m_transparentOverlay = transparent;
193 m_img = convertToGLFormat(img);
194 m_zx = (double)m_pictureWidth / m_img.width();
195 m_zy = (double)m_pictureHeight / m_img.height();
196 if(m_transparentOverlay) {
198 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_COLOR);
204 void CDeckLinkGLWidget::hideOverlay()
210 void CDeckLinkGLWidget::initializeGL()
212 if(deckLinkScreenPreviewHelper != NULL) {
214 deckLinkScreenPreviewHelper->InitializeGL();
215 glShadeModel(GL_FLAT);
216 glDisable(GL_DEPTH_TEST);
217 glDisable(GL_CULL_FACE);
218 glDisable(GL_LIGHTING);
219 glDisable(GL_DITHER);
222 //Documents/images/alpha2.png");//
223 //m_texture = bindTexture(convertToGLFormat(img), GL_TEXTURE_RECTANGLE_EXT, GL_RGBA8, QGLContext::LinearFilteringBindOption);
228 /*void CDeckLinkGLWidget::initializeOverlayGL ()
231 glEnable(GL_TEXTURE_RECTANGLE_EXT);
235 void CDeckLinkGLWidget::paintOverlayGL()
237 makeOverlayCurrent();
239 //glClearDepth(0.5f);
240 //glPixelTransferf(GL_ALPHA_SCALE, 10);
241 //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
246 void CDeckLinkGLWidget::paintGL()
250 qglClearColor(m_backgroundColor);
251 //glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
252 glClear(GL_COLOR_BUFFER_BIT);
253 deckLinkScreenPreviewHelper->PaintGL();
254 if(!m_img.isNull()) {
255 glPixelZoom(m_zx, m_zy);
256 glDrawPixels(m_img.width(), m_img.height(), GL_RGBA, GL_UNSIGNED_BYTE, m_img.bits());
261 void CDeckLinkGLWidget::paintEvent(QPaintEvent *event)
265 QRect r = event->rect();
268 m_frame->GetBytes(&frameBytes);
269 QImage img((uchar*)frameBytes, m_frame->GetWidth(), m_frame->GetHeight(), QImage::Format_ARGB32);//m_frame->GetPixelFormat());
270 QRectF re(0, 0, width(), height());
271 p.drawImage(re, img);
276 void CDeckLinkGLWidget::resizeGL(int width, int height)
279 m_pictureHeight = height;
280 m_pictureWidth = width;
281 int calculatedWidth = g_aspect_ratio * height;
282 if(calculatedWidth > width) m_pictureHeight = width / g_aspect_ratio;
284 int calculatedHeight = width / g_aspect_ratio;
285 if(calculatedHeight > height) m_pictureWidth = height * g_aspect_ratio;
287 glViewport((width - m_pictureWidth) / 2, (height - m_pictureHeight) / 2, m_pictureWidth, m_pictureHeight);
288 glMatrixMode(GL_PROJECTION);
290 glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
291 glMatrixMode(GL_MODELVIEW);
292 glRasterPos2i(-1, -1);
293 if(!m_img.isNull()) {
294 m_zx = (double)m_pictureWidth / m_img.width();
295 m_zy = (double)m_pictureHeight / m_img.height();
301 /*void CDeckLinkGLWidget::resizeOverlayGL ( int width, int height )
303 int newwidth = width;
304 int newheight = height;
305 int calculatedWidth = g_aspect_ratio * height;
306 if (calculatedWidth > width) newheight = width / g_aspect_ratio;
308 int calculatedHeight = width / g_aspect_ratio;
309 if (calculatedHeight > height) newwidth = height * g_aspect_ratio;
311 glViewport((width - newwidth) / 2, (height - newheight) / 2, newwidth, newheight);
312 glMatrixMode(GL_PROJECTION);
314 glOrtho(0, width, 0, height, -1.0, 1.0);
315 glMatrixMode(GL_MODELVIEW);
319 HRESULT CDeckLinkGLWidget::QueryInterface(REFIID iid, LPVOID *ppv)
323 return E_NOINTERFACE;
326 ULONG CDeckLinkGLWidget::AddRef()
330 oldValue = refCount.fetchAndAddAcquire(1);
331 return (ULONG)(oldValue + 1);
334 ULONG CDeckLinkGLWidget::Release()
338 oldValue = refCount.fetchAndAddAcquire(-1);
343 return (ULONG)(oldValue - 1);
346 HRESULT CDeckLinkGLWidget::DrawFrame(IDeckLinkVideoFrame* theFrame)
348 if(deckLinkScreenPreviewHelper != NULL && theFrame != NULL) {
352 deckLinkScreenPreviewHelper->SetFrame(theFrame);
359 DeckLinkCaptureDelegate::DeckLinkCaptureDelegate() : m_refCount(0)
361 pthread_mutex_init(&m_mutex, NULL);
364 DeckLinkCaptureDelegate::~DeckLinkCaptureDelegate()
366 pthread_mutex_destroy(&m_mutex);
369 ULONG DeckLinkCaptureDelegate::AddRef(void)
371 pthread_mutex_lock(&m_mutex);
373 pthread_mutex_unlock(&m_mutex);
375 return (ULONG)m_refCount;
378 ULONG DeckLinkCaptureDelegate::Release(void)
380 pthread_mutex_lock(&m_mutex);
382 pthread_mutex_unlock(&m_mutex);
384 if(m_refCount == 0) {
389 return (ULONG)m_refCount;
392 HRESULT DeckLinkCaptureDelegate::VideoInputFrameArrived(IDeckLinkVideoInputFrame* videoFrame, IDeckLinkAudioInputPacket* audioFrame)
394 IDeckLinkVideoFrame* rightEyeFrame = NULL;
395 IDeckLinkVideoFrame3DExtensions* threeDExtensions = NULL;
397 void* audioFrameBytes;
399 // Handle Video Frame
401 // If 3D mode is enabled we retreive the 3D extensions interface which gives.
402 // us access to the right eye frame by calling GetFrameForRightEye() .
403 if((videoFrame->QueryInterface(IID_IDeckLinkVideoFrame3DExtensions, (void **) &threeDExtensions) != S_OK) ||
404 (threeDExtensions->GetFrameForRightEye(&rightEyeFrame) != S_OK)) {
405 rightEyeFrame = NULL;
408 if(videoFrame->GetFlags() & bmdFrameHasNoInputSource) {
409 emit gotMessage(i18n("Frame (%1) - No input signal", frameCount));
410 fprintf(stderr, "Frame received (#%lu) - No input signal detected\n", frameCount);
412 const char *timecodeString = NULL;
413 if(g_timecodeFormat != 0) {
414 IDeckLinkTimecode *timecode;
415 if(videoFrame->GetTimecode(g_timecodeFormat, &timecode) == S_OK) {
416 timecode->GetString(&timecodeString);
419 // There seems to be No timecode with HDMI... Using frame number
420 emit gotTimeCode(frameCount);
421 /*fprintf(stderr, "Frame received (#%lu) [%s] - %s - Size: %li bytes\n",
423 timecodeString != NULL ? timecodeString : "No timecode",
424 rightEyeFrame != NULL ? "Valid Frame (3D left/right)" : "Valid Frame",
425 videoFrame->GetRowBytes() * videoFrame->GetHeight());*/
428 free((void*)timecodeString);
430 if(!doCaptureFrame.isEmpty()) {
431 videoFrame->GetBytes(&frameBytes);
432 if(doCaptureFrame.endsWith("raw")) {
433 // Save as raw uyvy422 imgage
434 videoOutputFile = open(doCaptureFrame.toUtf8().constData(), O_WRONLY | O_CREAT/*|O_TRUNC*/, 0664);
435 write(videoOutputFile, frameBytes, videoFrame->GetRowBytes() * videoFrame->GetHeight());
436 close(videoOutputFile);
437 emit frameSaved(doCaptureFrame);
439 QImage image(videoFrame->GetWidth(), videoFrame->GetHeight(), QImage::Format_ARGB32_Premultiplied);
440 //convert from uyvy422 to rgba
441 yuv2rgb_int((uchar *)frameBytes, (uchar *)image.bits(), videoFrame->GetWidth(), videoFrame->GetHeight());
442 image.save(doCaptureFrame);
443 emit frameSaved(doCaptureFrame);
445 doCaptureFrame.clear();
448 if(videoOutputFile != -1) {
449 videoFrame->GetBytes(&frameBytes);
450 write(videoOutputFile, frameBytes, videoFrame->GetRowBytes() * videoFrame->GetHeight());
453 rightEyeFrame->GetBytes(&frameBytes);
454 write(videoOutputFile, frameBytes, videoFrame->GetRowBytes() * videoFrame->GetHeight());
460 if(g_maxFrames > 0 && frameCount >= g_maxFrames) {
461 pthread_cond_signal(&sleepCond);
465 // Handle Audio Frame
467 if(audioOutputFile != -1) {
468 audioFrame->GetBytes(&audioFrameBytes);
469 write(audioOutputFile, audioFrameBytes, audioFrame->GetSampleFrameCount() * g_audioChannels *(g_audioSampleDepth / 8));
475 HRESULT DeckLinkCaptureDelegate::VideoInputFormatChanged(BMDVideoInputFormatChangedEvents events, IDeckLinkDisplayMode *mode, BMDDetectedVideoInputFormatFlags)
482 /*int usage(int status)
485 IDeckLinkDisplayMode *displayMode;
486 int displayModeCount = 0;
489 "Usage: Capture -m <mode id> [OPTIONS]\n"
494 while (displayModeIterator->Next(&displayMode) == S_OK)
496 char * displayModeString = NULL;
498 result = displayMode->GetName((const char **) &displayModeString);
501 BMDTimeValue frameRateDuration, frameRateScale;
502 displayMode->GetFrameRate(&frameRateDuration, &frameRateScale);
504 fprintf(stderr, " %2d: %-20s \t %li x %li \t %g FPS\n",
505 displayModeCount, displayModeString, displayMode->GetWidth(), displayMode->GetHeight(), (double)frameRateScale / (double)frameRateDuration);
507 free(displayModeString);
511 // Release the IDeckLinkDisplayMode object to prevent a leak
512 displayMode->Release();
516 " -p <pixelformat>\n"
517 " 0: 8 bit YUV (4:2:2) (default)\n"
518 " 1: 10 bit YUV (4:2:2)\n"
519 " 2: 10 bit RGB (4:4:4)\n"
520 " -t <format> Print timecode\n"
523 " serial: Serial Timecode\n"
524 " -f <filename> Filename raw video will be written to\n"
525 " -a <filename> Filename raw audio will be written to\n"
526 " -c <channels> Audio Channels (2, 8 or 16 - default is 2)\n"
527 " -s <depth> Audio Sample Depth (16 or 32 - default is 16)\n"
528 " -n <frames> Number of frames to capture (default is unlimited)\n"
529 " -3 Capture Stereoscopic 3D (Requires 3D Hardware support)\n"
531 "Capture video and/or audio to a file. Raw video and/or audio can be viewed with mplayer eg:\n"
533 " Capture -m2 -n 50 -f video.raw -a audio.raw\n"
534 " mplayer video.raw -demuxer rawvideo -rawvideo pal:uyvy -audiofile audio.raw -audio-demuxer 20 -rawaudio rate=48000\n"
544 BmdCaptureHandler::BmdCaptureHandler(QVBoxLayout *lay, QWidget *parent):
545 CaptureHandler(lay, parent),
547 deckLinkIterator(NULL),
552 displayModeIterator(NULL)
556 void BmdCaptureHandler::startPreview(int deviceId, int captureMode)
558 deckLinkIterator = CreateDeckLinkIteratorInstance();
559 BMDVideoInputFlags inputFlags = 0;
560 BMDDisplayMode selectedDisplayMode = bmdModeNTSC;
561 BMDPixelFormat pixelFormat = bmdFormat8BitYUV;
562 int displayModeCount = 0;
565 bool foundDisplayMode = false;
568 /*pthread_mutex_init(&sleepMutex, NULL);
569 pthread_cond_init(&sleepCond, NULL);*/
570 kDebug() << "/// INIT CAPTURE ON DEV: " << deviceId;
572 if(!deckLinkIterator) {
573 emit gotMessage(i18n("This application requires the DeckLink drivers installed."));
574 fprintf(stderr, "This application requires the DeckLink drivers installed.\n");
579 /* Connect to selected DeckLink instance */
580 for(int i = 0; i < deviceId + 1; i++)
581 result = deckLinkIterator->Next(&deckLink);
583 fprintf(stderr, "No DeckLink PCI cards found.\n");
584 emit gotMessage(i18n("No DeckLink PCI cards found."));
589 if(deckLink->QueryInterface(IID_IDeckLinkInput, (void**)&deckLinkInput) != S_OK) {
594 delegate = new DeckLinkCaptureDelegate();
595 connect(delegate, SIGNAL(gotTimeCode(ulong)), this, SIGNAL(gotTimeCode(ulong)));
596 connect(delegate, SIGNAL(gotMessage(const QString &)), this, SIGNAL(gotMessage(const QString &)));
597 connect(delegate, SIGNAL(frameSaved(const QString)), this, SIGNAL(frameSaved(const QString)));
598 deckLinkInput->SetCallback(delegate);
600 previewView = new CDeckLinkGLWidget(deckLinkInput, m_parent);
601 m_layout->addWidget(previewView);
602 //previewView->resize(parent->size());
603 previewView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
604 previewView->DrawFrame(NULL);
606 // Obtain an IDeckLinkDisplayModeIterator to enumerate the display modes supported on output
607 result = deckLinkInput->GetDisplayModeIterator(&displayModeIterator);
609 emit gotMessage(i18n("Could not obtain the video output display mode iterator - result = ", result));
610 fprintf(stderr, "Could not obtain the video output display mode iterator - result = %08x\n", result);
615 g_videoModeIndex = captureMode;
616 /*g_audioChannels = 2;
617 g_audioSampleDepth = 16;*/
619 // Parse command line options
620 /*while ((ch = getopt(argc, argv, "?h3c:s:f:a:m:n:p:t:")) != -1)
625 g_videoModeIndex = atoi(optarg);
628 g_audioChannels = atoi(optarg);
629 if (g_audioChannels != 2 &&
630 g_audioChannels != 8 &&
631 g_audioChannels != 16)
633 fprintf(stderr, "Invalid argument: Audio Channels must be either 2, 8 or 16\n");
638 g_audioSampleDepth = atoi(optarg);
639 if (g_audioSampleDepth != 16 && g_audioSampleDepth != 32)
641 fprintf(stderr, "Invalid argument: Audio Sample Depth must be either 16 bits or 32 bits\n");
646 g_videoOutputFile = optarg;
649 g_audioOutputFile = optarg;
652 g_maxFrames = atoi(optarg);
655 inputFlags |= bmdVideoInputDualStream3D;
660 case 0: pixelFormat = bmdFormat8BitYUV; break;
661 case 1: pixelFormat = bmdFormat10BitYUV; break;
662 case 2: pixelFormat = bmdFormat10BitRGB; break;
664 fprintf(stderr, "Invalid argument: Pixel format %d is not valid", atoi(optarg));
669 if (!strcmp(optarg, "rp188"))
670 g_timecodeFormat = bmdTimecodeRP188;
671 else if (!strcmp(optarg, "vitc"))
672 g_timecodeFormat = bmdTimecodeVITC;
673 else if (!strcmp(optarg, "serial"))
674 g_timecodeFormat = bmdTimecodeSerial;
677 fprintf(stderr, "Invalid argument: Timecode format \"%s\" is invalid\n", optarg);
687 if(g_videoModeIndex < 0) {
688 emit gotMessage(i18n("No video mode specified"));
689 fprintf(stderr, "No video mode specified\n");
694 /*if (g_videoOutputFile != NULL)
696 videoOutputFile = open(g_videoOutputFile, O_WRONLY|O_CREAT|O_TRUNC, 0664);
697 if (videoOutputFile < 0)
699 emit gotMessage(i18n("Could not open video output file %1", g_videoOutputFile));
700 fprintf(stderr, "Could not open video output file \"%s\"\n", g_videoOutputFile);
704 if (g_audioOutputFile != NULL)
706 audioOutputFile = open(g_audioOutputFile, O_WRONLY|O_CREAT|O_TRUNC, 0664);
707 if (audioOutputFile < 0)
709 emit gotMessage(i18n("Could not open audio output file %1", g_audioOutputFile));
710 fprintf(stderr, "Could not open audio output file \"%s\"\n", g_audioOutputFile);
715 while(displayModeIterator->Next(&displayMode) == S_OK) {
716 if(g_videoModeIndex == displayModeCount) {
717 BMDDisplayModeSupport result;
718 const char *displayModeName;
720 foundDisplayMode = true;
721 displayMode->GetName(&displayModeName);
722 selectedDisplayMode = displayMode->GetDisplayMode();
724 g_aspect_ratio = (double) displayMode->GetWidth() / (double) displayMode->GetHeight();
726 deckLinkInput->DoesSupportVideoMode(selectedDisplayMode, pixelFormat, bmdVideoInputFlagDefault, &result, NULL);
728 if(result == bmdDisplayModeNotSupported) {
729 emit gotMessage(i18n("The display mode %1 is not supported with the selected pixel format", displayModeName));
730 fprintf(stderr, "The display mode %s is not supported with the selected pixel format\n", displayModeName);
735 if(inputFlags & bmdVideoInputDualStream3D) {
736 if(!(displayMode->GetFlags() & bmdDisplayModeSupports3D)) {
737 emit gotMessage(i18n("The display mode %1 is not supported with 3D", displayModeName));
738 fprintf(stderr, "The display mode %s is not supported with 3D\n", displayModeName);
747 displayMode->Release();
750 if(!foundDisplayMode) {
751 emit gotMessage(i18n("Invalid mode %1 specified", g_videoModeIndex));
752 fprintf(stderr, "Invalid mode %d specified\n", g_videoModeIndex);
757 result = deckLinkInput->EnableVideoInput(selectedDisplayMode, pixelFormat, inputFlags);
759 emit gotMessage(i18n("Failed to enable video input. Is another application using the card?"));
760 fprintf(stderr, "Failed to enable video input. Is another application using the card?\n");
765 result = deckLinkInput->EnableAudioInput(bmdAudioSampleRate48kHz, g_audioSampleDepth, g_audioChannels);
770 deckLinkInput->SetScreenPreviewCallback(previewView);
771 result = deckLinkInput->StartStreams();
773 qDebug() << "/// CAPTURE FAILED....";
774 emit gotMessage(i18n("Capture failed"));
780 // Block main thread until signal occurs
781 /* pthread_mutex_lock(&sleepMutex);
782 pthread_cond_wait(&sleepCond, &sleepMutex);
783 pthread_mutex_unlock(&sleepMutex);*/
788 close(videoOutputFile);
790 close(audioOutputFile);
792 if (displayModeIterator != NULL)
794 displayModeIterator->Release();
795 displayModeIterator = NULL;
798 if (deckLinkInput != NULL)
800 deckLinkInput->Release();
801 deckLinkInput = NULL;
804 if (deckLink != NULL)
810 if (deckLinkIterator != NULL)
811 deckLinkIterator->Release();
815 BmdCaptureHandler::~BmdCaptureHandler()
820 void BmdCaptureHandler::startCapture(const QString &path)
823 QString videopath = path + "_video_" + QString::number(i).rightJustified(4, '0', false) + ".raw";
824 QString audiopath = path + "_audio_" + QString::number(i).rightJustified(4, '0', false) + ".raw";
825 while(QFile::exists(videopath) || QFile::exists(audiopath)) {
827 videopath = path + "_video_" + QString::number(i).rightJustified(4, '0', false) + ".raw";
828 audiopath = path + "_audio_" + QString::number(i).rightJustified(4, '0', false) + ".raw";
830 videoOutputFile = open(videopath.toUtf8().constData(), O_WRONLY | O_CREAT | O_TRUNC, 0664);
831 if(videoOutputFile < 0) {
832 emit gotMessage(i18n("Could not open video output file %1", videopath));
833 fprintf(stderr, "Could not open video output file \"%s\"\n", videopath.toUtf8().constData());
836 if(KdenliveSettings::hdmicaptureaudio()) {
837 audioOutputFile = open(audiopath.toUtf8().constData(), O_WRONLY | O_CREAT | O_TRUNC, 0664);
838 if(audioOutputFile < 0) {
839 emit gotMessage(i18n("Could not open audio output file %1", audiopath));
840 fprintf(stderr, "Could not open video output file \"%s\"\n", audiopath.toUtf8().constData());
846 void BmdCaptureHandler::stopCapture()
849 close(videoOutputFile);
851 close(audioOutputFile);
852 videoOutputFile = -1;
853 audioOutputFile = -1;
856 void BmdCaptureHandler::captureFrame(const QString &fname)
858 doCaptureFrame = fname;
861 void BmdCaptureHandler::showOverlay(QImage img, bool transparent)
863 if(previewView) previewView->showOverlay(img, transparent);
866 void BmdCaptureHandler::hideOverlay()
868 if(previewView) previewView->hideOverlay();
871 void BmdCaptureHandler::hidePreview(bool hide)
873 if(previewView) previewView->setHidden(hide);
876 void BmdCaptureHandler::stopPreview()
878 if(!previewView) return;
879 if(deckLinkInput != NULL) deckLinkInput->StopStreams();
881 close(videoOutputFile);
883 close(audioOutputFile);
885 if(displayModeIterator != NULL) {
886 displayModeIterator->Release();
887 displayModeIterator = NULL;
890 if(deckLinkInput != NULL) {
891 deckLinkInput->Release();
892 deckLinkInput = NULL;
895 if(deckLink != NULL) {
900 if(deckLinkIterator != NULL) {
901 deckLinkIterator->Release();
902 deckLinkIterator = NULL;
905 if(previewView != NULL) {
910 /*if (delegate != NULL)