SK-AM62A-LP: OX05B1S: Pipeline using TIOVX features results in Trace/breakpoint trap (code dump)

Part Number: SK-AM62A-LP

Tool/software:

Hi,

I'd like to transfer the following gstreamer pipeline into a c/c++ code project running at a SK-AM62A-LP eval board with a OX05B1S sensor connected (with a SDK 10.0 flashed on SD-card).
The pipeline:
gst-launch-1.0 v4l2src device=/dev/video4 io-mode=dmabuf-import ! \
video/x-bayer, width=2592, height=1944, framerate=30/1, format=bggi10 ! \
queue ! tiovxisp sink_0::pool-size=2 sink_0::device=/dev/v4l-subdev2 sensor-name=SENSOR_OX05B1S \
dcc-isp-file=/opt/imaging/ox05b1s/linear/dcc_viss.bin sink_0::dcc-2a-file=/opt/imaging/ox05b1s/linear/dcc_2a.bin format-msb=9 ! \
queue ! tiovxldc dcc-file=/opt/imaging/ox05b1s/linear/dcc_ldc.bin sensor-name=SENSOR_OX05B1S ! \
video/x-raw, format=NV12, width=2592, height=1944, framerate=30/1 ! queue ! \
videoconvert ! v4l2h264enc extra-controls="controls,h264_i_frame_period=30" ! rtph264pay ! udpsink host=192.168.1.10 port=5000

leads to the following output on the terminal and streaming of the video over UDP works as expected:
APP: Init ... !!!
17547.106726 s: MEM: Init ... !!!
17547.106781 s: MEM: Initialized DMA HEAP (fd=8) !!!
17547.106909 s: MEM: Init ... Done !!!
17547.106921 s: IPC: Init ... !!!
17547.125298 s: IPC: Init ... Done !!!
REMOTE_SERVICE: Init ... !!!
REMOTE_SERVICE: Init ... Done !!!
17547.130279 s: GTC Frequency = 200 MHz
APP: Init ... Done !!!
17547.130390 s:  VX_ZONE_INIT:Enabled
17547.130407 s:  VX_ZONE_ERROR:Enabled
17547.130417 s:  VX_ZONE_WARNING:Enabled
17547.131215 s:  VX_ZONE_INIT:[tivxPlatformCreateTargetId:124] Added target MPU-0  
17547.131552 s:  VX_ZONE_INIT:[tivxPlatformCreateTargetId:124] Added target MPU-1  
17547.131805 s:  VX_ZONE_INIT:[tivxPlatformCreateTargetId:124] Added target MPU-2  
17547.132027 s:  VX_ZONE_INIT:[tivxPlatformCreateTargetId:124] Added target MPU-3  
17547.132057 s:  VX_ZONE_INIT:[tivxInitLocal:136] Initialization Done !!!
17547.132626 s:  VX_ZONE_INIT:[tivxHostInitLocal:106] Initialization Done for HOST !!!
Setting pipeline to PAUSED ...
Pipeline is live and does not need PREROLL ...
Pipeline is PREROLLED ...
Setting pipeline to PLAYING ...
New clock: GstSystemClock
Redistribute latency...
Redistribute latency...
^Chandling interrupt.
Interrupt: Stopping pipeline ...
Execution ended after 0:00:16.475206910
Setting pipeline to NULL ...
Freeing pipeline ...
17563.763335 s:  VX_ZONE_INIT:[tivxHostDeInitLocal:120] De-Initialization Done for HOST !!!
17563.767903 s:  VX_ZONE_INIT:[tivxDeInitLocal:206] De-Initialization Done !!!
APP: Deinit ... !!!
REMOTE_SERVICE: Deinit ... !!!
REMOTE_SERVICE: Deinit ... Done !!!
17563.768338 s: IPC: Deinit ... !!!
17563.768880 s: IPC: DeInit ... Done !!!
17563.768918 s: MEM: Deinit ... !!!
17563.769031 s: DDR_SHARED_MEM: Alloc's: 33 alloc's of 139155656 bytes  
17563.769047 s: DDR_SHARED_MEM: Free's : 33 free's  of 139155656 bytes  
17563.769057 s: DDR_SHARED_MEM: Open's : 0 allocs  of 0 bytes  
17563.769071 s: MEM: Deinit ... Done !!!
APP: Deinit ... Done !!!

