Creative Communities of the World Forums

The peer to peer support community for media production professionals.

Activity › Forums › Blackmagic Design › BlueScreen when using bmdVideoOutputDualStream3D

  • BlueScreen when using bmdVideoOutputDualStream3D

    Posted by Erwin Kloibhofer on January 31, 2012 at 2:32 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;
    };

    Erwin Kloibhofer replied 14 years, 8 months ago 1 Member · 0 Replies
  • 0 Replies

Sorry, there were no replies found.

We use anonymous cookies to give you the best experience we can.
Our Privacy policy | GDPR Policy