Insert MISB KLV into TS stream
KlvInjector SDK can receive TS streams over udp or rtp / rtsp and add metadata, remultiplexing the stream. The output can be further sent over the network or saved to file (or both).
Let's create a simple application that inserts Klv metadata into transport stream.
First things first, let's 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:
CKlvInjector m_KlvInjector = new CKlvInjector();
// Setup events
m_KlvInjector.PlayerEvent += new NotifyPlayerEvent(OnPlayerEvent); // Player general events notification
m_KlvInjector.ErrorEvent += new NotifyError(OnErrorEvent); // Player error events
m_KlvInjector.PidDetectionEvent += new NotifyPidDetection(OnPidDetectionEvent); // PID detection events (video / KLV / audio / data)
m_KlvInjector.SyncFrameEvent += new NotifySyncFrame(OnSyncFrameEvent); // Synchronized Video frames / Klv / Private data
There are some additional parameters that may be configured:
// Setup video / audio rendering
m_KlvInjector.RenderVideo = true; // Set to true if you want to decode and show the video
m_KlvInjector.RenderAudio = false; // Set to true if you want to decode the audio
// Set Window handle to render video to. If set to 0, the default window will be created internally.
m_KlvInjector.Hwnd = 0;
// Configure KlvInsertion mode - SYNC or ASYNC
m_klvProps = new KlvDataPropsWr(ProcessingModeWr.INSERT_KLV_ASYNC);
// Configure uncompressed video extraction mode. Please note, depending on video resolution, this is a pretty resource demanding operation, so do not request uncompressed vdieo frames unless you need them.
m_KlvInjector.VideoCaptureMode.uncompressedVideo = UncompressedVideoModeWr.UncompressedVideoMode_None;
// Configure compressed video extraction mode. Note, if you intend to insert packets on the video frame callback context, set it to true, otherwise the event will never fire
m_KlvInjector.VideoCaptureMode.fCompressedVideo = true;
// If your source is a udp stream, set Caching (de-jitter) buffer. Set to minimal possible value (depending on your stream) to get a low latency stream playback. Note, this is a latency you add, so be careful.
m_KlvInjector.Caching = 300;
Next, we'll configure the output. We can have both network and file targets, so the resulted STANAG stream will be simultaneously recorded to file and recasted to the network.
// Network stream target
m_KlvInjector.NetTarget.Url = "udp://127.0.0.1:1234"; // output url. For example, udp://225.1.1.1:1234 to send the stream as multicast udp
m_KlvInjector.NetTarget.Use = true; // Enable network stream output.
// 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; // No segmentation
m_KlvInjector.FileTarget.Use = true; // Enable file recording output.
We're almost done. Last thing to do is to actually configure what we want to do with KLV PID. The best place for this would be at the runtime, when we get the detection event. Here we have all the information needed. The source stream may already have KLV or Data Pids, so here we can decide whether to add an additional Klv PID, replace the existing one, etc. If your source stream does not have a Klv pid you can just call m_KlvInjector.AddKlvPidToOutput method.
void OnPidDetectionEvent(List<PidInfoWr> pidList)
{
pidList.ForEach(pid =>
{
Console.WriteLine("Pid 0X{0} type {1}", pid.streamId.ToString("X"), pid.streamType, Color.LightGray);
// Find video pid. We'll use it for statistics.
if (pid.streamType == StreamType.VIDEO)
m_VideoPid = pid.streamId;
// Find first Klv PID. If already present in the stream, we'll replace it with our data. If there is no KLV, we'll use the default 0X1F1 value.
if (pid.streamType == StreamType.KLV && m_KlvPid == -1)
m_KlvPid = pid.streamId;
});
// Add KLV PID to multiplexer
m_KlvInjector.AddKlvPidToOutput(m_KlvPid != -1 ? m_KlvPid : 0X1F1, m_klvProps);
}
If there is a need to drop an existing Klv data or process and reinsert it, call m_KlvInjector.IgnorePidInOutput(klvPid) followed by m_KlvInjector.AddKlvPidToOutput(newKlvPid);
There are some additional parameters that can be configured but for the sake of simplicity we'll first go with defaults.
Initialize the Injector and start processing.
// Initialize injector
m_KlvInjector.Init(m_Url); // The url is a file path or Udp url, like udp://227.1.1.1:30120. To select specific network interface, add Nic selection - udp://227.1.1.1:30120/nic=192.168.1.10
// Start Processing
m_KlvInjector.Start();
Now the process is running and we can insert the Klv data when needed.
m_KlvInjector.WritePacketToOutputPid(m_InsertKlvPid, pckt, timestamp);
- timestamp - timestamp for SYNC KLV. Reference clock (100-nanosecond). You can set -1 or nothing at all. In the later case the timestamp will be set automatically.
- pcktBuf - RAW Klv buffer.
See more info on Stream validation