Hello,how can i specify the infoadas's pad to output the video format ( format: NV12) I want ?
—————–Pad Templates for InfoADAS:
SRC template: 'src'
Availability: Sometimes
Capabilities:
video/x-raw
format: NV12
width: [ 1, 2147483647 ]
height: [ 1, 2147483647 ]
framerate: [ 0/1, 2147483647/1 ]
video/x-raw
format: BGRA
width: [ 1, 2147483647 ]
height: [ 1, 2147483647 ]
framerate: [ 0/1, 2147483647/1 ]
************ I want to implemnt the following pipeline, fitering! output NV12, whait should I do, in the code?
gst-launch-1.0 -e infoadas chain="lvds-srv-3d-880×1080" name=q \
q.stitched ! waylandsink use-drm=true sync=false \
q.left ! queue ! waylandsink use-drm=true sync=false \
q.right ! queue ! waylandsink use-drm=true sync=false \
q.front ! queue ! waylandsink use-drm=true sync=false \
q.back ! queue ! 'video/x-raw,format=NV12' ! waylandsink use-drm=true sync=false
hao huang:
I tried to use the following methods,but none of them worked.
_________________________________________________________
//#include <gst/gst.h>
#include <stdio.h>
#include <string.h>#ifdef HAVE_CONFIG_H
#include "config.h"
#endif#ifdef WIN32
#include <windows.h>
#endif//#include <GL/gl.h>
//#include "SDL/SDL.h"
//#include "SDL/SDL_opengl.h"#ifndef WIN32
//#include <GL/glx.h>
//#include "SDL/SDL_syswm.h"
//#include <gst/gl/x11/gstgldisplay_x11.h>
#endif#include <gst/gst.h>
//#include <gst/gl/gl.h>#include <gst/video/video-format.h>
#include <gst/video/video-info.h>//#include <video-enumtypes.h>
/* Structure to contain all our information, so we can pass it to callbacks */#define WIDTH_VIDEO 880/* Amount of bytes we are sending in each buffer */
#define HEIGHT_VIDEO 1080/* Amount of bytes we are sending in each buffer *///GstVideoInfo info;
typedef struct _panorama{GstElement *left_queue;GstElement *right_queue;GstElement *front_queue;GstElement *back_queue;GstElement *left_waylandsink;GstElement *right_waylandsink;GstElement *front_waylandsink;GstElement *back_waylandsink;//GstElement *infoadas_360;GstElement *infoadas_360_queue;GstElement *stitch_waylandsink;//GstElement *pipeline;// GstElementFactory *infoadas_factory;GstElementFactory *queue_factory;GstElementFactory *waylandsink_factory;}CustomData;
/* Handler for the pad-added signal */
static void pad_added_handler (GstElement *src, GstPad *pad, CustomData *data);
GstCaps *videosrc_caps;
//—————————————————————————— 2018/4/20
/* Functions below print the Capabilities in a human-friendly format */
static gboolean print_field (GQuark field, const GValue * value, gpointer pfx) {gchar *str = gst_value_serialize (value);
g_print ("%s%15s: %s\n", (gchar *) pfx, g_quark_to_string (field), str);g_free (str);return TRUE;
}static void print_caps (const GstCaps * caps, const gchar * pfx) {guint i;
g_return_if_fail (caps != NULL);
if (gst_caps_is_any (caps)) {g_print ("%sANY\n", pfx);return;}if (gst_caps_is_empty (caps)) {g_print ("%sEMPTY\n", pfx);return;}
for (i = 0; i < gst_caps_get_size (caps); i++) {GstStructure *structure = gst_caps_get_structure (caps, i);
g_print ("%s%s\n", pfx, gst_structure_get_name (structure));gst_structure_foreach (structure, print_field, (gpointer) pfx);}
}/* Prints information about a Pad Template, including its Capabilities */
static void print_pad_templates_information (GstElementFactory * factory) {const GList *pads;GstStaticPadTemplate *padtemplate;
g_print ("—————– Long-name: Pad Templates for %s:\n", gst_element_factory_get_longname (factory));if (!gst_element_factory_get_num_pad_templates (factory)) {g_print ("none\n");return;}
pads = gst_element_factory_get_static_pad_templates (factory);while (pads) {padtemplate = pads->data;pads = g_list_next (pads);//—if (padtemplate->direction == GST_PAD_SRC)g_print ("SRC template: '%s'\n", padtemplate->name_template);else if (padtemplate->direction == GST_PAD_SINK)g_print ("SINK template: '%s'\n", padtemplate->name_template);elseg_print ("UNKNOWN!!! template: '%s'\n", padtemplate->name_template);//—if (padtemplate->presence == GST_PAD_ALWAYS)g_print ("Availability: Always\n");else if (padtemplate->presence == GST_PAD_SOMETIMES)g_print ("Availability: Sometimes\n");else if (padtemplate->presence == GST_PAD_REQUEST) {g_print ("Availability: On request\n");} elseg_print ("Availability: UNKNOWN!!!\n");//—if (padtemplate->static_caps.string) {GstCaps *caps;g_print ("Capabilities:\n");caps = gst_static_caps_get (&padtemplate->static_caps);print_caps (caps, "");gst_caps_unref (caps);}//—g_print ("\n");}
}/* Shows the CURRENT capabilities of the requested pad in the given element */
static void print_pad_capabilities (GstElement *element, gchar *pad_name) {GstPad *pad = NULL;GstCaps *caps = NULL;
/* Retrieve pad */pad = gst_element_get_static_pad (element, pad_name);if (!pad) {g_printerr ("Could not retrieve pad '%s'\n", pad_name);return;}
/* Retrieve negotiated caps (or acceptable caps if negotiation is not finished yet) */caps = gst_pad_get_current_caps (pad);if (!caps)caps = gst_pad_query_caps (pad, NULL);
/* Print and free */g_print ("Caps for the %s pad:\n", pad_name);print_caps (caps, "");gst_caps_unref (caps);gst_object_unref (pad);
}int main(int argc, char *argv[]) {CustomData data;GstBus *bus;GstMessage *msg;GstStateChangeReturn ret;gboolean terminate = FALSE;
// GstVideoInfo info;// GstCaps *video_caps;
/* Initialize GStreamer */gst_init (&argc, &argv);/* Create the element factories */data.infoadas_factory = gst_element_factory_find ("infoadas");data.queue_factory = gst_element_factory_find ("queue");data.waylandsink_factory = gst_element_factory_find ("waylandsink");if (!data.waylandsink_factory || !data.queue_factory || !data.infoadas_factory) {g_printerr ("Not all element factories could be created.\n");return -1;}
/* Print information about the pad templates of these factories */print_pad_templates_information (data.infoadas_factory);print_pad_templates_information (data.queue_factory);print_pad_templates_information (data.waylandsink_factory);
/* Create the elements */data.left_queue = gst_element_factory_make ("queue", "left_queue");data.right_queue = gst_element_factory_make ("queue", "right_queue");data.front_queue = gst_element_factory_make ("queue", "front_queue");data.back_queue = gst_element_factory_make ("queue", "back_queue");data.left_waylandsink = gst_element_factory_make ("waylandsink", "left_waylandsink");data.right_waylandsink = gst_element_factory_make ("waylandsink", "right_waylandsink");data.front_waylandsink = gst_element_factory_make ("waylandsink", "front_waylandsink");data.back_waylandsink = gst_element_factory_make ("waylandsink", "back_waylandsink");data.infoadas_360 = gst_element_factory_create (data.infoadas_factory, "infoadas_360");data.infoadas_360_queue = gst_element_factory_create (data.queue_factory, "infoadas_360_queue");data.stitch_waylandsink = gst_element_factory_create (data.waylandsink_factory, "stitch_waylandsink");
/* Create the empty pipeline */data.pipeline = gst_pipeline_new ("test-pipeline");if (!data.left_queue || !data.right_queue || !data.front_queue || !data.back_queue) {g_printerr ("left…queue: Not all elements could be created.\n");return -1; } if (!data.left_waylandsink || !data.right_waylandsink || !data.front_waylandsink || !data.back_waylandsink) {g_printerr ("left…waylandsink: Not all elements could be created.\n");return -1; }if (!data.infoadas_360 || !data.infoadas_360_queue || !data.stitch_waylandsink) {g_printerr ("infoadas…: Not all elements could be created.\n");return -1; }gst_bin_add_many (GST_BIN (data.pipeline),data.infoadas_360, data.infoadas_360_queue, data.stitch_waylandsink,data.left_queue, data.left_waylandsink,data.right_queue, data.right_waylandsink,data.front_queue, data.front_waylandsink, data.back_queue, data.back_waylandsink, NULL);if (gst_element_link_many(data.infoadas_360_queue, data.stitch_waylandsink, NULL) != TRUE || gst_element_link_many(data.left_queue, data.left_waylandsink, NULL) != TRUE || gst_element_link_many(data.right_queue, data.right_waylandsink, NULL) != TRUE ||gst_element_link_many(data.front_queue, data.front_waylandsink, NULL) != TRUE ||gst_element_link_many(data.back_queue, data.back_waylandsink, NULL) != TRUE) {g_printerr ("360 could not be linked.\n");gst_object_unref (data.pipeline);return -1;}// gboolean link;// link = gst_element_link_filtered(data.infoadas_360_queue, data.stitch_waylandsink, videosrc_caps); // if(!link){// g_printerr("—————————————— !!");// }// link = gst_element_link_filtered(data.left_queue, data.left_waylandsink, videosrc_caps);// if(!link){// g_printerr("—————————————— !!");// }// link = gst_element_link_filtered(data.right_queue, data.right_waylandsink, videosrc_caps);// if(!link){// g_printerr("—————————————— !!");// }// link = gst_element_link_filtered(data.front_queue, data.front_waylandsink, videosrc_caps);// if(!link){// g_printerr("—————————————— !!");// }// link = gst_element_link_filtered(data.back_queue, data.back_waylandsink, videosrc_caps);// if(!link){// g_printerr("—————————————— !!");// }g_object_set(data.stitch_waylandsink, "sync", FALSE, "use-drm", TRUE, NULL);g_object_set(data.left_waylandsink, "sync", FALSE, "use-drm", TRUE, NULL);g_object_set(data.right_waylandsink, "sync", FALSE, "use-drm", TRUE, NULL); g_object_set(data.front_waylandsink, "sync", FALSE, "use-drm", TRUE, NULL);g_object_set(data.back_waylandsink, "sync", FALSE, "use-drm", TRUE, NULL);g_signal_connect (data.infoadas_360, "pad-added", G_CALLBACK (pad_added_handler), &data);g_object_set(data.infoadas_360, "chain", "lvds-srv-3d-880×1080", NULL); //lvds-srv-3d-880×1080
//// g_object_set(G_OBJECT(data.back_queue), "caps", gst_caps_new_simple("video/x-raw",// "format", G_TYPE_STRING, "NV12",// "width", G_TYPE_INT, 800,// "height", G_TYPE_INT, 1080,// NULL),NULL);
//set the default info for a video frame of format and width and height. ———————————————————————————————-
// gboolean// gst_video_info_set_format(GstVideoInfo *info,// GstVideoFormat format,// guint width// guint height);
// /* Configure appsrc : planar 4:2:0 YUV with interleaved UV plane*/// gst_video_info_set_format (&info, GST_VIDEO_FORMAT_NV12, WIDTH_VIDEO, HEIGHT_VIDEO);// //convert the value of 'info' into a GstCaps.// video_caps = gst_video_info_to_caps (&info);// g_object_set (data.infoadas_360, "caps", video_caps, "format", GST_FORMAT_TIME, NULL);/* Print initial negotiated caps (in NULL state) */// g_print ("——————- infoadas:In NULL state:\n");// print_pad_capabilities (data.infoadas_360, "src");
// g_print ("——————- queue_sink:In NULL state:\n");// print_pad_capabilities (data.infoadas_360_queue, "sink");// g_print ("——————- queue_src:In NULL state:\n");// print_pad_capabilities (data.infoadas_360_queue, "src");
// g_print ("——————- waylandsink:In NULL state:\n");// print_pad_capabilities (data.stitch_waylandsink, "sink");
/* Start playing */ret = gst_element_set_state (data.pipeline, GST_STATE_PLAYING);if (ret == GST_STATE_CHANGE_FAILURE) {g_printerr ("Unable to set the pipeline to the playing state.\n");gst_object_unref (data.pipeline);return -1;}
/* Listen to the bus */bus = gst_element_get_bus (data.pipeline);do {msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE,GST_MESSAGE_STATE_CHANGED | GST_MESSAGE_ERROR | GST_MESSAGE_EOS);
/* 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 (data.pipeline)) {GstState old_state, new_state, pending_state;gst_message_parse_state_changed (msg, &old_state, &new_state, &pending_state);g_print ("~~~~~~~~~~ Pipeline state changed from %s to %s:\n",gst_element_state_get_name (old_state), gst_element_state_get_name (new_state));/* Print the current capabilities of the sink element */g_print ("—— !!! ————————– infoadas: \n");print_pad_capabilities (data.infoadas_360, "src");g_print ("—— !!! ————————– queue_sink: \n");print_pad_capabilities (data.infoadas_360_queue, "sink");g_print ("—— !!! ————————– queue_src: \n");print_pad_capabilities (data.infoadas_360_queue, "src");g_print ("—— !!! ————————– waylandsink: \n");print_pad_capabilities (data.stitch_waylandsink, "sink");}break;default:/* We should not reach here */g_printerr ("Unexpected message received.\n");break;}gst_message_unref (msg);}} while (!terminate);
/* Free resources */gst_object_unref (bus);gst_element_set_state (data.pipeline, GST_STATE_NULL);gst_object_unref (data.pipeline);return 0;
}/* This function will be called by the pad-added signal */
static void pad_added_handler (GstElement *src, GstPad *new_pad, CustomData *data) {GstPad *sink_pad;GstPadLinkReturn ret;GstCaps *new_pad_caps = NULL;GstStructure *new_pad_struct = NULL;const gchar *new_pad_type = NULL;gchar *pad_name_new;const gchar *srcpadname;const gchar *destpadname;GstElement *dest;char pad_name_static1[20] = "front";char pad_name_static2[20] = "right";char pad_name_static3[20] = "back";char pad_name_static4[20] = "left";char pad_name_static5[20] = "stitched";//g_print ("Received new pad '%s' from '%s':\n", GST_PAD_NAME (new_pad), GST_ELEMENT_NAME (src));
pad_name_new= gst_pad_get_name(new_pad);if(strcmp(pad_name_new, pad_name_static5) == 0){sink_pad = gst_element_get_static_pad (data->infoadas_360_queue, "sink");g_print ("Link new pad '%s' from '%s':\n", GST_PAD_NAME (new_pad), GST_ELEMENT_NAME (src));dest = data->infoadas_360_queue;};if(strcmp(pad_name_new, pad_name_static4) == 0){sink_pad = gst_element_get_static_pad (data->left_queue, "sink");g_print ("Link new pad '%s' from '%s':\n", GST_PAD_NAME (new_pad), GST_ELEMENT_NAME (src));dest = data->left_queue;};
if(strcmp(pad_name_new, pad_name_static2) == 0){sink_pad = gst_element_get_static_pad (data->right_queue, "sink");g_print ("Link new pad '%s' from '%s':\n", GST_PAD_NAME (new_pad), GST_ELEMENT_NAME (src));dest = data->right_queue;};if(strcmp(pad_name_new, pad_name_static1) == 0){sink_pad = gst_element_get_static_pad (data->front_queue, "sink");g_print ("Link new pad '%s' from '%s':\n", GST_PAD_NAME (new_pad), GST_ELEMENT_NAME (src));dest = data->front_queue;};
if(strcmp(pad_name_new, pad_name_static3) == 0){sink_pad = gst_element_get_static_pad (data->back_queue, "sink");g_print ("Link new pad '%s' from '%s':\n", GST_PAD_NAME (new_pad), GST_ELEMENT_NAME (src));dest = data->back_queue;};
/* If our converter is already linked, we have nothing to do here */if (gst_pad_is_linked (sink_pad)) {g_print ("We are already linked. Ignoring.\n");goto exit;}else{g_print ("We haven't connected yet . . .\n");}
/*Pad Templates:SRC template: 'src'Availability: SometimesCapabilities:video/x-rawformat: NV12width: [ 1, 2147483647 ]height: [ 1, 2147483647 ]framerate: [ 0/1, 2147483647/1 ]video/x-rawformat: BGRAwidth: [ 1, 2147483647 ]height: [ 1, 2147483647 ]framerate: [ 0/1, 2147483647/1 ]*//* Check the new pad's type *///new_pad_caps = gst_pad_get_current_caps (new_pad);new_pad_caps = gst_pad_query_caps(new_pad, NULL);new_pad_struct = gst_caps_get_structure (new_pad_caps, 0);new_pad_type = gst_structure_get_name (new_pad_struct);if (!g_str_has_prefix (new_pad_type, "video/x-raw")) { g_print ("It has type '%s' which is not raw audio. Ignoring.\n", new_pad_type);goto exit;}
/* Attempt the link */// ret = gst_pad_link (new_pad, sink_pad);// if (GST_PAD_LINK_FAILED (ret)) {// g_print ("Type is '%s' but link failed.\n", new_pad_type);// } else {// g_print ("Link succeeded (type '%s').\n", new_pad_type);// }videosrc_caps = gst_caps_new_simple("video/x-raw","format", G_TYPE_STRING, "NV12","width", G_TYPE_INT, 880,"height", G_TYPE_INT, 1080,NULL);
srcpadname = gst_pad_get_name(new_pad);destpadname = gst_pad_get_name(sink_pad);gst_element_link_pads_filtered(src, srcpadname, dest, NULL, videosrc_caps);//GValue framerate = G_VALUE_INIT;
//g_value_set_int(&framerate, 22);//GST_VIDEO_FORMAT_NV12 22//gst_caps_set_value(new_pad_caps, "format" , &framerate);
//———————- display pad !g_print ("callbacks++++++++++++++++++++++++++++++++++++++++++Caps for the %s pad:\n", pad_name_new);print_caps (new_pad_caps, "");exit:/* Unreference the new pad's caps, if we got them */if (new_pad_caps != NULL)gst_caps_unref (new_pad_caps);
/* Unreference the sink pad */gst_object_unref (sink_pad);
}
Shine:
回复 hao huang:
您用的是DRA汽车电子芯片吧?汽车电子器件需要通过TI sales或者代理商提供技术支持。有到e2e上专门的汽车电子论坛咨询过吗?
e2e.ti.com/…/1020
yongqing wang:
回复 hao huang:
你使用的是什么芯片
yongqing wang:
回复 Shine:
你使用的是什么芯片