All pastes #1455530 Raw Edit

Miscellany

public text v1 · immutable
#1455530 ·published 2009-06-10 16:43 UTC
rendered paste body
/*!
    \author CIO-SLI
    \brief Gstreamer base player for omap (but also x86)
    play an uri using playbin
    Check that TI's plugin are here. If so use TI's sink with default/user options.
*/

/******************************************************************************
                                STD INCLUDES
******************************************************************************/
// for getopt
#include <unistd.h>
#include <stdio.h>
#include <gst/gst.h>
// for strtol
#include <stdlib.h>
// strdup
#include <string.h>

/******************************************************************************
                                SPECIFIC INCLUDES
******************************************************************************/

/******************************************************************************
                                TYPES
******************************************************************************/
//! TI Video codec enum
typedef enum t_ti_plugins {
TP_AUDDEC,
TP_AUDDEC1,
TP_VIDDEC,
TP_VIDDEC2,
TP_TISINK,
TP_LAST
} T_TI_PLUGINS ;

//! stuff to parse struct options
typedef struct t_options {
    gboolean bTestSink ; //!< Test the configured video sink
    gboolean bFrameAcc ; //!< Enable/Disable Frame Accel copy
    gchar * uri ;
} T_OPTIONS ;

/******************************************************************************
                                GLOBALS
******************************************************************************/

#define STR_TIAUDDEC    "TIAuddec"
#define STR_TIAUDDEC1   "TIAuddec1"
#define STR_TIVIDEC     "TIViddec"
#define STR_TIVIDEC2    "TIViddec2"
#define STR_TISINK      "TIDmaiVideoSink"

//! Liste des plugins
const char * const g_szGstTIplugins[] =	{ STR_TIAUDDEC, STR_TIAUDDEC1, STR_TIVIDEC, STR_TIVIDEC2,STR_TISINK } ;

//! options for the player and gstreamer
static T_OPTIONS   sOpts = {0} ;

/******************************************************************************
                                PROTOYPES AND MACROS
******************************************************************************/
//! loop waiting for bus message
static void event_loop (GstElement * pipe) ;

//! Parse user options
static gint opt_parse(gint argc, char * argv[], T_OPTIONS * popts) ;

//! print usage
static void print_usage(const gchar * name) ;

//! free options ressources
static void delete_opts(void) ;

/******************************************************************************
                                FUNCTIONS
******************************************************************************/

