get bytes of a frame using csharp

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

tomsap

  • Posts: 19
  • Joined: Tue Mar 03, 2020 4:17 pm
  • Real Name: Tom Saplonsky

get bytes of a frame using csharp

PostTue Mar 03, 2020 4:30 pm

Hello,

I am trying to use my blackmagic 4k extreme with the latest SDK to get the value of a frame in bytes from a camera that i connect to him.
I try to use the example program that in the SDK folder that called csharpstills, but when I compile and run it, it crashed with the error that say there is a counter of an event that is blow zero.
Maybe someone know how to solve it or why this is happend?
or there is a simple option or an example that I can get the bytes of a frame without using csharpstills program?

Thank you!
Offline

Cameron Nichols

Blackmagic Design

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

Re: get bytes of a frame using csharp

PostTue Mar 03, 2020 10:05 pm

Hi Tom,

Can you share what you capture interval and number of stills you have set in StillsCSharp? There is a countdown that is decremented for each frame captured, but it is not expected to fall below zero.

To get raw buffer of the frame, you should call IDeckLinkVideoFrame.GetBytes. This is demonstrated on the BGRA converted frame in the VideoFrameArrived event handler in Stills.cs.

Regards
Cameron
Offline

tomsap

  • Posts: 19
  • Joined: Tue Mar 03, 2020 4:17 pm
  • Real Name: Tom Saplonsky

Re: get bytes of a frame using csharp

PostMon Mar 09, 2020 7:56 am

Thank you for your replay,

I want to capture one frame, so I set the Frame Interval and the Number Stills to be with the value of 1.
After that I get the message that the m_captureCountdown count below zero and the program crash. Why is it happening?

Tom.
Offline

Cameron Nichols

Blackmagic Design

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

Re: get bytes of a frame using csharp

PostFri Mar 13, 2020 5:41 am

Hi Tom,

What is the incoming video mode and pixel format that you are receiving?

Regards
Cameron
Offline

tomsap

  • Posts: 19
  • Joined: Tue Mar 03, 2020 4:17 pm
  • Real Name: Tom Saplonsky

Re: get bytes of a frame using csharp

PostFri Mar 13, 2020 8:26 pm

Hi Nichols,

I use standard pal for video mode. I get the same error for 8 bit pixel format and also for 10 bit pixel format.

Thank you,

Tom.
Offline

tomsap

  • Posts: 19
  • Joined: Tue Mar 03, 2020 4:17 pm
  • Real Name: Tom Saplonsky

Re: get bytes of a frame using csharp

PostSun Apr 19, 2020 12:59 pm

someone please can help?
Offline

cameronleeperlm

  • Posts: 6
  • Joined: Thu Nov 21, 2019 8:57 pm
  • Real Name: Cam Leeper

Re: get bytes of a frame using csharp

PostThu Apr 30, 2020 3:15 pm

I would check m_captureCountdown which is a countdown event. It should be putting the numericUpDownCaptureNumberStills.Value there. m_captureCountdown is what the task is waiting on as frames arrived. It counts down at the m_captureCountdown.Signal().

Also for your pixel format I would select the Format Detection checkbox to see how it is being read by default.

Using C# Stills I used Marshal.Copy to get the byte[]
Code: Select all
//The GetBytes method allows direct access to the data buffer of a video IDeckLinkVideoFrame bgra32Frame = m_frameConverter.ConvertFrame(e.videoFrame);
bgra32Frame.GetBytes(out IntPtr bgra32FrameBytes);
int frameSize = bgra32Frame.GetRowBytes() * bgra32Frame.GetHeight();
byte[] frameBytes = new byte[frameSize];
Marshal.Copy(bgra32FrameBytes, frameBytes, 0, frameSize);
Offline

tomsap

  • Posts: 19
  • Joined: Tue Mar 03, 2020 4:17 pm
  • Real Name: Tom Saplonsky

Re: get bytes of a frame using csharp

PostSun May 24, 2020 7:25 pm

Thank you for your replay,
I manage to get the value of the bytes with this code,

Code: Select all
//The GetBytes method allows direct access to the data buffer of a video IDeckLinkVideoFrame bgra32Frame = m_frameConverter.ConvertFrame(e.videoFrame);
bgra32Frame.GetBytes(out IntPtr bgra32FrameBytes);
int frameSize = bgra32Frame.GetRowBytes() * bgra32Frame.GetHeight();
byte[] frameBytes = new byte[frameSize];
Marshal.Copy(bgra32FrameBytes, frameBytes, 0, frameSize);


When i run the csharpstills program, i can choose only 8-bit YUV or 10-bit YUV (I have 4k Extreme) in the dropdown menu.
The problem is that when I choose 8-bit YUV or 10-bit YUV I get the same values of bytes in my array! Why is this happening?

Thanks,
Tom.
Offline

Cameron Nichols

Blackmagic Design

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