I tried to transfer the pipeline into c-code ( see code attached)

#include <gst/gst.h>

int main(int argc, char *argv[]) {
    GstElement *pipeline, *source, *capsfilter1, *queue1, *tiovxisp, *queue2;
    GstElement *tiovxldc, *capsfilter2, *queue3, *videoconvert, *h264enc, *rtph264pay, *udpsink, *testsink;
    GstCaps *caps, *caps2;
    GstBus *bus;
    GstMessage *msg;
    GstPad *isp_sink_pad, *src_pad;
    GstPadLinkReturn link_ret;
    GstStateChangeReturn state_ret;
    gboolean terminate = FALSE;
    GstBufferPool *buffer_pool;
    GstStructure *pool_config;

    /* Initialize GStreamer */
    gst_init(&argc, &argv);

    /* Create the elements */
    source = gst_element_factory_make("v4l2src", "source");
    capsfilter1 = gst_element_factory_make("capsfilter", "capsfilter1");
    queue1 = gst_element_factory_make("queue", "queue1");
    tiovxisp = gst_element_factory_make("tiovxisp", "tiovxisp");
    queue2 = gst_element_factory_make("queue", "queue2");
    tiovxldc = gst_element_factory_make("tiovxldc", "tiovxldc");
    capsfilter2 = gst_element_factory_make("capsfilter", "capsfilter2");
    queue3 = gst_element_factory_make("queue", "queue3");
    videoconvert = gst_element_factory_make("videoconvert", "videoconvert");
    h264enc = gst_element_factory_make("v4l2h264enc", "h264enc");
    rtph264pay = gst_element_factory_make("rtph264pay", "rtph264pay");
    udpsink = gst_element_factory_make("udpsink", "udpsink");
    testsink = gst_element_factory_make("fpsdisplaysink", "testsink");

    /* Check if all elements are created */
    if (!source || !capsfilter1 || !queue1 || !tiovxisp || !queue2 ||
        !tiovxldc || !capsfilter2 || !queue3 || !videoconvert || !h264enc ||
        !rtph264pay || !udpsink || !testsink) {
        g_printerr("Not all elements could be created.\n");
        return -1;
    }

    /* Create the empty pipeline */
    pipeline = gst_pipeline_new("my-pipeline");

    if (!pipeline) {
        g_printerr("Pipeline could not be created.\n");
        return -1;
    } else {
        g_print("Pipeline created. \n");
    }

    /* Set element properties */
    g_object_set(source, "device", "/dev/video4", "io-mode", 4, NULL); // io-mode=dmabuf-import

    /* Create caps for source and downstream elements */
    // Caps for Bayer format
    caps = gst_caps_new_simple("video/x-bayer",
                               "width", G_TYPE_INT, 2592,
                               "height", G_TYPE_INT, 1944,
                               "framerate", GST_TYPE_FRACTION, 30, 1,
                               "format", G_TYPE_STRING, "bggi10",
                               NULL);

    g_object_set(capsfilter1, "caps", caps, NULL);

    g_object_set(tiovxisp, 
                "sensor-name", "SENSOR_OX05B1S",
                "dcc-isp-file", "/opt/imaging/ox05b1s/linear/dcc_viss.bin",
                "format-msb", 9,
                NULL);

    g_print("ISP properties set. \n");

    g_object_set(tiovxldc,
                 "sensor-name", "SENSOR_OX05B1S",
                 "dcc-file", "/opt/imaging/ox05b1s/linear/dcc_ldc.bin",
                 NULL);

    g_print("LDC properties set. \n");

    /* Enhance the h264enc element */
    g_object_set(h264enc,
             "extra-controls", "controls,h264_i_frame_period=30",
             NULL);

    g_print("H264 Encoder properties set.\n");
 
    // Caps after tiovxldc for raw video
    caps2 = gst_caps_new_simple("video/x-raw",
                                "format", G_TYPE_STRING, "NV12",
                                "width", G_TYPE_INT, 2592,
                                "height", G_TYPE_INT, 1944,
                                "framerate", GST_TYPE_FRACTION, 30, 1,
                                NULL);
    
    // Set UDP sink properties
    g_object_set(udpsink,
                 "host", "192.168.1.10",
                 "port", 5000,
                 NULL);

    g_object_set(testsink,
                "video-sink","fakesink",
                "textoverlay","false",
                NULL);

    g_print("Sink properties set. \n");

        /* Debugging output for caps negotiation */
    g_print("Caps for capsfilter1: %s\n", gst_caps_to_string(caps));
    g_print("Caps for capsfilter2: %s\n", gst_caps_to_string(caps2));

    /* Create a buffer pool for efficient buffer management */
    buffer_pool = gst_buffer_pool_new();
    pool_config = gst_buffer_pool_get_config(buffer_pool);
    gst_buffer_pool_config_set_params(pool_config, caps2, 2592 * 1944 * 1.5, 2, 5); // Assuming NV12 format
    if (!gst_buffer_pool_set_config(buffer_pool, pool_config)) {
        g_printerr("Failed to configure buffer pool.\n");
        return -1;
    }

    /* Activate the buffer pool */
    if (!gst_buffer_pool_set_active(buffer_pool, TRUE)) {
        g_printerr("Failed to activate buffer pool.\n");
        return -1;
    }

    g_print("Buffer pool created and activated.\n");

    /* Build the pipeline */
    gst_bin_add_many(GST_BIN(pipeline),
                     source, capsfilter1, queue1, tiovxisp, queue2, tiovxldc,
                     capsfilter2, queue3, videoconvert, h264enc, rtph264pay, udpsink,
                     NULL);
    g_print("Pipeline set up. \n");

    /* Request sink pad from the ISP element */
    isp_sink_pad = gst_element_request_pad_simple(tiovxisp, "sink_0");
    if (!isp_sink_pad) {
        g_printerr("Failed to request sink pad from tiovxisp!\n");
        return -1;
    } else {
        g_print("Request sink pad successful.\n");
    }

    /* Set properties on the requested pad */
    g_object_set(isp_sink_pad, 
                        "pool-size", 2,
                        "device", "/dev/v4l-subdev2", 
                        "dcc-2a-file", "/opt/imaging/ox05b1s/linear/dcc_2a.bin",
                        NULL);

    /* Retrieve the src pad from the source element */
    src_pad = gst_element_get_static_pad(queue1, "src");
    if (!src_pad) {
        g_printerr("Failed to get src pad from queue element!\n");
        gst_object_unref(isp_sink_pad);
        return -1;
    } else {
        g_print("Successful getting src pad from queue element.\n");
    }

    /* Link source element to requested pad from isp */
    link_ret = gst_pad_link(src_pad, isp_sink_pad);
    if (link_ret != GST_PAD_LINK_OK) {
        g_printerr("Source element and ISP element could not be linked.\n");
        gst_object_unref(pipeline);
        return -1;
    } else {
        g_print("Source element and ISP linked.\n");
    }
    gst_object_unref(src_pad);
    gst_object_unref(isp_sink_pad);

    /* Link first elements */
    if (!gst_element_link_many(source, capsfilter1, queue1, NULL)) {
        g_printerr("Elements could not be linked.\n");
        gst_object_unref(pipeline);
        return -1;
    } else {
        g_print("First elements linked.\n");
    }

    // Link next elements in the pipeline 
    if (!gst_element_link_many(tiovxisp, queue2, tiovxldc, NULL)) {
        g_printerr("Elements could not be linked.\n");
        gst_object_unref(pipeline);
        return -1;
    } else {
        g_print("Next elements linked.\n");
    }
    
    if (!gst_element_link(tiovxldc, capsfilter2)) {
        g_printerr("Elements could not be linked.\n");
        gst_object_unref(pipeline);
        return -1;
    } else {
        g_print("Next elements linked.\n");
    }

    g_object_set(capsfilter2,"caps",caps2,NULL);

    if (!gst_element_link_many(capsfilter2, queue3, videoconvert, h264enc, rtph264pay, udpsink, NULL)) {
        g_printerr("Elements could not be linked.\n");
        gst_object_unref(pipeline);
        return -1;
    } else {
        g_print("Remaining elements linked.\n");
    }   

    /* Unref caps only after all elements are linked and pipeline is set to PLAYING */
    gst_caps_unref(caps);
    gst_caps_unref(caps2);

    /* Start playing */
    state_ret = gst_element_set_state(pipeline, GST_STATE_PLAYING);
    if (state_ret == GST_STATE_CHANGE_FAILURE) {
        g_printerr("Unable to set the pipeline to the playing state.\n");
        gst_object_unref(pipeline);
        return -1;
    } else {
        g_print("Pipeline in playing state.\n");
    }

    /* Wait until error or EOS */
    bus = gst_element_get_bus(pipeline);

    do {
        msg = gst_bus_timed_pop_filtered(bus, GST_CLOCK_TIME_NONE, static_cast<GstMessageType>(GST_MESSAGE_ERROR | GST_MESSAGE_EOS | GST_MESSAGE_STATE_CHANGED));


        /* Parse message */
        if (msg != NULL) {
            GError *err;
            gchar *debug_info;

            switch (GST_MESSAGE_TYPE (msg)) {
                case GST_MESSAGE_ERROR:
                    gst_message_parse_error (msg, &err, &debug_info);
                    g_printerr ("Error received from element %s: %s\n", GST_OBJECT_NAME (msg->src), err->message);
                    g_printerr ("Debugging information: %s\n", debug_info ? debug_info : "none");
                    g_clear_error (&err);
                    g_free (debug_info);
                    terminate = TRUE;
                    break;
                case GST_MESSAGE_EOS:
                    g_print ("End-Of-Stream reached.\n");
                    terminate = TRUE;
                    break;
                case GST_MESSAGE_STATE_CHANGED:
                    /* We are only interested in state-changed messages from the pipeline */
                    if (GST_MESSAGE_SRC (msg) == GST_OBJECT (pipeline)) {
                        GstState old_state, new_state, pending_state;
                        gst_message_parse_state_changed (msg, &old_state, &new_state, &pending_state);
                        g_print ("\nPipeline state changed from %s to %s / pending state is %s.\n",
                            gst_element_state_get_name (old_state), gst_element_state_get_name (new_state),gst_element_state_get_name(pending_state));
                    }
                    break;
                default:
                    /* We should not reach here because we only asked for ERRORs, EOS and STATE_CHANGED */
                    g_printerr ("Unexpected message received.\n");
                    break;
            }
            gst_message_unref (msg);
        }
    } while (!terminate);

    /* Clean up */
    gst_object_unref(bus);
    gst_element_set_state(pipeline, GST_STATE_NULL);
    gst_element_release_request_pad(tiovxisp, isp_sink_pad);
    gst_object_unref(isp_sink_pad);
    gst_object_unref(buffer_pool);
    gst_object_unref(pipeline);

    return 0;
}

