hsu / libklv

Simple C++ library that implements a KLV class

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

libklv

libklv is a simple C++14 library that implements a KLV class and parser. This library tries to abide by the SMPTE 336M-2007 standard for KLV in motion imagery. This project was motivated by the need for a library to inject and decode UAS KLV metadata from MPEG2-TS video.

References

  • "Data Encoding Protocol Using Key-Length Value" SMPTE 336-2007
  • "NATO Digital Motion Imagery Standard" STANAG 4609
  • "UAS Datalink Local Set" MISB ST 0601.8

Dependencies

Google Test is used in this project as a Git submodules and is therefor built and linked when this project is built.

Checkout

To checkout/clone this project, run:

git clone https://github.com/Hunter522/libklv.git
cd libklv
git submodule update --init --recursive

Build

To build:

cd libklv
mkdir build && cd build
cmake ..
make

This will build a libklv.so file in the build/ directory.

Run tests

To run unit tests, build the project and then:

cd libklv/build
./runUnitTests

Usage

Take a look at some of the unit tests to get an idea on how to use this library. KlvParserTest.cpp shows how to use the KlvParser class to parse incoming bytes and construct a KLV object.

This library offers a few classes to allow one to decode and encode KLV data. These classes include:

  • KLV
  • KlvParser

To use these classes, simply include these headers:

#include "Klv.h"
#include "KlvParser.hpp"

Decoding KLV

To construct KLV objects, you can manually create them:

std::vector<uint8_t> key = { 0x06, 0x0E, 0x2B, 0x34, 0x02, 0x0B, 0x01, 0x01, 0x0E, 0x01, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00 };
std::vector<uint8_t> len = { 0x81, 0x90 };
std::vector<uint8_t> val = { 0x02, 0x08, 0x00, 0x04, 0x6C, 0xAE, 0x70, 0xF9, 0x80, 0xCF, 0x41, 0x01, 0x01, 0x05, 0x02, 0xE1, 0x91, 0x06, 0x02, 0x06, 0x0D, 0x07, 0x02, 0x0A, 0xE1, 0x0B, 0x02, 0x49, 0x52, 0x0C, 0x0E, 0x47, 0x65, 0x6F, 0x64, 0x65, 0x74, 0x69, 0x63, 0x20, 0x57, 0x47, 0x53, 0x38, 0x34, 0x0D, 0x04, 0x4D, 0xCC, 0x41, 0x90, 0x0E, 0x04, 0xB1, 0xD0, 0x3D, 0x96, 0x0F, 0x02, 0x1B, 0x2E, 0x10, 0x02, 0x00, 0x84, 0x11, 0x02, 0x00, 0x4A, 0x12, 0x04, 0xE7, 0x23, 0x0B, 0x61, 0x13, 0x04, 0xFD, 0xE8, 0x63, 0x8E, 0x14, 0x04, 0x03, 0x0B, 0xC7, 0x1C, 0x15, 0x04, 0x00, 0x9F, 0xB9, 0x38, 0x16, 0x04, 0x00, 0x00, 0x01, 0xF8, 0x17, 0x04, 0x4D, 0xEC, 0xDA, 0xF4, 0x18, 0x04, 0xB1, 0xBC, 0x81, 0x74, 0x19, 0x02, 0x0B, 0x8A, 0x28, 0x04, 0x4D, 0xEC, 0xDA, 0xF4, 0x29, 0x04, 0xB1, 0xBC, 0x81, 0x74, 0x2A, 0x02, 0x0B, 0x8A, 0x38, 0x01, 0x31, 0x39, 0x04, 0x00, 0x9F, 0x85, 0x4D, 0x01, 0x02, 0xB7, 0xEB };
KLV klv(key, len, val);

or use the KlvParser class to decode a byte vector (originating from a file, or perhaps a incoming data stream):

std::vector<uint8_t> test_pkt_uas = {0x06, 0x0E, 0x2B, 0x34, 0x02, 0x0B, 0x01, 0x01, 0x0E, 0x01, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x81, 0x90, 0x02, 0x08, 0x00, 0x04, 0x6C, 0xAE, 0x70, 0xF9, 0x80, 0xCF, 0x41, 0x01, 0x01, 0x05, 0x02, 0xE1, 0x91, 0x06, 0x02, 0x06, 0x0D, 0x07, 0x02, 0x0A, 0xE1, 0x0B, 0x02, 0x49, 0x52, 0x0C, 0x0E, 0x47, 0x65, 0x6F, 0x64, 0x65, 0x74, 0x69, 0x63, 0x20, 0x57, 0x47, 0x53, 0x38, 0x34, 0x0D, 0x04, 0x4D, 0xCC, 0x41, 0x90, 0x0E, 0x04, 0xB1, 0xD0, 0x3D, 0x96, 0x0F, 0x02, 0x1B, 0x2E, 0x10, 0x02, 0x00, 0x84, 0x11, 0x02, 0x00, 0x4A, 0x12, 0x04, 0xE7, 0x23, 0x0B, 0x61, 0x13, 0x04, 0xFD, 0xE8, 0x63, 0x8E, 0x14, 0x04, 0x03, 0x0B, 0xC7, 0x1C, 0x15, 0x04, 0x00, 0x9F, 0xB9, 0x38, 0x16, 0x04, 0x00, 0x00, 0x01, 0xF8, 0x17, 0x04, 0x4D, 0xEC, 0xDA, 0xF4, 0x18, 0x04, 0xB1, 0xBC, 0x81, 0x74, 0x19, 0x02, 0x0B, 0x8A, 0x28, 0x04, 0x4D, 0xEC, 0xDA, 0xF4, 0x29, 0x04, 0xB1, 0xBC, 0x81, 0x74, 0x2A, 0x02, 0x0B, 0x8A, 0x38, 0x01, 0x31, 0x39, 0x04, 0x00, 0x9F, 0x85, 0x4D, 0x01, 0x02, 0xB7, 0xEB};

// you must provide the parser with a vector<KlvParser::KeyEncoding>
KlvParser parser({KlvParser::KEY_ENCODING_16_BYTE, KlvParser::KEY_ENCODING_BER_OID});
KLV* parsed_klv = NULL;
for(int i = 0; i < test_pkt_uas.size(); i++) {
     parsed_klv = parser.parseByte(test_pkt_uas[i]);
     
     if(parsed_klv != NULL)
        break;
}

The KLV class offers a method (indexToMap()) to index itself and all of its children (if the value has local KLV) into a flattened map. This method returns a unordered_map where the key is the KLV key byte vector and the value being the KLV itself. The map can then be used to easily access the different child KLV elements by simply using the KLV key/tag.

Encoding KLV

Once a KLV object is constructed, you can encode the KLV into a byte vector by simply calling KLV::toBytes().

License

This project uses the MIT license. See LICENSE.txt.

About

Simple C++ library that implements a KLV class

License:MIT License


Languages

Language:C++ 96.1%Language:CMake 3.9%