VideoInputFormatChanged() sometimes not called
Posted: Wed Apr 22, 2015 3:59 pm
Most of the time our VideoInputFormatChanged()
callback gets called, but sometimes it doesn't.
Typically, the problem is easiest to reproduce when exactly 2 of the 4 inputs on a DeckLink Quad
card are plugged in and changing format simultaneously.
When this happens, our VideoInputFrameArrived() callback continues to get called with flag
'bmdFrameHasNoInputSource'
Is there any API to force the VideoInputFormatChanged callback to happen, or to query what the last callback was.
One thing I don't want to do is poll continuously. I want to retry exactly once after a failure and a timeout.
If there was an inexpensive API which I could poll to detect a missed format change,
this would solve our issues.
By inexpensive, I mean an API which requires no semaphore locking in my code OR in SDK driver code.
I don't want this question to devolve into a discussion about machine sleep.
Putting the machine to sleep is an unfair test.
However, in general I’ve found that if my code can handle unfair tests, like waking from sleep,
then it can handle just about any dicey situation.
Our Macs have sleep disabled, power saving disabled, as well as many other System Preferences which could slow down the Mac or cause apps to nap.
This bug is very difficult to reproduce, but one way to reproduce this bug every time is to put the Mac to sleep, then make a change, then wake Mac up from sleep.
We use the DeckLink SDK extensively. We have at least 100 machines with DeckLink cards.
callback gets called, but sometimes it doesn't.
Typically, the problem is easiest to reproduce when exactly 2 of the 4 inputs on a DeckLink Quad
card are plugged in and changing format simultaneously.
When this happens, our VideoInputFrameArrived() callback continues to get called with flag
'bmdFrameHasNoInputSource'
Is there any API to force the VideoInputFormatChanged callback to happen, or to query what the last callback was.
One thing I don't want to do is poll continuously. I want to retry exactly once after a failure and a timeout.
If there was an inexpensive API which I could poll to detect a missed format change,
this would solve our issues.
By inexpensive, I mean an API which requires no semaphore locking in my code OR in SDK driver code.
I don't want this question to devolve into a discussion about machine sleep.
Putting the machine to sleep is an unfair test.
However, in general I’ve found that if my code can handle unfair tests, like waking from sleep,
then it can handle just about any dicey situation.
Our Macs have sleep disabled, power saving disabled, as well as many other System Preferences which could slow down the Mac or cause apps to nap.
This bug is very difficult to reproduce, but one way to reproduce this bug every time is to put the Mac to sleep, then make a change, then wake Mac up from sleep.
- Code: Select all
I use this design pattern for this type of thing:
driver code:
int globalChangeIncrement; // increments after every change
driver code:
if ( changeDetected )
{
globalChangeIncrement++;
// sometimes I use this instead, when multiple threads could be writing this:
#include <libkern/OSAtomic.h>
OSAtomicIncrement32Barrier( & globalChangeIncrement );
callbackToCustomersCode(); // such as VideoInputFormatChanged()
}
SDK API:
static int IDeckLinkInput::GetGlobalChangeIncrement()
{
return globalChangeIncrement;
}
USAGE EXAMPLE
static int sCustomerChangeIncrement;
HRESULT DeckLinkInput::VideoInputFormatChanged (BMDVideoInputFormatChangedEvents evt, IDeckLinkDisplayMode* newmode, BMDDetectedVideoInputFormatFlags flags)
{
sCustomerChangeIncrement = decklinkinput-> GetGlobalChangeIncrement()
… process change
}
I could then write code that polls this variable once every 5 seconds:
if ( decklink_is_not_working &&
no_changes_in_last_5_seconds &&
sCustomerChangeIncrement != decklinkinput-> GetGlobalChangeIncrement() )
{
scheduleCleanUpAndReInit(); // which calls StopStreams, etc, etc.
}
We use the DeckLink SDK extensively. We have at least 100 machines with DeckLink cards.