Example #1
0
IDeckLinkDisplayMode *BMDOutputDelegate::GetDisplayModeByIndex(int selectedIndex)
{
	// Populate the display mode combo with a list of display modes supported by the installed DeckLink card
	IDeckLinkDisplayModeIterator*		displayModeIterator;
	IDeckLinkDisplayMode*			deckLinkDisplayMode;
	IDeckLinkDisplayMode*			selectedMode = NULL;
	int index = 0;

	if (m_deckLinkOutput->GetDisplayModeIterator(&displayModeIterator) != S_OK)
		goto bail;
		
	while (displayModeIterator->Next(&deckLinkDisplayMode) == S_OK)
	{
		const char *modeName;
	
		if (deckLinkDisplayMode->GetName(&modeName) == S_OK)
		{
				if (index == selectedIndex)
				{
					printf("Selected mode: %s\n", modeName);
					selectedMode = deckLinkDisplayMode;
					goto bail;
				}
		}
		index++;
	}
bail:
	displayModeIterator->Release();
	return selectedMode; 
}
Example #2
0
    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, &timescale );
                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;
    }
Example #3
0
	IDeckLinkDisplayMode* getDisplayMode()
	{
		mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( getConsumer() ) );
		IDeckLinkDisplayModeIterator* iter = NULL;
		IDeckLinkDisplayMode* mode = NULL;
		IDeckLinkDisplayMode* result = 0;

		if ( m_deckLinkOutput->GetDisplayModeIterator( &iter ) == S_OK )
		{
			while ( !result && iter->Next( &mode ) == S_OK )
			{
				m_width = mode->GetWidth();
				m_height = mode->GetHeight();
				mode->GetFrameRate( &m_duration, &m_timescale );
				m_fps = (double) m_timescale / m_duration;
				int p = mode->GetFieldDominance() == bmdProgressiveFrame;
				mlt_log_verbose( getConsumer(), "BMD mode %dx%d %.3f fps prog %d\n", m_width, m_height, m_fps, p );

				if ( m_width == profile->width && p == profile->progressive
					 && (int) m_fps == (int) mlt_profile_fps( profile )
					 && ( m_height == profile->height || ( m_height == 486 && profile->height == 480 ) ) )
					result = mode;
				else
					SAFE_RELEASE( mode );
			}
			SAFE_RELEASE( iter );
		}

		return result;
	}
Example #4
0
        void open_input(unsigned int norm) {
            IDeckLinkDisplayModeIterator *it;

            assert(deckLink != NULL);
            assert(norm < sizeof(norms) / sizeof(struct decklink_norm));

            if (deckLink->QueryInterface(IID_IDeckLinkInput,
                    (void **) &deckLinkInput) != S_OK) {
                        
                throw std::runtime_error(
                    "DeckLink input: failed to get IDeckLinkInput"
                );
            }

            if (deckLinkInput->GetDisplayModeIterator(&it) != S_OK) {
                throw std::runtime_error(
                    "DeckLink input: failed to get display mode iterator"
                );
            }
            
            dominance = find_dominance(norms[norm].mode, it);

            it->Release( );

            if (deckLinkInput->EnableVideoInput(norms[norm].mode,
                    bpf, 0) != S_OK) {
                
                throw std::runtime_error(
                    "DeckLink input: failed to enable video input"
                );
            }

            fprintf(stderr, "DeckLink: opening input using norm %s\n",
                    norms[norm].name);
        }
bool	PlaybackHelper::setupDeckLinkOutput()
{
	bool							result = false;
    IDeckLinkDisplayModeIterator*	displayModeIterator = NULL;
    IDeckLinkDisplayMode*			deckLinkDisplayMode = NULL;
	
	m_width = -1;
	
	// set callback
	m_deckLinkOutput->SetScheduledFrameCompletionCallback(this);
	
	// get frame scale and duration for the video mode
    if (m_deckLinkOutput->GetDisplayModeIterator(&displayModeIterator) != S_OK)
		goto bail;
	
    while (displayModeIterator->Next(&deckLinkDisplayMode) == S_OK)
    {
		if (deckLinkDisplayMode->GetDisplayMode() == bmdModeNTSC)
		{
			m_width = deckLinkDisplayMode->GetWidth();
			m_height = deckLinkDisplayMode->GetHeight();
			deckLinkDisplayMode->GetFrameRate(&m_frameDuration, &m_timeScale);
			deckLinkDisplayMode->Release();
			
			break;
		}
		
		deckLinkDisplayMode->Release();
    }
	
    displayModeIterator->Release();
	
	if (m_width == -1)
	{
		fprintf(stderr, "Unable to find requested video mode\n");
		goto bail;
	}
	
	// enable video output
	if (m_deckLinkOutput->EnableVideoOutput(bmdModeNTSC, bmdVideoOutputFlagDefault) != S_OK)
	{
		fprintf(stderr, "Could not enable video output\n");
		goto bail;
	}
	
	// create coloured frames
	if (! createFrames())
		goto bail;
	
	result = true;
	
bail:
	if (! result)
	{
		// release coloured frames
		releaseFrames();
	}
	
	return result;
}
Example #6
0
IDeckLinkDisplayMode *Player::GetDisplayModeByIndex(int selectedIndex)
{
    // Populate the display mode combo with a list of display modes supported by the installed DeckLink card
    IDeckLinkDisplayModeIterator *displayModeIterator;
    IDeckLinkDisplayMode *deckLinkDisplayMode;
    IDeckLinkDisplayMode *selectedMode = NULL;
    int index                          = 0;

    if (m_deckLinkOutput->GetDisplayModeIterator(&displayModeIterator) != S_OK)
        goto bail;
    while (displayModeIterator->Next(&deckLinkDisplayMode) == S_OK) {
        BMDProbeString str;

        if (deckLinkDisplayMode->GetName(&str) == S_OK) {
            if (index == selectedIndex) {
                printf("Selected mode: %s\n\n\n", ToStr(str));
                selectedMode = deckLinkDisplayMode;
                FreeStr(str);
                goto bail;
            }
        }
        index++;
    }
bail:
    displayModeIterator->Release();
    return selectedMode;
}
void CSignalGeneratorDlg::RefreshDisplayModeMenu(void)
{
	// Populate the display mode combo with a list of display modes supported by the installed DeckLink card
	IDeckLinkDisplayModeIterator*	displayModeIterator;
	IDeckLinkDisplayMode*			deckLinkDisplayMode;
	BMDPixelFormat					pixelFormat;
	
	pixelFormat = (BMDPixelFormat)m_pixelFormatCombo.GetItemData(m_pixelFormatCombo.GetCurSel());

	for (int i = 1; i < m_videoFormatCombo.GetCount(); i++)
	{
		deckLinkDisplayMode = (IDeckLinkDisplayMode*)m_videoFormatCombo.GetItemDataPtr(i-1);
		deckLinkDisplayMode->Release();
	}
	m_videoFormatCombo.ResetContent();
	
	if (m_deckLinkOutput->GetDisplayModeIterator(&displayModeIterator) != S_OK)
		return;
	
	while (displayModeIterator->Next(&deckLinkDisplayMode) == S_OK)
	{
		BSTR					modeName;
		int						newIndex;
		HRESULT					hr;
		BMDDisplayModeSupport	displayModeSupport;
		BMDVideoOutputFlags		videoOutputFlags = bmdVideoOutputDualStream3D;

		if (deckLinkDisplayMode->GetName(&modeName) != S_OK)
		{
			deckLinkDisplayMode->Release();
			continue;
		}
		
		CString modeNameCString(modeName);
		newIndex = m_videoFormatCombo.AddString(modeNameCString);
		m_videoFormatCombo.SetItemDataPtr(newIndex, deckLinkDisplayMode); 
		
		hr = m_deckLinkOutput->DoesSupportVideoMode(deckLinkDisplayMode->GetDisplayMode(), pixelFormat, videoOutputFlags, &displayModeSupport, NULL);
		if (hr != S_OK || ! displayModeSupport)
		{
			SysFreeString(modeName);
			continue;
		}

		CString modeName3DCString(modeName);
		modeName3DCString += _T(" 3D");
		newIndex = m_videoFormatCombo.AddString(modeName3DCString);
		m_videoFormatCombo.SetItemDataPtr(newIndex, deckLinkDisplayMode);
		deckLinkDisplayMode->AddRef();

		SysFreeString(modeName);
	}
	displayModeIterator->Release();

	m_videoFormatCombo.SetCurSel(0);
}
bool DeckLinkController::selectDevice(int index)  {
	IDeckLinkAttributes* deckLinkAttributes = NULL;
	IDeckLinkDisplayModeIterator* displayModeIterator = NULL;
	IDeckLinkDisplayMode* displayMode = NULL;
	bool result = false;
	
	// Check index
	if (index >= deviceList.size()) {
		ofLogError("DeckLinkController") << "This application was unable to select the device.";
		goto bail;
	}
	
	// A new device has been selected.
	// Release the previous selected device and mode list
	if (deckLinkInput != NULL)
		deckLinkInput->Release();
	
	while(modeList.size() > 0) {
		modeList.back()->Release();
		modeList.pop_back();
	}
	
	
	// Get the IDeckLinkInput for the selected device
	if ((deviceList[index]->QueryInterface(IID_IDeckLinkInput, (void**)&deckLinkInput) != S_OK)) {
		ofLogError("DeckLinkController") << "This application was unable to obtain IDeckLinkInput for the selected device.";
		deckLinkInput = NULL;
		goto bail;
	}
	
	//
	// Retrieve and cache mode list
	if (deckLinkInput->GetDisplayModeIterator(&displayModeIterator) == S_OK) {
		while (displayModeIterator->Next(&displayMode) == S_OK)
			modeList.push_back(displayMode);
		
		displayModeIterator->Release();
	}
	
	//
	// Check if input mode detection format is supported.
	
	supportFormatDetection = false; // assume unsupported until told otherwise
	if (deviceList[index]->QueryInterface(IID_IDeckLinkAttributes, (void**) &deckLinkAttributes) == S_OK) {
		if (deckLinkAttributes->GetFlag(BMDDeckLinkSupportsInputFormatDetection, &supportFormatDetection) != S_OK)
			supportFormatDetection = false;
		
		deckLinkAttributes->Release();
	}
	
	result = true;
	
bail:
	return result;
}
Example #9
0
	bool Output::startDeckLink(BMDDisplayMode mode)
	{
		IDeckLinkDisplayModeIterator* pDLDisplayModeIterator = NULL;
		IDeckLinkDisplayMode* pDLDisplayMode = NULL;

		if (pDLOutput->GetDisplayModeIterator(&pDLDisplayModeIterator) == S_OK)
		{
			while (pDLDisplayModeIterator->Next(&pDLDisplayMode) == S_OK)
			{
				if (pDLDisplayMode->GetDisplayMode() == mode)
				{
					break;
				}
			}

			pDLDisplayModeIterator->Release();
		}

		if (!pDLDisplayMode)
		{
			ofLogError("ofxDeckLinkAPI::Output") << "invalid display mode";
			return false;
		}

		uiFrameWidth = pDLDisplayMode->GetWidth();
		uiFrameHeight = pDLDisplayMode->GetHeight();

		pixels[0].allocate(uiFrameWidth, uiFrameHeight, 4);
		pixels[1].allocate(uiFrameWidth, uiFrameHeight, 4);

		front_buffer = &pixels[0];
		back_buffer = &pixels[1];

		pDLDisplayMode->GetFrameRate(&frameDuration, &frameTimescale);

		uiFPS = ((frameTimescale + (frameDuration - 1)) / frameDuration);

		if (pDLOutput->EnableVideoOutput(pDLDisplayMode->GetDisplayMode(), bmdVideoOutputFlagDefault) != S_OK)
			return false;

		if (pDLOutput->CreateVideoFrame(uiFrameWidth, uiFrameHeight, uiFrameWidth * 4, bmdFormat8BitARGB, bmdFrameFlagDefault, &pDLVideoFrame) != S_OK)
			return false;

		uiTotalFrames = 0;

		resetFrame();
		setPreroll();

		pDLOutput->StartScheduledPlayback(0, frameTimescale, 1);

		return true;
	}
