views:

94

answers:

3

I want to make a GStreamer application which takes a xml file process its content which provides information like image url, its weight and the duration for which it is going to be displayed on the screen.

The xml file can be clearly processed in C using libxml. But how can we create a slideshow of the images using the GStreamer libraries. I want to use GStreamer because the hardware and the SDK I am using provide native support for GStreamer.

Are there any GStreamer plugins to do the same. Or how else can be done. I know GStreamer basics and can write code in C for GStreamer application.

+1  A: 

You have to create a pipeline with an imagefreeze element and change the source location when the image must be changed.

An example application (in Python) that shows two still images from hard disk:

import pygst
pygst.require("0.10")
import gst

player = gst.Pipeline("player")
source = gst.element_factory_make("filesrc", "file-source")
source.set_property("location", "image1.jpeg")
jpg_decoder = gst.element_factory_make("jpegdec", "jpg-decoder")
freeze = gst.element_factory_make("imagefreeze", "freeze")
colorspace = gst.element_factory_make("ffmpegcolorspace", "colorspace")
sink = gst.element_factory_make("ximagesink", "imagesink")

player.add(source, jpg_decoder, freeze, colorspace, sink)
gst.element_link_many(source, jpg_decoder, freeze, colorspace, sink)
player.set_state(gst.STATE_PLAYING)

inp = raw_input("Press enter:")
player.set_state(gst.STATE_READY)
source.set_property("location", "image2.jpeg")
player.set_state(gst.STATE_PLAYING)
inp = raw_input("Press enter again:")
sast
When I write " gst-launch -v filesrc location=some.png ! decodebin2 ! imagefreeze ! autovideosink " on the terminal it gives me an error WARNING: erroneous pipeline: no element "imagefreeze". Though I have installed gstreamer and all the available plugins.
abhishekgupta92
Your command works at least in Ubuntu 10.10. Imagefreeze is in "good" plugins, maybe you are using an old version. You can try "freeze" element instead, it is in "bad" plugins.
sast
I tried this in Ubuntu 10.04 and Ubuntu 10.04 as well. Also, I had the package gstremear0.10-plugins-good installed so I don't think my package is obsolete.
abhishekgupta92
Ubuntu 10.04 has version 0.10.21 of "good" plugins while 10.10 has version 0.10.25. It seems that imagefreeze element has been added in between.
sast
I get the same error with freeze (and also imagefreeze) element, but command "gst-launch -v filesrc location=some.png ! decodebin2 ! freeze ! ffmpegcolorspace ! ximagesink" works. The problem seems to be in linking decodebin2 and autovideosink.
sast
I created an equivalent c file for the solution that you propose. Even it doesn't seem to work.
abhishekgupta92
http://docs.google.com/View?id=dgtpd46k_172hmzbp7dg
abhishekgupta92
I installed all the updated versions using the source. Now, i am encountering the following problem.
abhishekgupta92
On doing " gst-launch -v filesrc location=some.png ! decodebin2 ! imagefreeze ! autovideosink"
abhishekgupta92
Setting pipeline to PAUSED .../GstPipeline:pipeline0/GstDecodeBin2:decodebin20/GstTypeFindElement:typefind.GstPad:src: caps = image/jpeg, width=(int)800, height=(int)600Pipeline is PREROLLING .../GstPipeline:pipeline0/GstDecodeBin2:decodebin20/GstJpegDec:jpegdec0.GstPad:sink: caps = image/jpeg, width=(int)800, height=(int)600/GstPipeline:pipeline0/GstDecodeBin2:decodebin20.GstDecodePad:src0: caps = video/x-raw-yuv, format=(fourcc)I420, width=(int)800, height=(int)600, framerate=(fraction)0/1
abhishekgupta92
/GstPipeline:pipeline0/GstDecodeBin2:decodebin20/GstJpegDec:jpegdec0.GstPad:src: caps = video/x-raw-yuv, format=(fourcc)I420, width=(int)800, height=(int)600, framerate=(fraction)0/1ERROR: from element /GstPipeline:pipeline0/GstFileSrc:filesrc0: Internal data flow error.Additional debug info:gstbasesrc.c(2550): gst_base_src_loop (): /GstPipeline:pipeline0/GstFileSrc:filesrc0:streaming task paused, reason not-negotiated (-4)ERROR: pipeline doesn't want to preroll.Setting pipeline to NULL ...
abhishekgupta92
/GstPipeline:pipeline0/GstDecodeBin2:decodebin20.GstDecodePad:src0: caps = NULL/GstPipeline:pipeline0/GstDecodeBin2:decodebin20/GstJpegDec:jpegdec0.GstPad:src: caps = NULL/GstPipeline:pipeline0/GstDecodeBin2:decodebin20/GstJpegDec:jpegdec0.GstPad:sink: caps = NULL/GstPipeline:pipeline0/GstDecodeBin2:decodebin20/GstTypeFindElement:typefind.GstPad:src: caps = NULLFreeing pipeline ...
abhishekgupta92
Your C file does not work because you do not link the elements. Add "gst_element_link_many (source, jpg_decoder, freeze, colorspace, sink, NULL);" after "gst_bin_add_many" line.
sast
A: 

