ILMKlvParser Interface

The ILMKlvParser interface is provided by the LEAD MPEG-2 Transport Demultiplexer to simplify the task of parsing KLV data. It can be obtained from the demultiplexer by calling ILMMpgDmx::GetKlvParser.

Data types:

typedef enum SearchKeyConstants
{
   SearchKey_Exact = 1, /* Find the exact key only. The key version number must match. */
   SearchKey_AnyVersion = 2, /* Ignore the version number when doing the search. */
   SearchKey_DesignatorOnly = 3, /* Find the key by the designator only. Ignore the key representation and version number */

   SearchKey_Recursive = 0x00000010, /* Search the key recursively in the subkeys. */
} SearchKeyConstants;

 

typedef enum ErrorConstants
{
   KLV_KEY_NOT_FOUND = 0x80050010, /* The KLV key was not found */
   KLV_BAD_KEY = 0x80050011, /* The KLV key is bad */
} ErrorConstants;

 

Interface Properties:

 

Type

Name

Description

long

Count

The number of complete top-level KLV keys contained in the internal interface buffer. An incomplete KLV key will not be included in the count.

Interface Methods:

HRESULT AddData(VARIANT *pData, long lDataSize, long Flags);

Parameters

pData

Pointer to a variant containing the private data.

lDataSize

The size of data contained in pData.

Flags

The flags value describing the position of this data packet within the private data sample. See the DataFlagConstants enumeration for a list of possible flags.

Description

This method can be used to begin parsing private data containing KLV packets. After calling this function, you can parse the data by calling GetKey, FindKey and FindKeyStr.

This method is designed to be called in response to a call to ILMMpgDmxCallback::DataAvailable. You can call AddData with the corresponding parameters from ILMMpgDmxCallback::DataAvailable (pData, lData, Flags).

You should call this function ONLY if ILMMpgDmxCallback::DataAvailable is called and Flags has DataFlag_IsKLV set. Although you can call this function if the flag in question is not set, that will be pointless because the parsing function will most likely fail.

If you do not pass the data received from ILMMpgDmxCallback::DataAvailable and you want to pass as pData a variant that you create, follow the following rules:

If Flag_BeginSample is set in Flags, AddData will clear the previous data from the buffer. If Flag_BeginSample is not set, the new data is appended to the data set by the previous AddData call.

Example:

AddData(var1, 2048, DataFlag_BeginSample); /* Now we have 2048 bytes worth of data */

AddData(var2, 2048, DataFlag_EndSample); /* Now we have 4096 bytes worth of data, made up of data contained in var1 and var2 */

AddData(var3, 2048, DataFlag_BeginSample); /* Now we have 2048 bytes worth of data, made up of data contained in var3. The previous 4096 bytes have been discarded because DataFlag_BeginSample was passed to AddData */

Returns

S_OK if successful, < 0 if an error occurred.

Common error codes:

E_POINTER                  [0x80004003] pData is NULL

E_INVALIDARG             [0x80070057] pData is not a byte array variant

 

HRESULT GetKey(long keyIndex, VARIANT *pKey, VARIANT *pKeyData, long *pDataSize);

Parameters

keyIndex

The index of the key to retrieve. The index is 0-based, so allowed values are 0..Count – 1

pKey

Pointer to a VARIANT that will be updated with a key describing the data. The key will be a 16-byte array describing the variant data or a 4-byte long (local keys). This key tells you how to interpret the key data contained in pKeyData.

pKeyData

Pointer to a VARIANT that will be updated key data. The key data will be a byte array variant regardless of the real format of the key data.

pDataSize

Pointer to a long variable that will be updated with the number of bytes stored in pKeyData. This is the same as the size of the pKeyData variant.

Description

Use this method to enumerate all the keys contained in a private data sample. This method will enumerate all the data passed to AddData since the last call that had the DataFlag_BeginSample flag set.

The method allocates data for the pKey and pKeyData variants. You should make sure you free the memory allocated in these variants if your programming language does not do so automatically. For example, VB automatically frees this memory, but C/C++ does not. In C++, you free the variant memory by calling VariantClear. Please consult the documentation for your programming language for more information on how to free the variant data.

You should examine pKey to find out how you are supposed to interpret the key data. The ILMKlvParser will not interpret the key data for you. There is no single document describing all the KLV keys that you might find in a stream. You will find various documents describing certain lists of currently defined keys. But each company that generates MPEG-2 transport streams or files might write their own internal keys in a private data stream. At the time of writing this documentation, the following documents contained information on KLV keys and how to interpret their content:

Based on information on this and other documents that you might find, you should interpret the key data accordingly. For example:

Key: 06 0E 2B 34 01 01 01 04 07 02 01 01 01 05 00 00

