HRESULT TestPattern::CreateFrame(IDeckLinkVideoFrame** frame, void (*fillFunc)(IDeckLinkVideoFrame*))
{
	HRESULT						result;
	int							bytesPerPixel = GetBytesPerPixel(m_config->m_pixelFormat);
	IDeckLinkMutableVideoFrame*	newFrame = NULL;
	IDeckLinkMutableVideoFrame*	referenceFrame = NULL;
	IDeckLinkVideoConversion*	frameConverter = NULL;

	*frame = NULL;

	result = m_deckLinkOutput->CreateVideoFrame(m_frameWidth, m_frameHeight, m_frameWidth * bytesPerPixel, m_config->m_pixelFormat, bmdFrameFlagDefault, &newFrame);
	if (result != S_OK)
	{
		fprintf(stderr, "Failed to create video frame\n");
		goto bail;
	}

	if (m_config->m_pixelFormat == bmdFormat8BitYUV)
	{
		fillFunc(newFrame);
	}
	else
	{
		// Create a black frame in 8 bit YUV and convert to desired format
		result = m_deckLinkOutput->CreateVideoFrame(m_frameWidth, m_frameHeight, m_frameWidth * 2, bmdFormat8BitYUV, bmdFrameFlagDefault, &referenceFrame);
		if (result != S_OK)
		{
			fprintf(stderr, "Failed to create reference video frame\n");
			goto bail;
		}

		fillFunc(referenceFrame);

		frameConverter = CreateVideoConversionInstance();

		result = frameConverter->ConvertFrame(referenceFrame, newFrame);
		if (result != S_OK)
		{
			fprintf(stderr, "Failed to convert frame\n");
			goto bail;
		}
	}

	*frame = newFrame;
	newFrame = NULL;

bail:
	if (referenceFrame != NULL)
		referenceFrame->Release();

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

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

	return result;
}
示例#2
0
BMDOutputDelegate::BMDOutputDelegate(IDeckLink* link)
	: m_deckLink(link)
	, m_deckLinkConverter(0)
	, m_rgbFrame(0)
	, m_yuvFrame(0)
	, m_running(false)
	, m_frameSet(false)
	, m_frameReceivedCount(0)
{
	// Obtain the audio/video output interface (IDeckLinkOutput)
	if (m_deckLink->QueryInterface(IID_IDeckLinkOutput, (void**)&m_deckLinkOutput) != S_OK)
		goto bail;
		
	#ifdef Q_OS_WIN
	if(CoCreateInstance(CLSID_CDeckLinkVideoConversion, NULL, CLSCTX_ALL,IID_IDeckLinkVideoConversion, (void**)&m_deckLinkConverter) != S_OK)
	#else
	if(!(m_deckLinkConverter = CreateVideoConversionInstance()))
	#endif
 	{
 		qDebug() << "BMDCaptureDelegate: Cannot create an instance of IID_IDeckLinkVideoConversion, therefore cannot convert YUV->RGB, therefore we will not emit proper RGB frames now.";
 		m_deckLinkConverter = NULL;
 		goto bail;
 	}

	// Provide this class as a delegate to the audio and video output interfaces
	m_deckLinkOutput->SetScheduledFrameCompletionCallback(this);
	
	// Start.
	StartRunning();
	
	return;
		
bail:
	if (m_running == true)
	{
		StopRunning();
	}
	else
	{
		// Release any resources that were partially allocated
		if (m_deckLinkOutput != NULL)
		{
			m_deckLinkOutput->Release();
			m_deckLinkOutput = NULL;
		}
		//
		if (m_deckLink != NULL)
		{
			m_deckLink->Release();
			m_deckLink = NULL;
		}
	}
	
	return ;
	
};
示例#3
0
int main(int argc, char *argv[])
{
    HRESULT							result;
    int								exitStatus = 1;
    int								idx;

    pthread_mutex_init(&g_sleepMutex, NULL);
    pthread_cond_init(&g_sleepCond, NULL);

    signal(SIGINT, sigfunc);
    signal(SIGTERM, sigfunc);
    signal(SIGHUP, sigfunc);

    // Process the command line arguments
    if (!g_config.ParseArguments(argc, argv))
    {
        g_config.DisplayUsage(exitStatus);
        cleanup();
        return exitStatus;
    }

    g_lcm = new lcm::LCM();
    g_conversionInst = CreateVideoConversionInstance();

    // Get the DeckLink device
    g_deckLinkIterator = CreateDeckLinkIteratorInstance();
    if (!g_deckLinkIterator)
    {
        fprintf(stderr, "This application requires the DeckLink drivers installed.\n");
        cleanup();
        return exitStatus;
    }

    idx = g_config.m_deckLinkIndex;

    while ((result = g_deckLinkIterator->Next(&g_deckLink)) == S_OK)
    {
        if (idx == 0)
            break;
        --idx;

        g_deckLink->Release();
    }

    if (result != S_OK || g_deckLink == NULL)
    {
        fprintf(stderr, "Unable to get DeckLink device %u\n", g_config.m_deckLinkIndex);
        cleanup();
        return exitStatus;
    }

    // Get the input (capture) interface of the DeckLink device
    result = g_deckLink->QueryInterface(IID_IDeckLinkInput, (void**)&g_deckLinkInput);
    if (result != S_OK)
    {
        cleanup();
        return exitStatus;
    }



    // Get the output (display) interface of the DeckLink device
    if (g_deckLink->QueryInterface(IID_IDeckLinkOutput, (void**)&g_deckLinkOutput) != S_OK)
    {
        cleanup();
        return exitStatus;
    }


    // Get the display mode
    if (g_config.m_displayModeIndex == -1)
    {
        // Check the card supports format detection
        result = g_deckLink->QueryInterface(IID_IDeckLinkAttributes, (void**)&g_deckLinkAttributes);
        if (result == S_OK)
        {
            result = g_deckLinkAttributes->GetFlag(BMDDeckLinkSupportsInputFormatDetection, &g_formatDetectionSupported);
            if (result != S_OK || !g_formatDetectionSupported)
            {
                fprintf(stderr, "Format detection is not supported on this device\n");
                cleanup();
                return exitStatus;
            }
        }

        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(&g_displayModeIterator);
    if (result != S_OK)
    {
        cleanup();
        return exitStatus;
    }

    while ((result = g_displayModeIterator->Next(&g_displayMode)) == S_OK)
    {
        if (idx == 0)
            break;
        --idx;

        g_displayMode->Release();
    }

    if (result != S_OK || g_displayMode == NULL)
    {
        fprintf(stderr, "Unable to get display mode %d\n", g_config.m_displayModeIndex);
        cleanup();
        return exitStatus;
    }

    // Get display mode name
    result = g_displayMode->GetName((const char**)&g_displayModeName);
    if (result != S_OK)
    {
        g_displayModeName = (char *)malloc(32);
        snprintf(g_displayModeName, 32, "[index %d]", g_config.m_displayModeIndex);
    }

    // Check display mode is supported with given options
    result = g_deckLinkInput->DoesSupportVideoMode(g_displayMode->GetDisplayMode(), g_config.m_pixelFormat, bmdVideoInputFlagDefault, &g_displayModeSupported, NULL);
    if (result != S_OK)
    {
        cleanup();
        return exitStatus;
    }

    if (g_displayModeSupported == bmdDisplayModeNotSupported)
    {
        fprintf(stderr, "The display mode %s is not supported with the selected pixel format\n", g_displayModeName);
        cleanup();
        return exitStatus;
    }

    if (g_config.m_inputFlags & bmdVideoInputDualStream3D)
    {
        if (!(g_displayMode->GetFlags() & bmdDisplayModeSupports3D))
        {
            fprintf(stderr, "The display mode %s is not supported with 3D\n", g_displayModeName);
            cleanup();
            return exitStatus;
        }
    }

    // Print the selected configuration
    g_config.DisplayConfiguration();

    // Configure the capture callback
    g_delegate = new DeckLinkCaptureDelegate();
    g_deckLinkInput->SetCallback(g_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);
            cleanup();
            return exitStatus;
        }
    }

    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);
            cleanup();
            return exitStatus;
        }
    }

    // Block main thread until signal occurs
    while (!g_do_exit)
    {
        // Start capturing
        result = g_deckLinkInput->EnableVideoInput(g_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");
        }
        else
        {
            result = g_deckLinkInput->EnableAudioInput(bmdAudioSampleRate48kHz, g_config.m_audioSampleDepth, g_config.m_audioChannels);
            if (result == S_OK)
            {
                frameConsumer.Start();

                result = g_deckLinkInput->StartStreams();
                if (result == S_OK)
                {
                    // 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");
                    frameConsumer.Stop();
                    g_deckLinkInput->StopStreams();
                    g_deckLinkInput->DisableAudioInput();
                    g_deckLinkInput->DisableVideoInput();
                }
            }
        }
    }

    cleanup();

    return exitStatus;
}