// select output device
bool DeckLinkController::selectOutputDevice(int index)  {
    IDeckLinkAttributes* deckLinkAttributes = NULL;
    IDeckLinkDisplayModeIterator* displayModeIterator = NULL;
    IDeckLinkDisplayMode* displayMode = NULL;
    bool result = false;
    
    // Check index
    if (index >= deviceList.size()) {
        ofLogError("DeckLinkController") << "This application was unable to select the device.";
        goto bail;
    }
    
    // A new device has been selected.
    // Release the previous selected device and mode list
    if (deckLinkInput != NULL)
        deckLinkInput->Release();
    
    while(modeList.size() > 0) {
        modeList.back()->Release();
        modeList.pop_back();
    }
    
    
    // Get the IDeckLinkOutput for the selected device
    if ((deviceList[index]->QueryInterface(IID_IDeckLinkOutput, (void**)&deckLinkOutput) != S_OK)) {
        ofLogError("DeckLinkController") << "This application was unable to obtain IDeckLinkOutput for the selected device.";
        deckLinkOutput = NULL;
        goto bail;
    }

    
    if ((deckLinkOutput->CreateVideoFrame(1280, 720, 1280*4,bmdFormat8BitBGRA, bmdFrameFlagDefault, &videoFrame) != S_OK)) {
        ofLogError("DeckLinkController") << "Create video frame error";
        goto bail;
    }

    
    // Retrieve and cache mode list
    if (deckLinkOutput->GetDisplayModeIterator(&displayModeIterator) == S_OK) {
        while (displayModeIterator->Next(&displayMode) == S_OK) {
            modeList.push_back(displayMode);
        }
        displayModeIterator->Release();
    }

    result = true;
    
bail:
    return result;
}
Example #11
0
int ff_decklink_list_formats(AVFormatContext *avctx, decklink_direction_t direction)
{
    struct decklink_cctx *cctx = (struct decklink_cctx *)avctx->priv_data;
    struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx;
    IDeckLinkDisplayModeIterator *itermode;
    IDeckLinkDisplayMode *mode;
    uint32_t format_code;
    HRESULT res;

    if (direction == DIRECTION_IN) {
        int ret;
        ret = decklink_select_input(avctx, bmdDeckLinkConfigAudioInputConnection);
        if (ret < 0)
            return ret;
        ret = decklink_select_input(avctx, bmdDeckLinkConfigVideoInputConnection);
        if (ret < 0)
            return ret;
        res = ctx->dli->GetDisplayModeIterator (&itermode);
    } else {
        res = ctx->dlo->GetDisplayModeIterator (&itermode);
    }

    if (res!= S_OK) {
            av_log(avctx, AV_LOG_ERROR, "Could not get Display Mode Iterator\n");
            return AVERROR(EIO);
    }

    av_log(avctx, AV_LOG_INFO, "Supported formats for '%s':\n\tformat_code\tdescription",
               avctx->filename);
    while (itermode->Next(&mode) == S_OK) {
        BMDTimeValue tb_num, tb_den;
        mode->GetFrameRate(&tb_num, &tb_den);
        format_code = av_bswap32(mode->GetDisplayMode());
        av_log(avctx, AV_LOG_INFO, "\n\t%.4s\t\t%ldx%ld at %d/%d fps",
                (char*) &format_code, mode->GetWidth(), mode->GetHeight(),
                (int) tb_den, (int) tb_num);
        switch (mode->GetFieldDominance()) {
        case bmdLowerFieldFirst:
        av_log(avctx, AV_LOG_INFO, " (interlaced, lower field first)"); break;
        case bmdUpperFieldFirst:
        av_log(avctx, AV_LOG_INFO, " (interlaced, upper field first)"); break;
        }
        mode->Release();
    }
    av_log(avctx, AV_LOG_INFO, "\n");

    itermode->Release();

    return 0;
}
Example #12
0
		//----------
		Specification DeckLink::open(shared_ptr<Base::InitialisationSettings> initialisationSettings) {
			auto settings = this->getTypedSettings<InitialisationSettings>(initialisationSettings);

			auto devices = ofxBlackmagic::Iterator::getDeviceList();
			if (devices.empty()) {
				throw(ofxMachineVision::Exception("No DeckLink devices available"));
			}
			if (devices.size() <= (unsigned int)settings->deviceID) {
				string str = "deviceID [" + ofToString(settings->deviceID) + "] out of range. [" + ofToString(devices.size()) + "] devices available";
				throw(ofxMachineVision::Exception(str));
			}
			this->device = devices[settings->deviceID];
			int width, height;

			this->displayMode = static_cast<_BMDDisplayMode>(settings->displayMode.get());

			try {
				CHECK_ERRORS(device.device->QueryInterface(IID_IDeckLinkInput, (void**)&this->input), "Failed to query interface");
				CHECK_ERRORS(this->input->SetCallback(this), "Failed to set input callback");

				//find the current display mode
				IDeckLinkDisplayModeIterator * displayModeIterator = 0;
				CHECK_ERRORS(input->GetDisplayModeIterator(&displayModeIterator), "Couldn't get DisplayModeIterator");
				IDeckLinkDisplayMode * displayModeTest = nullptr;
				IDeckLinkDisplayMode * displayModeFound = nullptr;
				while (displayModeIterator->Next(&displayModeTest) == S_OK) {
					if (displayModeTest->GetDisplayMode() == this->displayMode) {
						displayModeFound = displayModeTest;
					}
				}

				if (!displayModeFound) {
					CHECK_ERRORS(S_FALSE, "Cannot find displayMode");
				}
				width = displayModeFound->GetWidth();
				height = displayModeFound->GetHeight();
			}
			catch (std::exception e) {
				throw(ofxMachineVision::Exception(e.what()));
			}
			
			this->openTime = ofGetElapsedTimeMicros();
			this->frameIndex = 0;

			Specification specification(width, height, "BlackMagic", device.modelName);
			specification.addFeature(ofxMachineVision::Feature::Feature_DeviceID);
			specification.addFeature(ofxMachineVision::Feature::Feature_FreeRun);

			return specification;
		}
