예제 #1
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;
	}
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;
}
예제 #3
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;
    }
예제 #4
0
int
usage (int status)
{
  HRESULT result;
  IDeckLinkDisplayMode *displayMode;
  int displayModeCount = 0;

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

  while (displayModeIterator->Next (&displayMode) == S_OK) {
    char *displayModeString = NULL;

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

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

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

  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"
      "    -f <filename>        Filename raw video will be written to\n"
      "    -a <filename>        Filename raw audio will be written to\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 -m2 -n 50 -f video.raw -a audio.raw\n"
      "    mplayer video.raw -demuxer rawvideo -rawvideo pal:uyvy -audiofile audio.raw -audio-demuxer 20 -rawaudio rate=48000\n");

  exit (status);
}
예제 #5
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;
	}
예제 #6
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;
		}
예제 #7
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;
}
예제 #8
0
void Player::StartRunning(int videomode)
{
    IDeckLinkDisplayMode *videoDisplayMode = NULL;
    unsigned long audioSamplesPerFrame;

    // Get the display mode for 1080i 59.95
    videoDisplayMode = GetDisplayModeByIndex(videomode);

    if (!videoDisplayMode)
        return;

    m_frameWidth  = videoDisplayMode->GetWidth();
    m_frameHeight = videoDisplayMode->GetHeight();
    videoDisplayMode->GetFrameRate(&m_frameDuration, &m_frameTimescale);

    // Set the video output mode
    if (m_deckLinkOutput->EnableVideoOutput(videoDisplayMode->GetDisplayMode(),
                                            bmdVideoOutputFlagDefault) !=
        S_OK) {
        fprintf(stderr, "Failed to enable video output\n");
        return;
    }

    // Set the audio output mode
    if (m_deckLinkOutput->EnableAudioOutput(bmdAudioSampleRate48kHz,
                                            m_audioSampleDepth,
                                            audio_st->codec->channels,
                                            bmdAudioOutputStreamTimestamped) !=
        S_OK) {
        fprintf(stderr, "Failed to enable audio output\n");
        return;
    }

    for (unsigned i = 0; i < 10; i++)
        ScheduleNextFrame(true);

    // Begin audio preroll.  This will begin calling our audio callback, which will start the DeckLink output stream.
//    m_audioBufferOffset = 0;
    if (m_deckLinkOutput->BeginAudioPreroll() != S_OK) {
        fprintf(stderr, "Failed to begin audio preroll\n");
        return;
    }

    m_running = true;

    return;
}
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;
}
예제 #10
0
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();
	}
}
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;
}
예제 #12
0
int ff_decklink_set_format(AVFormatContext *avctx,
                               int width, int height,
                               int tb_num, int tb_den,
                               enum AVFieldOrder field_order,
                               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;

    av_log(avctx, AV_LOG_DEBUG, "Trying to find mode for frame size %dx%d, frame timing %d/%d, field order %d, direction %d, mode number %d, format code %s\n",
        width, height, tb_num, tb_den, field_order, direction, num, (cctx->format_code) ? cctx->format_code : "(unset)");

    if (ctx->duplex_mode) {
        DECKLINK_BOOL duplex_supported = false;

        if (ctx->attr->GetFlag(BMDDeckLinkSupportsDuplexModeConfiguration, &duplex_supported) != S_OK)
            duplex_supported = false;

        if (duplex_supported) {
            res = ctx->cfg->SetInt(bmdDeckLinkConfigDuplexMode, ctx->duplex_mode == 2 ? bmdDuplexModeFull : bmdDuplexModeHalf);
            if (res != S_OK)
                av_log(avctx, AV_LOG_WARNING, "Setting duplex mode failed.\n");
            else
                av_log(avctx, AV_LOG_VERBOSE, "Successfully set duplex mode to %s duplex.\n", ctx->duplex_mode == 2 ? "full" : "half");
        } else {
            av_log(avctx, AV_LOG_WARNING, "Unable to set duplex mode, because it is not supported.\n");
        }
    }

    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);
    }

    char format_buf[] = "    ";
    if (cctx->format_code)
        memcpy(format_buf, cctx->format_code, FFMIN(strlen(cctx->format_code), sizeof(format_buf)));
    BMDDisplayMode target_mode = (BMDDisplayMode)AV_RB32(format_buf);
    AVRational target_tb = av_make_q(tb_num, tb_den);
    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();
        BMDDisplayMode bmd_mode = mode->GetDisplayMode();
        BMDFieldDominance bmd_field_dominance = mode->GetFieldDominance();

        mode->GetFrameRate(&bmd_tb_num, &bmd_tb_den);
        AVRational mode_tb = av_make_q(bmd_tb_num, bmd_tb_den);

        if ((bmd_width == width &&
             bmd_height == height &&
             !av_cmp_q(mode_tb, target_tb) &&
             field_order_eq(field_order, bmd_field_dominance))
             || i == num
             || target_mode == bmd_mode) {
            ctx->bmd_mode   = bmd_mode;
            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 = bmd_field_dominance;
            av_log(avctx, AV_LOG_INFO, "Found Decklink mode %d x %d with rate %.2f%s\n",
                bmd_width, bmd_height, 1/av_q2d(mode_tb),
                (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;
}
void	CSignalGeneratorDlg::StartRunning ()
{
	IDeckLinkDisplayMode*	videoDisplayMode = NULL;
	BMDVideoOutputFlags		videoOutputFlags = bmdVideoOutputFlagDefault;
	int						curSelection;
	CString					videoFormatName;

	curSelection = m_videoFormatCombo.GetCurSel();
	m_videoFormatCombo.GetLBText(curSelection, videoFormatName);
	if (videoFormatName.Find(_T(" 3D"), 0) != -1)
		videoOutputFlags = bmdVideoOutputDualStream3D;
	
	// Determine the audio and video properties for the output stream
	m_outputSignal = (OutputSignal)m_outputSignalCombo.GetCurSel();
	m_audioChannelCount = m_audioChannelCombo.GetItemData(m_audioChannelCombo.GetCurSel());
	m_audioSampleDepth = (BMDAudioSampleType)m_audioSampleDepthCombo.GetItemData(m_audioSampleDepthCombo.GetCurSel());
	m_audioSampleRate = bmdAudioSampleRate48kHz;
	//
	// - Extract the IDeckLinkDisplayMode from the display mode popup menu (stashed in the item's tag)
	videoDisplayMode = (IDeckLinkDisplayMode*)m_videoFormatCombo.GetItemDataPtr(m_videoFormatCombo.GetCurSel());
	m_frameWidth = videoDisplayMode->GetWidth();
	m_frameHeight = videoDisplayMode->GetHeight();
	videoDisplayMode->GetFrameRate(&m_frameDuration, &m_frameTimescale);
	// Calculate the number of frames per second, rounded up to the nearest integer.  For example, for NTSC (29.97 FPS), framesPerSecond == 30.
	m_framesPerSecond = (unsigned long)((m_frameTimescale + (m_frameDuration-1))  /  m_frameDuration);
	
	// Set the video output mode
	if (m_deckLinkOutput->EnableVideoOutput(videoDisplayMode->GetDisplayMode(), videoOutputFlags) != S_OK)
		goto bail;

	// Set the audio output mode
	if (m_deckLinkOutput->EnableAudioOutput(bmdAudioSampleRate48kHz, m_audioSampleDepth, m_audioChannelCount, bmdAudioOutputStreamTimestamped) != S_OK)
		goto bail;
	
	// Generate one second of audio tone
	m_audioSamplesPerFrame = (unsigned long)((m_audioSampleRate * m_frameDuration) / m_frameTimescale);
	m_audioBufferSampleLength = (unsigned long)((m_framesPerSecond * m_audioSampleRate * m_frameDuration) / m_frameTimescale);
	m_audioBuffer = HeapAlloc(GetProcessHeap(), 0, (m_audioBufferSampleLength * m_audioChannelCount * (m_audioSampleDepth / 8)));
	if (m_audioBuffer == NULL)
		goto bail;
	FillSine(m_audioBuffer, m_audioBufferSampleLength, m_audioChannelCount, m_audioSampleDepth);
	
	// Generate a frame of black
	m_videoFrameBlack = CreateBlackFrame();
	if (! m_videoFrameBlack)
		goto bail;

	// Generate a frame of colour bars
	m_videoFrameBars = CreateBarsFrame();
	if (! m_videoFrameBars)
		goto bail;

	// Begin video preroll by scheduling a second of frames in hardware
	m_totalFramesScheduled = 0;
	for (unsigned i = 0; i < m_framesPerSecond; i++)
		ScheduleNextFrame(true);
	
	// Begin audio preroll.  This will begin calling our audio callback, which will start the DeckLink output stream.
	m_totalAudioSecondsScheduled = 0;
	if (m_deckLinkOutput->BeginAudioPreroll() != S_OK)
		goto bail;
	
	// Success; update the UI
	m_running = true;
	m_startButton.SetWindowText(_T("Stop"));
	// Disable the user interface while running (prevent the user from making changes to the output signal)
	EnableInterface(FALSE);
	
	return;
	
bail:
	// *** Error-handling code.  Cleanup any resources that were allocated. *** //
	StopRunning();
}
void SignalGenerator::startRunning()
{
	IDeckLinkDisplayMode*	videoDisplayMode = NULL;
	BMDVideoOutputFlags		videoOutputFlags = 0;
	QVariant v;
	// Determine the audio and video properties for the output stream
	v = ui->outputSignalPopup->itemData(ui->outputSignalPopup->currentIndex());
	outputSignal = (OutputSignal)v.value<int>();	
	
	v = ui->audioChannelPopup->itemData(ui->audioChannelPopup->currentIndex());
	audioChannelCount = v.value<int>();	
	
	v = ui->audioSampleDepthPopup->itemData(ui->audioSampleDepthPopup->currentIndex());
	audioSampleDepth = v.value<int>();	
	audioSampleRate = bmdAudioSampleRate48kHz;
	
	//
	// - Extract the IDeckLinkDisplayMode from the display mode popup menu (stashed in the item's tag)
	v = ui->videoFormatPopup->itemData(ui->videoFormatPopup->currentIndex());
	videoDisplayMode = (IDeckLinkDisplayMode *)v.value<void*>();
	
	frameWidth = videoDisplayMode->GetWidth();
	frameHeight = videoDisplayMode->GetHeight();
	
	videoDisplayMode->GetFrameRate(&frameDuration, &frameTimescale);
	// Calculate the number of frames per second, rounded up to the nearest integer.  For example, for NTSC (29.97 FPS), framesPerSecond == 30.
	framesPerSecond = (frameTimescale + (frameDuration-1))  /  frameDuration;
	
	if (videoDisplayMode->GetDisplayMode() == bmdModeNTSC ||
		videoDisplayMode->GetDisplayMode() == bmdModeNTSC2398 ||
		videoDisplayMode->GetDisplayMode() == bmdModePAL)
	{
		timeCodeFormat = bmdTimecodeVITC;
		videoOutputFlags |= bmdVideoOutputVITC;
	}
	else
	{
		timeCodeFormat = bmdTimecodeRP188Any;
		videoOutputFlags |= bmdVideoOutputRP188;
	}

	if (timeCode)
		delete timeCode;
	timeCode = new Timecode(framesPerSecond);


	// Set the video output mode
	if (deckLinkOutput->EnableVideoOutput(videoDisplayMode->GetDisplayMode(), videoOutputFlags) != S_OK)
		goto bail;
	
	// Set the audio output mode
	if (deckLinkOutput->EnableAudioOutput(bmdAudioSampleRate48kHz, audioSampleDepth, audioChannelCount, bmdAudioOutputStreamTimestamped) != S_OK)
		goto bail;
	
	
	// Generate one second of audio tone
	audioSamplesPerFrame = ((audioSampleRate * frameDuration) / frameTimescale);
	audioBufferSampleLength = (framesPerSecond * audioSampleRate * frameDuration) / frameTimescale;
	audioBuffer = malloc(audioBufferSampleLength * audioChannelCount * (audioSampleDepth / 8));
	if (audioBuffer == NULL)
		goto bail;
	FillSine(audioBuffer, audioBufferSampleLength, audioChannelCount, audioSampleDepth);
	
	// Generate a frame of black
	if (deckLinkOutput->CreateVideoFrame(frameWidth, frameHeight, frameWidth*2, bmdFormat8BitYUV, bmdFrameFlagDefault, &videoFrameBlack) != S_OK)
		goto bail;
	FillBlack(videoFrameBlack);
	
	// Generate a frame of colour bars
	if (deckLinkOutput->CreateVideoFrame(frameWidth, frameHeight, frameWidth*2, bmdFormat8BitYUV, bmdFrameFlagDefault, &videoFrameBars) != S_OK)
		goto bail;
	FillColourBars(videoFrameBars);
	
	// Begin video preroll by scheduling a second of frames in hardware
	totalFramesScheduled = 0;
	for (unsigned int i = 0; i < framesPerSecond; i++)
		scheduleNextFrame(true);
	
	// Begin audio preroll.  This will begin calling our audio callback, which will start the DeckLink output stream.
	totalAudioSecondsScheduled = 0;
	if (deckLinkOutput->BeginAudioPreroll() != S_OK)
		goto bail;
	
	// Success; update the UI
	running = true;
	ui->startButton->setText("Stop");
	// Disable the user interface while running (prevent the user from making changes to the output signal)
	enableInterface(false);
	
	return;
	
bail:
	QMessageBox::critical(this, "Failed to start output", "Failed to start output");
	// *** Error-handling code.  Cleanup any resources that were allocated. *** //
	stopRunning();
}
예제 #15
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;
}
예제 #16
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;
}
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;
}
/**
* 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");
}
예제 #19
0
파일: decklink.cpp 프로젝트: chouquette/vlc
static int Open(vlc_object_t *p_this)
{
    demux_t     *demux = (demux_t*)p_this;
    demux_sys_t *sys;
    int         ret = VLC_EGENERIC;
    int         card_index;
    int         physical_channels = 0;
    int         rate;
    BMDVideoInputFlags flags = bmdVideoInputFlagDefault;

    /* Only when selected */
    if (*demux->psz_access == '\0')
        return VLC_EGENERIC;

    /* Set up demux */
    demux->pf_demux = NULL;
    demux->pf_control = Control;
    demux->info.i_update = 0;
    demux->info.i_title = 0;
    demux->info.i_seekpoint = 0;
    demux->p_sys = sys = (demux_sys_t*)calloc(1, sizeof(demux_sys_t));
    if (!sys)
        return VLC_ENOMEM;

    vlc_mutex_init(&sys->pts_lock);

    sys->tenbits = var_InheritBool(p_this, "decklink-tenbits");

    IDeckLinkIterator *decklink_iterator = CreateDeckLinkIteratorInstance();
    if (!decklink_iterator) {
        msg_Err(demux, "DeckLink drivers not found.");
        goto finish;
    }

    card_index = var_InheritInteger(demux, "decklink-card-index");
    if (card_index < 0) {
        msg_Err(demux, "Invalid card index %d", card_index);
        goto finish;
    }

    for (int i = 0; i <= card_index; i++) {
        if (sys->card)
            sys->card->Release();
        if (decklink_iterator->Next(&sys->card) != S_OK) {
            msg_Err(demux, "DeckLink PCI card %d not found", card_index);
            goto finish;
        }
    }

    const char *model_name;
    if (sys->card->GetModelName(&model_name) != S_OK)
        model_name = "unknown";

    msg_Dbg(demux, "Opened DeckLink PCI card %d (%s)", card_index, model_name);

    if (sys->card->QueryInterface(IID_IDeckLinkInput, (void**)&sys->input) != S_OK) {
        msg_Err(demux, "Card has no inputs");
        goto finish;
    }

    /* Set up the video and audio sources. */
    if (sys->card->QueryInterface(IID_IDeckLinkConfiguration, (void**)&sys->config) != S_OK) {
        msg_Err(demux, "Failed to get configuration interface");
        goto finish;
    }

    if (sys->card->QueryInterface(IID_IDeckLinkAttributes, (void**)&sys->attributes) != S_OK) {
        msg_Err(demux, "Failed to get attributes interface");
        goto finish;
    }

    if (GetVideoConn(demux) || GetAudioConn(demux))
        goto finish;

    BMDPixelFormat fmt;
    fmt = sys->tenbits ? bmdFormat10BitYUV : bmdFormat8BitYUV;
    if (sys->attributes->GetFlag(BMDDeckLinkSupportsInputFormatDetection, &sys->autodetect) != S_OK) {
        msg_Err(demux, "Failed to query card attribute");
        goto finish;
    }

    /* Get the list of display modes. */
    IDeckLinkDisplayModeIterator *mode_it;
    if (sys->input->GetDisplayModeIterator(&mode_it) != S_OK) {
        msg_Err(demux, "Failed to enumerate display modes");
        goto finish;
    }

    union {
        BMDDisplayMode id;
        char str[4];
    } u;

    u.id = 0;

    char *mode;
    mode = var_CreateGetNonEmptyString(demux, "decklink-mode");
    if (mode)
        sys->autodetect = false; // disable autodetection if mode was set

    if (sys->autodetect) {
        msg_Dbg(demux, "Card supports input format detection");
        flags |= bmdVideoInputEnableFormatDetection;
        /* Enable a random format, we will reconfigure on format detection */
        u.id = htonl(bmdModeHD1080p2997);
    } else {
        if (!mode || strlen(mode) < 3 || strlen(mode) > 4) {
            msg_Err(demux, "Invalid mode: \'%s\'", mode ? mode : "");
            free(mode);
            goto finish;
        }

        msg_Dbg(demux, "Looking for mode \'%s\'", mode);
        memcpy(u.str, mode, 4);
        if (u.str[3] == '\0')
            u.str[3] = ' '; /* 'pal'\0 -> 'pal ' */
        free(mode);
    }

    es_format_t video_fmt;
    video_fmt.video.i_width = 0;

    for (IDeckLinkDisplayMode *m;; m->Release()) {
        if ((mode_it->Next(&m) != S_OK) || !m)
            break;

        const char *mode_name;
        BMDTimeValue frame_duration, time_scale;
        uint32_t field_flags;
        const char *field = GetFieldDominance(m->GetFieldDominance(), &field_flags);
        BMDDisplayMode id = ntohl(m->GetDisplayMode());

        if (m->GetName(&mode_name) != S_OK)
            mode_name = "unknown";
        if (m->GetFrameRate(&frame_duration, &time_scale) != S_OK) {
            time_scale = 0;
            frame_duration = 1;
        }

        msg_Dbg(demux, "Found mode '%4.4s': %s (%dx%d, %.3f fps%s)",
                 (char*)&id, mode_name,
                 (int)m->GetWidth(), (int)m->GetHeight(),
                 double(time_scale) / frame_duration, field);

        if (u.id == id) {
            video_fmt = GetModeSettings(demux, m);
            msg_Dbg(demux, "Using that mode");
        }
    }

    mode_it->Release();

    if (video_fmt.video.i_width == 0) {
        msg_Err(demux, "Unknown video mode `%4.4s\' specified.", (char*)&u.id);
        goto finish;
    }

    if (sys->input->EnableVideoInput(htonl(u.id), fmt, flags) != S_OK) {
        msg_Err(demux, "Failed to enable video input");
        goto finish;
    }

    /* Set up audio. */
    sys->channels = var_InheritInteger(demux, "decklink-audio-channels");
    switch (sys->channels) {
    case 0:
        break;
    case 2:
        physical_channels = AOUT_CHANS_STEREO;
        break;
    case 8:
        physical_channels = AOUT_CHANS_7_1;
        break;
    //case 16:
    default:
        msg_Err(demux, "Invalid number of channels (%d), disabling audio", sys->channels);
        sys->channels = 0;
    }
    rate = var_InheritInteger(demux, "decklink-audio-rate");
    if (rate > 0 && sys->channels > 0) {
        if (sys->input->EnableAudioInput(rate, bmdAudioSampleType16bitInteger, sys->channels) != S_OK) {
            msg_Err(demux, "Failed to enable audio input");
            goto finish;
        }
    }

    sys->delegate = new DeckLinkCaptureDelegate(demux);
    sys->input->SetCallback(sys->delegate);

    if (sys->input->StartStreams() != S_OK) {
        msg_Err(demux, "Could not start streaming from SDI card. This could be caused "
                          "by invalid video mode or flags, access denied, or card already in use.");
        goto finish;
    }

    msg_Dbg(demux, "added new video es %4.4s %dx%d",
             (char*)&video_fmt.i_codec, video_fmt.video.i_width, video_fmt.video.i_height);
    sys->video_es = es_out_Add(demux->out, &video_fmt);

    es_format_t audio_fmt;
    es_format_Init(&audio_fmt, AUDIO_ES, VLC_CODEC_S16N);
    audio_fmt.audio.i_channels = sys->channels;
    audio_fmt.audio.i_physical_channels = physical_channels;
    audio_fmt.audio.i_rate = rate;
    audio_fmt.audio.i_bitspersample = 16;
    audio_fmt.audio.i_blockalign = audio_fmt.audio.i_channels * audio_fmt.audio.i_bitspersample / 8;
    audio_fmt.i_bitrate = audio_fmt.audio.i_channels * audio_fmt.audio.i_rate * audio_fmt.audio.i_bitspersample;

    msg_Dbg(demux, "added new audio es %4.4s %dHz %dbpp %dch",
             (char*)&audio_fmt.i_codec, audio_fmt.audio.i_rate, audio_fmt.audio.i_bitspersample, audio_fmt.audio.i_channels);
    sys->audio_es = es_out_Add(demux->out, &audio_fmt);

    ret = VLC_SUCCESS;

