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