int ff_decklink_list_formats(AVFormatContext *avctx, decklink_direction_t direction)
{
    struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data;
    struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx;
    IDeckLinkDisplayModeIterator *itermode;
    IDeckLinkDisplayMode *mode;
    int i=0;
    HRESULT res;

    if (direction == DIRECTION_IN) {
        res = ctx->dli->GetDisplayModeIterator (&itermode);
    } else {
        res = ctx->dlo->GetDisplayModeIterator (&itermode);
    }

    if (res!= S_OK) {
            av_log(avctx, AV_LOG_ERROR, "Could not get Display Mode Iterator\n");
            return AVERROR(EIO);
    }

    av_log(avctx, AV_LOG_INFO, "Supported formats for '%s':\n",
               avctx->filename);
    while (itermode->Next(&mode) == S_OK) {
        BMDTimeValue tb_num, tb_den;
        mode->GetFrameRate(&tb_num, &tb_den);
        av_log(avctx, AV_LOG_INFO, "\t%d\t%ldx%ld at %d/%d fps",
                ++i,mode->GetWidth(), mode->GetHeight(),
                (int) tb_den, (int) tb_num);
        switch (mode->GetFieldDominance()) {
        case bmdLowerFieldFirst:
        av_log(avctx, AV_LOG_INFO, " (interlaced, lower field first)"); break;
        case bmdUpperFieldFirst:
        av_log(avctx, AV_LOG_INFO, " (interlaced, upper field first)"); break;
        }
        av_log(avctx, AV_LOG_INFO, "\n");
        mode->Release();
    }

    itermode->Release();

    return 0;
}
Example #14
0
        void open_card( ) {
            IDeckLinkDisplayModeIterator *it;

            /* get the DeckLinkOutput interface */
            if (deckLink->QueryInterface(IID_IDeckLinkOutput, 
                    (void **)&deckLinkOutput) != S_OK) {
                
                throw std::runtime_error(
                    "Failed to get DeckLink output interface handle"
                );
            }
            
            if (deckLinkOutput->SetScheduledFrameCompletionCallback(this) 
                   != S_OK) {

                throw std::runtime_error(
                    "Failed to set DeckLink frame completion callback"
                );
            }

            /* attempt to determine field dominance */
            if (deckLinkOutput->GetDisplayModeIterator(&it) != S_OK) {
                throw std::runtime_error(
                    "DeckLink output: failed to get display mode iterator"
                );
            }
            
            dominance = find_dominance(norms[norm].mode, it);

            it->Release( );

            /* and we're off to the races */
            if (deckLinkOutput->EnableVideoOutput(norms[norm].mode,
                    bmdVideoOutputFlagDefault) != S_OK) {
                
                throw std::runtime_error(
                    "Failed to enable DeckLink video output"
                );
            }
        }