finish:
    if (decklink_iterator)
        decklink_iterator->Release();

    if (ret != VLC_SUCCESS)
        Close(p_this);

    return ret;
}
예제 #20
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;
}
예제 #21
0
void BMDOutputDelegate::StartRunning ()
{
	IDeckLinkDisplayMode*	videoDisplayMode = NULL;
	
	// Get the display mode for 1080i 59.95 - mode 6
	// Changed to NTSC 23.98 - JB 20110215
	videoDisplayMode = GetDisplayModeByIndex(1);

	if (!videoDisplayMode)
		return;

	m_frameWidth = videoDisplayMode->GetWidth();
	m_frameHeight = videoDisplayMode->GetHeight();
	videoDisplayMode->GetFrameRate(&m_frameDuration, &m_frameTimescale);
	
	// Calculate the number of frames per second, rounded up to the nearest integer.  For example, for NTSC (29.97 FPS), framesPerSecond == 30.
	m_framesPerSecond = (unsigned long)((m_frameTimescale + (m_frameDuration-1))  /  m_frameDuration);
	
	
	QImage image(m_frameWidth,m_frameHeight, QImage::Format_ARGB32);
	image.fill(Qt::green);
	//m_frame = VideoFramePtr(new VideoFrame(image, 1000/30));
	
	HRESULT res;
	
	// Set the video output mode
	if (m_deckLinkOutput->EnableVideoOutput(videoDisplayMode->GetDisplayMode(), bmdVideoOutputFlagDefault) != S_OK)
	{
		//fprintf(stderr, "Failed to enable video output\n");
		qDebug() << "BMDOutputDelegate::StartRunning(): Failed to EnableVideoOutput()";
		goto bail;
	}
	
	res = m_deckLinkOutput->CreateVideoFrame(
		m_frameWidth,
		m_frameHeight,
		m_frameWidth * 4,
		bmdFormat8BitBGRA, 
		bmdFrameFlagDefault,
		&m_rgbFrame);
	
	if(res != S_OK)
	{
		qDebug() << "BMDOutputDelegate::StartRunning: Error creating RGB frame, res:"<<res;
		goto bail;
	}
	
	res = m_deckLinkOutput->CreateVideoFrame(
		m_frameWidth,
		m_frameHeight,
		m_frameWidth * 2,
		bmdFormat8BitYUV, 
		bmdFrameFlagDefault,
		&m_yuvFrame);
	
	if(res != S_OK)
	{
		qDebug() << "BMDOutputDelegate::StartRunning: Error creating YUV frame, res:"<<res;
		goto bail;
	}


// 	// Generate a frame of black
// 	if (m_deckLinkOutput->CreateVideoFrame(m_frameWidth, m_frameHeight, m_frameWidth*2, bmdFormat8BitYUV, bmdFrameFlagDefault, &m_videoFrameBlack) != S_OK)
// 	{
// 		fprintf(stderr, "Failed to create video frame\n");	
// 		goto bail;
// 	}
// 	FillBlack(m_videoFrameBlack);
// 	
// 	// Generate a frame of colour bars
// 	if (m_deckLinkOutput->CreateVideoFrame(m_frameWidth, m_frameHeight, m_frameWidth*2, bmdFormat8BitYUV, bmdFrameFlagDefault, &m_videoFrameBars) != S_OK)
// 	{
// 		fprintf(stderr, "Failed to create video frame\n");
// 		goto bail;
// 	}
// 	FillColourBars(m_videoFrameBars);
	
	
	// Begin video preroll by scheduling a second of frames in hardware
	m_totalFramesScheduled = 0;
  	for (unsigned i = 0; i < m_framesPerSecond; i++)
  	{
  		PrepareFrame();
 		ScheduleNextFrame(true);
 	}
	
	// Args: startTime, timeScale, playback speed (1.0 = normal)
	m_deckLinkOutput->StartScheduledPlayback(0, 100, 1.0);
	
	m_running = true;
	
	return;
	
bail:
	// *** Error-handling code.  Cleanup any resources that were allocated. *** //
	StopRunning();
}
예제 #22
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();
}
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();
}
예제 #24
0
int ff_decklink_set_format(AVFormatContext *avctx,
                               int width, int height,
                               int tb_num, int tb_den,
                               enum AVFieldOrder field_order,
                               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;

    av_log(avctx, AV_LOG_DEBUG, "Trying to find mode for frame size %dx%d, frame timing %d/%d, field order %d, direction %d, mode number %d, format code %s\n",
        width, height, tb_num, tb_den, field_order, direction, num, (cctx->format_code) ? cctx->format_code : "(unset)");

    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);
    }

    char format_buf[] = "    ";
    if (cctx->format_code)
        memcpy(format_buf, cctx->format_code, FFMIN(strlen(cctx->format_code), sizeof(format_buf)));
    BMDDisplayMode target_mode = (BMDDisplayMode)AV_RB32(format_buf);
    AVRational target_tb = av_make_q(tb_num, tb_den);
    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();
        BMDDisplayMode bmd_mode = mode->GetDisplayMode();
        BMDFieldDominance bmd_field_dominance = mode->GetFieldDominance();

        mode->GetFrameRate(&bmd_tb_num, &bmd_tb_den);
        AVRational mode_tb = av_make_q(bmd_tb_num, bmd_tb_den);

        if ((bmd_width == width &&
             bmd_height == height &&
             !av_cmp_q(mode_tb, target_tb) &&
             field_order_eq(field_order, bmd_field_dominance))
             || i == num
             || target_mode == bmd_mode) {
            ctx->bmd_mode   = bmd_mode;
            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 = bmd_field_dominance;
            av_log(avctx, AV_LOG_INFO, "Found Decklink mode %d x %d with rate %.2f%s\n",
                bmd_width, bmd_height, 1/av_q2d(mode_tb),
                (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, (BMDPixelFormat) cctx->raw_format,
                                           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;
}
예제 #25
0
파일: Config.cpp 프로젝트: Gastd/oh-distro
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);
}