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, 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 the 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