File / Network Stream Playback and Klv Extraction

File / Stream Playback.

KlvInjector SDK is based on STANAG Player SDK and therefore can provide the same basic player functionality.
KlvInjector SDK allows both file and low latency stream playback as well as HLS playback (with file segments stored locally or at the http server)

This is an example of KlvInjector SDK usage in STANAG 4609 file / stream player application.

There are 4 steps:

Phase Description
Creating Instance Create player instance
Setting events Add events (playback, detection, frame / data / errors)
Configure params Configure operational mode and other parameters
Call commands Start / Stop, etc

Use Case.

Demo Application receives a stream url (or file path) as input parameter, detects video and KLV metadata information and plays back the video. To perform this task, the KlvPlayerLib instance will be used. For more details on the interfaces please see \ref IStCoreWr.

Creating Player Instance.

First, make sure you have all prerequisites in place. For more info see STANAG Player SDK.

Create the player instance:


// Create Player instance
var m_KlvPlayer = new CKlvInjector();

Configuring events.

Setup events

// Setup events
m_KlvPlayer.PlayerEvent += new NotifyPlayerEvent(OnPlayerEvent);                   //  Player general events notification                
m_KlvPlayer.ErrorEvent += new NotifyError(OnErrorEvent);                           //  Player error events
m_KlvPlayer.PidDetectionEvent += new NotifyPidDetection(OnPidDetectionEvent);      //  PID detection events (video / KLV / audio / data)
m_KlvPlayer.SyncFrameEvent += new NotifySyncFrame(OnSyncFrameEvent);               //  Synchronized Video frames / Klv / Private data. For more info on Video / Data sync see \ref pageSync 

Initializing Player

Initialize the Player

// Setup Url for network playback. You can pass multiple parameters via url. 
// For example, udp://227.1.1.1:30120/nic=172.16.106.10/timeout=10000 allows you 
// to setup network interface (nic) and timeout parameters in addition to the IP address and Port.

Uri Url = new Uri(@"udp://227.1.1.1:30120");

// You can set a caching time. Caching time interval (in ms) allows initial caching configuration.
// Increase its value to achieve smooth network playback. Decrease the value of this parameter in order to acheive a low latency playback.
m_KlvPlayer.Caching = 300;

// Initialize
m_KlvPlayer.Init(Url.OriginalString); 

Optional parameters

m_KlvPlayer.RenderVideo - true / false                            // Set to true if you want to render the video, false if you don't need it (when you only need metadata or decoder frames)
m_KlvPlayer.RenderAudio - true / false                            // Set to true if you need audio processing.
m_KlvPlayer.VideoCaptureMode.uncompressedVideo - 
                             UncompressedVideoMode_None
                             UncompressedVideoMode_Rgb
                             UncompressedVideoMode_Yuv
                             UncompressedVideoMode_Grayscale
m_KlvPlayer.VideoCaptureMode.fCompressedVideo - true / false      // set to true if you don't need an uncompressed frame, but still want to get video timing info.
m_KlvPlayer.Hwnd                                                  // Window handle to render video to. If set to 0, the window will be created internally.
m_KlvPlayer.Caching - buffer size in ms                           // Caching for dejitter buffer. Set to minimal possible value to get a low latency stream playback,
m_KlvPlayer.MaxSyncDelay - buffer size in ms                      // Allowed Sync time for video / data synchronization
m_KlvPlayer.CalculatePacketRate - true / false                    // Enable / disable Calculation of average rate for received packets

Starting Player

Now, all you need is to start playback.

// Start Playback
m_KlvPlayer.Start();

Video will be rendered in the Window provided during the initialization phase and \b OnKlvDataEvent method will be called on Klv data arrival.

Playback Events

During the playback, the relevant events (if set) will be fired.

More info on Playback Events

Raw Klv

KlvInjector SDK provides an option for extracting and encoding the RAW klv items (tag/value buffer). This can be especially useful for data manipulation where you need the original klvs.
There are some additional benefits of using RAW Klv for data manipulation:

  • No "generation loss" when you have to re-encode compressed values, without changing them
  • Lower CPU usage, as no MISB decoding / Encoding is performed

RAW klv is presented as an array of klv items.

    /// <summary>
    /// KlvItem - Raw Klv item
    /// </summary>
    public class KlvItem
    {
        public ushort Tag { get; set; }  
        public byte[] Value { get; set; }

        public KlvItem(ushort tag, byte [] value)
        {
            this.Tag = tag;
            this.Value = value;
        }
    }

Let's assume you have to replace some of the klv items, without changing the rest.

JObject decodedData = (JObject)kf.decodedData;

// Here, as an example, we'll add/overite tag 3 'Mission Id" 
// The straightforward method - we simply get the decoded data, replace the required value and encode the whole packet back.

decodedData["3"] = m_NewMissionId;

// A better option, which would eliminate a "generation loss" while decoding/encoding compressed data is to only re-encode the specific klv item value and re-calculate the packet checksum. 
// You can use kf.rawKlvItems and misb601.EncodePacketRawKlv(rawKlvItems) for that. 
var decodedRawKlv = (KlvItem[])kf.rawKlvItems;
var missionItem = decodedRawKlv.FirstOrDefault(item => item.Tag == 3);
if (missionItem != null)
    missionItem.Value = Encoding.UTF8.GetBytes(m_NewMissionId);  

var versionItem = decodedRawKlv.Find(item => item.Tag == 65);
if (versionItem != null)
    versionItem.Value = new byte[1] { 14 };

// Re-encode the packet
var bufReencode = m_KlvInjector.Misb601.EncodePacketRawKlv(decodedRawKlv);