BMDDisplayMode getDisplayMode( mlt_profile profile, int vancLines ) { IDeckLinkDisplayModeIterator* iter = NULL; IDeckLinkDisplayMode* mode = NULL; BMDDisplayMode result = (BMDDisplayMode) bmdDisplayModeNotSupported; if ( m_decklinkInput->GetDisplayModeIterator( &iter ) == S_OK ) { while ( !result && iter->Next( &mode ) == S_OK ) { int width = mode->GetWidth(); int height = mode->GetHeight(); BMDTimeValue duration; BMDTimeScale timescale; mode->GetFrameRate( &duration, ×cale ); double fps = (double) timescale / duration; int p = mode->GetFieldDominance() == bmdProgressiveFrame; m_topFieldFirst = mode->GetFieldDominance() == bmdUpperFieldFirst; m_colorspace = ( mode->GetFlags() & bmdDisplayModeColorspaceRec709 ) ? 709 : 601; mlt_log_verbose( getProducer(), "BMD mode %dx%d %.3f fps prog %d tff %d\n", width, height, fps, p, m_topFieldFirst ); if ( width == profile->width && p == profile->progressive && ( height + vancLines == profile->height || ( height == 486 && profile->height == 480 + vancLines ) ) && fps == mlt_profile_fps( profile ) ) result = mode->GetDisplayMode(); SAFE_RELEASE( mode ); } SAFE_RELEASE( iter ); } return result; }
/** * process the arugments * return negative value of failed */ int Window::processArguments(int argc, char* argv[]){ IDeckLinkAttributes *deckLinkAttributes = NULL; DeckLinkCaptureDelegate *delegate; IDeckLinkDisplayMode *displayMode; BMDVideoInputFlags inputFlags = 0; BMDDisplayMode selectedDisplayMode = bmdModeNTSC; BMDPixelFormat pixelFormat = bmdFormat8BitYUV; int displayModeCount = 0; int exitStatus = 1; int ch; bool foundDisplayMode = false; HRESULT result; int dnum = 0; IDeckLink *tempLink = NULL; int found = 0; bool supported = 0; int64_t ports; int itemCount; int vinput = 0; int64_t vport = 0; IDeckLinkConfiguration *deckLinkConfiguration = NULL; bool flickerremoval = true; bool pnotpsf = true; // Parse command line options while ((ch = getopt(argc, argv, "?h3c:d:s:f:a:m:n:p:t:u::vi:jy")) != -1) { switch (ch) { case 'i': vinput = atoi(optarg); break; case 'd': card = atoi(optarg); break; case 'm': g_videoModeIndex = atoi(optarg); break; case 'n': g_maxFrames = atoi(optarg); break; case '3': inputFlags |= bmdVideoInputDualStream3D; break; case 'p': switch(atoi(optarg)) { case 0: pixelFormat = bmdFormat8BitYUV; break; case 1: pixelFormat = bmdFormat10BitYUV; break; case 2: pixelFormat = bmdFormat10BitRGB; break; default: fprintf(stderr, "Invalid argument: Pixel format %d is not valid", atoi(optarg)); exit(1); } break; case 't': if (!strcmp(optarg, "rp188")) g_timecodeFormat = bmdTimecodeRP188Any; else if (!strcmp(optarg, "vitc")) g_timecodeFormat = bmdTimecodeVITC; else if (!strcmp(optarg, "serial")) g_timecodeFormat = bmdTimecodeSerial; else { fprintf(stderr, "Invalid argument: Timecode format \"%s\" is invalid\n", optarg); exit(1); } break; case '?': case 'h': usage(); } } if (!deckLinkIterator) { fprintf(stderr, "This application requires the DeckLink drivers installed.\n"); return -1; } /* Connect to the first DeckLink instance */ while (deckLinkIterator->Next(&tempLink) == S_OK) { if (card != dnum) { dnum++; // Release the IDeckLink instance when we've finished with it to prevent leaks tempLink->Release(); continue; } else { deckLink = tempLink; found = 1; } dnum++; } if (! found ) { fprintf(stderr, "No DeckLink PCI cards found.\n"); return -1; } if (deckLink->QueryInterface(IID_IDeckLinkInput, (void**)&deckLinkInput) != S_OK) return -1; // Query the DeckLink for its attributes interface result = deckLink->QueryInterface(IID_IDeckLinkAttributes, (void**)&deckLinkAttributes); if (result != S_OK) { fprintf(stderr, "Could not obtain the IDeckLinkAttributes interface - result = %08x\n", result); } result = deckLinkAttributes->GetFlag(BMDDeckLinkSupportsInputFormatDetection, &supported); if (result == S_OK) { fprintf(stderr, " %-40s %s\n", "Input mode detection supported ?", (supported == true) ? "Yes" : "No"); } else { fprintf(stderr, "Could not query the input mode detection attribute- result = %08x\n", result); } fprintf(stderr, "Supported video input connections (-i [input #]:\n "); itemCount = 0; result = deckLinkAttributes->GetInt(BMDDeckLinkVideoInputConnections, &ports); if (result == S_OK) { if (ports & bmdVideoConnectionSDI) { fprintf(stderr, "%d: SDI, ", bmdVideoConnectionSDI); itemCount++; } if (ports & bmdVideoConnectionHDMI) { fprintf(stderr, "%d: HDMI, ", bmdVideoConnectionHDMI); itemCount++; } if (ports & bmdVideoConnectionOpticalSDI) { fprintf(stderr, "%d: Optical SDI, ", bmdVideoConnectionOpticalSDI); itemCount++; } if (ports & bmdVideoConnectionComponent) { fprintf(stderr, "%d: Component, ", bmdVideoConnectionComponent); itemCount++; } if (ports & bmdVideoConnectionComposite) { fprintf(stderr, "%d: Composite, ", bmdVideoConnectionComposite); itemCount++; } if (ports & bmdVideoConnectionSVideo) { fprintf(stderr, "%d: S-Video, ", bmdVideoConnectionSVideo); itemCount++; } } fprintf(stderr, "\n"); //glWidget->initShaderProgram(); delegate = new DeckLinkCaptureDelegate(glWidget); connect(delegate, SIGNAL(updateGLSignal()), glWidget, SLOT(updateGLSlot())); deckLinkInput->SetCallback(delegate); // Obtain an IDeckLinkDisplayModeIterator to enumerate the display modes supported on output result = deckLinkInput->GetDisplayModeIterator(&displayModeIterator); if (result != S_OK) { fprintf(stderr, "Could not obtain the video output display mode iterator - result = %08x\n", result); return -1; } if (g_videoModeIndex < 0) { fprintf(stderr, "No video mode specified\n"); usage(); return -1; } while (displayModeIterator->Next(&displayMode) == S_OK) { if (g_videoModeIndex == displayModeCount) { BMDDisplayModeSupport result; const char *displayModeName; foundDisplayMode = true; displayMode->GetName(&displayModeName); selectedDisplayMode = displayMode->GetDisplayMode(); deckLinkInput->DoesSupportVideoMode(selectedDisplayMode, pixelFormat, bmdVideoInputFlagDefault, &result, NULL); if (result == bmdDisplayModeNotSupported) { fprintf(stderr, "The display mode %s is not supported with the selected pixel format\n", displayModeName); return -1; } if (inputFlags & bmdVideoInputDualStream3D) { if (!(displayMode->GetFlags() & bmdDisplayModeSupports3D)) { fprintf(stderr, "The display mode %s is not supported with 3D\n", displayModeName); return -1; } } fprintf(stderr, "Selecting mode: %s\n", displayModeName); break; } displayModeCount++; displayMode->Release(); } if (!foundDisplayMode) { fprintf(stderr, "Invalid mode %d specified\n", g_videoModeIndex); return -1; } // Query the DeckLink for its configuration interface result = deckLinkInput->QueryInterface(IID_IDeckLinkConfiguration, (void**)&deckLinkConfiguration); if (result != S_OK) { fprintf(stderr, "Could not obtain the IDeckLinkConfiguration interface: %08x\n", result); } BMDVideoConnection conn; switch (vinput) { case 0: conn = bmdVideoConnectionSDI; break; case 1: conn = bmdVideoConnectionHDMI; break; case 2: conn = bmdVideoConnectionComponent; break; case 3: conn = bmdVideoConnectionComposite; break; case 4: conn = bmdVideoConnectionSVideo; break; case 5: conn = bmdVideoConnectionOpticalSDI; break; default: break; } conn = vinput; // Set the input desired result = deckLinkConfiguration->SetInt(bmdDeckLinkConfigVideoInputConnection, conn); if(result != S_OK) { fprintf(stderr, "Cannot set the input to [%d]\n", conn); return -1; } // check input result = deckLinkConfiguration->GetInt(bmdDeckLinkConfigVideoInputConnection, &vport); if (vport == bmdVideoConnectionSDI) fprintf(stderr, "Before Input configured for SDI\n"); if (vport == bmdVideoConnectionHDMI) fprintf(stderr, "Before Input configured for HDMI\n"); if (deckLinkConfiguration->SetFlag(bmdDeckLinkConfigFieldFlickerRemoval, flickerremoval) == S_OK) { fprintf(stderr, "Flicker removal set : %d\n", flickerremoval); } else { fprintf(stderr, "Flicker removal NOT set\n"); } if (deckLinkConfiguration->SetFlag(bmdDeckLinkConfigUse1080pNotPsF, pnotpsf) == S_OK) { fprintf(stderr, "bmdDeckLinkConfigUse1080pNotPsF: %d\n", pnotpsf); } else { fprintf(stderr, "bmdDeckLinkConfigUse1080pNotPsF NOT set\n"); } //if (deckLinkConfiguration->SetFlag(bmdDeckLinkConfigVideoInputConnection, conn) == S_OK) { //fprintf(stderr, "Input set to: %d\n", vinput); //} result = deckLinkConfiguration->GetInt(bmdDeckLinkConfigVideoInputConnection, &vport); if (vport == bmdVideoConnectionSDI) fprintf(stderr, "After Input configured for SDI\n"); if (vport == bmdVideoConnectionHDMI) fprintf(stderr, "After Input configured for HDMI\n"); result = deckLinkInput->EnableVideoInput(selectedDisplayMode, pixelFormat, inputFlags); if(result != S_OK) { fprintf(stderr, "Failed to enable video input. Is another application using the card?\n"); return -1; } displayWidth = displayMode->GetWidth(); displayHeight = displayMode->GetHeight(); displayMode->GetFrameRate(&frameRateDuration, &frameRateScale); displayFPS = (double)frameRateScale / (double)frameRateDuration; //set to delegate delegate->setWidth(displayWidth); delegate->setHeight(displayHeight); delegate->setFPS(displayFPS); delegate->setFrameRateDuration(frameRateDuration); delegate->setFrameRateScale(frameRateScale); //set texture width and height glWidget->setTextureWidth(displayWidth); glWidget->setTextureHeight(displayHeight); glWidget->initBuffer(); fprintf(stderr, "GetFrameRate: %10ld %10ld --> fps %g\n", (long)frameRateScale, (long)frameRateDuration, displayFPS); result = deckLinkInput->StartStreams(); if(result != S_OK){ fprintf(stderr, "Cannot start streams...\n"); return -1; } fprintf(stderr, "Finish procesing arguments \n"); }
int main(int argc, char *argv[]) { HRESULT result; int exitStatus = 1; int idx; IDeckLinkIterator* deckLinkIterator = NULL; IDeckLink* deckLink = NULL; IDeckLinkAttributes* deckLinkAttributes = NULL; bool formatDetectionSupported; IDeckLinkDisplayModeIterator* displayModeIterator = NULL; IDeckLinkDisplayMode* displayMode = NULL; char* displayModeName = NULL; BMDDisplayModeSupport displayModeSupported; DeckLinkCaptureDelegate* delegate = NULL; pthread_mutex_init(&g_sleepMutex, NULL); pthread_cond_init(&g_sleepCond, NULL); signal(SIGINT, sigfunc); signal(SIGTERM, sigfunc); signal(SIGHUP, sigfunc); // Network g_video_sock = socket(AF_INET, SOCK_STREAM, 0); g_video_addr.sin_family = AF_INET; g_video_addr.sin_port = htons(62310); g_video_addr.sin_addr.s_addr = inet_addr("192.168.100.31"); connect(g_video_sock, (struct sockaddr *)&g_video_addr, sizeof(g_video_addr)); g_audio_sock = socket(AF_INET, SOCK_STREAM, 0); g_audio_addr.sin_family = AF_INET; g_audio_addr.sin_port = htons(62311); g_audio_addr.sin_addr.s_addr = inet_addr("192.168.100.31"); connect(g_audio_sock, (struct sockaddr *)&g_audio_addr, sizeof(g_audio_addr)); // Process the command line arguments if (!g_config.ParseArguments(argc, argv)) { g_config.DisplayUsage(exitStatus); goto bail; } // Get the DeckLink device deckLinkIterator = CreateDeckLinkIteratorInstance(); if (!deckLinkIterator) { fprintf(stderr, "This application requires the DeckLink drivers installed.\n"); goto bail; } idx = g_config.m_deckLinkIndex; while ((result = deckLinkIterator->Next(&deckLink)) == S_OK) { if (idx == 0) break; --idx; deckLink->Release(); } if (result != S_OK || deckLink == NULL) { fprintf(stderr, "Unable to get DeckLink device %u\n", g_config.m_deckLinkIndex); goto bail; } // Get the input (capture) interface of the DeckLink device result = deckLink->QueryInterface(IID_IDeckLinkInput, (void**)&g_deckLinkInput); if (result != S_OK) goto bail; // Get the display mode if (g_config.m_displayModeIndex == -1) { // Check the card supports format detection result = deckLink->QueryInterface(IID_IDeckLinkAttributes, (void**)&deckLinkAttributes); if (result == S_OK) { result = deckLinkAttributes->GetFlag(BMDDeckLinkSupportsInputFormatDetection, &formatDetectionSupported); if (result != S_OK || !formatDetectionSupported) { fprintf(stderr, "Format detection is not supported on this device\n"); goto bail; } } g_config.m_inputFlags |= bmdVideoInputEnableFormatDetection; // Format detection still needs a valid mode to start with idx = 0; } else { idx = g_config.m_displayModeIndex; } result = g_deckLinkInput->GetDisplayModeIterator(&displayModeIterator); if (result != S_OK) { goto bail; } while ((result = displayModeIterator->Next(&displayMode)) == S_OK) { if (idx == 0) { break; } --idx; displayMode->Release(); } if (result != S_OK || displayMode == NULL) { fprintf(stderr, "Unable to get display mode %d\n", g_config.m_displayModeIndex); goto bail; } // Get display mode name result = displayMode->GetName((const char**)&displayModeName); if (result != S_OK) { displayModeName = (char *)malloc(32); snprintf(displayModeName, 32, "[index %d]", g_config.m_displayModeIndex); } // Check display mode is supported with given options result = g_deckLinkInput->DoesSupportVideoMode(displayMode->GetDisplayMode(), g_config.m_pixelFormat, bmdVideoInputFlagDefault, &displayModeSupported, NULL); if (result != S_OK) goto bail; if (displayModeSupported == bmdDisplayModeNotSupported) { fprintf(stderr, "The display mode %s is not supported with the selected pixel format\n", displayModeName); goto bail; } if (g_config.m_inputFlags & bmdVideoInputDualStream3D) { if (!(displayMode->GetFlags() & bmdDisplayModeSupports3D)) { fprintf(stderr, "The display mode %s is not supported with 3D\n", displayModeName); goto bail; } } // Print the selected configuration g_config.DisplayConfiguration(); // Configure the capture callback delegate = new DeckLinkCaptureDelegate(); g_deckLinkInput->SetCallback(delegate); // Open output files // if (g_config.m_videoOutputFile != NULL) // { // g_videoOutputFile = open(g_config.m_videoOutputFile, O_WRONLY|O_CREAT|O_TRUNC, 0664); // if (g_videoOutputFile < 0) // { // fprintf(stderr, "Could not open video output file \"%s\"\n", g_config.m_videoOutputFile); // goto bail; // } // } // // if (g_config.m_audioOutputFile != NULL) // { // g_audioOutputFile = open(g_config.m_audioOutputFile, O_WRONLY|O_CREAT|O_TRUNC, 0664); // if (g_audioOutputFile < 0) // { // fprintf(stderr, "Could not open audio output file \"%s\"\n", g_config.m_audioOutputFile); // goto bail; // } // } // Block main thread until signal occurs while (!g_do_exit) { // Start capturing result = g_deckLinkInput->EnableVideoInput(displayMode->GetDisplayMode(), g_config.m_pixelFormat, g_config.m_inputFlags); if (result != S_OK) { fprintf(stderr, "Failed to enable video input. Is another application using the card?\n"); goto bail; } result = g_deckLinkInput->EnableAudioInput(bmdAudioSampleRate48kHz, g_config.m_audioSampleDepth, g_config.m_audioChannels); if (result != S_OK) goto bail; result = g_deckLinkInput->StartStreams(); if (result != S_OK) goto bail; // All Okay. exitStatus = 0; pthread_mutex_lock(&g_sleepMutex); pthread_cond_wait(&g_sleepCond, &g_sleepMutex); pthread_mutex_unlock(&g_sleepMutex); fprintf(stderr, "Stopping Capture\n"); g_deckLinkInput->StopStreams(); g_deckLinkInput->DisableAudioInput(); g_deckLinkInput->DisableVideoInput(); } bail: if (g_videoOutputFile != 0) close(g_videoOutputFile); if (g_audioOutputFile != 0) close(g_audioOutputFile); if (displayModeName != NULL) free(displayModeName); if (displayMode != NULL) displayMode->Release(); if (displayModeIterator != NULL) displayModeIterator->Release(); if (g_deckLinkInput != NULL) { g_deckLinkInput->Release(); g_deckLinkInput = NULL; } if (deckLinkAttributes != NULL) deckLinkAttributes->Release(); if (deckLink != NULL) deckLink->Release(); if (deckLinkIterator != NULL) deckLinkIterator->Release(); close(g_video_sock); close(g_audio_sock); return exitStatus; }
int main (int argc, char *argv[]) { IDeckLinkIterator *deckLinkIterator = CreateDeckLinkIteratorInstance (); DeckLinkCaptureDelegate *delegate; IDeckLinkDisplayMode *displayMode; BMDVideoInputFlags inputFlags = 0; BMDDisplayMode selectedDisplayMode = bmdModeNTSC; BMDPixelFormat pixelFormat = bmdFormat8BitYUV; int displayModeCount = 0; int exitStatus = 1; int ch; bool foundDisplayMode = false; HRESULT result; pthread_mutex_init (&sleepMutex, NULL); pthread_cond_init (&sleepCond, NULL); if (!deckLinkIterator) { fprintf (stderr, "This application requires the DeckLink drivers installed.\n"); goto bail; } /* Connect to the first DeckLink instance */ result = deckLinkIterator->Next (&deckLink); if (result != S_OK) { fprintf (stderr, "No DeckLink PCI cards found.\n"); goto bail; } if (deckLink->QueryInterface (IID_IDeckLinkInput, (void **) &deckLinkInput) != S_OK) goto bail; delegate = new DeckLinkCaptureDelegate (); deckLinkInput->SetCallback (delegate); // Obtain an IDeckLinkDisplayModeIterator to enumerate the display modes supported on output result = deckLinkInput->GetDisplayModeIterator (&displayModeIterator); if (result != S_OK) { fprintf (stderr, "Could not obtain the video output display mode iterator - result = %08x\n", result); goto bail; } // Parse command line options while ((ch = getopt (argc, argv, "?h3c:s:f:a:m:n:p:t:")) != -1) { switch (ch) { case 'm': g_videoModeIndex = atoi (optarg); break; case 'c': g_audioChannels = atoi (optarg); if (g_audioChannels != 2 && g_audioChannels != 8 && g_audioChannels != 16) { fprintf (stderr, "Invalid argument: Audio Channels must be either 2, 8 or 16\n"); goto bail; } break; case 's': g_audioSampleDepth = atoi (optarg); if (g_audioSampleDepth != 16 && g_audioSampleDepth != 32) { fprintf (stderr, "Invalid argument: Audio Sample Depth must be either 16 bits or 32 bits\n"); goto bail; } break; case 'f': g_videoOutputFile = optarg; break; case 'a': g_audioOutputFile = optarg; break; case 'n': g_maxFrames = atoi (optarg); break; case '3': inputFlags |= bmdVideoInputDualStream3D; break; case 'p': switch (atoi (optarg)) { case 0: pixelFormat = bmdFormat8BitYUV; break; case 1: pixelFormat = bmdFormat10BitYUV; break; case 2: pixelFormat = bmdFormat10BitRGB; break; default: fprintf (stderr, "Invalid argument: Pixel format %d is not valid", atoi (optarg)); goto bail; } break; case 't': if (!strcmp (optarg, "rp188")) g_timecodeFormat = bmdTimecodeRP188; else if (!strcmp (optarg, "vitc")) g_timecodeFormat = bmdTimecodeVITC; else if (!strcmp (optarg, "serial")) g_timecodeFormat = bmdTimecodeSerial; else { fprintf (stderr, "Invalid argument: Timecode format \"%s\" is invalid\n", optarg); goto bail; } break; case '?': case 'h': usage (0); } } if (g_videoModeIndex < 0) { fprintf (stderr, "No video mode specified\n"); usage (0); } if (g_videoOutputFile != NULL) { videoOutputFile = open (g_videoOutputFile, O_WRONLY | O_CREAT | O_TRUNC, 0664); if (videoOutputFile < 0) { fprintf (stderr, "Could not open video output file \"%s\"\n", g_videoOutputFile); goto bail; } } if (g_audioOutputFile != NULL) { audioOutputFile = open (g_audioOutputFile, O_WRONLY | O_CREAT | O_TRUNC, 0664); if (audioOutputFile < 0) { fprintf (stderr, "Could not open audio output file \"%s\"\n", g_audioOutputFile); goto bail; } } while (displayModeIterator->Next (&displayMode) == S_OK) { if (g_videoModeIndex == displayModeCount) { BMDDisplayModeSupport result; const char *displayModeName; foundDisplayMode = true; displayMode->GetName (&displayModeName); selectedDisplayMode = displayMode->GetDisplayMode (); deckLinkInput->DoesSupportVideoMode (selectedDisplayMode, pixelFormat, bmdVideoInputFlagDefault, &result, NULL); if (result == bmdDisplayModeNotSupported) { fprintf (stderr, "The display mode %s is not supported with the selected pixel format\n", displayModeName); goto bail; } if (inputFlags & bmdVideoInputDualStream3D) { if (!(displayMode->GetFlags () & bmdDisplayModeSupports3D)) { fprintf (stderr, "The display mode %s is not supported with 3D\n", displayModeName); goto bail; } } break; } displayModeCount++; displayMode->Release (); } if (!foundDisplayMode) { fprintf (stderr, "Invalid mode %d specified\n", g_videoModeIndex); goto bail; } result = deckLinkInput->EnableVideoInput (selectedDisplayMode, pixelFormat, inputFlags); if (result != S_OK) { fprintf (stderr, "Failed to enable video input. Is another application using the card?\n"); goto bail; } result = deckLinkInput->EnableAudioInput (bmdAudioSampleRate48kHz, g_audioSampleDepth, g_audioChannels); if (result != S_OK) { goto bail; } result = deckLinkInput->StartStreams (); if (result != S_OK) { goto bail; } // All Okay. exitStatus = 0; // Block main thread until signal occurs pthread_mutex_lock (&sleepMutex); pthread_cond_wait (&sleepCond, &sleepMutex); pthread_mutex_unlock (&sleepMutex); fprintf (stderr, "Stopping Capture\n"); bail: if (videoOutputFile) close (videoOutputFile); if (audioOutputFile) close (audioOutputFile); if (displayModeIterator != NULL) { displayModeIterator->Release (); displayModeIterator = NULL; } if (deckLinkInput != NULL) { deckLinkInput->Release (); deckLinkInput = NULL; } if (deckLink != NULL) { deckLink->Release (); deckLink = NULL; } if (deckLinkIterator != NULL) deckLinkIterator->Release (); return exitStatus; }