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.
*/
/******************************************************************************
STDINCLUDES
******************************************************************************/
// for getopt
#include <unistd.h>
#include <stdio.h>
#include <gst/gst.h>
// for strtol
#include <stdlib.h>
// strdup
#include <string.h>
/******************************************************************************
SPECIFICINCLUDES
******************************************************************************/
/******************************************************************************
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} ;
/******************************************************************************
PROTOYPESANDMACROS
******************************************************************************/
//! 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 TIelement
GstElementFactory *factory = NULL ;
GstElement * VideoSink = NULL ;
GstElement *playbin = NULL ;
GstElement *videotestsrc = NULL ;
// program
// TODOparse 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, µ, &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 ;
// TODOget 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);
}
// FIXMEelse ...
// 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 TIboard 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:u:")) != -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 'u':
popts->uri = strdup(optarg) ;
default :
ret = -1 ;
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) ;
}