//! Boucle principale
int main (int argc, char *argv[])
{
    gint i;
	const gchar *nano_str ;
	guint major, minor, micro, nano;
	// factory to produce the gst TI element
	GstElementFactory *factory = NULL ;
    GstElement * VideoSink = NULL ;
    GstElement *playbin = NULL ;
    GstElement *videotestsrc = NULL ;

    // program
    // TODO parse user options

    // make sure we have a URI
    if (argc < 2)
    {
        print_usage(argv[0]) ;
        return -1;
    }

	// gst init
    if (opt_parse(argc, argv, &sOpts) !=0)
    {
        print_usage(argv[0]) ;
        return -1 ;
    }

	gst_init (&argc, &argv);


	// Now get version info
	gst_version (&major, &minor, &micro, &nano);
	switch (nano)
    {
        case 1 :
            nano_str = "(CVS)";
            break ;
        case 2 :
            nano_str = "(Prerelease)";
            break ;
        default :
            nano_str = "";
            break ;
    }
	printf ("This program is linked against GStreamer %d.%d.%d %s\n",
          major, minor, micro, nano_str);

	// Check that the TI's codec here and display info
	for(i=0 ; i<TP_LAST ; i++)
	{
        factory = gst_element_factory_find (g_szGstTIplugins[i]);
        if (!factory)
        {
            g_print ("You don't have the %s element installed!\n", g_szGstTIplugins[i]);
        }
        else
        {
            g_print ("The '%s' element is a member of the category %s.\n"
                   "Description: %s\n",
                   gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)),
                   gst_element_factory_get_klass (factory),
                   gst_element_factory_get_description (factory));
            gst_object_unref(factory) ;
         }
	}

	// If TIDmaiVideoSink exist create it and apply parameters by default/given by user
    factory = gst_element_factory_find (g_szGstTIplugins[TP_TISINK]);
    if (factory)
    {
        g_print ("Creating and setting TI Video sink !\n");
        VideoSink = gst_element_factory_create (factory, "sink");
        if (!VideoSink)
        {
            g_print ("Failed to create videosink element, even though its factory exists!\n");
            gst_object_unref( G_OBJECT(factory) );
            factory = NULL ;
            return -1;
        }
        gst_object_unref( G_OBJECT(factory) );
        factory = NULL ;
        // TODO get hese options from user
        g_object_set (VideoSink,
                        "displayStd",   "V4L2",
                        "displayDevice","/dev/video1",
                        "videoStd",     "VGA",
                        "videoOutput",  "LCD",
                        "resizer",      FALSE,
                        "numBufs",      -1,
                        "rotation",     270,
                        "framerate",    -1,
                        "accelFrameCopy",sOpts.bFrameAcc,
                        NULL);
    }
    else
    {
        g_print ("playbin will select video sink !\n");
    }

    // usr videotestsrc if asked
    if(sOpts.bTestSink)
    {
        // Infortunately playbin doesn't work with videotestsrc so create the pipeline
        playbin = gst_pipeline_new ("pipeline");
        g_assert (playbin);
        videotestsrc = gst_element_factory_make ("videotestsrc", "videotestsrc");
        g_assert (videotestsrc);
        // for x86 arch
        if (!VideoSink)
        {
            VideoSink = gst_element_factory_make ("ximagesink", "ximagesink");
            g_assert (VideoSink);
        }
        // FIXME else ...
        // add objects to the main pipeline
        gst_bin_add_many (GST_BIN (playbin), videotestsrc, VideoSink, NULL);

        // link the elements
        gst_element_link_many (videotestsrc, VideoSink, NULL);
    }
    else
    {
        // Create the pipeline
        playbin = gst_element_factory_make ("playbin2", "playbin2");
        g_assert (playbin);
        g_object_set (G_OBJECT(playbin), "uri", sOpts.uri, NULL);
        // We are on omap TI board so setup playbin with TI video sink
        if(VideoSink)
        {
            g_object_set (G_OBJECT(playbin), "video-sink", VideoSink, NULL);
        }
    }


    // Run the pipeline
    gst_element_set_state (playbin, GST_STATE_PLAYING);

    // Run event loop listening for bus messages until EOS or ERROR
    event_loop (playbin);

    // also clean up
    g_print ("clean up before exiting!\n");
    gst_element_set_state (playbin, GST_STATE_NULL);
    gst_object_unref (GST_OBJECT (playbin));
    gst_object_unref (GST_OBJECT (VideoSink));
    delete_opts() ;
    return 0;
}


//! loop waiting for bus message
static void event_loop (GstElement * pipe)
{
    GstBus *bus = NULL ;
    GstMessage *message = NULL ;
    GError *gerror = NULL ;
    gchar *debug = NULL ;

    bus = gst_element_get_bus (GST_ELEMENT (pipe));
    while (TRUE)
    {
        message = gst_bus_poll (bus, GST_MESSAGE_ANY, -1);
        g_assert (message != NULL);
        switch (message->type)
        {
            case GST_MESSAGE_EOS:
                gst_message_unref (message);
                return;
            case GST_MESSAGE_WARNING:
            case GST_MESSAGE_ERROR:
                gst_message_parse_error (message, &gerror, &debug);
                gst_object_default_error (GST_MESSAGE_SRC (message), gerror, debug);
                gst_message_unref (message);
                g_error_free (gerror);
                g_free (debug);
                return;
            default:
                gst_message_unref (message);
            break;
        }
    }
}

//! Parse user options
static gint opt_parse(gint argc, char * argv[], T_OPTIONS * popts)
{
    gint opt = 0;
    gint ret = 0 ;
    // for option string description see help function
    while ((opt=getopt(argc, argv, "vhta:z:")) != -1)
    {
        switch(opt)
        {
            case 'v':
            case 'h':
                ret = -1 ;
                break ;
            case 'w':
                popts->bTestSink = TRUE ;
                break ;
            case 'a':
                popts->bFrameAcc = (strtol(optarg, (char**)NULL, 10) == 0) ? FALSE : TRUE ;
                break ;
            case 'z':
                popts->uri = strdup(optarg) ;
            default :
                ret = 0 ;
                break;
        }
    }
   return 0 ;
}

//! print usage
static void print_usage(const gchar * name)
{
        g_print ("Usage: %s <URI> [options]\n", name);
}

//! free options ressources
static void delete_opts(void)
{
    free(sOpts.uri) ;
}