FORUMS: list search recent posts

BlueScreen when using bmdVideoOutputDualStream3D

COW Forums : Blackmagic Design

<< PREVIOUS   •   VIEW ALL   •   PRINT   •   NEXT >>
Erwin Kloibhofer
BlueScreen when using bmdVideoOutputDualStream3D
on Jan 31, 2012 at 2:32:36 am

For the last couple of days I am struggling to find the cause of the following problem: a very minimal DirectX9 based Windows test application stops receiving ScheduledFrameCompleted() after a period anywhere between 5 and 60 minutes, but the app keeps on running anyway. Then when I try to exit the application it gets stuck inside DisableVideoOutput(). The only thing left at this point is to kill the process via the TaskManager, which then results in a BlueScreen (PROCESS_HAS_LOCKED_PAGES in "ntoskrnl.exe").

I have two Windows Pro 7 machines (64 bit) available with a Decklink HD Extreme 3D plugged in each of them. The hardware setup is relatively similar, both use a Radeon HD 5770, although my workstation here has a Core-i5 processor, and the second machine (btw 1000 km away from here), is Xeon based. I am using the same Radeon drivers (12.1), and Decklink drivers (9.0).

This issue only occurs on the remote machine, not on my local workstation here. I only have these 2 machines available, if I had a third one I could probably tell if this is a hardware problem, a driver issue or a problem with my code.

Now for the code: I am using bmdVideoOutputDualStream3D to output a fill and key stream on the Decklink Extreme - so I basically "mis-use" the 3D feature. Although Blackmagic support recommended to do it this way, since that's the only way to get in-sync fill and key streams.

First thing I noticed when programming, was that the ordinary IDeckLinkMutableVideoFrame class can not be used when using the bmdVideoOutputDualStream3D flag. So I put together the "DeckLink3dVideoFrame" class, based on code fragments I found on the Blackmagic mailing list.

My test code is very simple, basically it does this:


BeginScene
Clear
// no rendering what so ever happens
EndScene
Present
GetRenderTargetData
StoreFrameBufferForLaterUse


When ScheduledFrameCompleted() is called I memcpy the previously stored frame into the frame buffer of the left eye, and at the same time copy the alpha-channel into the right eye frame-buffer, using the CPU.

This all works perfectly on my work-station here, and only shows that malfunction on the remote machine. There are two methods to avoid the malfunction:

1) Use bmdVideoOutputFlagDefault instead of bmdVideoOutputDualStream3D when calling EnableVideoOutput() (but still keep on using the DeckLink3dVideoFrame class)
2) Comment out the call to IDirect3DDevice9::GetRenderTargetData()

In case of 1) this could point to a problem inside DeckLink3dVideoFrame class, which as I mentioned is based on code-fragements. Could someone have a look at it? Of course this could also be caused by a driver error, or a hardware problem.

I think I picked up somewhere that bmdVideoOutputDualStream3D only works with YUV? However I passed bmdFormat8BitBGRA as the screen-format when creating the buffer, and this works flawlessly on my machine here.

I would really appreciate any pointers, because I am sort of running out of ideas...

Here's the code for DeckLink3dVideoFrame:


// -----------------------------------------------------------------------------
class DecklinkOutput::DeckLink3dVideoFrame : public IDeckLinkVideoFrame, public IDeckLinkVideoFrame3DExtensions
// -----------------------------------------------------------------------------
{
public:
DeckLink3dVideoFrame() : mRightEyeFrame(0), mWidth(0), mHeight(0), mPitch(0), mBuffer(0), mRefCount(1) {}
virtual ~DeckLink3dVideoFrame() { delete mBuffer; }

bool CreateVideoFrame(int w, int h, int pitch, BMDPixelFormat pixelFormat)
{
mWidth = w;
mHeight = h;
mPitch = pitch;
mPixelFormat = pixelFormat;

mBuffer = new BYTE[mPitch * mHeight];
return true;
}

long STDMETHODCALLTYPE GetWidth() { return mWidth; }
long STDMETHODCALLTYPE GetHeight() { return mHeight; }
long STDMETHODCALLTYPE GetRowBytes() { return mPitch; }
BMDPixelFormat STDMETHODCALLTYPE GetPixelFormat() { return mPixelFormat; }
BMDFrameFlags STDMETHODCALLTYPE GetFlags() { return 0; }

HRESULT STDMETHODCALLTYPE GetBytes(void** buffer)
{
*buffer = mBuffer;
return S_OK;
}

void SetRightEyeFrame(DeckLink3dVideoFrame* right) { mRightEyeFrame = right; }

HRESULT STDMETHODCALLTYPE GetTimecode(BMDTimecodeFormat format, IDeckLinkTimecode **timecode) { return E_FAIL; }
HRESULT STDMETHODCALLTYPE GetAncillaryData(IDeckLinkVideoFrameAncillary **ancillary) { return E_FAIL; }

HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, LPVOID* ppv)
{
HRESULT result = E_NOINTERFACE;

// initialize the return result
*ppv = NULL;

// obtain the IUnknown interface and compare it the provided REFIID
if (iid == IID_IUnknown)
{
*ppv = this;
AddRef();
result = S_OK;
}
else if (iid == IID_IDeckLinkVideoFrame3DExtensions)
{
*ppv = (IDeckLinkVideoFrame3DExtensions*)this;
AddRef();
result = S_OK;
}

return result;
}

ULONG STDMETHODCALLTYPE AddRef()
{
return InterlockedIncrement((LONG*)&mRefCount);
}

ULONG STDMETHODCALLTYPE Release()
{
int newRefValue = InterlockedDecrement((LONG*)&mRefCount);

if (newRefValue == 0)
{
delete this;
return 0;
}

return newRefValue;
}

BMDVideo3DPackingFormat STDMETHODCALLTYPE Get3DPackingFormat()
{
if (mRightEyeFrame)
return bmdVideo3DPackingLeftOnly;
else
return bmdVideo3DPackingRightOnly;
}

HRESULT STDMETHODCALLTYPE GetFrameForRightEye(IDeckLinkVideoFrame** rightEyeFrame)
{
*rightEyeFrame = mRightEyeFrame;

if (mRightEyeFrame)
{
mRightEyeFrame->AddRef();
return S_OK;
}
else
{
return S_FALSE;
}
}

private:
int mRefCount;
DeckLink3dVideoFrame* mRightEyeFrame;

int mWidth;
int mHeight;
int mPitch;
BMDPixelFormat mPixelFormat;
BYTE* mBuffer;
};



Return to posts index

<< PREVIOUS   •   VIEW ALL   •   PRINT   •   NEXT >>
© 2017 CreativeCOW.net All Rights Reserved
[TOP]