but running in a memory allocation problem:

root@am62axx-evm:/home/weston# GST_DEBUG=":5" ./ox05-demo  
APP: Init ... !!!
17914.434153 s: MEM: Init ... !!!
17914.434216 s: MEM: Initialized DMA HEAP (fd=8) !!!
17914.434346 s: MEM: Init ... Done !!!
17914.434358 s: IPC: Init ... !!!
17914.452482 s: IPC: Init ... Done !!!
REMOTE_SERVICE: Init ... !!!
REMOTE_SERVICE: Init ... Done !!!
17914.457812 s: GTC Frequency = 200 MHz
APP: Init ... Done !!!
17914.457934 s:  VX_ZONE_INIT:Enabled
17914.457949 s:  VX_ZONE_ERROR:Enabled
17914.457959 s:  VX_ZONE_WARNING:Enabled
17914.458900 s:  VX_ZONE_INIT:[tivxPlatformCreateTargetId:124] A[ 5021.018302] __vm_enough_memory: pid: 1883, comm: ox05-de
mo, not enough memory for the allocation
dded target MPU-0  
17914.459185 s:  VX_ZONE_INIT:[tivxPlatform[ 5021.029639] __vm_enough_memory: pid: 1883, comm: ox05-demo, not enough memory
for the allocation
CreateTargetId:124] Added target MPU-1  
17914.459412 s:  VX_ZO[ 5021.043910] __vm_enough_memory: pid: 1883, comm: ox05-demo, not enough memory for the allocation
NE_INIT:[tivxPlatformCreateTargetId:124] Added target MPU-2  
1[ 5021.058237] __vm_enough_memory: pid: 1883, comm: ox05-demo, not enough memory for the allocation
7914.459629 s:  VX_ZONE_INIT:[tivxPlatformCreateTargetId:124] Ad[ 5021.072814] audit: type=1701 audit(1732970449.624:91): au
id=4294967295 uid=0 gid=0 ses=4294967295 pid=1883 comm="ox05-demo" exe="/home/weston/ox05-demo" sig=5 res=1
ded target MPU-3  
17914.459663 s:  VX_ZONE_INIT:[tivxInitLocal[ 5021.097937] audit: type=1334 audit(1732970449.652:92): prog-id=50 op=LOAD
:136] Initialization Done !!!
17914.459769 s:  VX_ZONE_INIT:[t[ 5021.105034] audit: type=1334 audit(1732970449.656:93): prog-id=51 op=LOAD
ivxHostInitLocal:106] Initialization Done for HOST !!!
Pipeline[ 5021.117344] audit: type=1334 audit(1732970449.668:94): prog-id=52 op=LOAD
created.  
ISP properties set.  
LDC properties set.  