Re: get bytes of a frame using csharp

PostWed May 27, 2020 12:47 am

Hi Tom,

I believe the issue is found in the IDeckLinkInputCallback.VideoInputFormatChanged callback, if you are using auto-mode detection, then the capture will actually be either 8-bit BGRA or 8-bit YUV, depending of the colorspace detected on the wire.

The intention for the Capture Pixel Format combo is informative, to visually see the auto-detected captured pixel format. I don't believe the intention was for this to be selectable capture pixel format. I will add this to be improved in sample in the future.

Either way, the sample will convert the incoming frame to BGRA, so it is compatible with Bitmap source format PixelFormat.Format32bppArgb.

Regards
Cameron
Offline

tomsap

  • Posts: 19
  • Joined: Tue Mar 03, 2020 4:17 pm
  • Real Name: Tom Saplonsky

Re: get bytes of a frame using csharp

PostWed May 27, 2020 10:47 am

Thank you Cameron for your replay.

I do not understand how can I get a byte array of 10 bit YUV when I don't use auto-detected captured pixel format. I know that the 4k Extreme can do that.

Tom.
Offline

Cameron Nichols

Blackmagic Design

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

Re: get bytes of a frame using csharp

PostThu May 28, 2020 12:19 am

Hi Tom,

In the sample there is no correlation between the Combobox and the actual pixel format, this will be resolved in a future release. To change to 10-bit YUV, modify DeckLinkInputDevice.cs:

In StartCapture method modify the call to IDeckLinkInput::EnableVideoInput as follows,
Code: Select all
            // Set the video input mode
            m_deckLinkInput.EnableVideoInput(displayMode.GetDisplayMode(), _BMDPixelFormat.bmdFormat10BitYUV, videoInputFlags);

If later you are using auto-mode detection, you will need to also change IDeckLinkInputCallback.VideoInputFormatChanged callback:
Code: Select all
           var pixelFormat = _BMDPixelFormat.bmdFormat10BitYUV;
            if (detectedSignalFlags.HasFlag(_BMDDetectedVideoInputFormatFlags.bmdDetectedVideoInputRGB444))
                pixelFormat = _BMDPixelFormat.bmdFormat8BitBGRA;

Regards
Cameron
Offline

tomsap

  • Posts: 19
  • Joined: Tue Mar 03, 2020 4:17 pm
  • Real Name: Tom Saplonsky

Re: get bytes of a frame using csharp

PostThu May 28, 2020 1:30 pm

Hi Cameron,

I change the things that you mentioned in the DeckLinkInputDevice.cs, but I have the same problem, the byte array in 10 and 8 bit YUV are the same (also in the size of the array they are ths same)!

I'm trying to figure out why this is happenin, so I change this code:

Code: Select all
//The GetBytes method allows direct access to the data buffer of a video IDeckLinkVideoFrame bgra32Frame = m_frameConverter.ConvertFrame(e.videoFrame);
bgra32Frame.GetBytes(out IntPtr bgra32FrameBytes);
int frameSize = bgra32Frame.GetRowBytes() * bgra32Frame.GetHeight();
byte[] frameBytes = new byte[frameSize];
Marshal.Copy(bgra32FrameBytes, frameBytes, 0, frameSize);


to this one:

Code: Select all
//The GetBytes method allows direct access to the data buffer of a video IDeckLinkVideoFrame
e.videoFrame.GetBytes(out IntPtr bgra32FrameBytes);
int frameSize = e.videoFrame.GetRowBytes() * e.videoFrame.GetHeight();
byte[] frameBytes = new byte[frameSize];
Marshal.Copy(bgra32FrameBytes, frameBytes, 0, frameSize);


(I'm not using this line: bgra32Frame = m_frameConverter.ConvertFrame(e.videoFrame)).

and now I get that in the 8 bit YUV the size of the byte array is 720*576*2 (this is good because I am working with PAL 625i50) but in 10 bit YUV the size is 1105920.

Maybe I am doing something wrong or the new code is the solution?

Thank you,

Tom.
Offline

tomsap

  • Posts: 19
  • Joined: Tue Mar 03, 2020 4:17 pm
  • Real Name: Tom Saplonsky

Re: get bytes of a frame using csharp

PostSun Jun 21, 2020 1:12 pm

someone please can help?
Offline

Cameron Nichols

Blackmagic Design

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

Re: get bytes of a frame using csharp

PostMon Jun 22, 2020 11:38 am

Hi Tom,

The frame size seems reasonable. Refer to Section 3.4 Pixel Format in the DeckLink SDK manual.

For bmdFormat10BitYUV (v210) -
int framesize = ((Width + 47) / 48) * 128 * Height = rowbytes * Height

When width = 720, height = 576; framesize = 1105920 bytes.

Regards
Cameron

Return to Software Developers

Who is online

Users browsing this forum: No registered users and 14 guests