]> git.sesse.net Git - kdenlive/blob - src/blackmagic/devices.cpp
7277c6c3f7dc21306c0864dd491a2c4dd9b854d7
[kdenlive] / src / blackmagic / devices.cpp
1 /***************************************************************************
2  *   Copyright (C) 2007 by Jean-Baptiste Mardelle (jb@kdenlive.org)        *
3  *                                                                         *
4  *   This program is free software; you can redistribute it and/or modify  *
5  *   it under the terms of the GNU General Public License as published by  *
6  *   the Free Software Foundation; either version 2 of the License, or     *
7  *   (at your option) any later version.                                   *
8  *                                                                         *
9  *   This program is distributed in the hope that it will be useful,       *
10  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
12  *   GNU General Public License for more details.                          *
13  *                                                                         *
14  *   You should have received a copy of the GNU General Public License     *
15  *   along with this program; if not, write to the                         *
16  *   Free Software Foundation, Inc.,                                       *
17  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
18  ***************************************************************************/
19
20
21 #include "devices.h"
22
23 #include <KDebug>
24 #include <KLocale>
25
26
27 BMInterface::BMInterface()
28 {
29 }
30
31 //static
32 bool BMInterface::getBlackMagicDeviceList(KComboBox *devicelist, KComboBox *modelist)
33 {
34     IDeckLinkIterator* deckLinkIterator;
35     IDeckLink* deckLink;
36     int numDevices = 0;
37     HRESULT result;
38     bool found = false;
39
40     // Create an IDeckLinkIterator object to enumerate all DeckLink cards in the system
41     deckLinkIterator = CreateDeckLinkIteratorInstance();
42     if(deckLinkIterator == NULL) {
43         kDebug() << "A DeckLink iterator could not be created.  The DeckLink drivers may not be installed.";
44         return found;
45     }
46
47     // Enumerate all cards in this system
48     while(deckLinkIterator->Next(&deckLink) == S_OK) {
49         char *      deviceNameString = NULL;
50
51         //if (numDevices > 1)
52         kDebug() << "// FOUND a BM device\n\n+++++++++++++++++++++++++++++++++++++";
53
54         // *** Print the model name of the DeckLink card
55         result = deckLink->GetModelName((const char **) &deviceNameString);
56         if(result == S_OK) {
57             QString deviceName(deviceNameString);
58             free(deviceNameString);
59
60             IDeckLinkInput*                 deckLinkInput = NULL;
61             IDeckLinkDisplayModeIterator*       displayModeIterator = NULL;
62             IDeckLinkDisplayMode*               displayMode = NULL;
63             HRESULT                             result;
64
65             // Query the DeckLink for its configuration interface
66             result = deckLink->QueryInterface(IID_IDeckLinkInput, (void**)&deckLinkInput);
67             if(result != S_OK) {
68                 kDebug() << "Could not obtain the IDeckLinkInput interface - result = " << result;
69                 return found;
70             }
71
72             // Obtain an IDeckLinkDisplayModeIterator to enumerate the display modes supported on output
73             result = deckLinkInput->GetDisplayModeIterator(&displayModeIterator);
74             if(result != S_OK) {
75                 kDebug() << "Could not obtain the video input display mode iterator - result = " << result;
76                 return found;
77             }
78             QStringList availableModes;
79             // List all supported output display modes
80             while(displayModeIterator->Next(&displayMode) == S_OK) {
81                 char *          displayModeString = NULL;
82
83                 result = displayMode->GetName((const char **) &displayModeString);
84                 if(result == S_OK) {
85                     //char                  modeName[64];
86                     int                     modeWidth;
87                     int                     modeHeight;
88                     BMDTimeValue            frameRateDuration;
89                     BMDTimeScale            frameRateScale;
90                     //int                       pixelFormatIndex = 0; // index into the gKnownPixelFormats / gKnownFormatNames arrays
91                     //BMDDisplayModeSupport displayModeSupport;
92
93
94                     // Obtain the display mode's properties
95                     modeWidth = displayMode->GetWidth();
96                     modeHeight = displayMode->GetHeight();
97                     displayMode->GetFrameRate(&frameRateDuration, &frameRateScale);
98                     QString description = QString(displayModeString) + " (" + QString::number(modeWidth) + "x" + QString::number(modeHeight) + " - " + QString::number((double)frameRateScale / (double)frameRateDuration) + i18n("fps") + ")";
99                     availableModes << description;
100                     //modelist->addItem(description);
101                     //printf(" %-20s \t %d x %d \t %7g FPS\t", displayModeString, modeWidth, modeHeight, (double)frameRateScale / (double)frameRateDuration);
102
103                     // Print the supported pixel formats for this display mode
104                     /*while ((gKnownPixelFormats[pixelFormatIndex] != 0) && (gKnownPixelFormatNames[pixelFormatIndex] != NULL))
105                     {
106                         if ((deckLinkOutput->DoesSupportVideoMode(displayMode->GetDisplayMode(), gKnownPixelFormats[pixelFormatIndex], bmdVideoOutputFlagDefault, &displayModeSupport, NULL) == S_OK)
107                             && (displayModeSupport != bmdDisplayModeNotSupported))
108                         {
109                             printf("%s\t", gKnownPixelFormatNames[pixelFormatIndex]);
110                         }
111                         pixelFormatIndex++;
112                     }*/
113                     free(displayModeString);
114                 }
115
116                 // Release the IDeckLinkDisplayMode object to prevent a leak
117                 displayMode->Release();
118             }
119             devicelist->addItem(deviceName, availableModes);
120             devicelist->setItemData(devicelist->count() - 1, numDevices, Qt::UserRole + 1);
121             found = true;
122         }
123
124
125         //print_attributes(deckLink);
126
127         // ** List the video output display modes supported by the card
128         //print_output_modes(deckLink);
129
130         // ** List the input and output capabilities of the card
131         //print_capabilities(deckLink);
132
133         // Release the IDeckLink instance when we've finished with it to prevent leaks
134         deckLink->Release();
135         
136         // Increment the total number of DeckLink cards found
137         numDevices++;
138     }
139
140     deckLinkIterator->Release();
141     if(modelist != NULL && devicelist->count() > 0) {
142         QStringList modes = devicelist->itemData(devicelist->currentIndex()).toStringList();
143         modelist->insertItems(0, modes);
144     }
145     return found;
146 }
147
148 //static
149 bool BMInterface::getBlackMagicOutputDeviceList(KComboBox *devicelist)
150 {
151     IDeckLinkIterator* deckLinkIterator;
152     IDeckLink* deckLink;
153     int numDevices = 0;
154     HRESULT result;
155     bool found = false;
156
157     // Create an IDeckLinkIterator object to enumerate all DeckLink cards in the system
158     deckLinkIterator = CreateDeckLinkIteratorInstance();
159     if(deckLinkIterator == NULL) {
160         kDebug() << "A DeckLink iterator could not be created.  The DeckLink drivers may not be installed.";
161         return found;
162     }
163
164     // Enumerate all cards in this system
165     while(deckLinkIterator->Next(&deckLink) == S_OK) {
166         char *      deviceNameString = NULL;
167
168         kDebug() << "// FOUND a BM device\n\n+++++++++++++++++++++++++++++++++++++";
169
170         // *** Print the model name of the DeckLink card
171         result = deckLink->GetModelName((const char **) &deviceNameString);
172         if(result == S_OK) {
173             QString deviceName(deviceNameString);
174             free(deviceNameString);
175
176             IDeckLinkOutput*                 deckLinkOutput = NULL;
177             IDeckLinkDisplayModeIterator*       displayModeIterator = NULL;
178             //IDeckLinkDisplayMode*               displayMode = NULL;
179             HRESULT                             result;
180
181             // Query the DeckLink for its configuration interface
182             result = deckLink->QueryInterface(IID_IDeckLinkInput, (void**)&deckLinkOutput);
183             if(result != S_OK) {
184                 kDebug() << "Could not obtain the IDeckLinkInput interface - result = " << result;
185                 return found;
186             }
187
188             // Obtain an IDeckLinkDisplayModeIterator to enumerate the display modes supported on output
189             result = deckLinkOutput->GetDisplayModeIterator(&displayModeIterator);
190             if(result != S_OK) {
191                 kDebug() << "Could not obtain the video input display mode iterator - result = " << result;
192                 return found;
193             }
194             /*QStringList availableModes;
195             // List all supported output display modes
196             while(displayModeIterator->Next(&displayMode) == S_OK) {
197                 char *          displayModeString = NULL;
198
199                 result = displayMode->GetName((const char **) &displayModeString);
200                 if(result == S_OK) {
201                     //char                  modeName[64];
202                     int                     modeWidth;
203                     int                     modeHeight;
204                     BMDTimeValue            frameRateDuration;
205                     BMDTimeScale            frameRateScale;
206                     //int                       pixelFormatIndex = 0; // index into the gKnownPixelFormats / gKnownFormatNames arrays
207                     //BMDDisplayModeSupport displayModeSupport;
208
209
210                     // Obtain the display mode's properties
211                     modeWidth = displayMode->GetWidth();
212                     modeHeight = displayMode->GetHeight();
213                     displayMode->GetFrameRate(&frameRateDuration, &frameRateScale);
214                     QString description = QString(displayModeString) + " (" + QString::number(modeWidth) + "x" + QString::number(modeHeight) + " - " + QString::number((double)frameRateScale / (double)frameRateDuration) + i18n("fps") + ")";
215                     description.append(" " + QString::number(modeWidth) + ":" + QString::number(modeHeight) + ":" + QString::number(frameRateScale) + ":" + QString::number(frameRateDuration) + ":" + QString::number(displayMode->GetFieldDominance() == bmdProgressiveFrame));
216                     availableModes << description;
217                     free(displayModeString);
218                 }
219
220                 // Release the IDeckLinkDisplayMode object to prevent a leak
221                 displayMode->Release();
222             }*/
223             devicelist->addItem(deviceName, numDevices++);
224             found = true;
225         }
226
227         // Release the IDeckLink instance when we've finished with it to prevent leaks
228         deckLink->Release();
229     }
230
231     deckLinkIterator->Release();
232     return found;
233 }
234
235 //static
236 bool BMInterface::isSupportedProfile(int card, QMap< QString, QString > properties)
237 {
238     IDeckLinkIterator* deckLinkIterator;
239     IDeckLink* deckLink;
240     HRESULT result;
241     bool found = false;
242
243     // Create an IDeckLinkIterator object to enumerate all DeckLink cards in the system
244     deckLinkIterator = CreateDeckLinkIteratorInstance();
245     if(deckLinkIterator == NULL) {
246         kDebug() << "A DeckLink iterator could not be created.  The DeckLink drivers may not be installed.";
247         return false;
248     }
249
250     while(card >= 0 && deckLinkIterator->Next(&deckLink) == S_OK) {
251         card --;
252     }
253
254     IDeckLinkOutput*                 deckLinkOutput = NULL;
255     IDeckLinkDisplayModeIterator*       displayModeIterator = NULL;
256     IDeckLinkDisplayMode*               displayMode = NULL;
257
258     // Query the DeckLink for its configuration interface
259     result = deckLink->QueryInterface(IID_IDeckLinkInput, (void**)&deckLinkOutput);
260     if(result != S_OK) {
261         kDebug() << "Could not obtain the IDeckLinkInput interface - result = " << result;
262         return false;
263     }
264
265     // Obtain an IDeckLinkDisplayModeIterator to enumerate the display modes supported on output
266     result = deckLinkOutput->GetDisplayModeIterator(&displayModeIterator);
267     if(result != S_OK) {
268         kDebug() << "Could not obtain the video input display mode iterator - result = " << result;
269         return false;
270     }
271     // List all supported output display modes
272     BMDTimeValue            frameRateDuration;
273     BMDTimeScale            frameRateScale;
274     
275     while(displayModeIterator->Next(&displayMode) == S_OK) {
276         if (displayMode->GetWidth() == properties.value("width").toInt() && displayMode->GetHeight() == properties.value("height").toInt()) {
277             int progressive = displayMode->GetFieldDominance() == bmdProgressiveFrame;
278             if (progressive == properties.value("progressive").toInt()) {
279                 displayMode->GetFrameRate(&frameRateDuration, &frameRateScale);
280                 if (frameRateScale / properties.value("frame_rate_num").toDouble() * properties.value("frame_rate_den").toDouble() == frameRateDuration) {
281                     found = true;
282                     break;
283                 }
284             }
285         }
286         displayMode->Release();
287     }
288
289     deckLink->Release();
290     deckLinkIterator->Release();
291     return found;
292 }
293
294
295 //static
296 QStringList BMInterface::supportedModes(int card)
297 {
298     IDeckLinkIterator* deckLinkIterator;
299     IDeckLink* deckLink;
300     HRESULT result;
301     QStringList modes;
302
303     // Create an IDeckLinkIterator object to enumerate all DeckLink cards in the system
304     deckLinkIterator = CreateDeckLinkIteratorInstance();
305     if(deckLinkIterator == NULL) {
306         kDebug() << "A DeckLink iterator could not be created.  The DeckLink drivers may not be installed.";
307         return modes;
308     }
309
310     while(card >= 0 && deckLinkIterator->Next(&deckLink) == S_OK) {
311         card --;
312     }
313
314     IDeckLinkOutput*                 deckLinkOutput = NULL;
315     IDeckLinkDisplayModeIterator*       displayModeIterator = NULL;
316     IDeckLinkDisplayMode*               displayMode = NULL;
317
318     // Query the DeckLink for its configuration interface
319     result = deckLink->QueryInterface(IID_IDeckLinkInput, (void**)&deckLinkOutput);
320     if(result != S_OK) {
321         kDebug() << "Could not obtain the IDeckLinkInput interface - result = " << result;
322         return modes;
323     }
324
325     // Obtain an IDeckLinkDisplayModeIterator to enumerate the display modes supported on output
326     result = deckLinkOutput->GetDisplayModeIterator(&displayModeIterator);
327     if(result != S_OK) {
328         kDebug() << "Could not obtain the video input display mode iterator - result = " << result;
329         return modes;
330     }
331
332     while(displayModeIterator->Next(&displayMode) == S_OK) {
333         char *          displayModeString = NULL;
334         result = displayMode->GetName((const char **) &displayModeString);
335         if(result == S_OK) {
336             QString description = QString(displayModeString);
337             modes.append(description);
338             free(displayModeString);
339         }
340         // Release the IDeckLinkDisplayMode object to prevent a leak
341         displayMode->Release();
342     }
343
344     deckLink->Release();
345     deckLinkIterator->Release();
346     return modes;
347 }
348