]> git.sesse.net Git - kdenlive/blob - src/blackmagic/devices.cpp
First steps to support MLT's new Blackmagic's consumer (means external video display...
[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         // Increment the total number of DeckLink cards found
52         numDevices++;
53         //if (numDevices > 1)
54         kDebug() << "// FOUND a BM device\n\n+++++++++++++++++++++++++++++++++++++";
55
56         // *** Print the model name of the DeckLink card
57         result = deckLink->GetModelName((const char **) &deviceNameString);
58         if(result == S_OK) {
59             QString deviceName(deviceNameString);
60             free(deviceNameString);
61
62             IDeckLinkInput*                 deckLinkInput = NULL;
63             IDeckLinkDisplayModeIterator*       displayModeIterator = NULL;
64             IDeckLinkDisplayMode*               displayMode = NULL;
65             HRESULT                             result;
66
67             // Query the DeckLink for its configuration interface
68             result = deckLink->QueryInterface(IID_IDeckLinkInput, (void**)&deckLinkInput);
69             if(result != S_OK) {
70                 kDebug() << "Could not obtain the IDeckLinkInput interface - result = " << result;
71                 return found;
72             }
73
74             // Obtain an IDeckLinkDisplayModeIterator to enumerate the display modes supported on output
75             result = deckLinkInput->GetDisplayModeIterator(&displayModeIterator);
76             if(result != S_OK) {
77                 kDebug() << "Could not obtain the video input display mode iterator - result = " << result;
78                 return found;
79             }
80             QStringList availableModes;
81             // List all supported output display modes
82             while(displayModeIterator->Next(&displayMode) == S_OK) {
83                 char *          displayModeString = NULL;
84
85                 result = displayMode->GetName((const char **) &displayModeString);
86                 if(result == S_OK) {
87                     //char                  modeName[64];
88                     int                     modeWidth;
89                     int                     modeHeight;
90                     BMDTimeValue            frameRateDuration;
91                     BMDTimeScale            frameRateScale;
92                     //int                       pixelFormatIndex = 0; // index into the gKnownPixelFormats / gKnownFormatNames arrays
93                     //BMDDisplayModeSupport displayModeSupport;
94
95
96                     // Obtain the display mode's properties
97                     modeWidth = displayMode->GetWidth();
98                     modeHeight = displayMode->GetHeight();
99                     displayMode->GetFrameRate(&frameRateDuration, &frameRateScale);
100                     QString description = QString(displayModeString) + " (" + QString::number(modeWidth) + "x" + QString::number(modeHeight) + " - " + QString::number((double)frameRateScale / (double)frameRateDuration) + i18n("fps") + ")";
101                     availableModes << description;
102                     //modelist->addItem(description);
103                     //printf(" %-20s \t %d x %d \t %7g FPS\t", displayModeString, modeWidth, modeHeight, (double)frameRateScale / (double)frameRateDuration);
104
105                     // Print the supported pixel formats for this display mode
106                     /*while ((gKnownPixelFormats[pixelFormatIndex] != 0) && (gKnownPixelFormatNames[pixelFormatIndex] != NULL))
107                     {
108                         if ((deckLinkOutput->DoesSupportVideoMode(displayMode->GetDisplayMode(), gKnownPixelFormats[pixelFormatIndex], bmdVideoOutputFlagDefault, &displayModeSupport, NULL) == S_OK)
109                             && (displayModeSupport != bmdDisplayModeNotSupported))
110                         {
111                             printf("%s\t", gKnownPixelFormatNames[pixelFormatIndex]);
112                         }
113                         pixelFormatIndex++;
114                     }*/
115                     free(displayModeString);
116                 }
117
118                 // Release the IDeckLinkDisplayMode object to prevent a leak
119                 displayMode->Release();
120             }
121             devicelist->addItem(deviceName, availableModes);
122             found = true;
123         }
124
125
126         //print_attributes(deckLink);
127
128         // ** List the video output display modes supported by the card
129         //print_output_modes(deckLink);
130
131         // ** List the input and output capabilities of the card
132         //print_capabilities(deckLink);
133
134         // Release the IDeckLink instance when we've finished with it to prevent leaks
135         deckLink->Release();
136     }
137
138     deckLinkIterator->Release();
139     if(modelist != NULL && devicelist->count() > 0) {
140         QStringList modes = devicelist->itemData(devicelist->currentIndex()).toStringList();
141         modelist->insertItems(0, modes);
142     }
143     return found;
144 }
145
146 //static
147 bool BMInterface::getBlackMagicOutputDeviceList(KComboBox *devicelist)
148 {
149     IDeckLinkIterator* deckLinkIterator;
150     IDeckLink* deckLink;
151     int numDevices = 0;
152     HRESULT result;
153     bool found = false;
154
155     // Create an IDeckLinkIterator object to enumerate all DeckLink cards in the system
156     deckLinkIterator = CreateDeckLinkIteratorInstance();
157     if(deckLinkIterator == NULL) {
158         kDebug() << "A DeckLink iterator could not be created.  The DeckLink drivers may not be installed.";
159         return found;
160     }
161
162     // Enumerate all cards in this system
163     while(deckLinkIterator->Next(&deckLink) == S_OK) {
164         char *      deviceNameString = NULL;
165
166         // Increment the total number of DeckLink cards found
167         numDevices++;
168         //if (numDevices > 1)
169         kDebug() << "// FOUND a BM device\n\n+++++++++++++++++++++++++++++++++++++";
170
171         // *** Print the model name of the DeckLink card
172         result = deckLink->GetModelName((const char **) &deviceNameString);
173         if(result == S_OK) {
174             QString deviceName(deviceNameString);
175             free(deviceNameString);
176
177             IDeckLinkOutput*                 deckLinkOutput = NULL;
178             IDeckLinkDisplayModeIterator*       displayModeIterator = NULL;
179             IDeckLinkDisplayMode*               displayMode = NULL;
180             HRESULT                             result;
181
182             // Query the DeckLink for its configuration interface
183             result = deckLink->QueryInterface(IID_IDeckLinkInput, (void**)&deckLinkOutput);
184             if(result != S_OK) {
185                 kDebug() << "Could not obtain the IDeckLinkInput interface - result = " << result;
186                 return found;
187             }
188
189             // Obtain an IDeckLinkDisplayModeIterator to enumerate the display modes supported on output
190             result = deckLinkOutput->GetDisplayModeIterator(&displayModeIterator);
191             if(result != S_OK) {
192                 kDebug() << "Could not obtain the video input display mode iterator - result = " << result;
193                 return found;
194             }
195             /*QStringList availableModes;
196             // List all supported output display modes
197             while(displayModeIterator->Next(&displayMode) == S_OK) {
198                 char *          displayModeString = NULL;
199
200                 result = displayMode->GetName((const char **) &displayModeString);
201                 if(result == S_OK) {
202                     //char                  modeName[64];
203                     int                     modeWidth;
204                     int                     modeHeight;
205                     BMDTimeValue            frameRateDuration;
206                     BMDTimeScale            frameRateScale;
207                     //int                       pixelFormatIndex = 0; // index into the gKnownPixelFormats / gKnownFormatNames arrays
208                     //BMDDisplayModeSupport displayModeSupport;
209
210
211                     // Obtain the display mode's properties
212                     modeWidth = displayMode->GetWidth();
213                     modeHeight = displayMode->GetHeight();
214                     displayMode->GetFrameRate(&frameRateDuration, &frameRateScale);
215                     QString description = QString(displayModeString) + " (" + QString::number(modeWidth) + "x" + QString::number(modeHeight) + " - " + QString::number((double)frameRateScale / (double)frameRateDuration) + i18n("fps") + ")";
216                     description.append(" " + QString::number(modeWidth) + ":" + QString::number(modeHeight) + ":" + QString::number(frameRateScale) + ":" + QString::number(frameRateDuration) + ":" + QString::number(displayMode->GetFieldDominance() == bmdProgressiveFrame));
217                     availableModes << description;
218                     free(displayModeString);
219                 }
220
221                 // Release the IDeckLinkDisplayMode object to prevent a leak
222                 displayMode->Release();
223             }*/
224             devicelist->addItem(deviceName);
225             found = true;
226         }
227
228         // Release the IDeckLink instance when we've finished with it to prevent leaks
229         deckLink->Release();
230     }
231
232     deckLinkIterator->Release();
233     return found;
234 }
235
236 //static
237 bool BMInterface::isSupportedProfile(int card, QMap< QString, QString > properties)
238 {
239     IDeckLinkIterator* deckLinkIterator;
240     IDeckLink* deckLink;
241     HRESULT result;
242     bool found = false;
243
244     // Create an IDeckLinkIterator object to enumerate all DeckLink cards in the system
245     deckLinkIterator = CreateDeckLinkIteratorInstance();
246     if(deckLinkIterator == NULL) {
247         kDebug() << "A DeckLink iterator could not be created.  The DeckLink drivers may not be installed.";
248         return false;
249     }
250
251     while(card >= 0 && deckLinkIterator->Next(&deckLink) == S_OK) {
252         card --;
253     }
254
255     IDeckLinkOutput*                 deckLinkOutput = NULL;
256     IDeckLinkDisplayModeIterator*       displayModeIterator = NULL;
257     IDeckLinkDisplayMode*               displayMode = NULL;
258
259     // Query the DeckLink for its configuration interface
260     result = deckLink->QueryInterface(IID_IDeckLinkInput, (void**)&deckLinkOutput);
261     if(result != S_OK) {
262         kDebug() << "Could not obtain the IDeckLinkInput interface - result = " << result;
263         return false;
264     }
265
266     // Obtain an IDeckLinkDisplayModeIterator to enumerate the display modes supported on output
267     result = deckLinkOutput->GetDisplayModeIterator(&displayModeIterator);
268     if(result != S_OK) {
269         kDebug() << "Could not obtain the video input display mode iterator - result = " << result;
270         return false;
271     }
272     // List all supported output display modes
273     BMDTimeValue            frameRateDuration;
274     BMDTimeScale            frameRateScale;
275     
276     while(displayModeIterator->Next(&displayMode) == S_OK) {
277         if (displayMode->GetWidth() == properties.value("width").toInt() && displayMode->GetHeight() == properties.value("height").toInt()) {
278             int progressive = displayMode->GetFieldDominance() == bmdProgressiveFrame;
279             if (progressive == properties.value("progressive").toInt()) {
280                 displayMode->GetFrameRate(&frameRateDuration, &frameRateScale);
281                 if (frameRateScale / properties.value("frame_rate_num").toDouble() * properties.value("frame_rate_den").toDouble() == frameRateDuration) {
282                     found = true;
283                     break;
284                 }
285             }
286         }
287         displayMode->Release();
288     }
289
290     deckLink->Release();
291     deckLinkIterator->Release();
292     return found;
293 }
294
295
296 //static
297 QStringList BMInterface::supportedModes(int card)
298 {
299     IDeckLinkIterator* deckLinkIterator;
300     IDeckLink* deckLink;
301     HRESULT result;
302     QStringList modes;
303
304     // Create an IDeckLinkIterator object to enumerate all DeckLink cards in the system
305     deckLinkIterator = CreateDeckLinkIteratorInstance();
306     if(deckLinkIterator == NULL) {
307         kDebug() << "A DeckLink iterator could not be created.  The DeckLink drivers may not be installed.";
308         return modes;
309     }
310
311     while(card >= 0 && deckLinkIterator->Next(&deckLink) == S_OK) {
312         card --;
313     }
314
315     IDeckLinkOutput*                 deckLinkOutput = NULL;
316     IDeckLinkDisplayModeIterator*       displayModeIterator = NULL;
317     IDeckLinkDisplayMode*               displayMode = NULL;
318
319     // Query the DeckLink for its configuration interface
320     result = deckLink->QueryInterface(IID_IDeckLinkInput, (void**)&deckLinkOutput);
321     if(result != S_OK) {
322         kDebug() << "Could not obtain the IDeckLinkInput interface - result = " << result;
323         return modes;
324     }
325
326     // Obtain an IDeckLinkDisplayModeIterator to enumerate the display modes supported on output
327     result = deckLinkOutput->GetDisplayModeIterator(&displayModeIterator);
328     if(result != S_OK) {
329         kDebug() << "Could not obtain the video input display mode iterator - result = " << result;
330         return modes;
331     }
332
333     while(displayModeIterator->Next(&displayMode) == S_OK) {
334         char *          displayModeString = NULL;
335         result = displayMode->GetName((const char **) &displayModeString);
336         if(result == S_OK) {
337             QString description = QString(displayModeString);
338             modes.append(description);
339             free(displayModeString);
340         }
341         // Release the IDeckLinkDisplayMode object to prevent a leak
342         displayMode->Release();
343     }
344
345     deckLink->Release();
346     deckLinkIterator->Release();
347     return modes;
348 }
349