diff --git a/tools/.gitignore b/tools/.gitignore index b5ae73baf9..e5db16aaa4 100644 --- a/tools/.gitignore +++ b/tools/.gitignore @@ -8,4 +8,5 @@ Makefile.in gstreamer-launch gstreamer-register +gstreamer-inspect *.xml diff --git a/tools/Makefile.am b/tools/Makefile.am index 0701fa5897..814fb27cb5 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -1,4 +1,4 @@ -bin_PROGRAMS = gstreamer-launch gstreamer-register +bin_PROGRAMS = gstreamer-launch gstreamer-register gstreamer-inspect CFLAGS = -Wall -O2 diff --git a/tools/gstreamer-inspect.c b/tools/gstreamer-inspect.c new file mode 100644 index 0000000000..cbe76d5b7a --- /dev/null +++ b/tools/gstreamer-inspect.c @@ -0,0 +1,88 @@ +#include + +int main(int argc,char *argv[]) { + GstElementFactory *factory; + GstElement *element; + GstElementClass *gstelement_class; + GList *pads; + GstPad *pad; + + gst_init(&argc,&argv); + + factory = gst_elementfactory_find(argv[1]); + element = gst_elementfactory_create(factory,argv[1]); + gstelement_class = GST_ELEMENT_CLASS (GTK_OBJECT (element)->klass); + + printf("Element Details:\n"); + printf(" Long name:\t%s\n",factory->details->longname); + printf(" Class:\t%s\n",factory->details->klass); + printf(" Description:\t%s\n",factory->details->description); + printf(" Version:\t%s\n",factory->details->version); + printf(" Author(s):\t%s\n",factory->details->author); + printf(" Copyright:\t%s\n",factory->details->copyright); + printf("\n"); + + printf("Element Flags:\n"); + if (GST_FLAG_IS_SET(element,GST_ELEMENT_COMPLEX)) + printf(" GST_ELEMENT_COMPLEX\n"); + if (GST_FLAG_IS_SET(element,GST_ELEMENT_DECOUPLED)) + printf(" GST_ELEMENT_DECOUPLED\n"); + if (GST_FLAG_IS_SET(element,GST_ELEMENT_THREAD_SUGGESTED)) + printf(" GST_ELEMENT_THREADSUGGESTED\n"); + if (GST_FLAG_IS_SET(element,GST_ELEMENT_NO_SEEK)) + printf(" GST_ELEMENT_NO_SEEK\n"); + if (! GST_FLAG_IS_SET(element, GST_ELEMENT_COMPLEX | GST_ELEMENT_DECOUPLED | + GST_ELEMENT_THREAD_SUGGESTED | GST_ELEMENT_NO_SEEK)) + printf(" no flags set\n"); + printf("\n"); + + + printf("Element Implementation:\n"); + if (element->loopfunc) + printf(" loopfunc()-based element\n"); + else + printf(" No loopfunc(), must be chain-based or not configured yet\n"); + if (gstelement_class->change_state) + printf(" Has change_state() function\n"); + else + printf(" No change_state() class function\n"); + if (gstelement_class->save_thyself) + printf(" Has custom save_thyself() class function\n"); + if (gstelement_class->restore_thyself) + printf(" Has custom restore_thyself() class function\n"); + printf("\n"); + + + printf("Pads:\n"); + pads = gst_element_get_pad_list(element); + while (pads) { + pad = GST_PAD(pads->data); + pads = g_list_next(pads); + if (gst_pad_get_direction(pad) == GST_PAD_SRC) + printf(" SRC: %s\n",gst_pad_get_name(pad)); + else if (gst_pad_get_direction(pad) == GST_PAD_SINK) + printf(" SINK: %s\n",gst_pad_get_name(pad)); + else + printf(" UNKNOWN!!!: %s\n",gst_pad_get_name(pad)); + + printf(" Implementation:\n"); + if (pad->chainfunc) + printf(" Has chainfunc(): %s\n",GST_DEBUG_FUNCPTR_NAME(pad->chainfunc)); + if (pad->getfunc) + printf(" Has getfunc(): %s\n",GST_DEBUG_FUNCPTR_NAME(pad->getfunc)); + if (pad->getregionfunc) + printf(" Has getregionfunc(): %s\n",GST_DEBUG_FUNCPTR_NAME(pad->getregionfunc)); + if (pad->qosfunc) + printf(" Has qosfunc(): %s\n",GST_DEBUG_FUNCPTR_NAME(pad->qosfunc)); + if (pad->eosfunc) { + if (pad->eosfunc == gst_pad_eos_func) + printf(" Has default eosfunc() gst_pad_eos_func()\n"); + else + printf(" Has eosfunc(): %s\n",GST_DEBUG_FUNCPTR_NAME(pad->eosfunc)); + } + printf("\n"); + } + printf("\n"); + + return 0; +} diff --git a/tools/gstreamer-launch.c b/tools/gstreamer-launch.c index 02d2fa4030..f0edf330d3 100644 --- a/tools/gstreamer-launch.c +++ b/tools/gstreamer-launch.c @@ -3,6 +3,29 @@ #include #include +guint bincount = 0; +guint threadcount = 0; +gint binlevel = 0; +GHashTable *elementcounts; +gboolean verbose = FALSE; +gboolean debug = FALSE; + +#define DEBUG(format,args...) G_STMT_START{ \ + if (debug) { \ + int ___i; \ + for (___i=0;___idata); pads = g_list_next (pads); @@ -116,41 +140,45 @@ gint parse_cmdline(int argc,char *argv[],GstBin *parent) { } } - if (!srcpad) fprintf(stderr,"error, can't find a src pad!!!\n"); - else fprintf(stderr,"have src pad %s:%s\n",GST_DEBUG_PAD_NAME(srcpad)); + if (!srcpad) DEBUG("error, can't find a src pad!!!\n"); + else DEBUG("have src pad %s:%s\n",GST_DEBUG_PAD_NAME(srcpad)); } // element, or beginning of bin or thread } else { - fprintf(stderr,"have element or bin/thread\n"); + DEBUG("have element or bin/thread\n"); // if we have a bin or thread starting if (strchr("({",arg[0])) { - if (arg[0] == '(') + if (arg[0] == '(') { // create a bin and add it to the current parent element = gst_bin_new(g_strdup_printf("bin%d",bincount++)); - else if (arg[0] == '{') + VERBOSE("CREATED bin %s\n",gst_element_get_name(element)); + } else if (arg[0] == '{') { // create a thread and add it to the current parent element = gst_thread_new(g_strdup_printf("thread%d",threadcount++)); + VERBOSE("CREATED thread %s\n",gst_element_get_name(element)); + } i += parse_cmdline(argc - i, argv + i + 1, GST_BIN (element)); // else we have an element } else { - fprintf(stderr,"attempting to create element '%s'\n",arg); + DEBUG("attempting to create element '%s'\n",arg); element = gst_elementfactory_make(arg,unique_name(arg)); - fprintf(stderr,"created element %s\n",gst_element_get_name(element)); + VERBOSE("CREATED element %s\n",gst_element_get_name(element)); + DEBUG("created element %s\n",gst_element_get_name(element)); } gst_bin_add (GST_BIN (parent), element); elementcount++; if (srcpad != NULL) { - fprintf(stderr,"need to connect to sinkpad %s:%s\n",GST_DEBUG_PAD_NAME(srcpad)); + DEBUG("need to connect to sinkpad %s:%s\n",GST_DEBUG_PAD_NAME(srcpad)); sinkpad = NULL; if (sinkpadname != NULL) - sinkpad = gst_element_get_pad(prevelement,sinkpadname); + sinkpad = gst_element_get_pad(previous,sinkpadname); if (!sinkpad) { // check through the list to find the first sink pad @@ -163,10 +191,10 @@ gint parse_cmdline(int argc,char *argv[],GstBin *parent) { } } - if (!sinkpad) fprintf(stderr,"error, can't find a sink pad!!!\n"); - else fprintf(stderr,"have sink pad %s:%s\n",GST_DEBUG_PAD_NAME(sinkpad)); + if (!sinkpad) DEBUG("error, can't find a sink pad!!!\n"); + else DEBUG("have sink pad %s:%s\n",GST_DEBUG_PAD_NAME(sinkpad)); - fprintf(stderr,"CONNECTING %s:%s and %s:%s\n",GST_DEBUG_PAD_NAME(srcpad),GST_DEBUG_PAD_NAME(sinkpad)); + VERBOSE("CONNECTING %s:%s and %s:%s\n",GST_DEBUG_PAD_NAME(srcpad),GST_DEBUG_PAD_NAME(sinkpad)); gst_pad_connect(srcpad,sinkpad); sinkpad = NULL; @@ -175,46 +203,49 @@ gint parse_cmdline(int argc,char *argv[],GstBin *parent) { // if we're the first element, ghost all the sinkpads if (elementcount == 1) { - fprintf(stderr,"first element, ghosting all of %s's sink pads to parent %s\n", - gst_element_get_name(element),gst_element_get_name(GST_ELEMENT(parent))); + DEBUG("first element, ghosting all of %s's sink pads to parent %s\n", + gst_element_get_name(element),gst_element_get_name(GST_ELEMENT(parent))); pads = gst_element_get_pad_list (element); while (pads) { sinkpad = GST_PAD (pads->data); pads = g_list_next (pads); - if (!sinkpad) fprintf(stderr,"much oddness, pad doesn't seem to exist\n"); + if (!sinkpad) DEBUG("much oddness, pad doesn't seem to exist\n"); else if (gst_pad_get_direction (sinkpad) == GST_PAD_SINK) { gst_element_add_ghost_pad (GST_ELEMENT (parent), sinkpad); - fprintf(stderr,"ghosted %s:%s\n",GST_DEBUG_PAD_NAME(sinkpad)); + DEBUG("ghosted %s:%s\n",GST_DEBUG_PAD_NAME(sinkpad)); } } } } i++; - prevelement = element; + previous = element; + if (!GST_IS_BIN(element)) prevelement = element; } // ghost all the src pads of the bin if (prevelement != NULL) { - fprintf(stderr,"last element, ghosting all of %s's src pads to parent %s\n", - gst_element_get_name(prevelement),gst_element_get_name(GST_ELEMENT(parent))); + DEBUG("last element, ghosting all of %s's src pads to parent %s\n", + gst_element_get_name(prevelement),gst_element_get_name(GST_ELEMENT(parent))); pads = gst_element_get_pad_list (prevelement); while (pads) { srcpad = GST_PAD (pads->data); pads = g_list_next (pads); - if (!srcpad) fprintf(stderr,"much oddness, pad doesn't seem to exist\n"); + if (!srcpad) DEBUG("much oddness, pad doesn't seem to exist\n"); else if (gst_pad_get_direction (srcpad) == GST_PAD_SRC) { gst_element_add_ghost_pad (GST_ELEMENT (parent), srcpad); - fprintf(stderr,"ghosted %s:%s\n",GST_DEBUG_PAD_NAME(srcpad)); + DEBUG("ghosted %s:%s\n",GST_DEBUG_PAD_NAME(srcpad)); } } } + binlevel--; + if (retval) return retval; if (closingchar != '\0') - fprintf(stderr,"returning IN THE WRONG PLACE\n"); - else fprintf(stderr,"ending pipeline\n"); + DEBUG("returning IN THE WRONG PLACE\n"); + else DEBUG("ending pipeline\n"); return i+1; } @@ -248,7 +279,7 @@ gint parse(int argc,char *argv[],GstBin *parent) { // now allocate the new argv array argvn = g_new0(char *,newargc+1); -fprintf(stderr,"supposed to have %d args\n",newargc); + DEBUG("supposed to have %d args\n",newargc); // now attempt to construct the new arg list j = 0;k = 0; @@ -260,7 +291,9 @@ fprintf(stderr,"supposed to have %d args\n",newargc); if (cmdline[k] == ' ') k++; argvn[j] = g_new0(char,(i-k)+1); memcpy(argvn[j],&cmdline[k],i-k); - j++; + + // catch misparses + if (strlen(argvn[j]) > 0) j++; } k = i; @@ -274,7 +307,7 @@ fprintf(stderr,"supposed to have %d args\n",newargc); // print them out for (i=0;i