Is a “User Defined Time Stamp (microseconds since 1970)” in msb bit order and that the key should be 8 bytes long. In this case, you should verify that *pDataSize is 8. If *pDataSize is 8, you should convert the 8-byte array into a 64-bit unsigned integer (or a double floating point if your programming language does not support 64-bit integers). You would then convert the 64-bit value into a date and time by counting the microseconds since 1970.

There are two types of keys:

  1. Universal (using a 16-byte key)  

  2. Local (using 1, 2 or 3-byte keys)

By default, the ILMKlvParser interface assumes the keys are universal. But you can instruct it to parse local keys as well by calling the SetParentKey method. The key type (universal or local) is determined by the format of the parent key. Note that the parent key itself can be universal or local.

If the key is universal, pKey will be filled with a byte array variant containing 16 elements (type VT_ARRAY | VT_UI1).

If the key is local, pKey will be filled with a long variant (type VT_I4).

Returns

S_OK if successful, < 0 if an error occurred.

Common error codes:

Value

Meaning

DISP_E_BADINDEX

[0x8002000B] keyIndex is invalid (< 0).

E_POINTER

[0x80004003] pKey, pKeyData or pDataSize is NULL.

KLV_KEY_NOT_FOUND

[0x80050010] The key was not found (keyIndex >= Count).

E_OUTOFMEMORY

[0x8007000E] Could not allocate memory for the pKey or pKeyData variants.

 

HRESULT FindKey(VARIANT *pKeyToFind, long searchFlags, VARIANT *pKey, VARIANT *pKeyData, long *pDataSize);

Parameters

pKeyToFind

Pointer to a variant describing which universal key to look for.

searchFlags

One of the flags in the SearchKeyConstants enumeration. These flags tell the parser whether the match should be exact or not and whether the search should be recursive.

pKey

Pointer to a VARIANT that will be updated with a key describing the data. The key will be a 16-byte array describing the variant data. This key tells you how to interpret the key data contained in pKeyData.

pKeyData

Pointer to a VARIANT that will be updated key data. The key data will be a byte array variant regardless of the real format of the key data.

pDataSize

Pointer to a long variable that will be updated with the number of bytes stored in pKeyData. This is the same as the size of the pKeyData variant.

Description

Use searchFlags to whether you require an exact match or not for the key you are looking for. Possible values for searchFlags are:

SearchKey_Exact

[1] An exact match is required. All 16 bytes of the key must match.

SearchKey_AnyVersion

[2] For a match to be acceptable, all key bytes must match, with the exception of the version key (the 7th byte).

SearchKey_DesignatorOnly

 

[3] For a match to be acceptable, the key designator component must match. The key designator is stored in the last 8 bytes of the key.

SearchKey_Recursive

 

[16] Search the key recursively, in the subkeys. This flag can be or-ed with one (and only one) of the above flags.

 

This function will go through the top keys in the buffer and compare them with the key passed in pKeyToFind. If the key from the buffer matches exactly or partially (if permitted by searchFlags), then the key found is stored in pKey, the key data is stored in pKeyData and the key length is stored in pDataSize.

To understand searchFlags better, read more information on KLV keys in the KLV Key information topic.

Returns

S_OK if successful, < 0 if an error occurred.

Common error codes:

Value

Meaning

E_POINTER

[0x80004003] pKey, pKeyData or pDataSize is NULL.

KLV_KEY_NOT_FOUND

[0x80050010] There is no key matching pKeyToFind and searchFlags.

E_OUTOFMEMORY

 [0x8007000E] Could not allocate memory for the pKey or pKeyData variants.

 

HRESULT FindKeyStr(BSTR When "getting" a BSTR property, the memory containing the string is allocated with SysAllocString. When this string is no longer needed, free this memory by calling SysFreeString if you are working in an environment such as C or C++ that does not automatically delete the memory. VB automatically deletes the memory, so VB programmers do not need to free the memory themselves. pKeyToFind, long searchFlags, VARIANT *pKey, VARIANT *pKeyData, long *pDataSize);

Parameters

pKeyToFind

Pointer to a string describing which universal key to look for.

searchFlags

One of the flags in the SearchKeyConstants enumeration. These flags tell the parser whether the match should be exact or not and whether the search should be recursive.

pKey

Pointer to a VARIANT that will be updated with a key describing the data. The key will be a 16-byte array describing the variant data. This key tells you how to interpret the key data contained in pKeyData.

pKeyData

Pointer to a VARIANT that will be updated key data. The key data will be a byte array variant regardless of the real format of the key data.

pDataSize

Pointer to a long variable that will be updated with the number of bytes stored in pKeyData. This is the same as the size of the pKeyData variant.

Description

This method works exactly like FindKey, except that the key to search for is passed as a string, rather than a VARIANT.

