- Posts: 1
- Joined: Fri Jan 26, 2018 3:17 pm
- Real Name: Saurabh Verma
Saving out capture to image file is not a native function of the DeckLink API. You will either need to write your own functions to write out BMP headers, or use an external library to do this for you (eg Windows Imaging Component or System.Image in the .NET Framework).
In either case, as a first step you will need to convert the incoming frame to BGRA 32-bit format (Pixel format bmdFormat8BitBGRA[1]). You can use the IDeckLinkVideoConversion Interface to perform the pixel format conversion.
You should create a class to define the BGRA frame that inherits from the IDeckLinkVideoFrame[3] base class. The class constructor should allocate the a frame buffer for the IDeckLinkVideoConversion to use via the GetBytes()[4] virtual function. The following is an example template for this class:
- Code: Select all
class Bgra32VideoFrame : IDeckLinkVideoFrame
{
private:
long m_width;
long m_height;
BMDFrameFlags m_flags;
LPVOID m_pixelBuffer = NULL;
ULONG m_refCount;
public:
Bgra32VideoFrame(long width, long height, BMDFrameFlags flags);
virtual ~Bgra32VideoFrame();
virtual long STDMETHODCALLTYPE GetWidth(void);
virtual long STDMETHODCALLTYPE GetHeight(void);
virtual long STDMETHODCALLTYPE GetRowBytes(void);
virtual HRESULT STDMETHODCALLTYPE GetBytes(void** buffer);
virtual BMDFrameFlags STDMETHODCALLTYPE GetFlags(void);
virtual BMDPixelFormat STDMETHODCALLTYPE GetPixelFormat(void);
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, LPVOID *ppv);
virtual ULONG STDMETHODCALLTYPE AddRef();
virtual ULONG STDMETHODCALLTYPE Release();
// Dummy implementations of remaining methods
virtual HRESULT STDMETHODCALLTYPE GetAncillaryData(IDeckLinkVideoFrameAncillary** ancillary);
virtual HRESULT STDMETHODCALLTYPE GetTimecode(BMDTimecodeFormat format, IDeckLinkTimecode** timecode);
};
Then inside your DeckLinkDevice::VideoInputFrameArrived() callback, create Bgra32VideoFrame object and call ConvertFrame method[5]. In sample, frameConverter is pointer of type IDeckLinkVideoConversion:
- Code: Select all
HRESULT DeckLinkDevice::VideoInputFrameArrived(/* in */ IDeckLinkVideoInputFrame* videoFrame, /* in */ IDeckLinkAudioInputPacket* audioPacket)
{
Bgra32VideoFrame* bgra32Frame;
HRESULT result = S_OK;
if (videoFrame)
{
bgra32Frame = new Bgra32VideoFrame(videoFrame->GetWidth(), videoFrame->GetHeight(), videoFrame->GetFlags());
result = frameConverter->ConvertFrame(videoFrame, (IDeckLinkVideoFrame*)bgra32Frame);
// Store bgra32Frame as BMP
...
delete bgra32Frame;
}
return result;
}
We intend to publish this content as a sample in the future.
Kind Regards
Cameron
Refs (DeckLink SDK Manual)
[1] 2.7.4 Pixel Formats
[2] 2.5.41 IDeckLinkVideoConversion Interface
[3] 2.5.5 IDeckLinkVideoFrame Interface
[4] 2.5.5.6 IDeckLinkVideoFrame::GetBytes method
[5] 2.5.41.1 IDeckLinkVideoConversion::ConvertFrame method