(ox05-demo:1883): GLib-ERROR **: 12:40:49.628: /usr/src/debug/glib-2.0/2.78.6/glib/gmem.c:169: failed to allocate 5392073911
2 bytes
Trace/breakpoint trap (core dumped)

Can someone help?

  • Hi Rowena,

    I noticed the following in your C code:

    g_object_set(source, "device", "/dev/video4", "io-mode", 4, NULL); // io-mode=dmabuf-import

    Please note that dmabuf-import is 5:

    gst-inspect-1.0 v4l2src | grep dmabuf-import
                               (5): dmabuf-import    - GST_V4L2_IO_DMABUF_IMPORT

    Can you try using 5 for io-mode?

    Regards,

    Jianzhong

  • Hi Jianzhong,

    thanks for your comment. I changed the respective io-mode

    g_object_set(source, "device", "/dev/video4", "io-mode", 5, NULL); // io-mode=dmabuf-import

    but the result is the same... I still get the memory allocation error
    root@am62axx-evm:/home/weston# GST_DEBUG=":5" ./ox05-demo  
    APP: Init ... !!!
     1021.813987 s: MEM: Init ... !!!
     1021.814056 s: MEM: Initialized DMA HEAP (fd=8) !!!
     1021.814217 s: MEM: Init ... Done !!!
     1021.814231 s: IPC: Init ... !!!
     1021.831760 s: IPC: Init ... Done !!!
    REMOTE_SERVICE: Init ... !!!
    REMOTE_SERVICE: Init ... Done !!!
     1021.842971 s: GTC Frequency = 200 MHz
    APP: Init ... Done !!!
     1021.846350 s:  VX_ZONE_INIT:Enabled
     1021.846376 s:  VX_ZONE_ERROR:Enabled
     1021.846386 s:  VX_ZONE_WARNING:Enabled
     1021.847546 s:  VX_ZONE_INIT:[tivxPlatformCreateTargetId:124] Added target MPU-0  
     1021.847708 s:  VX_ZONE_INIT:[tivxPlatformCreateTargetId:124] Added target MPU-1  
     1021.847808 s:  VX_ZONE_INIT:[tivxPlatformCreateTargetId:124] Added target MPU-2  
     1021.847906 s:  VX_ZONE_INIT:[tivxPlatformCreateTargetId:124] Added target MPU-3  
     1021.847920 s:  VX_ZONE_INIT:[tivxInitLocal:136] Initialization Done !!!
     1021.849144 s:  VX_ZONE_INIT:[tivxHostInitLocal:106] Initialization Done for HOST !!!
    Pipeline created. [   54.276364] __vm_enough_memory: pid: 1582, comm: ox05-demo, not enough memory for the allocation

    ISP properties set.  
    LDC properties set.  
    [   54.286567] __vm_enough_memory: pid: 1582, comm: ox05-demo, not enough memory for the allocation
    [   54.299300] __vm_enough_memory: pid: 1582, comm: ox05-demo, not enough memory for the allocation
    [   54.308198] __vm_enough_memory: pid: 1582, comm: ox05-demo, not enough memory for the allocation

    [   54.322109] audit: type=1701 audit(1732965560.448:30): auid=4294967295 uid=0 gid=0 ses=4294967295 pid=1582 comm="ox05-demo" exe="/home/weston/ox05-demo" sig=5 res=1
    (ox05-demo:1582): GLib-ERROR **: 11:19:20.444: /usr/src/debug/glib-2.0/2.78.6/glib/gmem.c:169: failed to all[   54.347319] audit: type=1334 audit(1732965560.472:31): prog-id=24 op=LOAD
    ocate 53920739112 bytes
    [   54.354764] audit: type=1334 audit(1732965560.480:32): prog-id=25 op=LOAD
    [   54.363668] audit: type=1334 audit(1732965560.488:33): prog-id=26 op=LOAD
    Trace/breakpoint trap (core dumped)

  • I'm not sure what caused the memory allocation error. Can you start from a simple pipeline, e.g., with just the v4l2src and a fakesink, and then add in more elements one by one and see which one cause the error?

  • I Jianzhong,
    according to your tip I striped my pipeline so that it only contains the v4l2src, the tiovxisp, tiovxldc and a fakesink.
    I created really simple c code where for a start using gst_parse_launch for starting the pipeline to check that it works even in a c context:


        /* Create the pipeline using gst_parse_launch */
        const gchar *pipeline_description =
            "v4l2src device=/dev/video4 io-mode=5 ! "
            "video/x-bayer, width=2592, height=1944, framerate=30/1, format=bggi10 ! "
            "tiovxisp sensor-name=SENSOR_OX05B1S dcc-isp-file=/opt/imaging/ox05b1s/linear/dcc_viss.bin format-msb=9 "
            "sink_0::pool-size=2 sink_0::device=/dev/v4l-subdev2 sink_0::dcc-2a-file=/opt/imaging/ox05b1s/linear/dcc_2a.bin ! "
            "tiovxldc sensor-name=SENSOR_OX05B1S dcc-file=/opt/imaging/ox05b1s/linear/dcc_ldc.bin ! "
            "video/x-raw, format=NV12, width=2592, height=1944, framerate=30/1 !"
            "fakesink";

        pipeline = gst_parse_launch(pipeline_description, NULL);
        if (!pipeline) {
            g_printerr("Pipeline could not be created.\n");
            return -1;
        }

    This works fine and so I started from scratch and decipher which settings from the pipeline belong / are associated to which element or pad (as capabilities or properties) using the respective information from gst-inspect-1.0 and https://github.com/TexasInstruments/edgeai-gst-plugins/wiki/ for the tiovx elements. For the tiovxisp I'm a bit confused:
    When looking at the pipeline part

    "tiovxisp sensor-name=SENSOR_OX05B1S dcc-isp-file=/opt/imaging/ox05b1s/linear/dcc_viss.bin format-msb=9 "
            "sink_0::pool-size=2 sink_0::device=/dev/v4l-subdev2 sink_0::dcc-2a-file=/opt/imaging/ox05b1s/linear/dcc_2a.bin ! "

    I would say that the sensor-name and dcc-isp-file are properties of the element and pool-size, device and dcc-a2-file are properties of the sink_0 which seams to be a onRequest pad (normally indicated in documentation by naming like src_% or sink_%).
    When I have a look on the documentation page https://github.com/TexasInstruments/edgeai-gst-plugins/wiki/tiovxisp it shows that the sink pad is an always pad and the src pad is an onRequest Pad and the properties like device, pool-size and dcc-a2-file are listed as properties of the element.

    So I'm not sure how to set up the tiovxisp factory correctly. Can you help?

  • Hello Rowena,

    Let me check with our Gstreamer team about this. Please give us a day or two to respond.

    Thanks for your patience.

    Jianzhong