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?