When I use "freeze" element instead it gives me following outpu :

Setting pipeline to PAUSED ...
/GstPipeline:pipeline0/GstDecodeBin2:decodebin20/GstTypeFindElement:typefind.GstPad:src: caps = image/png
Pipeline is PREROLLING ...
/GstPipeline:pipeline0/GstDecodeBin2:decodebin20/GstPngDec:pngdec0.GstPad:sink: caps = image/png
/GstPipeline:pipeline0/GstDecodeBin2:decodebin20/GstPngDec:pngdec0.GstPad:src: caps = video/x-raw-rgb, width=(int)1600, height=(int)1200, bpp=(int)24, framerate=(fraction)0/1, depth=(int)24, endianness=(int)4321, red_mask=(int)16711680, green_mask=(int)65280, blue_mask=(int)255
ERROR: from element /GstPipeline:pipeline0/GstDecodeBin2:decodebin20/GstPngDec:pngdec0: Internal data stream error.
Additional debug info:
gstpngdec.c(553): gst_pngdec_task (): /GstPipeline:pipeline0/GstDecodeBin2:decodebin20/GstPngDec:pngdec0:
stream stopped, reason not-linked
ERROR: pipeline doesn't want to preroll.
Setting pipeline to NULL ...
/GstPipeline:pipeline0/GstDecodeBin2:decodebin20.GstDecodePad:src0: caps = NULL
/GstPipeline:pipeline0/GstDecodeBin2:decodebin20/GstPngDec:pngdec0.GstPad:src: caps = NULL
/GstPipeline:pipeline0/GstDecodeBin2:decodebin20/GstPngDec:pngdec0.GstPad:sink: caps = NULL
/GstPipeline:pipeline0/GstDecodeBin2:decodebin20/GstTypeFindElement:typefind.GstPad:src: caps = NULL
Freeing pipeline ...

The image freeze element is not working and giving me following error:

WARNING: erroneous pipeline: no element "imagefreeze"

I have the gstreamer0.10-plugins-good installed so I don't think my package are obsolete.

abhishekgupta92
+1  A: 

Try the following piece of code of C :

#include <gst/gst.h>
#include <glib.h>

char *strcpy(char *dest, const xmlChar *src)
{
    unsigned i;
    for (i=0; src[i] != '\0'; ++i)
    dest[i] = src[i];
        dest[i] = '\0';
    return dest;
}


int main (int   argc, char *argv[])

