Page 1 of 1

Receiving only half of the frames with new SDK

PostPosted: Sun Apr 11, 2021 6:49 pm
by RoestBM
Some years ago (2015) I wrote a video replay software based on an example in the SDK.

It uses this file more or less unchanged pastebin.com/crePMhTh (apparently I am not allowed to post url's) only at the bottom in the VideoInputFrameArrived function I then call my own handler for the frame. For the new SDK I had to rename IDeckLinkAttributes to IDeckLinkProfileAttributes to make it compile again. Surprising that was all.

The program works again, it opens the video but only receives about 13 frames per second on a UltraStudio Mini Recorder from a camera in 1080i50.

Any advice on what may go wrong here would be really appreciated.

Re: Receiving only half of the frames with new SDK

PostPosted: Mon Apr 12, 2021 3:51 pm
by Xtreemtec
No can not post links until you have 10+ posts on the forum. ( Robot prevention ;) )

Re: Receiving only half of the frames with new SDK

PostPosted: Wed Apr 28, 2021 5:58 am
by Cameron Nichols
Hi Otto,

I had a look through your source in pastebin. I believe the issue relates to one of 2 issues:

In the VideoInputFrameArrived callback, check that the call to
Code: Select all
Global::frameStore->receiveFrame( videoFrame, audioPacket );
does not exceed the frame period. If this occurs then you will end up with backlog of input frames queued waiting for subsequent IDeckLinkInputCallback::VideoInputFrameArrived callbacks. The method IDeckLinkOutput::GetBufferedVideoFrameCount will provide clue whether input frames are being buffered.

The second suggestion, is in Desktop Video 11.6, new format detection flags for detecting depth were added. I suggest making the following change to your VideoInputFormatChanged callback:
Code: Select all
HRESULT DeckLinkDevice::VideoInputFormatChanged(/* in */ BMDVideoInputFormatChangedEvents notificationEvents, /* in */ IDeckLinkDisplayMode *newMode, /* in */ BMDDetectedVideoInputFormatFlags detectedSignalFlags )
{
    unsigned int    modeIndex = 0;
    BMDPixelFormat  pixelFormat = m_pixelFormat;
 
    // Restart capture with the new video mode if told to
    if( !m_applyDetectedInputMode )
        goto bail;
 
    if (notificationEvents & bmdVideoInputColorspaceChanged)
    {
        if( detectedSignalFlags & bmdDetectedVideoInputRGB444 )
            pixelFormat = bmdFormat10BitRGB;
        else if (detectedSignalFlags & bmdDetectedVideoInputYCbCr422)
            pixelFormat = bmdFormat8BitYUV;
        else
            goto bail;
    }

    // Restart streams if either dispay mode or colorspace has changed
    if ((notificationEvents & bmdVideoInputDisplayModeChanged) || (pixelFormat != m_pixelFormat))
    {
        // Stop the capture
        m_deckLinkInput->StopStreams( );
 
        // Set the video input mode
        if( m_deckLinkInput->EnableVideoInput( newMode->GetDisplayMode( ), pixelFormat, bmdVideoInputEnableFormatDetection ) != S_OK )
        {
            // Let the UI know we couldnt restart the capture with the detected input mode
            //PostMessage( m_uiDelegate->GetSafeHwnd( ), WM_ERROR_RESTARTING_CAPTURE_MESSAGE, 0, 0 );
            goto bail;
        }
 
        // Start the capture
        if( m_deckLinkInput->StartStreams( ) != S_OK )
        {
            // Let the UI know we couldnt restart the capture with the detected input mode
            //PostMessage( m_uiDelegate->GetSafeHwnd( ), WM_ERROR_RESTARTING_CAPTURE_MESSAGE, 0, 0 );
            goto bail;
        }
 
        m_pixelFormat = pixelFormat;
    }

    if (notificationEvents & bmdVideoInputDisplayModeChanged)
    {
        // Find the index of the new mode in the mode list so we can update the UI
        while( modeIndex < m_modeList.size( ) )
        {
            if( m_modeList[modeIndex]->GetDisplayMode( ) == newMode->GetDisplayMode( ) )
            {
                //PostMessage( m_uiDelegate->GetSafeHwnd( ), WM_SELECT_VIDEO_MODE_MESSAGE, modeIndex, 0 );
                if( m_uiDelegate ) m_uiDelegate->onMessage( (int)MessageType::SELECT_VIDEO_MODE, modeIndex );
                break;
            }
            modeIndex++;
        }
    }
 
bail:
    return S_OK;
}

Create member variable m_pixelFormat keep track of whether output mode is bmdFormat8BitYUV or bmdFormat10BitRGB for when detected colorspace/depth is different to the output pixel format.

Regards
Cameron

Re: Receiving only half of the frames with new SDK

PostPosted: Thu Apr 29, 2021 9:54 am
by RoestBM
Thanks, for the answer. The change to DeckLinkDevice::VideoInputFormatChanged() did the trick. Topic resolved.