pKeyToFind is a string containing a hexadecimal representation of the bytes in the key. Each byte should be represented by two hexadecimal digits. Each digit can be:

Space characters are ignored. For example, “06 0E 2B 34 01 01 01 04 07 02 01 01 01 05 00 00” is equivalent to “060E2B34010101040702010101050000”.

For more information on each parameter, see the description for FindKey.

Returns

S_OK if successful, < 0 if an error occurred.

Common error codes:

Value

Meaning

E_POINTER

[0x80004003] pKey, pKeyData or pDataSize is NULL.

KLV_KEY_NOT_FOUND

[0x80050010] There is no key matching pKeyToFind and searchFlags.

E_OUTOFMEMORY

 [0x8007000E] Could not allocate memory for the pKey or pKeyData variants.

KLV_BAD_KEY

[0x80050011] The key string is invalid: the key string should contain a hexadecimal representation of a 16-byte value, with 2 digits per byte (32 digits total).

 

 

HRESULT SetParentKey(VARIANT *pParentKey, long parentGroup, long *pKeyLength, long *pDataLength);

Parameters

pParentKey

[optional] Pointer to a variant describing the universal parent key. Pass NULL if you indicate the type of the group containing the keys using the parentGroup parameter. If you pass a valid key, you should pass 0 for parentGroup.

parentGroup

[optional] Value indicating the registry designator values. It should be one of the KlvGroupConstants enumeration values. You can also pass 0, in which case the parent key is passed through the pParentKey parameter.

pKeyLength

[optional] Pointer to a long that will be updated with the number of bytes used to store the key describing the data. If the value stored is -1, then the keys use variable length. A value of 16 indicate the use of universal keys. A value less than 16 indicate the use of local keys.

pDataLength

Pointer to a long that will be updated with the number of bytes used to store the data for each key. A value of -1 indicate variable length.

Description

This method instructs the enumeration properties and methods what sort of data is contained in the private data. If you do not call this method, the private data is assumed to contain universal keys. You must call this method to correctly parse data blocks containing local keys.

Call this method whenever enumerating subkeys contained in a higher level key.

Additionally, you can use this method to parse slightly incorrect files containing local subkeys where there should have been universal subkeys and vice versa.

In general, a universal key contains subkeys if KLVOFFSET_REGISTRYCATEGORY byte is set to REGISTRYCATEGORY_GROUPS (2). In this case, the KLVOFFSET_REGISTRYDESIGNATOR ("registry designator") byte of the universal key indicates what type of subkeys are used:

  1. Universal (1, 2) or

  2. Local (3, 0x0B, 0x13, 0x1B, etc).

Also, there are several ways of storing local keys, so the registry designator byte indicates whether the keys are local or universal and  the format of local keys (if applicable). See the KlvGroupConstants enumeration for more details on how to describe the format of the local keys.

 

Returns

S_OK if successful, < 0 if an error occurred.

Common error codes:

Value

Meaning

E_INVALIDARG

 [0x80070057] The registry designator value is invalid.

 

HRESULT FindKeyInt(long nKeyToFind, long searchFlags, VARIANT *pKeyData, long *pDataSize);

Parameters

nKeyToFind

Value describing which local key to look for.

searchFlags

Indicates whether the search is recursive (SearchKey_Recursive) or not (0).

pKeyData

Pointer to a VARIANT that will update key data. The key data will be a byte array variant regardless of the real format of the key data.

pDataSize

Pointer to a long variable that will be updated with the number of bytes stored in pKeyData. This is the same as the size of the pKeyData variant.

Description

This method is similar with FindKey and FindKeyStr, except that the key to search for is passed as a long, rather than a VARIANT or BSTR When "getting" a BSTR property, the memory containing the string is allocated with SysAllocString. When this string is no longer needed, free this memory by calling SysFreeString if you are working in an environment such as C or C++ that does not automatically delete the memory. VB automatically deletes the memory, so VB programmers do not need to free the memory themselves.. Also, this function searches in a list of local keys.

Indicate that the keys are local and the format of the local keys by calling SetParentKey method.

For more information on each parameter, see the description for FindKey.

Returns

S_OK if successful, < 0 if an error occurred.

Common error codes:

Value

Meaning

E_POINTER

[0x80004003] pKey, pKeyData or pDataSize is NULL.

KLV_KEY_NOT_FOUND

[0x80050010] There is no key matching pKeyToFind and searchFlags.

E_OUTOFMEMORY

 [0x8007000E] Could not allocate memory for the pKey or pKeyData variants.

KLV_BAD_KEY

[0x80050011] The key string is invalid: The key string should contain a hexadecimal representation of a 16-byte value, with 2 digits per byte (32 digits total).