{
char *docname;
char *image1 = malloc(1000);
char *image2 = malloc(1000);

docname = "input.xml";

//parse the document
xmlDocPtr doc;
xmlNodePtr cur1, cur2, cur3;

doc = xmlParseFile(docname);

if (doc == NULL ) {
    fprintf(stderr,"Document not parsed successfully. \n");
    return -1;
}

cur1 = xmlDocGetRootElement(doc);

if (cur1 == NULL) {
    fprintf(stderr,"Empty Document\n");
    xmlFreeDoc(doc);
    return -1;
}

if (xmlStrcmp(cur1->name, (const xmlChar *) "start")) {
    fprintf(stderr,"document of the wrong type, root node is supposed to be start");
    xmlFreeDoc(doc);
    return -1;
}

int flag=0;
cur2 = cur1->xmlChildrenNode;
while (cur2 != NULL)
{
    if ((!xmlStrcmp(cur2->name, (const xmlChar *)"image")))
    {
        //parseVideo (doc, cur2);
        xmlChar *key;
        cur3 = cur2->xmlChildrenNode;
        while (cur3 != NULL) 
        {
            if ((!xmlStrcmp(cur3->name, (const xmlChar *)"filename"))) 
            {
                key = xmlNodeListGetString(doc, cur3->xmlChildrenNode, 1);
                //printf("Name of the file is: %s\n", key);
                xmlFree(key);
            }

            if ((!xmlStrcmp(cur3->name, (const xmlChar *)"src"))) 
            {
                key = xmlNodeListGetString(doc, cur3->xmlChildrenNode, 1);
                if (flag == 1)
                {
                        strcpy(image2, key);
                        printf("the image 2 is %s \n", image2);
                        flag = 2;
                }
                if(flag == 0)
                {
                        strcpy(image1, key);
                        printf("the image 1 is %s \n", image1);
                        flag = 1;
                }
                    //printf("SRC of the file is: %s\n", key);
                xmlFree(key);
            }

            if ((!xmlStrcmp(cur3->name, (const xmlChar *)"duration"))) 
            {
                key = xmlNodeListGetString(doc, cur3->xmlChildrenNode, 1);
                //printf("No. of seconds the image should be displayed is: %s\n", key);
                xmlFree(key);
            }

            if ((!xmlStrcmp(cur3->name, (const xmlChar *)"weight"))) 
            {
                key = xmlNodeListGetString(doc, cur3->xmlChildrenNode, 1);
                //printf("The weight of the image is: %s\n", key);
                xmlFree(key);
            }
        cur3 = cur3->next;
        }
    }
cur2 = cur2->next;
}

xmlFreeDoc(doc);

GstElement *pipeline, *source, *jpg_decoder, *freeze, *colorspace, *sink;

  /* Initialisation */
gst_init (&argc, &argv);

/* Create gstreamer elements */
pipeline = gst_pipeline_new ("image-player");
if(!pipeline)
{
    g_printerr ("Pipeline could not be created. Exiting.\n");
    return -1;
}

  source   = gst_element_factory_make ("filesrc",       "file-source");
  //set the location of the file to the argv[1]
  g_object_set (G_OBJECT (source), "location", image1, NULL);
if(!source)
{
    g_printerr ("File could not be created. Exiting.\n");
    return -1;
}

jpg_decoder  = gst_element_factory_make ("jpegdec", "jpg-decoder");
if(!jpg_decoder)
{
    g_printerr ("Jpg Decoder could not be created. Exiting.\n");
    return -1;
}  

freeze = gst_element_factory_make("imagefreeze", "freeze");
if(!freeze)
{
    g_printerr ("ImageFreeze could not be created. Exiting.\n");
    return -1;
}  

colorspace = gst_element_factory_make("ffmpegcolorspace", "colorspace");
if(!colorspace)
{
    g_printerr ("Colorspace could not be created. Exiting.\n");
    return -1;
}  

sink     = gst_element_factory_make ("ximagesink", "imagesink");
if(!sink)
{
    g_printerr ("Image sink could not be created. Exiting.\n");
    return -1;
}

/* file-source | jpg-decoder | image-freeze | colorspace | sink */
gst_bin_add_many (GST_BIN (pipeline), source, jpg_decoder, freeze, colorspace, sink, NULL);
gst_element_link_many (source, jpg_decoder, freeze, colorspace, sink, NULL);

/* Set the pipeline to "playing" state*/
g_print ("Now playing: %s\n", image1);
gst_element_set_state (pipeline, GST_STATE_PLAYING);

getchar();
gst_element_set_state (pipeline, GST_STATE_READY);
g_object_set (G_OBJECT (source), "location", image2, NULL);
gst_element_set_state (pipeline, GST_STATE_PLAYING);
getchar();

/* Out of the main loop, clean up nicely */
g_print ("Returned, stopping playback\n");
gst_element_set_state (pipeline, GST_STATE_NULL);

g_print ("Deleting pipeline\n");
gst_object_unref (GST_OBJECT (pipeline));

    return 0;
}
Abhishek Gupta
Thanks for working out the errors Abhishek (we share the same name :P). This script is working fine but not giving me any output on the screen. I am compiling it using gcc -Wall $(pkg-config --cflags --libs gstreamer-0.10) app.c -o app -I/usr/include/libxml2 -lxml2 . The app file is generated and gives me the following output : the image 1 is 1.png the image 2 is 2.png Now playing: 1.png
abhishekgupta92
It is working on my laptop Ubuntu 8.10.
Abhishek Gupta