]> git.sesse.net Git - kdenlive/blob - src/blackmagic/devices.cpp
3be150a225a651ee7d9f36c71278a685f4ebbb84
[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         kDebug() << "// FOUND a BM device\n\n+++++++++++++++++++++++++++++++++++++";
167
168         // *** Print the model name of the DeckLink card
169         result = deckLink->GetModelName((const char **) &deviceNameString);
170         if(result == S_OK) {
171             QString deviceName(deviceNameString);
172             free(deviceNameString);
173
174             IDeckLinkOutput*                 deckLinkOutput = NULL;
175             IDeckLinkDisplayModeIterator*       displayModeIterator = NULL;
176             //IDeckLinkDisplayMode*               displayMode = NULL;
177             HRESULT                             result;
178
179             // Query the DeckLink for its configuration interface
180             result = deckLink->QueryInterface(IID_IDeckLinkInput, (void**)&deckLinkOutput);
181             if(result != S_OK) {
182                 kDebug() << "Could not obtain the IDeckLinkInput interface - result = " << result;
183                 return found;
184             }
185
186             // Obtain an IDeckLinkDisplayModeIterator to enumerate the display modes supported on output
187             result = deckLinkOutput->GetDisplayModeIterator(&displayModeIterator);
188             if(result != S_OK) {
189                 kDebug() << "Could not obtain the video input display mode iterator - result = " << result;
190                 return found;
191             }
192             /*QStringList availableModes;
193             // List all supported output display modes
194             while(displayModeIterator->Next(&displayMode) == S_OK) {
195                 char *          displayModeString = NULL;
196
197                 result = displayMode->GetName((const char **) &displayModeString);
198                 if(result == S_OK) {
199                     //char                  modeName[64];
200                     int                     modeWidth;
201                     int                     modeHeight;
202                     BMDTimeValue            frameRateDuration;
203                     BMDTimeScale            frameRateScale;
204                     //int                       pixelFormatIndex = 0; // index into the gKnownPixelFormats / gKnownFormatNames arrays
205                     //BMDDisplayModeSupport displayModeSupport;
206
207
208                     // Obtain the display mode's properties
209                     modeWidth = displayMode->GetWidth();
210                     modeHeight = displayMode->GetHeight();
211                     displayMode->GetFrameRate(&frameRateDuration, &frameRateScale);
212                     QString description = QString(displayModeString) + " (" + QString::number(modeWidth) + "x" + QString::number(modeHeight) + " - " + QString::number((double)frameRateScale / (double)frameRateDuration) + i18n("fps") + ")";
213                     description.append(" " + QString::number(modeWidth) + ":" + QString::number(modeHeight) + ":" + QString::number(frameRateScale) + ":" + QString::number(frameRateDuration) + ":" + QString::number(displayMode->GetFieldDominance() == bmdProgressiveFrame));
214                     availableModes << description;
215                     free(displayModeString);
216                 }
217
218                 // Release the IDeckLinkDisplayMode object to prevent a leak
219                 displayMode->Release();
220             }*/
221             devicelist->addItem(deviceName, numDevices++);
222             found = true;
223         }
224
225         // Release the IDeckLink instance when we've finished with it to prevent leaks
226         deckLink->Release();
227     }
228
229     deckLinkIterator->Release();
230     return found;
231 }
232
233 //static
234 bool BMInterface::isSupportedProfile(int card, QMap< QString, QString > properties)
235 {
236     IDeckLinkIterator* deckLinkIterator;
237     IDeckLink* deckLink;
238     HRESULT result;
239     bool found = false;
240
241     // Create an IDeckLinkIterator object to enumerate all DeckLink cards in the system
242     deckLinkIterator = CreateDeckLinkIteratorInstance();
243     if(deckLinkIterator == NULL) {
244         kDebug() << "A DeckLink iterator could not be created.  The DeckLink drivers may not be installed.";
245         return false;
246     }
247
248     while(card >= 0 && deckLinkIterator->Next(&deckLink) == S_OK) {
249         card --;
250     }
251
252     IDeckLinkOutput*                 deckLinkOutput = NULL;
253     IDeckLinkDisplayModeIterator*       displayModeIterator = NULL;
254     IDeckLinkDisplayMode*               displayMode = NULL;
255
256     // Query the DeckLink for its configuration interface
257     result = deckLink->QueryInterface(IID_IDeckLinkInput, (void**)&deckLinkOutput);
258     if(result != S_OK) {
259         kDebug() << "Could not obtain the IDeckLinkInput interface - result = " << result;
260         return false;
261     }
262
263     // Obtain an IDeckLinkDisplayModeIterator to enumerate the display modes supported on output
264     result = deckLinkOutput->GetDisplayModeIterator(&displayModeIterator);
265     if(result != S_OK) {
266         kDebug() << "Could not obtain the video input display mode iterator - result = " << result;
267         return false;
268     }
269     // List all supported output display modes
270     BMDTimeValue            frameRateDuration;
271     BMDTimeScale            frameRateScale;
272     
273     while(displayModeIterator->Next(&displayMode) == S_OK) {
274         if (displayMode->GetWidth() == properties.value("width").toInt() && displayMode->GetHeight() == properties.value("height").toInt()) {
275             int progressive = displayMode->GetFieldDominance() == bmdProgressiveFrame;
276             if (progressive == properties.value("progressive").toInt()) {
277                 displayMode->GetFrameRate(&frameRateDuration, &frameRateScale);
278                 if (frameRateScale / properties.value("frame_rate_num").toDouble() * properties.value("frame_rate_den").toDouble() == frameRateDuration) {
279                     found = true;
280                     break;
281                 }
282             }
283         }
284         displayMode->Release();
285     }
286
287     deckLink->Release();
288     deckLinkIterator->Release();
289     return found;
290 }
291
292
293 //static
294 QStringList BMInterface::supportedModes(int card)
295 {
296     IDeckLinkIterator* deckLinkIterator;
297     IDeckLink* deckLink;
298     HRESULT result;
299     QStringList modes;
300
301     // Create an IDeckLinkIterator object to enumerate all DeckLink cards in the system
302     deckLinkIterator = CreateDeckLinkIteratorInstance();
303     if(deckLinkIterator == NULL) {
304         kDebug() << "A DeckLink iterator could not be created.  The DeckLink drivers may not be installed.";
305         return modes;
306     }
307
308     while(card >= 0 && deckLinkIterator->Next(&deckLink) == S_OK) {
309         card --;
310     }
311
312     IDeckLinkOutput*                 deckLinkOutput = NULL;
313     IDeckLinkDisplayModeIterator*       displayModeIterator = NULL;
314     IDeckLinkDisplayMode*               displayMode = NULL;
315
316     // Query the DeckLink for its configuration interface
317     result = deckLink->QueryInterface(IID_IDeckLinkInput, (void**)&deckLinkOutput);
318     if(result != S_OK) {
319         kDebug() << "Could not obtain the IDeckLinkInput interface - result = " << result;
320         return modes;
321     }
322
323     // Obtain an IDeckLinkDisplayModeIterator to enumerate the display modes supported on output
324     result = deckLinkOutput->GetDisplayModeIterator(&displayModeIterator);
325     if(result != S_OK) {
326         kDebug() << "Could not obtain the video input display mode iterator - result = " << result;
327         return modes;
328     }
329
330     while(displayModeIterator->Next(&displayMode) == S_OK) {
331         char *          displayModeString = NULL;
332         result = displayMode->GetName((const char **) &displayModeString);
333         if(result == S_OK) {
334             QString description = QString(displayModeString);
335             modes.append(description);
336             free(displayModeString);
337         }
338         // Release the IDeckLinkDisplayMode object to prevent a leak
339         displayMode->Release();
340     }
341
342     deckLink->Release();
343     deckLinkIterator->Release();
344     return modes;
345 }
346