Creating STANAG 4609 stream from uncompressed frames.

In this article, we’ll show how to put together a simple application that encodes uncompressed frames (bitmaps) into H.264 video and inserts ASYNC Klv or SYNC Klv data into a transport stream. Let's use KlvInjector SDK.

We'll be dynamically generating the images for, but of course, you can get them from any source, like files or on the fly decoded streams...

First, we have to create a VS project, add the references and make sure all the required dependencies are copied to the target directory.

Next, we create an instance of the Klv Injector, initialize it and add events:
 
// Create Player instance
CKlvInjector m_KlvInjector = new CKlvInjector();

// Setup events
m_KlvInjector.PlayerEvent += new NotifyPlayerEvent(OnPlayerEvent);
m_KlvInjector.ErrorEvent += new NotifyError(OnErrorEvent);
There are some additional parameters that may be configured:
// Setup video / audio rendering
// Set to true if you want to decode and show the video
m_KlvInjector.RenderVideo = true; 
m_KlvInjector.RenderAudio = false;

// Set Window handle to render video to. If set to 0, a default window will be created internally.
m_KlvInjector.Hwnd = 0;

// Configure KlvInsertion mode - SYNC or ASYNC
m_klvProps = new KlvDataPropsWr(ProcessingModeWr.INSERT_KLV_SYNC);
Next, we'll configure the output. In this demo we'll have both network and file targets, so the resulted STANAG stream will be simultaneously recorded to file and sent to the network.
// Network stream target
m_KlvInjector.NetTarget.Url = m_targetUrl;
m_KlvInjector.NetTarget.Use = true;

// File target
m_KlvInjector.FileTarget.Dir = Path.GetDirectoryName(m_targetFile);
m_KlvInjector.FileTarget.Name = Path.GetFileName(m_targetFile);
m_KlvInjector.FileTarget.SegmentationType = FileSegmentationType.SegmentationType_None;
m_KlvInjector.FileTarget.Use = true;
As we need to encode video, lets set the related parameters:
var rawVideoFrameProps = new RawVideoFramePropsWr();
rawVideoFrameProps.Height = 1920;
rawVideoFrameProps.Width = 1080;
rawVideoFrameProps.RawVideoFrameType = VideoFrameType.RGB24;
rawVideoFrameProps.EncodingParams.BitRate = 1024 * 1000;  // Target video bitrate in kb/s
rawVideoFrameProps.EncodingParams.Width = -1;             // use source Width
rawVideoFrameProps.EncodingParams.Height = -1;            // use source Height

int m_VideoPid = 0X1F0;
 
Next, configure the Klv part: 
var m_klvProps = new KlvDataPropsWr(ProcessingModeWr.INSERT_KLV_SYNC);  // We'll be using Sync klv that allows frame accurate synchronization of video and Klv telemetry
int m_KlvPid = 0X1F1;

Now, we just need to init and start the Injector and pump video frames accompanied with the Klv data

// Initialize injector
m_KlvInjector.Init();
// Start Processing
m_KlvInjector.Start();

// Add video and Klv Pids
m_KlvInjector.AddVideoPidToOutput(m_VideoPid, rawVideoFrameProps);
m_KlvInjector.AddKlvPidToOutput(m_KlvPid, m_klvProps);

The injector is running now. We just need to send the images and the Klv metadata at the desired frame rate (like 30 fps).

m_KlvInjector.WritePacketToOutputPid(m_VideoPid, frameBmp, timestamp);
m_KlvInjector.WritePacketToOutputPid(m_KlvPid, pcktBuf, timestamp);
  • frameBmp - bitmap. The bitmap can be created dynamically, as in the sample app or taken from the stream/file, after some pre-processing.
  •  timestamp - timestamp for video and SYNC KLV. Reference clock (100-nanosecond).
  • pcktBuf - RAW Klv buffer.

That's it.  Let's look at the results...  

More info on KlvInjector SDK.

 

No Comments

Post a Comment