Example #15
0
IDeckLinkDisplayMode* BMDConfig::GetDeckLinkDisplayMode(IDeckLink* deckLink, int idx)
{
	HRESULT							result;
	IDeckLinkDisplayMode*			displayMode = NULL;
	IDeckLinkInput*					deckLinkInput = NULL;
	IDeckLinkDisplayModeIterator*	displayModeIterator = NULL;
	int								i = idx;

	result = deckLink->QueryInterface(IID_IDeckLinkInput, (void**)&deckLinkInput);
	if (result != S_OK)
		goto bail;

	result = deckLinkInput->GetDisplayModeIterator(&displayModeIterator);
	if (result != S_OK)
		goto bail;

	while ((result = displayModeIterator->Next(&displayMode)) == S_OK)
	{
		if (i == 0)
			break;
		--i;

		displayMode->Release();
	}

	if (result != S_OK)
		goto bail;

bail:
	if (displayModeIterator)
		displayModeIterator->Release();

	if (deckLinkInput)
		deckLinkInput->Release();

	return displayMode;
}
Example #16
0
bool BMDOpenGLOutput::Start()
{
    IDeckLinkDisplayModeIterator*		pDLDisplayModeIterator;
    IDeckLinkDisplayMode*				pDLDisplayMode = NULL;

    // Get first avaliable video mode for Output
    if (pDLOutput->GetDisplayModeIterator(&pDLDisplayModeIterator) == S_OK)
    {
        if (pDLDisplayModeIterator->Next(&pDLDisplayMode) != S_OK)
        {
            QMessageBox::critical(NULL,"DeckLink error.", "Cannot find video mode.");
            pDLDisplayModeIterator->Release();
            return false;
        }
        pDLDisplayModeIterator->Release();
    }

    uiFrameWidth = pDLDisplayMode->GetWidth();
    uiFrameHeight = pDLDisplayMode->GetHeight();
    pDLDisplayMode->GetFrameRate(&frameDuration, &frameTimescale);

    uiFPS = ((frameTimescale + (frameDuration-1))  /  frameDuration);

    if (pDLOutput->EnableVideoOutput(pDLDisplayMode->GetDisplayMode(), bmdVideoOutputFlagDefault) != S_OK)
        return false;

    // Flip frame vertical, because OpenGL rendering starts from left bottom corner
    if (pDLOutput->CreateVideoFrame(uiFrameWidth, uiFrameHeight, uiFrameWidth*4, bmdFormat8BitBGRA, bmdFrameFlagFlipVertical, &pDLVideoFrame) != S_OK)
        return false;

    uiTotalFrames = 0;

    ResetFrame();
    SetPreroll();

    pContext->makeCurrent();

    pGLScene->InitScene();

    glGenFramebuffersEXT(1, &idFrameBuf);
    glGenRenderbuffersEXT(1, &idColorBuf);
    glGenRenderbuffersEXT(1, &idDepthBuf);

    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, idFrameBuf);

    glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, idColorBuf);
    glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA8, uiFrameWidth, uiFrameHeight);
    glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, idDepthBuf);
    glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, uiFrameWidth, uiFrameHeight);

    glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, idColorBuf);
    glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, idDepthBuf);

    glStatus = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
    if (glStatus != GL_FRAMEBUFFER_COMPLETE_EXT)
    {
        QMessageBox::critical(NULL,"OpenGL initialization error.", "Cannot initialize framebuffer.");
        return false;
    }

    pFrameBuf = (char*)malloc(pDLVideoFrame->GetRowBytes() * uiFrameHeight);
    UpdateScene();

    pDLOutput->StartScheduledPlayback(0, 100, 1.0);

    return true;
}
Example #17
0
int _tmain(int argc, _TCHAR* argv[])
{
	int						numDevices = 0; 
	HRESULT					result;
	IDeckLinkAttributes		*deckLinkAttributes = NULL;
	HRESULT					attributeResult;
	BOOL					keyingSupported;
	BOOL					HDkeyingSupported;
	int						selectedMode = 0;

	printf("GDI Keyer Sample Application\n\n"); 
	// Initialize COM on this thread
	result = CoInitialize(NULL);

	if (FAILED(result))
	{
		fprintf(stderr, "Initialization of COM failed - result = %08x.\n", result);
		return 1;
	}
	
	// Create an IDeckLinkIterator object to enumerate all DeckLink cards in the system
	result = CoCreateInstance(CLSID_CDeckLinkIterator, NULL, CLSCTX_ALL, IID_IDeckLinkIterator, (void**)&deckLinkIterator);
	if (FAILED(result))
	{
		fprintf(stderr, "A DeckLink iterator could not be created.  The DeckLink drivers may not be installed.\n");
		return 1;
	}

	// Enumerate all cards in this system 
	while (deckLinkIterator->Next(&deckLink) == S_OK) 
	{ 
		BSTR	deviceNameBSTR = NULL; 
		 
		// Increment the total number of DeckLink cards found 
		numDevices++; 
		if (numDevices > 1) 
			printf("\n\n");	 
		 
		// *** Print the model name of the DeckLink card 
		result = deckLink->GetModelName(&deviceNameBSTR); 
		if (result == S_OK) 
		{	
			_bstr_t deviceName(deviceNameBSTR);		

			printf("Found Blackmagic device: %s\n", (char*)deviceName);
			attributeResult = deckLink->QueryInterface(IID_IDeckLinkAttributes, (void**)&deckLinkAttributes);
			if (attributeResult != S_OK)
			{
				fprintf(stderr, "Could not obtain the IDeckLinkAttributes interface");
				return 1;
			}
			else
			{
				attributeResult = deckLinkAttributes->GetFlag(BMDDeckLinkSupportsInternalKeying, &keyingSupported);	// is keying supported on this device?
				if (attributeResult == S_OK && keyingSupported)			
				{
					IDeckLinkDisplayModeIterator* displayModeIterator = NULL;
					IDeckLinkDisplayMode* deckLinkDisplayMode = NULL;

					attributeResult = deckLinkAttributes->GetFlag(BMDDeckLinkSupportsHDKeying, &HDkeyingSupported);
					if (attributeResult == S_OK && HDkeyingSupported)
						printf("HD Mode keying supported.\n");
					else
						printf("SD Mode Keying supported.\n");
					// check if automode detection support - if so, use it for autodetection				
					if (CheckFormatDetect(deckLinkAttributes) == 0)
					{
						fprintf(stderr, "Input mode detection not supported\n");

						if (deckLink->QueryInterface(IID_IDeckLinkOutput, (void**)&deckLinkOutput) != S_OK)
						{
							fprintf(stderr, "Could not obtain the IDeckLinkOutput interface\n");
						}
						else
						{
							int		index = 0;
							if (deckLinkOutput->GetDisplayModeIterator(&displayModeIterator) != S_OK)
							{
								fprintf(stderr, "Could not obtain the display mode iterator\n");
							}
							else
							{
								printf("\n");
								while (displayModeIterator->Next(&deckLinkDisplayMode) == S_OK)
								{
									BSTR			displayModeBSTR = NULL;
									int				modeWidth;
									int				modeHeight;
									BMDTimeValue	frameRateDuration;
									BMDTimeScale	frameRateScale;

									// Obtain the display mode's properties
									modeWidth = deckLinkDisplayMode->GetWidth();
									modeHeight = deckLinkDisplayMode->GetHeight();
									deckLinkDisplayMode->GetFrameRate(&frameRateDuration, &frameRateScale);
									if ((deckLinkDisplayMode->GetWidth() > 720) && !HDkeyingSupported)
										continue;

									if (deckLinkDisplayMode->GetName(&displayModeBSTR) == S_OK)
									{
										_bstr_t			modeName(displayModeBSTR, false);
										// Skip HD modes on cards such as DeckLink SDI (only PAL/NTSC are supported for keying)
										printf("%d %-20s \t %d x %d \t %g FPS\n", index, (char*)modeName, modeWidth, modeHeight, (double)frameRateScale / (double)frameRateDuration);					
									}
									deckLinkDisplayMode->Release();
									index++;
								}
								displayModeIterator->Release();

								printf("Select Mode (0-%d):\n", index-1);

								scanf_s("%d", &selectedMode);
								printf("Mode selected: %d\n", selectedMode);
								if(selectedMode < index)
								{
									int modeCount = 0;
									if (deckLinkOutput->GetDisplayModeIterator(&displayModeIterator) != S_OK)
									{
										fprintf(stderr, "Could not obtain the display mode iterator\n");
									}
									else
									{
										while(displayModeIterator->Next(&deckLinkDisplayMode) == S_OK)
										{
											if (selectedMode == modeCount)
											{
												OutputGraphic(deckLinkDisplayMode);
												deckLinkDisplayMode->Release();
												break;
											}
											deckLinkDisplayMode->Release();
											modeCount++;
										}										
										displayModeIterator->Release();
									}									
								}
								else
								{
									printf("Illegal video mode selected\n");
								}
							}

							deckLinkOutput->Release();
						}
					}
				}

				deckLinkAttributes->Release();
				printf("Press Enter key to exit.\n");
				_getch();
			}		
		}		 
		deckLink->Release(); // Release the IDeckLink instance when we've finished with it to prevent leaks
 	} 

	if (deckLinkIterator != NULL)
		deckLinkIterator->Release();

	// If no DeckLink cards were found in the system, inform the users
	if (numDevices == 0) 
		printf("No Blackmagic Design devices were found.\n");

	// Uninitalize COM on this thread
	CoUninitialize();
	return 0;
}
Example #18
0
bool DeckLinkDevice::Init()
{
	ComPtr<IDeckLinkAttributes> attributes;
	const HRESULT result = device->QueryInterface(IID_IDeckLinkAttributes,
			(void **)&attributes);

	if (result == S_OK) {
		decklink_bool_t detectable = false;
		if (attributes->GetFlag(BMDDeckLinkSupportsInputFormatDetection,
				&detectable) == S_OK && !!detectable) {
			DeckLinkDeviceMode *mode = new DeckLinkDeviceMode(
					"Auto",
					MODE_ID_AUTO);
			inputModes.push_back(mode);
			inputModeIdMap[MODE_ID_AUTO] = mode;
		}
	}

	// Find input modes
	ComPtr<IDeckLinkInput> input;
	if (device->QueryInterface(IID_IDeckLinkInput, (void **) &input) == S_OK) {
		IDeckLinkDisplayModeIterator *modeIterator;
		if (input->GetDisplayModeIterator(&modeIterator) == S_OK) {
			IDeckLinkDisplayMode *displayMode;
			long long modeId = 1;

			while (modeIterator->Next(&displayMode) == S_OK) {
				if (displayMode == nullptr)
					continue;

				DeckLinkDeviceMode *mode =
						new DeckLinkDeviceMode(displayMode, modeId);
				inputModes.push_back(mode);
				inputModeIdMap[modeId] = mode;
				displayMode->Release();
				++modeId;
			}

			modeIterator->Release();
		}
	}

	// find output modes
	ComPtr<IDeckLinkOutput> output;
	if (device->QueryInterface(IID_IDeckLinkOutput, (void **) &output) == S_OK) {

		IDeckLinkDisplayModeIterator *modeIterator;
		if (output->GetDisplayModeIterator(&modeIterator) == S_OK) {
			IDeckLinkDisplayMode *displayMode;
			long long modeId = 1;

			while (modeIterator->Next(&displayMode) == S_OK) {
				if (displayMode == nullptr)
					continue;

				DeckLinkDeviceMode *mode =
						new DeckLinkDeviceMode(displayMode, modeId);
				outputModes.push_back(mode);
				outputModeIdMap[modeId] = mode;
				displayMode->Release();
				++modeId;
			}

			modeIterator->Release();
		}
	}

	// get keyer support
	attributes->GetFlag(BMDDeckLinkSupportsExternalKeying, &supportsExternalKeyer);
	attributes->GetFlag(BMDDeckLinkSupportsInternalKeying, &supportsInternalKeyer);

	decklink_string_t decklinkModelName;
	decklink_string_t decklinkDisplayName;

	if (device->GetModelName(&decklinkModelName) != S_OK)
		return false;
	DeckLinkStringToStdString(decklinkModelName, name);

	if (device->GetDisplayName(&decklinkDisplayName) != S_OK)
		return false;
	DeckLinkStringToStdString(decklinkDisplayName, displayName);

	hash = displayName;

	if (result != S_OK)
		return true;

	int64_t channels;
	/* Intensity Shuttle for Thunderbolt return 2; however, it supports 8 channels */
	if (name == "Intensity Shuttle Thunderbolt")
		maxChannel = 8;
	else if (attributes->GetInt(BMDDeckLinkMaximumAudioChannels, &channels) == S_OK)
		maxChannel = (int32_t)channels;
	else
		maxChannel = 2;

	/* http://forum.blackmagicdesign.com/viewtopic.php?f=12&t=33967
	 * BMDDeckLinkTopologicalID for older devices
	 * BMDDeckLinkPersistentID for newer ones */

	int64_t value;
	if (attributes->GetInt(BMDDeckLinkPersistentID,  &value) != S_OK &&
	    attributes->GetInt(BMDDeckLinkTopologicalID, &value) != S_OK)
		return true;

	std::ostringstream os;
	os << value << "_" << name;
	hash = os.str();
	return true;
}
Example #19
0
// Prepare IDeckLinkInput to capture video:
// - Get frame width, height, duration, ...
// - Setup callback object and video mode and
// - Start streams
bool	CaptureHelper::setupDeckLinkInput()
{
	bool							result = false;
    IDeckLinkDisplayModeIterator*	displayModeIterator = NULL;
    IDeckLinkDisplayMode*			deckLinkDisplayMode = NULL;
	
	m_width = -1;
	
	// get frame scale and duration for the video mode
    if (m_deckLinkInput->GetDisplayModeIterator(&displayModeIterator) != S_OK)
		goto bail;
	
    while (displayModeIterator->Next(&deckLinkDisplayMode) == S_OK)
    {
		if (deckLinkDisplayMode->GetDisplayMode() == BMD_DISPLAYMODE)
		{
			m_width = deckLinkDisplayMode->GetWidth();
			m_height = deckLinkDisplayMode->GetHeight();
			deckLinkDisplayMode->GetFrameRate(&m_frameDuration, &m_timeScale);
			deckLinkDisplayMode->Release();
			
			break;
		}
		
		deckLinkDisplayMode->Release();
    }
	
    displayModeIterator->Release();
	
	if (m_width == -1)
	{
		printf("Unable to find requested video mode\n");
		goto bail;
	}
	
	// convert the in- and out-point timecodes to a frame count
	GET_FRAME_COUNT(m_inPointFrameCount, START_TC, m_timeScale, m_frameDuration);
	GET_FRAME_COUNT(m_outPointFrameCount, STOP_TC, m_timeScale, m_frameDuration);
	
	// set callback
	m_deckLinkInput->SetCallback(this);
	
	// enable video input
	if (m_deckLinkInput->EnableVideoInput(BMD_DISPLAYMODE, PIXEL_FMT, bmdVideoInputFlagDefault) != S_OK)
	{
		printf("Could not enable video input\n");
		goto bail;
	}
	
	// start streaming
	if (m_deckLinkInput->StartStreams() != S_OK)
	{
		printf("Could not start streams\n");
		goto bail;
	}

	
	result = true;
	
bail:
	return result;
}
Example #20
0
void print_output_modes(IDeckLink *deckLink)
{
    IDeckLinkOutput *deckLinkOutput                   = NULL;
    IDeckLinkDisplayModeIterator *displayModeIterator = NULL;
    IDeckLinkDisplayMode *displayMode                 = NULL;
    HRESULT result;
    int displayModeCount = 0;

    // Query the DeckLink for its configuration interface
    result = deckLink->QueryInterface(IID_IDeckLinkOutput,
                                      (void **)&deckLinkOutput);
    if (result != S_OK) {
        fprintf(
            stderr,
            "Could not obtain the IDeckLinkOutput interface - result = %08x\n",
            result);
        goto bail;
    }

    // Obtain an IDeckLinkDisplayModeIterator to enumerate the display modes supported on output
    result = deckLinkOutput->GetDisplayModeIterator(&displayModeIterator);
    if (result != S_OK) {
        fprintf(
            stderr,
            "Could not obtain the video output display mode iterator - result = %08x\n",
            result);
        goto bail;
    }

    // List all supported output display modes
    printf("Supported video output display modes and pixel formats:\n");
    while (displayModeIterator->Next(&displayMode) == S_OK) {
        BMDProbeString str;

        result = displayMode->GetName(&str);
        if (result == S_OK) {
            char modeName[64];
            int modeWidth;
            int modeHeight;
            BMDTimeValue frameRateDuration;
            BMDTimeScale frameRateScale;
            int pixelFormatIndex = 0;                                                         // index into the gKnownPixelFormats / gKnownFormatNames arrays
            BMDDisplayModeSupport displayModeSupport;
            // Obtain the display mode's properties
            modeWidth  = displayMode->GetWidth();
            modeHeight = displayMode->GetHeight();
            displayMode->GetFrameRate(&frameRateDuration, &frameRateScale);
            printf("        %2d:   %-20s \t %d x %d \t %7g FPS\n",
                   displayModeCount++, ToStr(str), modeWidth, modeHeight,
                   (double)frameRateScale / (double)frameRateDuration);

            FreeStr(str);
        }
        // Release the IDeckLinkDisplayMode object to prevent a leak
        displayMode->Release();
    }
//	printf("\n");
bail:
    // Ensure that the interfaces we obtained are released to prevent a memory leak
    if (displayModeIterator != NULL)
        displayModeIterator->Release();
    if (deckLinkOutput != NULL)
        deckLinkOutput->Release();
}
bool ofxBlackmagicGrabber::initGrabber(int w, int h) {
	IDeckLinkIterator			*deckLinkIterator = CreateDeckLinkIteratorInstance();
	int							displayModeCount = 0;
	int							exitStatus = 1;
	bool 						foundDisplayMode = false;
	HRESULT						result;
	IDeckLinkDisplayModeIterator	*displayModeIterator;

	if (!deckLinkIterator){
		ofLogError(LOG_NAME) <<  "This application requires the DeckLink drivers installed.";
		goto bail;
	}

	for(int i=0;i<deviceID+1;i++){
		result = deckLinkIterator->Next(&deckLink);
		if (result != S_OK){
			ofLogError(LOG_NAME) <<  "Couldn't open device" << deviceID;
			goto bail;
		}
	}

	if (deckLink->QueryInterface(IID_IDeckLinkInput, (void**)&deckLinkInput) != S_OK)
		goto bail;

	deckLinkInput->SetCallback(this);

	// Obtain an IDeckLinkDisplayModeIterator to enumerate the display modes supported on output
	result = deckLinkInput->GetDisplayModeIterator(&displayModeIterator);
	if (result != S_OK){
		ofLogError(LOG_NAME) << "Could not obtain the video output display mode iterator - result =" << result;
		goto bail;
	}


	if (g_videoModeIndex < 0){
		ofLogError(LOG_NAME) <<  "No video mode specified, specify it before initGrabber using setVideoMode";
		goto bail;
	}


	while (displayModeIterator->Next(&displayMode) == S_OK){
		if (g_videoModeIndex == displayMode->GetDisplayMode()){
			BMDDisplayModeSupport result;
			CFStringRef displayModeName;

			foundDisplayMode = true;
			displayMode->GetName(&displayModeName);
			selectedDisplayMode = displayMode->GetDisplayMode();

			pixels[0].allocate(displayMode->GetWidth(),displayMode->GetHeight(),OF_IMAGE_COLOR);
			pixels[1].allocate(displayMode->GetWidth(),displayMode->GetHeight(),OF_IMAGE_COLOR);

			ofLogVerbose(LOG_NAME) << "device initialized:" << displayMode->GetWidth() << displayMode->GetHeight();

			deckLinkInput->DoesSupportVideoMode(selectedDisplayMode, pixelFormat, bmdVideoInputFlagDefault, &result, NULL);

			if (result == bmdDisplayModeNotSupported){
				ofLogError(LOG_NAME) <<  "The display mode" << displayModeName << "is not supported with the selected pixel format";
				goto bail;
			}

			if (inputFlags & bmdVideoInputDualStream3D){
				if (!(displayMode->GetFlags() & bmdDisplayModeSupports3D)){
					ofLogError(LOG_NAME) <<  "The display mode" << displayModeName  << "is not supported with 3D";
					goto bail;
				}
			}

			break;
		}
		displayModeCount++;
		displayMode->Release();
	}

	if (!foundDisplayMode){
		ofLogError(LOG_NAME) <<  "Invalid mode" << g_videoModeIndex << "specified";
		goto bail;
	}

	result = deckLinkInput->EnableVideoInput(selectedDisplayMode, pixelFormat, inputFlags);
	if(result != S_OK){
		ofLogError(LOG_NAME) <<  "Failed to enable video input. Is another application using the card?";
		goto bail;
	}

#if 0  // no audio by now
	result = deckLinkInput->EnableAudioInput(bmdAudioSampleRate48kHz, g_audioSampleDepth, g_audioChannels);
	if(result != S_OK){
		goto bail;
	}
#endif

	result = deckLinkInput->StartStreams();
	if(result != S_OK){
		goto bail;
	}

	// All Okay.
	exitStatus = 0;
	return true;

bail:

	if (displayModeIterator != NULL){
		displayModeIterator->Release();
		displayModeIterator = NULL;
	}

	if (deckLinkIterator != NULL)
		deckLinkIterator->Release();

	close();

	return false;
}
static void	print_output_modes (IDeckLink* deckLink)
{
	IDeckLinkOutput*					deckLinkOutput = NULL;
	IDeckLinkDisplayModeIterator*		displayModeIterator = NULL;
	IDeckLinkDisplayMode*				displayMode = NULL;
	HRESULT								result;

	// Query the DeckLink for its configuration interface
	result = deckLink->QueryInterface(IID_IDeckLinkOutput, (void**)&deckLinkOutput);
	if (result != S_OK)
	{
		fprintf(stderr, "Could not obtain the IDeckLinkOutput interface - result = %08x\n", result);
		goto bail;
	}

	// Obtain an IDeckLinkDisplayModeIterator to enumerate the display modes supported on output
	result = deckLinkOutput->GetDisplayModeIterator(&displayModeIterator);
	if (result != S_OK)
	{
		fprintf(stderr, "Could not obtain the video output display mode iterator - result = %08x\n", result);
		goto bail;
	}

	// List all supported output display modes
	printf("Supported video output display modes and pixel formats:\n");
	while (displayModeIterator->Next(&displayMode) == S_OK)
	{
		CFStringRef displayModeString;
		result = displayMode->GetName(&displayModeString);
		if (result == S_OK)
		{
			char					modeName[64];
			int						modeWidth;
			int						modeHeight;
			BMDTimeValue			frameRateDuration;
			BMDTimeScale			frameRateScale;
			int						pixelFormatIndex = 0; // index into the gKnownPixelFormats / gKnownFormatNames arrays
			BMDDisplayModeSupport	displayModeSupport;


			// Obtain the display mode's properties
			modeWidth = displayMode->GetWidth();
			modeHeight = displayMode->GetHeight();
			displayMode->GetFrameRate(&frameRateDuration, &frameRateScale);
			printf(" %-20s \t %d x %d \t %7g FPS\t", displayModeString, modeWidth, modeHeight, (double)frameRateScale / (double)frameRateDuration);

			// Print the supported pixel formats for this display mode
			while ((gKnownPixelFormats[pixelFormatIndex] != 0) && (gKnownPixelFormatNames[pixelFormatIndex] != NULL))
			{
				if ((deckLinkOutput->DoesSupportVideoMode(displayMode->GetDisplayMode(), gKnownPixelFormats[pixelFormatIndex], bmdVideoOutputFlagDefault, &displayModeSupport, NULL) == S_OK)
						&& (displayModeSupport != bmdDisplayModeNotSupported))
				{
					printf("%s\t", gKnownPixelFormatNames[pixelFormatIndex]);
				}
				pixelFormatIndex++;
			}

			printf("\n");

//			free(displayModeString);
		}

		// Release the IDeckLinkDisplayMode object to prevent a leak
		displayMode->Release();
	}

	printf("\n");

bail:
	// Ensure that the interfaces we obtained are released to prevent a memory leak
	if (displayModeIterator != NULL)
		displayModeIterator->Release();

	if (deckLinkOutput != NULL)
		deckLinkOutput->Release();
}
Example #23
0
av_cold int ff_decklink_write_header(AVFormatContext *avctx)
{
    struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data;
    struct decklink_ctx *ctx;
    IDeckLinkDisplayModeIterator *itermode;
    IDeckLinkIterator *iter;
    IDeckLink *dl = NULL;
    unsigned int n;

    ctx = (struct decklink_ctx *) av_mallocz(sizeof(struct decklink_ctx));
    if (!ctx)
        return AVERROR(ENOMEM);
    ctx->list_devices = cctx->list_devices;
    ctx->list_formats = cctx->list_formats;
    ctx->preroll      = cctx->preroll;
    cctx->ctx = ctx;

    iter = CreateDeckLinkIteratorInstance();
    if (!iter) {
        av_log(avctx, AV_LOG_ERROR, "Could not create DeckLink iterator\n");
        return AVERROR(EIO);
    }

    /* List available devices. */
    if (ctx->list_devices) {
        ff_decklink_list_devices(avctx);
        return AVERROR_EXIT;
    }

    /* Open device. */
    while (iter->Next(&dl) == S_OK) {
        const char *displayName;
        ff_decklink_get_display_name(dl, &displayName);
        if (!strcmp(avctx->filename, displayName)) {
            av_free((void *) displayName);
            ctx->dl = dl;
            break;
        }
        av_free((void *) displayName);
        dl->Release();
    }
    iter->Release();
    if (!ctx->dl) {
        av_log(avctx, AV_LOG_ERROR, "Could not open '%s'\n", avctx->filename);
        return AVERROR(EIO);
    }

    /* Get output device. */
    if (ctx->dl->QueryInterface(IID_IDeckLinkOutput, (void **) &ctx->dlo) != S_OK) {
        av_log(avctx, AV_LOG_ERROR, "Could not open output device from '%s'\n",
               avctx->filename);
        ctx->dl->Release();
        return AVERROR(EIO);
    }

    /* List supported formats. */
    if (ctx->list_formats) {
        ff_decklink_list_formats(avctx);
        ctx->dlo->Release();
        ctx->dl->Release();
        return AVERROR_EXIT;
    }

    if (ctx->dlo->GetDisplayModeIterator(&itermode) != S_OK) {
        av_log(avctx, AV_LOG_ERROR, "Could not get Display Mode Iterator\n");
        ctx->dl->Release();
        return AVERROR(EIO);
    }

    /* Setup streams. */
    for (n = 0; n < avctx->nb_streams; n++) {
        AVStream *st = avctx->streams[n];
        AVCodecContext *c = st->codec;
        if        (c->codec_type == AVMEDIA_TYPE_AUDIO) {
            if (decklink_setup_audio(avctx, st))
                goto error;
        } else if (c->codec_type == AVMEDIA_TYPE_VIDEO) {
            if (decklink_setup_video(avctx, st))
                goto error;
        } else {
            av_log(avctx, AV_LOG_ERROR, "Unsupported stream type.\n");
            goto error;
        }
    }
    itermode->Release();

    return 0;

error:

    ctx->dlo->Release();
    ctx->dl->Release();

    return AVERROR(EIO);
}
Example #24
0
void BMDConfig::DisplayUsage(int status)
{
	HRESULT							result = E_FAIL;
	IDeckLinkIterator*				deckLinkIterator = CreateDeckLinkIteratorInstance();
	IDeckLinkDisplayModeIterator*	displayModeIterator = NULL;

	IDeckLink*						deckLink = NULL;
	IDeckLink*						deckLinkSelected = NULL;
	int								deckLinkCount = 0;
	char*							deckLinkName = NULL;

	IDeckLinkAttributes*			deckLinkAttributes = NULL;
	bool							formatDetectionSupported;

	IDeckLinkInput*					deckLinkInput = NULL;
	IDeckLinkDisplayMode*			displayModeUsage;
	int								displayModeCount = 0;
	char*							displayModeName;

	fprintf(stderr,
		"Usage: Capture -d <device id> -m <mode id> [OPTIONS]\n"
		"\n"
		"    -d <device id>:\n"
	);

	// Loop through all available devices
	while (deckLinkIterator->Next(&deckLink) == S_OK)
	{
		result = deckLink->GetModelName((const char**)&deckLinkName);
		if (result == S_OK)
		{
			fprintf(stderr,
				"        %2d: %s%s\n",
				deckLinkCount,
				deckLinkName,
				deckLinkCount == m_deckLinkIndex ? " (selected)" : ""
			);

			free(deckLinkName);
		}

		if (deckLinkCount == m_deckLinkIndex)
			deckLinkSelected = deckLink;
		else
			deckLink->Release();

		++deckLinkCount;
	}

	if (deckLinkCount == 0)
		fprintf(stderr, "        No DeckLink devices found. Is the driver loaded?\n");

	deckLinkName = NULL;

	if (deckLinkSelected != NULL)
		deckLinkSelected->GetModelName((const char**)&deckLinkName);

	fprintf(stderr,
		"    -m <mode id>: (%s)\n",
		deckLinkName ? deckLinkName : ""
	);

	if (deckLinkName != NULL)
		free(deckLinkName);

	// Loop through all available display modes on the delected DeckLink device
	if (deckLinkSelected == NULL)
	{
		fprintf(stderr, "        No DeckLink device selected\n");
		goto bail;
	}

	result = deckLinkSelected->QueryInterface(IID_IDeckLinkAttributes, (void**)&deckLinkAttributes);
	if (result == S_OK)
	{
		result = deckLinkAttributes->GetFlag(BMDDeckLinkSupportsInputFormatDetection, &formatDetectionSupported);
		if (result == S_OK && formatDetectionSupported)
			fprintf(stderr, "        -1:  auto detect format\n");
	}

	result = deckLinkSelected->QueryInterface(IID_IDeckLinkInput, (void**)&deckLinkInput);
	if (result != S_OK)
		goto bail;

	result = deckLinkInput->GetDisplayModeIterator(&displayModeIterator);
	if (result != S_OK)
		goto bail;

	while (displayModeIterator->Next(&displayModeUsage) == S_OK)
	{
		result = displayModeUsage->GetName((const char **)&displayModeName);
		if (result == S_OK)
		{
			BMDTimeValue frameRateDuration;
			BMDTimeValue frameRateScale;

			displayModeUsage->GetFrameRate(&frameRateDuration, &frameRateScale);

			fprintf(stderr,
				"        %2d:  %-20s \t %li x %li \t %g FPS\n",
				displayModeCount,
				displayModeName,
				displayModeUsage->GetWidth(),
				displayModeUsage->GetHeight(),
				(double)frameRateScale / (double)frameRateDuration
			);

			free(displayModeName);
		}

		displayModeUsage->Release();
		++displayModeCount;
	}

bail:
	fprintf(stderr,
		"    -p <pixelformat>\n"
		"         0:  8 bit YUV (4:2:2) (default)\n"
		"         1:  10 bit YUV (4:2:2)\n"
		"         2:  10 bit RGB (4:4:4)\n"
		"    -t <format>          Print timecode\n"
		"         rp188:  RP 188\n"
		"         vitc:   VITC\n"
		"         serial: Serial Timecode\n"
		"    -v <filename>        Filename raw video will be written to\n"
		"    -a <filename>        Filename raw audio will be written to\n"
		"    -l <lcm channel>     Channel name to publish images to LCM\n"
		"    -q <jpeg quality>    JPEG compression quality for LCM images (1-100 - default is 90)\n"
		"    -c <channels>        Audio Channels (2, 8 or 16 - default is 2)\n"
		"    -s <depth>           Audio Sample Depth (16 or 32 - default is 16)\n"
		"    -n <frames>          Number of frames to capture (default is unlimited)\n"
		"    -3                   Capture Stereoscopic 3D (Requires 3D Hardware support)\n"
		"\n"
		"Capture video and/or audio to a file. Raw video and/or audio can be viewed with mplayer eg:\n"
		"\n"
		"    Capture -d 0 -m 2 -n 50 -v video.raw -a audio.raw\n"
		"    mplayer video.raw -demuxer rawvideo -rawvideo pal:uyvy -audiofile audio.raw -audio-demuxer 20 -rawaudio rate=48000\n"
    "\n"
    "LCM capture example command line:\n"
    "\n"
    "    DecklinkCapture -d 0 -m 14 -q 95 -l DECKLINK_VIDEO_CAPTURE\n"
    "\n"
	);

	if (deckLinkIterator != NULL)
		deckLinkIterator->Release();

	if (displayModeIterator != NULL)
		displayModeIterator->Release();

	if (deckLinkInput != NULL)
		deckLinkInput->Release();

	if (deckLinkAttributes != NULL)
		deckLinkAttributes->Release();

	if (deckLinkSelected != NULL)
		deckLinkSelected->Release();

	exit(status);
}
bool OpenGLComposite::InitDeckLink()
{
	bool							bSuccess = false;
	IDeckLinkIterator*				pDLIterator = NULL;
	IDeckLink*						pDL = NULL;
	IDeckLinkDisplayModeIterator*	pDLDisplayModeIterator = NULL;
	IDeckLinkDisplayMode*			pDLDisplayMode = NULL;
	BMDDisplayMode					displayMode = bmdModeHD1080i5994;		// mode to use for capture and playout
	float							fps;
	HRESULT							result;

	result = CoCreateInstance(CLSID_CDeckLinkIterator, NULL, CLSCTX_ALL, IID_IDeckLinkIterator, (void**)&pDLIterator);
	if (FAILED(result))
	{
		MessageBox(NULL, _T("Please install the Blackmagic DeckLink drivers to use the features of this application."), _T("This application requires the DeckLink drivers installed."), MB_OK);
		return false;
	}

	while (pDLIterator->Next(&pDL) == S_OK)
	{
		// Use first board found as capture device, second board will be playout device
		if (! mDLInput)
		{
			if (pDL->QueryInterface(IID_IDeckLinkInput, (void**)&mDLInput) != S_OK)
				goto error;
		}
		else if (! mDLOutput)
		{
			if (pDL->QueryInterface(IID_IDeckLinkOutput, (void**)&mDLOutput) != S_OK)
				goto error;
		}
	}

	if (! mDLOutput || ! mDLInput)
	{
		MessageBox(NULL, _T("Expected both Input and Output DeckLink devices"), _T("This application requires two DeckLink devices."), MB_OK);
		goto error;
	}

	if (mDLOutput->GetDisplayModeIterator(&pDLDisplayModeIterator) != S_OK)
	{
		MessageBox(NULL, _T("Cannot get Display Mode Iterator."), _T("DeckLink error."), MB_OK);
		goto error;
	}

	while (pDLDisplayModeIterator->Next(&pDLDisplayMode) == S_OK)
	{
		if (pDLDisplayMode->GetDisplayMode() == displayMode)
			break;

		pDLDisplayMode->Release();
		pDLDisplayMode = NULL;
	}
	pDLDisplayModeIterator->Release();

	if (pDLDisplayMode == NULL)
	{
		MessageBox(NULL, _T("Cannot get specified BMDDisplayMode."), _T("DeckLink error."), MB_OK);
		goto error;
	}

	mFrameWidth = pDLDisplayMode->GetWidth();
	mFrameHeight = pDLDisplayMode->GetHeight();

	if (! CheckOpenGLExtensions())
		goto error;

	if (! InitOpenGLState())
		goto error;

	// Compute a rotate angle rate so box will spin at a rate independent of video mode frame rate
	pDLDisplayMode->GetFrameRate(&mFrameDuration, &mFrameTimescale);
	fps = (float)mFrameTimescale / (float)mFrameDuration;
	mRotateAngleRate = 35.0f / fps;			// rotate box through 35 degrees every second

	// Resize window to match video frame, but scale large formats down by half for viewing
	if (mFrameWidth < 1920)
		resizeWindow(mFrameWidth, mFrameHeight);
	else
		resizeWindow(mFrameWidth / 2, mFrameHeight / 2);

	if (mFastTransferExtensionAvailable)
	{
		// Initialize fast video frame transfers
		if (! VideoFrameTransfer::initialize(mFrameWidth, mFrameHeight, mCaptureTexture, mFBOTexture))
		{
			MessageBox(NULL, _T("Cannot initialize video transfers."), _T("VideoFrameTransfer error."), MB_OK);
			goto error;
		}
	}

	// Capture will use a user-supplied frame memory allocator
	mCaptureAllocator = new PinnedMemoryAllocator(hGLDC, hGLRC, VideoFrameTransfer::CPUtoGPU, 3);

	if (mDLInput->SetVideoInputFrameMemoryAllocator(mCaptureAllocator) != S_OK)
		goto error;

	if (mDLInput->EnableVideoInput(displayMode, bmdFormat8BitYUV, bmdVideoInputFlagDefault) != S_OK)
		goto error;

	mCaptureDelegate = new CaptureDelegate(this);
	if (mDLInput->SetCallback(mCaptureDelegate) != S_OK)
		goto error;

	// Playout will use a user-supplied frame memory allocator
	mPlayoutAllocator = new PinnedMemoryAllocator(hGLDC, hGLRC, VideoFrameTransfer::GPUtoCPU, 1);

	if (mDLOutput->SetVideoOutputFrameMemoryAllocator(mPlayoutAllocator) != S_OK)
		goto error;

	if (mDLOutput->EnableVideoOutput(displayMode, bmdVideoOutputFlagDefault) != S_OK)
		goto error;

	// Create a queue of 10 IDeckLinkMutableVideoFrame objects to use for scheduling output video frames.
	// The ScheduledFrameCompleted() callback will immediately schedule a new frame using the next video frame from this queue.
	for (int i = 0; i < 10; i++)
	{
		// The frame read back from the GPU frame buffer and used for the playout video frame is in BGRA format.
		// The BGRA frame will be converted on playout to YCbCr either in hardware on most DeckLink cards or in software
		// within the DeckLink API for DeckLink devices without this hardware conversion.
		// If you want RGB 4:4:4 format to be played out "over the wire" in SDI, turn on the "Use 4:4:4 SDI" in the control
		// panel or turn on the bmdDeckLinkConfig444SDIVideoOutput flag using the IDeckLinkConfiguration interface.
		IDeckLinkMutableVideoFrame* outputFrame;
		if (mDLOutput->CreateVideoFrame(mFrameWidth, mFrameHeight, mFrameWidth*4, bmdFormat8BitBGRA, bmdFrameFlagFlipVertical, &outputFrame) != S_OK)
			goto error;

		mDLOutputVideoFrameQueue.push_back(outputFrame);
	}

	mPlayoutDelegate = new PlayoutDelegate(this);
	if (mPlayoutDelegate == NULL)
		goto error;

	if (mDLOutput->SetScheduledFrameCompletionCallback(mPlayoutDelegate) != S_OK)
		goto error;

	bSuccess = true;

error:
	if (!bSuccess)
	{
		if (mDLInput != NULL)
		{
			mDLInput->Release();
			mDLInput = NULL;
		}
		if (mDLOutput != NULL)
		{
			mDLOutput->Release();
			mDLOutput = NULL;
		}
	}

	if (pDL != NULL)
	{
		pDL->Release();
		pDL = NULL;
	}

	if (pDLIterator != NULL)
	{
		pDLIterator->Release();
		pDLIterator = NULL;
	}

	return bSuccess;
}
Example #26
0
av_cold int ff_decklink_read_header(AVFormatContext *avctx)
{
    struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data;
    struct decklink_ctx *ctx;
    IDeckLinkDisplayModeIterator *itermode;
    IDeckLinkIterator *iter;
    IDeckLink *dl = NULL;
    AVStream *st;
    HRESULT result;
    char fname[1024];
    char *tmp;
    int mode_num = 0;

    ctx = (struct decklink_ctx *) av_mallocz(sizeof(struct decklink_ctx));
    if (!ctx)
        return AVERROR(ENOMEM);
    ctx->list_devices = cctx->list_devices;
    ctx->list_formats = cctx->list_formats;
    ctx->preroll      = cctx->preroll;
    cctx->ctx = ctx;

    iter = CreateDeckLinkIteratorInstance();
    if (!iter) {
        av_log(avctx, AV_LOG_ERROR, "Could not create DeckLink iterator\n");
        return AVERROR(EIO);
    }

    /* List available devices. */
    if (ctx->list_devices) {
        ff_decklink_list_devices(avctx);
        return AVERROR_EXIT;
    }

    strcpy (fname, avctx->filename);
    tmp=strchr (fname, '@');
    if (tmp != NULL) {
        mode_num = atoi (tmp+1);
        *tmp = 0;
    }

    /* Open device. */
    while (iter->Next(&dl) == S_OK) {
        const char *displayName;
        ff_decklink_get_display_name(dl, &displayName);
        if (!strcmp(fname, displayName)) {
            av_free((void *) displayName);
            ctx->dl = dl;
            break;
        }
        av_free((void *) displayName);
        dl->Release();
    }
    iter->Release();
    if (!ctx->dl) {
        av_log(avctx, AV_LOG_ERROR, "Could not open '%s'\n", fname);
        return AVERROR(EIO);
    }

    /* Get input device. */
    if (ctx->dl->QueryInterface(IID_IDeckLinkInput, (void **) &ctx->dli) != S_OK) {
        av_log(avctx, AV_LOG_ERROR, "Could not open output device from '%s'\n",
               avctx->filename);
        ctx->dl->Release();
        return AVERROR(EIO);
    }

    /* List supported formats. */
    if (ctx->list_formats) {
        ff_decklink_list_formats(avctx, DIRECTION_IN);
        ctx->dli->Release();
        ctx->dl->Release();
        return AVERROR_EXIT;
    }

    if (ctx->dli->GetDisplayModeIterator(&itermode) != S_OK) {
        av_log(avctx, AV_LOG_ERROR, "Could not get Display Mode Iterator\n");
        ctx->dl->Release();
        return AVERROR(EIO);
    }

    if (mode_num > 0) {
        if (ff_decklink_set_format(avctx, DIRECTION_IN, mode_num) < 0) {
            av_log(avctx, AV_LOG_ERROR, "Could not set mode %d for %s\n", mode_num, fname);
            goto error;
        }
    }

    itermode->Release();

    /* Setup streams. */
    st = avformat_new_stream(avctx, NULL);
    if (!st) {
        av_log(avctx, AV_LOG_ERROR, "Cannot add stream\n");
        goto error;
    }
    st->codec->codec_type  = AVMEDIA_TYPE_AUDIO;
    st->codec->codec_id    = AV_CODEC_ID_PCM_S16LE;
    st->codec->sample_rate = bmdAudioSampleRate48kHz;
    st->codec->channels    = 2;
    avpriv_set_pts_info(st, 64, 1, 1000000);  /* 64 bits pts in us */
    ctx->audio_st=st;

    st = avformat_new_stream(avctx, NULL);
    if (!st) {
        av_log(avctx, AV_LOG_ERROR, "Cannot add stream\n");
        goto error;
    }
    st->codec->codec_type  = AVMEDIA_TYPE_VIDEO;
    st->codec->codec_id    = AV_CODEC_ID_RAWVIDEO;
    st->codec->width       = ctx->bmd_width;
    st->codec->height      = ctx->bmd_height;

    st->codec->pix_fmt     = AV_PIX_FMT_UYVY422;
    st->codec->time_base.den      = ctx->bmd_tb_den;
    st->codec->time_base.num      = ctx->bmd_tb_num;
    st->codec->bit_rate    = avpicture_get_size(st->codec->pix_fmt, ctx->bmd_width, ctx->bmd_height) * 1/av_q2d(st->codec->time_base) * 8;
    st->codec->codec_tag   = MKTAG('U', 'Y', 'V', 'Y');

    avpriv_set_pts_info(st, 64, 1, 1000000);  /* 64 bits pts in us */

    ctx->video_st=st;

    result = ctx->dli->EnableAudioInput(bmdAudioSampleRate48kHz, bmdAudioSampleType16bitInteger, 2);

    if (result != S_OK) {
        av_log(avctx, AV_LOG_ERROR, "Cannot enable audio input\n");
        goto error;
    }

    result = ctx->dli->EnableVideoInput(ctx->bmd_mode, bmdFormat8BitYUV, bmdVideoInputFlagDefault);

    if (result != S_OK) {
        av_log(avctx, AV_LOG_ERROR, "Cannot enable video input\n");
        goto error;
    }

    avpacket_queue_init (avctx, &ctx->queue);

    if (decklink_start_input (avctx) != S_OK) {
        av_log(avctx, AV_LOG_ERROR, "Cannot start input stream\n");
        goto error;
    }

    return 0;

error:

    ctx->dli->Release();
    ctx->dl->Release();

    return AVERROR(EIO);
}
void krad_decklink_capture_info () {

	IDeckLink *deckLink;
	IDeckLinkInput *deckLinkInput;
	IDeckLinkIterator *deckLinkIterator;
	IDeckLinkDisplayModeIterator *displayModeIterator;
	IDeckLinkDisplayMode *displayMode;
	
	HRESULT result;
	int displayModeCount;
	char *displayModeString;

	displayModeString = NULL;
	displayModeCount = 0;
	
	deckLinkIterator = CreateDeckLinkIteratorInstance();
	
	if (!deckLinkIterator) {
		printke ("Krad Decklink: This application requires the DeckLink drivers installed.\n");
	}
	
	/* Connect to the first DeckLink instance */
	result = deckLinkIterator->Next(&deckLink);
	if (result != S_OK) {
		printke ("Krad Decklink: No DeckLink PCI cards found.\n");
	}
    
	result = deckLink->QueryInterface(IID_IDeckLinkInput, (void**)&deckLinkInput);
	if (result != S_OK) {
		printke ("Krad Decklink: Fail QueryInterface\n");
	}
	
	result = deckLinkInput->GetDisplayModeIterator(&displayModeIterator);
	if (result != S_OK) {
		printke ("Krad Decklink: Could not obtain the video output display mode iterator - result = %08x\n", result);
	}


    while (displayModeIterator->Next(&displayMode) == S_OK) {

        result = displayMode->GetName((const char **) &displayModeString);
        
        if (result == S_OK) {
			
			BMDTimeValue frameRateDuration, frameRateScale;
			displayMode->GetFrameRate(&frameRateDuration, &frameRateScale);

			printkd ("%2d:  %-20s \t %li x %li \t %g FPS\n", 
				displayModeCount, displayModeString, displayMode->GetWidth(), displayMode->GetHeight(), 
				(double)frameRateScale / (double)frameRateDuration);
			
            free (displayModeString);
			displayModeCount++;
		}
		
		displayMode->Release();
	}
	
	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();
	}
}
void SignalGenerator::setup()
{
	IDeckLinkIterator*			deckLinkIterator = NULL;
	bool						success = false;
	
	// **** Find a DeckLink instance and obtain video output interface
	deckLinkIterator = CreateDeckLinkIteratorInstance();
	if (deckLinkIterator == NULL)
	{
		QMessageBox::critical(this, "This application requires the DeckLink drivers installed.", "Please install the Blackmagic DeckLink drivers to use the features of this application.");
		goto bail;
	}
	
	// Connect to the first DeckLink instance
	if (deckLinkIterator->Next(&deckLink) != S_OK)
	{
		QMessageBox::critical(this, "This application requires a DeckLink PCI card.", "You will not be able to use the features of this application until a DeckLink PCI card is installed.");
		goto bail;
	}
	
	// Obtain the audio/video output interface (IDeckLinkOutput)
	if (deckLink->QueryInterface(IID_IDeckLinkOutput, (void**)&deckLinkOutput) != S_OK)
		goto bail;
	
	// Create a delegate class to allow the DeckLink API to call into our code
	playerDelegate = new PlaybackDelegate(this, deckLinkOutput);
	if (playerDelegate == NULL)
		goto bail;
	// Provide the delegate to the audio and video output interfaces
	deckLinkOutput->SetScheduledFrameCompletionCallback(playerDelegate);
	deckLinkOutput->SetAudioCallback(playerDelegate);
	
	
	// Populate the display mode menu with a list of display modes supported by the installed DeckLink card
	IDeckLinkDisplayModeIterator*		displayModeIterator;
	IDeckLinkDisplayMode*				deckLinkDisplayMode;
	
	ui->videoFormatPopup->clear();
	if (deckLinkOutput->GetDisplayModeIterator(&displayModeIterator) != S_OK)
		goto bail;
	while (displayModeIterator->Next(&deckLinkDisplayMode) == S_OK)
	{
		const char *		modeName;
		
		if (deckLinkDisplayMode->GetName(&modeName) == S_OK)
		{
			ui->videoFormatPopup->addItem(modeName, QVariant::fromValue((void *)deckLinkDisplayMode));
		}
	}
	displayModeIterator->Release();
	enableInterface(true);	
	deckLinkOutput->SetScreenPreviewCallback(previewView);
	
	success = true;
	
bail:
	if (success == false)
	{
		// Release any resources that were partially allocated
		if (deckLinkOutput != NULL)
		{
			deckLinkOutput->Release();
			deckLinkOutput = NULL;
		}
		//
		if (deckLink != NULL)
		{
			deckLink->Release();
			deckLink = NULL;
		}

		// Disable the user interface if we could not succsssfully connect to a DeckLink device
		ui->startButton->setEnabled(false);
		enableInterface(false);
	}
	
	if (deckLinkIterator != NULL)
		deckLinkIterator->Release();
}
int ff_decklink_set_format(AVFormatContext *avctx,
                               int width, int height,
                               int tb_num, int tb_den,
                               decklink_direction_t direction, int num)
{
    struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data;
    struct decklink_ctx *ctx = (struct decklink_ctx *)cctx->ctx;
    BMDDisplayModeSupport support;
    IDeckLinkDisplayModeIterator *itermode;
    IDeckLinkDisplayMode *mode;
    int i = 1;
    HRESULT res;

    if (direction == DIRECTION_IN) {
        res = ctx->dli->GetDisplayModeIterator (&itermode);
    } else {
        res = ctx->dlo->GetDisplayModeIterator (&itermode);
    }

    if (res!= S_OK) {
            av_log(avctx, AV_LOG_ERROR, "Could not get Display Mode Iterator\n");
            return AVERROR(EIO);
    }


    if (tb_num == 1) {
        tb_num *= 1000;
        tb_den *= 1000;
    }
    ctx->bmd_mode = bmdModeUnknown;
    while ((ctx->bmd_mode == bmdModeUnknown) && itermode->Next(&mode) == S_OK) {
        BMDTimeValue bmd_tb_num, bmd_tb_den;
        int bmd_width  = mode->GetWidth();
        int bmd_height = mode->GetHeight();

        mode->GetFrameRate(&bmd_tb_num, &bmd_tb_den);

        if ((bmd_width == width && bmd_height == height &&
            bmd_tb_num == tb_num && bmd_tb_den == tb_den) || i == num) {
            ctx->bmd_mode   = mode->GetDisplayMode();
            ctx->bmd_width  = bmd_width;
            ctx->bmd_height = bmd_height;
            ctx->bmd_tb_den = bmd_tb_den;
            ctx->bmd_tb_num = bmd_tb_num;
            ctx->bmd_field_dominance = mode->GetFieldDominance();
            av_log(avctx, AV_LOG_INFO, "Found Decklink mode %d x %d with rate %.2f%s\n",
                bmd_width, bmd_height, (float)bmd_tb_den/(float)bmd_tb_num,
                (ctx->bmd_field_dominance==bmdLowerFieldFirst || ctx->bmd_field_dominance==bmdUpperFieldFirst)?"(i)":"");
        }

        mode->Release();
        i++;
    }

    itermode->Release();

    if (ctx->bmd_mode == bmdModeUnknown)
        return -1;
    if (direction == DIRECTION_IN) {
        if (ctx->dli->DoesSupportVideoMode(ctx->bmd_mode, bmdFormat8BitYUV,
                                           bmdVideoOutputFlagDefault,
                                           &support, NULL) != S_OK)
            return -1;
    } else {
        if (ctx->dlo->DoesSupportVideoMode(ctx->bmd_mode, bmdFormat8BitYUV,
                                           bmdVideoOutputFlagDefault,
                                           &support, NULL) != S_OK)
        return -1;
    }
    if (support == bmdDisplayModeSupported)
        return 0;

    return -1;
}
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;
}