Save capture card frame buffer to BMP image

Ask software engineering and SDK questions for developers working on Mac OS X, Windows or Linux.
  • Author
  • Message
Offline

sauverma

  • Posts: 1
  • Joined: Fri Jan 26, 2018 3:17 pm
  • Real Name: Saurabh Verma

Save capture card frame buffer to BMP image

PostFri Jan 26, 2018 3:25 pm

I need to create a BMP file of the frame that is inputting in the capture card.
I am using CapturePreview example program provided in SDK.
I understand that DeckLinkDevice::VideoInputFrameArrived() function is called when frame arrives.

Can some one please provide me a code snippet in C++ to save image(IDeckLinkVideoInputFrame* videoFrame) into BMP file. I am also OK with saving in some other image format.

It will be good to provide C++ code snippets without using any 3rd party library as I am not aware of how to add 3rd party lib/file in VS2013.
Offline

Cameron Nichols

Blackmagic Design

  • Posts: 442
  • Joined: Mon Sep 04, 2017 4:05 am

Re: Save capture card frame buffer to BMP image

PostMon Jan 29, 2018 4:03 am

Hi Saurabh,

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
Offline

dzhoshkun

  • Posts: 1
  • Joined: Wed Nov 21, 2018 1:22 pm
  • Real Name: Dzhoshkun Shakir

Re: Save capture card frame buffer to BMP image

PostThu Nov 22, 2018 10:45 am

Hi Cameron,

I have a DeckLink 4K Extreme 12G. Do I understand correctly from the specs that if I want to get BGRA data, the only way to do this is to capture in
Code: Select all
bmdFormat12BitRGB
or
Code: Select all
bmdFormat10BitYUV
and convert to
Code: Select all
 bmdFormat8BitBGRA
?

If I set the actual capture to
Code: Select all
 bmdFormat8BitBGRA
it does work, but returns overly-green frames, which I guess is a result of misinterpreting the data as BGRA.

Cheers,

Dzhoshkun

Return to Software Developers

Who is online

Users browsing this forum: Google [Bot] and 16 guests