source: trunk/src/testing/app/DecklinkCapture/decklinkcapture.cpp @ 4

Revision 4, 20.2 KB checked in by ajaworski, 13 years ago (diff)

Added modified SAGE sources

Line 
1#include "DeckLinkAPI.h"
2#include <stdio.h>
3#include <unistd.h>
4#include <string.h>
5
6// headers for SAGE
7#include "sail.h"
8#include "misc.h"
9
10
11void    print_input_modes (IDeckLink* deckLink);
12void    print_output_modes (IDeckLink* deckLink);
13
14void    print_input_capabilities (IDeckLink* deckLink);
15void    print_output_capabilities (IDeckLink* deckLink);
16
17void    print_capabilities();
18void    capture(int device, int mode, int connection);
19
20sail sageInf; // sail object
21void *PixelFrame;
22
23// 1080i
24//int winWidth = 1920;
25//int winHeight = 1080;
26
27// 720p
28//int winWidth = 1280;
29//int winHeight = 720;
30
31// PAL
32int winWidth = 720;
33int winHeight = 576;
34
35// NTSC
36//int winWidth = 720;
37//int winHeight = 486;
38
39
40
41int main (int argc, char** argv)
42{
43    int done = 0;
44   
45
46        if (argc == 1) {
47                fprintf(stderr, "Decklink Capture Program\n");
48        }
49        else {
50                if ( (argc==2) && (!strcmp(argv[1],"-h")) ) {
51                        fprintf(stderr, "Usage> %s \n", argv[0]);
52                        fprintf(stderr, "\t\t\t -l\tlist capabilities\n");
53                        fprintf(stderr, "\t\t\t -i input mode\tSelect a capture settings\n");
54                }
55                if ( (argc==2) && (!strcmp(argv[1],"-l")) ) {
56                        print_capabilities();
57                }
58                if ( (argc==4) && (!strcmp(argv[1],"-i")) ) {
59
60                int card = 0;
61                int mode = atoi(argv[2]);
62                int connexion = atoi(argv[3]);
63
64                // SAGE setup
65            sailConfig cfg;
66            cfg.init("decklinkcapture.conf");   // every app has a config file named "appName.conf"
67            std::cout << "SAIL configuration was initialized by decklinkcapture.conf" << std::endl;
68         
69            cfg.setAppName("decklinkcapture");
70            cfg.rank = 0;
71            cfg.resX = winWidth;
72            cfg.resY = winHeight;
73            cfg.winWidth = winWidth;
74            cfg.winHeight = winHeight;
75
76            sageRect renderImageMap;
77            renderImageMap.left = 0.0;
78            renderImageMap.right = 1.0;
79            renderImageMap.bottom = 0.0;
80            renderImageMap.top = 1.0;
81
82            cfg.imageMap = renderImageMap;
83            cfg.pixFmt = PIXFMT_YUV;
84            cfg.rowOrd = TOP_TO_BOTTOM;
85            cfg.master = true;
86                         
87            sageInf.init(cfg);
88            std::cout << "sail initialized " << std::endl;
89           
90                // Capture setup
91                capture(card, mode, connexion);
92            //capture(0, 3, 1); // 0: card0, 3: 1080i 50, 1: HDMI
93            //capture(0, 5, 1); // HD 1080i 59.94
94            //capture(0, 4, 2); // HD 1080i 59.94 Component
95            //capture(0, 5, 1); // HD 1080i 60
96            //capture(0, 2, 1); // PAL
97            //capture(0, 0, 1); // NTSC
98 
99                // Just wait and process messages
100            while (!done) {
101                sageMessage msg;
102               
103                if (sageInf.checkMsg(msg, false) > 0) {
104                    switch (msg.getCode()) {
105                        case APP_QUIT : {
106                            exit(0);
107                            break;
108                        }
109                    }
110                }   
111                sleep(1);
112            }
113           
114                }
115        }
116
117        return 0;
118}
119
120class VideoDelegate : public IDeckLinkInputCallback
121{
122private:
123        int32_t mRefCount;
124        double  lastTime;
125    int     framecount;
126   
127public:
128    VideoDelegate () {
129         framecount = 0;
130    };
131                                               
132        virtual HRESULT         QueryInterface (REFIID iid, LPVOID *ppv)
133        {};
134        virtual ULONG           AddRef (void) {
135        return mRefCount++;
136    };
137        virtual ULONG           Release (void) {
138        int32_t         newRefValue;
139       
140        newRefValue = mRefCount--;
141        if (newRefValue == 0)
142        {
143            delete this;
144            return 0;
145        }       
146        return newRefValue;
147    };
148
149        virtual HRESULT VideoInputFrameArrived (IDeckLinkVideoInputFrame* arrivedFrame,
150                                                IDeckLinkAudioInputPacket*);
151        virtual HRESULT VideoInputFormatChanged(BMDVideoInputFormatChangedEvents, IDeckLinkDisplayMode*, BMDDetectedVideoInputFormatFlags)
152        {};
153
154};
155
156HRESULT VideoDelegate::VideoInputFrameArrived (IDeckLinkVideoInputFrame* arrivedFrame,
157                                               IDeckLinkAudioInputPacket*)
158{
159                BMDTimeValue            frameTime, frameDuration;
160                int                                     hours, minutes, seconds, frames;
161                HRESULT                         theResult;
162               
163                arrivedFrame->GetStreamTime(&frameTime, &frameDuration, 600);
164               
165                hours = (frameTime / (600 * 60*60));
166                minutes = (frameTime / (600 * 60)) % 60;
167                seconds = (frameTime / 600) % 60;
168                frames = (frameTime / 6) % 100;
169                //fprintf(stderr, "frame> %02d:%02d:%02d:%02d", hours, minutes, seconds, frames);
170                //fprintf(stderr, "\t %dx%d\r", arrivedFrame->GetWidth(), arrivedFrame->GetHeight() );
171
172        arrivedFrame->GetBytes(&PixelFrame);
173        unsigned char *rgbBuffer = (unsigned char *)sageInf.getBuffer();
174        memcpy(rgbBuffer, PixelFrame, arrivedFrame->GetWidth()*arrivedFrame->GetHeight()*2);
175        sageInf.swapBuffer();
176   
177#if 0
178        char fn[128];
179        memset(fn, 0, 128);
180        sprintf(fn, "frame%04d.yuv", framecount);
181        FILE *f=fopen(fn, "w+");
182        fwrite(PixelFrame, 1, 1920*1080*2, f);
183        fclose(f);
184#endif   
185
186        framecount++;
187       
188        return S_OK;
189
190}
191
192
193void capture(int device, int mode, int connection)
194{
195    int dnum, mnum, cnum;
196        int     itemCount;
197   
198        IDeckLinkIterator *deckLinkIterator;
199        IDeckLink         *deckLink;
200        HRESULT            result;
201
202        IDeckLinkInput*               deckLinkInput = NULL;
203        IDeckLinkDisplayModeIterator* displayModeIterator = NULL;
204        IDeckLinkDisplayMode*         displayMode = NULL;
205        IDeckLinkConfiguration       *deckLinkConfiguration = NULL;
206    VideoDelegate                *delegate;
207
208//     PixelFrame = (void*)malloc(1920*1080*2);
209//     memset(PixelFrame, 0, 1920*1080*2);;
210   
211
212    fprintf(stderr, "Starting> Capture on device %d, mode %d, connection %d\n", device, mode, connection);
213   
214        // Create an IDeckLinkIterator object to enumerate all DeckLink cards in the system
215        deckLinkIterator = CreateDeckLinkIteratorInstance();
216        if (deckLinkIterator == NULL)
217        {
218                fprintf(stderr, "A DeckLink iterator could not be created (DeckLink drivers may not be installed).\n");
219                return;
220        }
221
222    dnum = 0;
223    deckLink = NULL;
224   
225        while (deckLinkIterator->Next(&deckLink) == S_OK)
226        {
227        if (device != dnum) {
228            dnum++;
229                // Release the IDeckLink instance when we've finished with it to prevent leaks
230            deckLink->Release();
231            continue;
232        }
233        dnum++;
234       
235                const char *deviceNameString = NULL;
236               
237            // *** Print the model name of the DeckLink card
238                result = deckLink->GetModelName(&deviceNameString);
239                if (result == S_OK)
240                {
241                        char deviceName[64];   
242                        fprintf(stderr, "Using device [%s]\n", deviceNameString);
243
244                // Query the DeckLink for its configuration interface
245            result = deckLink->QueryInterface(IID_IDeckLinkInput, (void**)&deckLinkInput);
246            if (result != S_OK)
247            {
248                fprintf(stderr, "Could not obtain the IDeckLinkInput interface - result = %08x\n", result);
249                return;
250            }
251
252                // Obtain an IDeckLinkDisplayModeIterator to enumerate the display modes supported on input
253            result = deckLinkInput->GetDisplayModeIterator(&displayModeIterator);
254            if (result != S_OK)
255            {
256                fprintf(stderr, "Could not obtain the video input display mode iterator - result = %08x\n", result);
257                return;
258            }
259
260            mnum = 0;
261            while (displayModeIterator->Next(&displayMode) == S_OK)
262            {
263                if (mode != mnum) {
264                    mnum++;
265                        // Release the IDeckLinkDisplayMode object to prevent a leak
266                    displayMode->Release();
267                    continue;
268                }
269                mnum++;               
270     
271                const char *displayModeString = NULL;
272               
273                result = displayMode->GetName(&displayModeString);
274                if (result == S_OK)
275                {
276                    BMDPixelFormat pf = bmdFormat8BitYUV;
277
278                    fprintf(stderr, "Stopping previous streams, if needed\n");
279                    deckLinkInput->StopStreams();
280
281                    const char *displayModeString = NULL;               
282                    displayMode->GetName(&displayModeString);
283                    fprintf(stderr, "Enable video input: %s\n", displayModeString);
284
285                    deckLinkInput->EnableVideoInput(displayMode->GetDisplayMode(), pf, 0);
286
287
288
289                    // Query the DeckLink for its configuration interface
290                    result = deckLinkInput->QueryInterface(IID_IDeckLinkConfiguration, (void**)&deckLinkConfiguration);
291                    if (result != S_OK)
292                    {
293                        fprintf(stderr, "Could not obtain the IDeckLinkConfiguration interface: %08x\n", result);
294                        return;
295                    }
296                    BMDVideoConnection conn;
297                    switch (connection) {
298                        case 0:
299                            conn = bmdVideoConnectionSDI;
300                            break;
301                        case 1:
302                            conn = bmdVideoConnectionHDMI;
303                            break;
304                        case 2:
305                            conn = bmdVideoConnectionComponent;
306                            break;
307                        case 3:
308                            conn = bmdVideoConnectionComposite;
309                            break;
310                        case 4:
311                            conn = bmdVideoConnectionSVideo;
312                            break;
313                        case 5:
314                            conn = bmdVideoConnectionOpticalSDI;
315                            break;
316                        default:
317                            break;
318                    }
319                   
320                    if (deckLinkConfiguration->SetVideoInputFormat(conn) == S_OK) {
321                        fprintf(stderr, "Input set to: %d\n", connection);
322                    }
323                   
324                    delegate = new VideoDelegate();
325                    deckLinkInput->SetCallback(delegate);
326                   
327                    fprintf(stderr, "Start capture\n", connection);
328                    deckLinkInput->StartStreams();
329
330               }
331
332            }
333       
334                }
335        }
336
337
338        // Release the IDeckLink instance when we've finished with it to prevent leaks
339    if (deckLink) deckLink->Release();
340        // Ensure that the interfaces we obtained are released to prevent a memory leak
341        if (displayModeIterator != NULL)
342                displayModeIterator->Release();
343
344   return;
345}
346   
347
348void print_capabilities()
349{
350        IDeckLinkIterator* deckLinkIterator;
351        IDeckLink*         deckLink;
352        int                numDevices = 0;
353        HRESULT            result;
354       
355        // Create an IDeckLinkIterator object to enumerate all DeckLink cards in the system
356        deckLinkIterator = CreateDeckLinkIteratorInstance();
357        if (deckLinkIterator == NULL)
358        {
359                fprintf(stderr, "A DeckLink iterator could not be created (DeckLink drivers may not be installed).\n");
360                return;
361        }
362       
363        // Enumerate all cards in this system
364        printf("Device(s):\n");
365        while (deckLinkIterator->Next(&deckLink) == S_OK)
366        {
367                const char *            deviceNameString = NULL;
368               
369            // *** Print the model name of the DeckLink card
370                result = deckLink->GetModelName(&deviceNameString);
371                if (result == S_OK)
372                {
373                        char                    deviceName[64];
374                       
375                        printf("\t%3d: =============== %s ===============\n", numDevices, deviceNameString);
376                }
377               
378            // ** List the video output display modes supported by the card
379                print_input_modes(deckLink);
380               
381            // ** List the input capabilities of the card
382                print_input_capabilities(deckLink);
383               
384            // Release the IDeckLink instance when we've finished with it to prevent leaks
385                deckLink->Release();
386
387            // Increment the total number of DeckLink cards found
388                numDevices++;
389        }
390       
391       
392        // If no DeckLink cards were found in the system, inform the user
393        if (numDevices == 0)
394                printf("No Blackmagic Design devices were found.\n");
395        printf("\n");
396}
397
398
399
400void print_input_modes (IDeckLink* deckLink)
401{
402        IDeckLinkInput*                         deckLinkInput = NULL;
403        IDeckLinkDisplayModeIterator*           displayModeIterator = NULL;
404        IDeckLinkDisplayMode*                   displayMode = NULL;
405        HRESULT                                 result;
406        int mm = 0;
407       
408        // Query the DeckLink for its configuration interface
409        result = deckLink->QueryInterface(IID_IDeckLinkInput, (void**)&deckLinkInput);
410        if (result != S_OK)
411        {
412                fprintf(stderr, "Could not obtain the IDeckLinkInput interface - result = %08x\n", result);
413                goto bail;
414        }
415       
416        // Obtain an IDeckLinkDisplayModeIterator to enumerate the display modes supported on input
417        result = deckLinkInput->GetDisplayModeIterator(&displayModeIterator);
418        if (result != S_OK)
419        {
420                fprintf(stderr, "Could not obtain the video input display mode iterator - result = %08x\n", result);
421                goto bail;
422        }
423       
424        // List all supported output display modes
425        printf("Supported video input display modes:\n");
426        while (displayModeIterator->Next(&displayMode) == S_OK)
427        {
428                const char *                    displayModeString = NULL;
429               
430                result = displayMode->GetName(&displayModeString);
431                if (result == S_OK)
432                {
433                        char            modeName[64];
434                        int             modeWidth;
435                        int             modeHeight;
436                        BMDTimeValue    frameRateDuration;
437                        BMDTimeScale    frameRateScale;
438                       
439                       
440                // Obtain the display mode's properties
441                        modeWidth = displayMode->GetWidth();
442                        modeHeight = displayMode->GetHeight();
443                        displayMode->GetFrameRate(&frameRateDuration, &frameRateScale);
444                        printf("\t%3d) %-20s \t %d x %d \t %g FPS\n", mm, displayModeString, modeWidth, modeHeight, (double)frameRateScale / (double)frameRateDuration);
445                        mm++;
446                }
447               
448            // Release the IDeckLinkDisplayMode object to prevent a leak
449                displayMode->Release();
450        }
451       
452        printf("\n");
453       
454  bail:
455        // Ensure that the interfaces we obtained are released to prevent a memory leak
456        if (displayModeIterator != NULL)
457                displayModeIterator->Release();
458       
459        if (deckLinkInput != NULL)
460                deckLinkInput->Release();
461}
462
463
464void    print_output_modes (IDeckLink* deckLink)
465{
466        IDeckLinkOutput*                                        deckLinkOutput = NULL;
467        IDeckLinkDisplayModeIterator*           displayModeIterator = NULL;
468        IDeckLinkDisplayMode*                           displayMode = NULL;
469        HRESULT                                                         result;
470       
471        // Query the DeckLink for its configuration interface
472        result = deckLink->QueryInterface(IID_IDeckLinkOutput, (void**)&deckLinkOutput);
473        if (result != S_OK)
474        {
475                fprintf(stderr, "Could not obtain the IDeckLinkOutput interface - result = %08x\n", result);
476                goto bail;
477        }
478       
479        // Obtain an IDeckLinkDisplayModeIterator to enumerate the display modes supported on output
480        result = deckLinkOutput->GetDisplayModeIterator(&displayModeIterator);
481        if (result != S_OK)
482        {
483                fprintf(stderr, "Could not obtain the video output display mode iterator - result = %08x\n", result);
484                goto bail;
485        }
486       
487        // List all supported output display modes
488        printf("Supported video output display modes:\n");
489        while (displayModeIterator->Next(&displayMode) == S_OK)
490        {
491                const char *                    displayModeString = NULL;
492               
493                result = displayMode->GetName(&displayModeString);
494                if (result == S_OK)
495                {
496                        char                    modeName[64];
497                        int                             modeWidth;
498                        int                             modeHeight;
499                        BMDTimeValue    frameRateDuration;
500                        BMDTimeScale    frameRateScale;
501                       
502                       
503                // Obtain the display mode's properties
504                        modeWidth = displayMode->GetWidth();
505                        modeHeight = displayMode->GetHeight();
506                        displayMode->GetFrameRate(&frameRateDuration, &frameRateScale);
507                        printf("\t%-20s \t %d x %d \t %g FPS\n", displayModeString, modeWidth, modeHeight, (double)frameRateScale / (double)frameRateDuration);
508                }
509               
510            // Release the IDeckLinkDisplayMode object to prevent a leak
511                displayMode->Release();
512        }
513       
514        printf("\n");
515       
516  bail:
517        // Ensure that the interfaces we obtained are released to prevent a memory leak
518        if (displayModeIterator != NULL)
519                displayModeIterator->Release();
520       
521        if (deckLinkOutput != NULL)
522                deckLinkOutput->Release();
523}
524
525void    print_input_capabilities (IDeckLink* deckLink)
526{
527        IDeckLinkConfiguration*         deckLinkConfiguration = NULL;
528        IDeckLinkConfiguration*         deckLinkValidator = NULL;
529        int                                                     itemCount;
530        HRESULT                                         result;
531        int mm = 0;
532       
533        // Query the DeckLink for its configuration interface
534        result = deckLink->QueryInterface(IID_IDeckLinkConfiguration, (void**)&deckLinkConfiguration);
535        if (result != S_OK)
536        {
537                fprintf(stderr, "Could not obtain the IDeckLinkConfiguration interface - result = %08x\n", result);
538                goto bail;
539        }
540       
541        // Obtain a validator object from the IDeckLinkConfiguration interface.
542        // The validator object implements IDeckLinkConfiguration, however, all configuration changes are ignored
543        // and will not take effect.  However, you can use the returned result code from the validator object
544        // to determine whether the card supports a particular configuration.
545       
546        result = deckLinkConfiguration->GetConfigurationValidator(&deckLinkValidator);
547        if (result != S_OK)
548        {
549                fprintf(stderr, "Could not obtain the configuration validator interface - result = %08x\n", result);
550                goto bail;
551        }
552       
553        // Use the validator object to determine which video input connections are available
554        printf("Supported video input connections:\n  ");
555        itemCount = 0;
556        if (deckLinkValidator->SetVideoInputFormat(bmdVideoConnectionSDI) == S_OK)
557        {
558                printf("\t%3d) SDI\n", itemCount);
559        }
560    itemCount++;
561        if (deckLinkValidator->SetVideoInputFormat(bmdVideoConnectionHDMI) == S_OK)
562        {
563                printf("\t%3d) HDMI\n", itemCount);
564        }
565    itemCount++;
566        if (deckLinkValidator->SetVideoInputFormat(bmdVideoConnectionComponent) == S_OK)
567        {
568                printf("\t%3d) Component\n", itemCount);
569        }
570    itemCount++;
571        if (deckLinkValidator->SetVideoInputFormat(bmdVideoConnectionComposite) == S_OK)
572        {
573                printf("\t%3d) Composite\n", itemCount);
574        }
575    itemCount++;
576        if (deckLinkValidator->SetVideoInputFormat(bmdVideoConnectionSVideo) == S_OK)
577        {
578                printf("\t%3d) S-Video\n", itemCount);
579        }
580    itemCount++;
581        if (deckLinkValidator->SetVideoInputFormat(bmdVideoConnectionOpticalSDI) == S_OK)
582        {
583                printf("\t%3d) Optical SDI\n", itemCount);
584        }
585       
586        printf("\n");
587       
588  bail:
589        if (deckLinkValidator != NULL)
590                deckLinkValidator->Release();
591       
592        if (deckLinkConfiguration != NULL)
593                deckLinkConfiguration->Release();
594}
595
596void    print_output_capabilities (IDeckLink* deckLink)
597{
598        IDeckLinkConfiguration*         deckLinkConfiguration = NULL;
599        IDeckLinkConfiguration*         deckLinkValidator = NULL;
600        int                                                     itemCount;
601        HRESULT                                         result;
602       
603        // Query the DeckLink for its configuration interface
604        result = deckLink->QueryInterface(IID_IDeckLinkConfiguration, (void**)&deckLinkConfiguration);
605        if (result != S_OK)
606        {
607                fprintf(stderr, "Could not obtain the IDeckLinkConfiguration interface - result = %08x\n", result);
608                goto bail;
609        }
610       
611        // Obtain a validator object from the IDeckLinkConfiguration interface.
612        // The validator object implements IDeckLinkConfiguration, however, all configuration changes are ignored
613        // and will not take effect.  However, you can use the returned result code from the validator object
614        // to determine whether the card supports a particular configuration.
615       
616        result = deckLinkConfiguration->GetConfigurationValidator(&deckLinkValidator);
617        if (result != S_OK)
618        {
619                fprintf(stderr, "Could not obtain the configuration validator interface - result = %08x\n", result);
620                goto bail;
621        }
622       
623        // Use the validator object to determine which video output connections are available
624        printf("Supported video output connections:\n  ");
625        itemCount = 0;
626        if (deckLinkValidator->SetVideoOutputFormat(bmdVideoConnectionSDI) == S_OK)
627        {
628                if (itemCount++ > 0)
629                        printf(", ");
630                printf("SDI");
631        }
632        if (deckLinkValidator->SetVideoOutputFormat(bmdVideoConnectionHDMI) == S_OK)
633        {
634                if (itemCount++ > 0)
635                        printf(", ");
636                printf("HDMI");
637        }
638        if (deckLinkValidator->SetVideoOutputFormat(bmdVideoConnectionComponent) == S_OK)
639        {
640                if (itemCount++ > 0)
641                        printf(", ");
642                printf("Component");
643        }
644        if (deckLinkValidator->SetVideoOutputFormat(bmdVideoConnectionComposite) == S_OK)
645        {
646                if (itemCount++ > 0)
647                        printf(", ");
648                printf("Composite");
649        }
650        if (deckLinkValidator->SetVideoOutputFormat(bmdVideoConnectionSVideo) == S_OK)
651        {
652                if (itemCount++ > 0)
653                        printf(", ");
654                printf("S-Video");
655        }
656        if (deckLinkValidator->SetVideoOutputFormat(bmdVideoConnectionOpticalSDI) == S_OK)
657        {
658                if (itemCount++ > 0)
659                        printf(", ");
660                printf("Optical SDI");
661        }
662       
663        printf("\n\n");
664       
665bail:
666        if (deckLinkValidator != NULL)
667                deckLinkValidator->Release();
668       
669        if (deckLinkConfiguration != NULL)
670                deckLinkConfiguration->Release();
671}
672
673
Note: See TracBrowser for help on using the repository browser.