LibMISB/Examples/Library basic usage: Difference between revisions

From RidgeRun Developer Wiki
No edit summary
No edit summary
 
(25 intermediate revisions by 6 users not shown)
Line 1: Line 1:
<noinclude>
<noinclude>
{{LibMISB/Head|previous=Getting_Started/How_to_compile|next=|keywords=}}
{{LibMISB/Head|previous=Examples|next=Examples/GStreamer_Application|metakeywords=}}
</noinclude>
</noinclude>


== Testing library ==


== Testing library ==
This library has an example that you can execute. This example is a metadata converter that can encode or decode metadata. If you want to encode, the input file must respect one of the supported formats and will return a binary file with metadata encoded. On the other hand, if you want to decode the program receives a binary file and converts it to the format file selected. Currently JSON format is supported for the input and output encoding files.
This library has an example that you can execute. This example is a metadata converter that can encode or decode metadata. If you want to encode, the input file must respect one of the formats developed (for this first version, only could use JSON format) and will return a binary file with metadata encoded. On the other hand, if you want to decode the program receives a binary file and converts it to the format file selected (for this first version, only could use JSON format).  


The executable is located on /misb-library/examples/misb/ or if you want to compile and execute the example file out of the project. The path of the example is located on /misb-library/examples/misb/misb-converter.cpp. To compile the example we suggest you follow the next Makefile:  
The executable is located on <code>/misb-library/examples/misb/</code> or if you want to compile and execute the example file out of the project. The path of the example is located on <code>/misb-library/examples/misb/misb-converter.cpp</code>. To compile the example we suggest you follow the next Makefile:  
<syntaxhighlight lang=Makefile>
<syntaxhighlight lang=Makefile>
FLAGS:=`pkg-config --cflags --libs misb-0.0`
FLAGS:=`pkg-config --cflags --libs misb-0.0`
Line 16: Line 14:
</syntaxhighlight>
</syntaxhighlight>


=== Encode command ===
The input JSON file that is going to be used is as follows:
To perform the encoding, the following command is executed. Where the '''--encode''' flag indicates that encoding is to be performed. The '''-i''' flag indicates the input file, where the metadata must be raw without encoding. On the other hand, the '''-o''' flag indicates the output file, which contains the encoded bytes in a binary file. The '''--verbose''' flag shows the KLV bytes encoded on the terminal.


<syntaxhighlight lang=C>
<syntaxhighlight lang=json>
./misb-converter --verbose --encode -i misb_ST0601_sample.json -o klv.bin
{
  "key": "060E2B34020B01010E01030101000000",
  "items": [
    {
      "tag": "2",
      "value": "Oct. 24, 2008. 00:13:29.913"
    },
    {
      "tag": "3",
      "value": "MISSION01"
    },
    {
      "tag": "4",
      "value": "AF-101"
    },
    {
      "tag": "5",
      "value": "159.97436"
    },
    {
      "tag": "15",
      "value": "14190.7195"
    }
  ]
}
</syntaxhighlight>
</syntaxhighlight>


=== Decode command ===
Or alternitevly if you want to use the 0903 standard:
To perform the decoding, the following command is executed. Where the '''--decode''' flag indicates that decoding is to be performed. The '''-i''' flag indicates the input file, where the metadata must be encoded. The '''-o''' flag indicates the output file, which contains the metadata decoded.
<syntaxhighlight lang=json>
{
    "key": "060E2B34020B01010E01030306000000",
    "items": [
      {
        "tag": "2",
        "value": "Apr. 19, 2001. 04:25:21.000"
      },
      {
          "tag": "101",
          "value": [
            {
              "tag": "targetId",
              "value": "1234"
            },
            {
              "tag": "1",
              "value": "409600"
            },
            {
              "tag": "3",
              "value": "409600"
            },
            {
              "tag": "5",
              "value": "80"
            },
            {
              "tag": "targetId",
              "value": "1235"
            },
            {
              "tag": "1",
              "value": "409601"
            },
            {
              "tag": "3",
              "value": "409601"
            }
          ]
      },
      {
        "tag": "6",
        "value": "2"
      }
    ]
  }


<syntaxhighlight lang=C>
./misb-converter --decode -i klv.bin -o output.json
</syntaxhighlight>
</syntaxhighlight>


== Reference application ==
In the following example, we show you how to use Gstreamer In-Band metadata to add a KLV packet (generated by LibMISB) into a Transport Stream. Based on [https://developer.ridgerun.com/wiki/index.php/GStreamer_In-Band_Metadata_for_MPEG_Transport_Stream/Examples/_C/C%2B%2B GStreamer In-Band Metadata for MPEG Transport Stream - Examples - C - C++]


<syntaxhighlight lang="C">
The following command is executed to perform the encoding. The'''--encode''' flag indicates that encoding is to be performed. The '''-i''' flag indicates the input file, where the metadata must be raw without encoding. On the other hand, the '''-o''' flag indicates the output file, which contains the encoded bytes in a binary file. The '''--verbose''' flag shows the KLV bytes encoded on the terminal.  
/* Copyright (C) 2022 RidgeRun, LLC (http://www.ridgerun.com)
* All Rights Reserved.
*
* The contents of this software are proprietary and confidential to RidgeRun,
* LLC. No part of this program may be photocopied, reproduced or translated
* into another programming language without prior written consent of
* RidgeRun, LLC. The user is free to modify the source code after obtaining
* a software license from RidgeRun.  All source code changes must be provided
* back to RidgeRun without any encumbrance.
*/


#include <glib.h>
<syntaxhighlight lang=bash>
#include <glib-unix.h>
./misb-converter --verbose --encode -i misb_ST0601_sample.json -o klv.bin
#include <gst/gst.h>
</syntaxhighlight>
or
<syntaxhighlight lang=bash>
./misb-converter --verbose --encode -i misb_ST0903_sample.json -o klv.bin
</syntaxhighlight>


#include <stdio.h>
#include <stdlib.h>
#include <string.h>


#define PIPELINE_DESCRIPTION                                                  \
Once the command is executed (with the <code>--verbose</code> flag), the KLV bytes are displayed. The 0601 klv.bin file contains the encoded bytes.
  "metasrc name=meta ! meta/x-klv,stream_type=21 ! mpegtsmux name=mux ! "      \
  "filesink name=sink location=./metadata_misb_library.ts videotestsrc "      \
  "is-live=true ! video/x-raw,width=640,height=480,framerate=30/1 ! queue ! "  \
  "x264enc ! mux."


#define METADATA_PERIOD_SECS 1
<syntaxhighlight>
#define FILE_LOCATION "./metadata_misb_library.ts"
INFO    6 14 43 52 2 11 1 1 14 1 3 1 1 0 0 0 44 2 8 0 4 89 249 174 32 34 168 3 9 77 73 83 83 73 79 78 48 49 4 6 65 70 45 49 48 49 5 2 113 194 15 2 194 33 65 1 17 1 2 164 125
</syntaxhighlight>


static guint8 klv_metadata[61];
=== Decode command ===


The following command is executed to perform the decoding. The '''--decode''' flag indicates that decoding is to be performed. The '''-i''' flag indicates the input file, where the metadata must be encoded. The '''-o''' flag indicates the output file containing the decoded metadata.


const char* filename = "klv.bin";
The encoded bytes found inside the 0601 klv.bin file are:
<syntaxhighlight>
6 14 43 52 2 11 1 1 14 1 3 1 1 0 0 0 44 2 8 0
4 89 249 174 32 34 168 3 9 77 73 83 83 73 79
78 48 49 4 6 65 70 45 49 48 49 5 2 113 194 15
2 194 33 65 1 17 1 2 164 125
</syntaxhighlight>


typedef struct _GstMetaDemo GstMetaDemo;
<syntaxhighlight lang=bash>
struct _GstMetaDemo {
./misb-converter --decode -i klv.bin -o output.json
  GstElement *pipeline;
</syntaxhighlight>
  GstElement *metasrc;
  GstElement *filesink;
  GMainLoop *main_loop;
};


static gboolean create_pipeline(GstMetaDemo *metademo);
Once the command is executed, it reports that a decoded file was generated. The content of the output.json file is
static void start_pipeline(GstMetaDemo *metademo);
static void stop_pipeline(GstMetaDemo *metademo);
static void release_resources(GstMetaDemo *metademo);
static gboolean bus_call(GstBus *bus, GstMessage *msg, gpointer data);
static gboolean handle_signal(gpointer data);


int main(int argc, char *argv[]) {
<syntaxhighlight lang=json>
struct stat sb;
{
 
  "key": "060E2B34020B01010E01030101000000",
  FILE* in_file = fopen(filename, "rb");
  "items": [
     if (!in_file) {
    {
        perror("fopen");
      "tag": "2",
        exit(EXIT_FAILURE);
      "value": "Oct. 24, 2008. 00:13:29.913"
    },
    {
      "tag": "3",
      "value": "MISSION01"
    },
    {
      "tag": "4",
      "value": "AF-101"
    },
    {
      "tag": "5",
      "value": "159.974365"
    },
    {
      "tag": "15",
      "value": "14190.719463"
    },
     {
      "tag": "65",
      "value": "17"
     }
     }
 
  ]
   
    if (stat(filename, &sb) == -1) {
        perror("stat");
        exit(EXIT_FAILURE);
    }
 
    fread(klv_metadata, sizeof(klv_metadata), 1, in_file);
 
    for(uint i = 0; i<sizeof(klv_metadata); i++)
        printf("%u ", klv_metadata[i]);
    printf("\n");
    fclose(in_file);
 
  GstMetaDemo *metademo = g_malloc(sizeof(GstMetaDemo));
  if(!metademo){
    g_print("Could not create demo\n");
    return 1;
  }
 
  g_unix_signal_add(SIGINT, (GSourceFunc)handle_signal, metademo);
 
  /* Initialization */
  gst_init(&argc, &argv);
 
  if (!create_pipeline(metademo)) {
    g_free(metademo);
    return 1;
  }
 
  /* Set the pipeline to "playing" state*/
  g_print("Playing pipeline\n");
  start_pipeline(metademo);
 
  /* Iterate */
  g_print("Running...\n");
  g_main_loop_run(metademo->main_loop);
 
  /* Out of the main loop, clean up nicely */
  g_print("Returned, stopping playback\n");
  release_resources(metademo);
 
  return 0;
}
}
</syntaxhighlight>


static gboolean bus_call(GstBus *bus, GstMessage *msg, gpointer data) {
and for the 0903:
  GMainLoop *loop = (GMainLoop *)data;


  switch (GST_MESSAGE_TYPE(msg)) {
<syntaxhighlight lang=json>
 
{
   case GST_MESSAGE_EOS:
  "key": "060E2B34020B01010E01030306000000",
     g_print("End of stream\n");
   "items": [
     g_main_loop_quit(loop);
     {
     break;
      "tag": "2",
 
      "value": "Apr. 19, 2001. 04:25:21.000"
  case GST_MESSAGE_ERROR: {
     },
    gchar *debug;
     {
    GError *error;
      "tag": "101",
 
      "value": [
    gst_message_parse_error(msg, &error, &debug);
        {
    g_free(debug);
          "tag": "id",
 
          "value": "1234"
    g_printerr("Error: %s\n", error->message);
        },
     g_error_free(error);
        {
 
          "tag": "1",
     g_main_loop_quit(loop);
          "value": "409600"
     break;
        },
  }
        {
  default:
          "tag": "3",
     break;
          "value": "409600"
  }
        },
 
        {
   return TRUE;
          "tag": "5",
          "value": "80"
        },
        {
          "tag": "id",
          "value": "1235"
        },
        {
          "tag": "1",
          "value": "409601"
        },
        {
          "tag": "3",
          "value": "409601"
        }
      ]
    },
     {
      "tag": "6",
      "value": "2"
     },
     {
      "tag": "4",
      "value": "6"
     }
   ]
}
}
</syntaxhighlight>


static gboolean create_pipeline(GstMetaDemo *metademo) {
As seen here some extra flags can be present after the decoding process since the encoding might add required tags to the encoding.


  GMainLoop *loop;
== Logging ==


  GstElement *pipeline = NULL;
You can enable the debugging using '''SetLogLevel''' in your application with the LibMISB. For example:
  GstElement *metasrc = NULL;
  GstElement *filesink = NULL;
  GstBus *bus = NULL;
  GByteArray *barray = NULL;
  guint8 *array_copy = NULL;
  guint metalen = 0;
  GError *error = NULL;


  if (!metademo) {
<syntaxhighlight lang=cpp>
    return FALSE;
   libmisb::LibMisb libmisb;
  }
   libmisb.SetLogLevel(LIBMISB_DEBUG);
 
  loop = g_main_loop_new(NULL, FALSE);
 
  pipeline = gst_parse_launch(PIPELINE_DESCRIPTION, &error);
 
  if (error) {
    g_printerr("Unable to build pipeline (%s)\n", error->message);
    g_clear_error(&error);
    return FALSE;
  }
 
  metasrc = gst_bin_get_by_name(GST_BIN(pipeline), "meta");
  if (!metasrc) {
    g_printerr("Could not get metadata element\n");
    return FALSE;
  }
 
  filesink = gst_bin_get_by_name(GST_BIN(pipeline), "sink");
  if (!filesink) {
    g_printerr("Could not get filesink element\n");
    return FALSE;
  }
 
  /*Prepare metadata*/
 
  /*We need to copy the array since the GByteArray will be the new owner and free it for us*/
  metalen = sizeof(klv_metadata);
  array_copy = g_malloc (metalen);
  memcpy (array_copy, klv_metadata, metalen);
 
  barray = g_byte_array_new_take(array_copy, metalen);
  g_object_set(metasrc, "metadata-binary", barray, NULL);
  g_boxed_free(G_TYPE_BYTE_ARRAY, barray);
 
  g_object_set(G_OBJECT(metasrc), "period", METADATA_PERIOD_SECS, NULL);
  g_object_set(G_OBJECT(filesink), "location", FILE_LOCATION, NULL);
 
  /* we add a message handler */
  bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
  gst_bus_add_watch(bus, bus_call, loop);
  gst_object_unref(bus);
 
  metademo->pipeline = pipeline;
  metademo->main_loop = loop;
   metademo->metasrc = metasrc;
   metademo->filesink = filesink;
 
  return TRUE;
}
 
static void start_pipeline(GstMetaDemo *metademo) {
  gst_element_set_state(metademo->pipeline, GST_STATE_PLAYING);
}
static void stop_pipeline(GstMetaDemo *metademo) {
  gst_element_set_state(metademo->pipeline, GST_STATE_NULL);
}
 
static void release_resources(GstMetaDemo *metademo) {
  if (!metademo) {
    return;
  }
 
  stop_pipeline(metademo);
 
  if (metademo->pipeline) {
    gst_object_unref(metademo->pipeline);
    metademo->pipeline = NULL;
  }
 
  if (metademo->metasrc) {
    gst_object_unref(metademo->metasrc);
    metademo->metasrc = NULL;
  }
 
  if (metademo->filesink) {
    gst_object_unref(metademo->filesink);
    metademo->filesink = NULL;
  }
 
  if (metademo->main_loop) {
    g_main_loop_unref(metademo->main_loop);
    metademo->main_loop = NULL;
  }
}
 
static gboolean handle_signal(gpointer data) {
  GstMetaDemo *metademo = (GstMetaDemo *)data;
 
  g_main_loop_quit(metademo->main_loop);
 
  return TRUE;
}
</syntaxhighlight>
</syntaxhighlight>


== Building the application ==
<noinclude>{{LibMISB/Foot|Examples|Examples/Add_data_to_MPEG_Transport_Stream}}</noinclude>
 
In order to build the appication, copy the example into a file called '''main.c''' and build using the following command:
 
<pre>
gcc -Wall main.c -o main `pkg-config --cflags --libs gstreamer-1.0`
</pre>
 
After this you will end up with a binary called main.
 
== Running the application ==
 
Execute the application with the following command:
 
<pre>
./main
</pre>
 
This will create a file called 'metadata_misb_library.ts''' in the same directory where the application is running.
 
Stop the application with '''Ctrl + C'''.

Latest revision as of 15:23, 19 September 2024



Previous: Examples Index Next: Examples/GStreamer_Application





Testing library

This library has an example that you can execute. This example is a metadata converter that can encode or decode metadata. If you want to encode, the input file must respect one of the supported formats and will return a binary file with metadata encoded. On the other hand, if you want to decode the program receives a binary file and converts it to the format file selected. Currently JSON format is supported for the input and output encoding files.

The executable is located on /misb-library/examples/misb/ or if you want to compile and execute the example file out of the project. The path of the example is located on /misb-library/examples/misb/misb-converter.cpp. To compile the example we suggest you follow the next Makefile:

FLAGS:=`pkg-config --cflags --libs misb-0.0`
misb-converter: misb-converter.cpp
	g++ -o misb-converter misb-converter.cpp $(FLAGS)

The input JSON file that is going to be used is as follows:

{ 
  "key": "060E2B34020B01010E01030101000000",
  "items": [
    {
      "tag": "2",
      "value": "Oct. 24, 2008. 00:13:29.913"
    },
    {
      "tag": "3",
      "value": "MISSION01"
    },
    {
      "tag": "4",
      "value": "AF-101"
    },
    {
      "tag": "5",
      "value": "159.97436"
    },
    {
      "tag": "15",
      "value": "14190.7195"
    }
  ]
}

Or alternitevly if you want to use the 0903 standard:

{ 
    "key": "060E2B34020B01010E01030306000000",
    "items": [
      {
        "tag": "2",
        "value": "Apr. 19, 2001. 04:25:21.000"
      },
      {
          "tag": "101",
          "value": [
            {
              "tag": "targetId",
              "value": "1234"
            },
            {
              "tag": "1",
              "value": "409600"
            },
            {
              "tag": "3",
              "value": "409600"
            },
            {
              "tag": "5",
              "value": "80"
            },
            {
              "tag": "targetId",
              "value": "1235"
            },
            {
              "tag": "1",
              "value": "409601"
            },
            {
              "tag": "3",
              "value": "409601"
            }
          ]
      },
      {
        "tag": "6",
        "value": "2"
      }
    ]
  }


The following command is executed to perform the encoding. The--encode flag indicates that encoding is to be performed. The -i flag indicates the input file, where the metadata must be raw without encoding. On the other hand, the -o flag indicates the output file, which contains the encoded bytes in a binary file. The --verbose flag shows the KLV bytes encoded on the terminal.

./misb-converter --verbose --encode -i misb_ST0601_sample.json -o klv.bin

or

./misb-converter --verbose --encode -i misb_ST0903_sample.json -o klv.bin


Once the command is executed (with the --verbose flag), the KLV bytes are displayed. The 0601 klv.bin file contains the encoded bytes.

INFO    6 14 43 52 2 11 1 1 14 1 3 1 1 0 0 0 44 2 8 0 4 89 249 174 32 34 168 3 9 77 73 83 83 73 79 78 48 49 4 6 65 70 45 49 48 49 5 2 113 194 15 2 194 33 65 1 17 1 2 164 125

Decode command

The following command is executed to perform the decoding. The --decode flag indicates that decoding is to be performed. The -i flag indicates the input file, where the metadata must be encoded. The -o flag indicates the output file containing the decoded metadata.

The encoded bytes found inside the 0601 klv.bin file are:

6 14 43 52 2 11 1 1 14 1 3 1 1 0 0 0 44 2 8 0 
4 89 249 174 32 34 168 3 9 77 73 83 83 73 79 
78 48 49 4 6 65 70 45 49 48 49 5 2 113 194 15 
2 194 33 65 1 17 1 2 164 125
./misb-converter --decode -i klv.bin -o output.json

Once the command is executed, it reports that a decoded file was generated. The content of the output.json file is

{
  "key": "060E2B34020B01010E01030101000000",
  "items": [
    {
      "tag": "2",
      "value": "Oct. 24, 2008. 00:13:29.913"
    },
    {
      "tag": "3",
      "value": "MISSION01"
    },
    {
      "tag": "4",
      "value": "AF-101"
    },
    {
      "tag": "5",
      "value": "159.974365"
    },
    {
      "tag": "15",
      "value": "14190.719463"
    },
    {
      "tag": "65",
      "value": "17"
    }
  ]
}

and for the 0903:

{
  "key": "060E2B34020B01010E01030306000000",
  "items": [
    {
      "tag": "2",
      "value": "Apr. 19, 2001. 04:25:21.000"
    },
    {
      "tag": "101",
      "value": [
        {
          "tag": "id",
          "value": "1234"
        },
        {
          "tag": "1",
          "value": "409600"
        },
        {
          "tag": "3",
          "value": "409600"
        },
        {
          "tag": "5",
          "value": "80"
        },
        {
          "tag": "id",
          "value": "1235"
        },
        {
          "tag": "1",
          "value": "409601"
        },
        {
          "tag": "3",
          "value": "409601"
        }
      ]
    },
    {
      "tag": "6",
      "value": "2"
    },
    {
      "tag": "4",
      "value": "6"
    }
  ]
}

As seen here some extra flags can be present after the decoding process since the encoding might add required tags to the encoding.

Logging

You can enable the debugging using SetLogLevel in your application with the LibMISB. For example:

  libmisb::LibMisb libmisb;
  libmisb.SetLogLevel(LIBMISB_DEBUG);


Previous: Examples Index Next: Examples/Add_data_to_MPEG_Transport_Stream