Commit 8a551247 authored by Lori Anderson's avatar Lori Anderson

Added the ability to test two pipelines. Also added ability to create a...

Added the ability to test two pipelines.  Also added ability to create a pipeline with autoaudiosink to aid in tracking down WebKit issues.
parent d4dced07
......@@ -42,6 +42,9 @@ static char g_uri[256];
static gboolean g_use_manual_bin_pipeline = FALSE;
static gboolean g_use_manual_elements_pipeline = FALSE;
static gboolean g_use_simple_pipeline = FALSE;
static gboolean g_use_two_pipelines = FALSE;
static gboolean g_use_auto_audio = FALSE;
static gboolean g_download_buffering = FALSE;
static gboolean g_use_dtcp = FALSE;
static gboolean g_format_bytes = FALSE;
......@@ -50,6 +53,7 @@ static gboolean g_do_seek = FALSE;
static gboolean g_zero_position = FALSE;
static gboolean g_positions = FALSE;
static gboolean g_states = FALSE;
static gboolean g_test_uri_switch = FALSE;
static int g_eos_max_cnt = 1;
static int g_eos_cnt = 0;
......@@ -81,6 +85,7 @@ typedef struct _CustomData {
gboolean seek_done; /* Have we performed the seek already? */
gint64 duration; /* How long does this media last, in nanoseconds */
gdouble rate; /* current playspeed */
GstElement *pipeline_2; /* Optional second pipeline element */
} CustomData;
// Local method declarations
......@@ -96,6 +101,8 @@ static void tsdemux_cb_pad_added (GstElement *tsdemux, GstPad *pad, gpointer dat
static gboolean link_video_elements(gchar* name, GstPad* tsdemux_src_pad, GstCaps* caps);
static gboolean link_audio_elements(gchar* name, GstPad* tsdemux_src_pad, GstCaps* caps);
static GstElement* create_simple_pipeline();
static gboolean create_auto_audio_sink(GstElement* pipeline);
static gboolean enable_download_buffering(GstElement* pipeline);
static void on_source_changed(GstElement* element, GParamSpec* param, gpointer data);
......@@ -104,7 +111,8 @@ static gboolean perform_test_rate_change(CustomData* data);
static gboolean perform_test_position(CustomData* data);
static gboolean perform_test_query(CustomData* data, gint64* position, GstFormat format);
static gboolean perform_test_seek(CustomData* data, gint64 position, GstFormat format, gfloat rate);
static gboolean set_pipeline_state(CustomData* data, GstState desired_state, gint timeoutSecs);
static gboolean perform_test_states(CustomData* data);
static gboolean set_pipeline_state(GstElement* pipeline, GstState desired_state, gint timeoutSecs);
static gboolean set_new_uri(CustomData* data);
static void handle_message (CustomData *data, GstMessage *msg);
......@@ -123,6 +131,7 @@ int main(int argc, char *argv[])
data.seek_enabled = FALSE;
data.seek_done = FALSE;
data.duration = GST_CLOCK_TIME_NONE;
data.pipeline_2 = NULL;
// Assign default values
strcpy(g_host, "192.168.2.2");
......@@ -166,6 +175,13 @@ int main(int argc, char *argv[])
g_print("Creating simple pipeline\n");
data.pipeline = create_simple_pipeline();
}
else if (g_use_two_pipelines)
{
g_print("Creating first of two pipelines\n");
data.pipeline = create_playbin_pipeline();
g_print("Creating second of two pipelines\n");
data.pipeline_2 = create_playbin_pipeline();
}
else
{
g_print("Creating pipeline using playbin\n");
......@@ -182,7 +198,7 @@ int main(int argc, char *argv[])
// Start playing
g_print("Pipeline created, start playing\n");
if (!set_pipeline_state(&data, GST_STATE_PLAYING, g_state_change_timeout_secs))
if (!set_pipeline_state(data.pipeline, GST_STATE_PLAYING, g_state_change_timeout_secs))
{
g_printerr ("Unable to set the pipeline to the playing state.\n");
return -1;
......@@ -190,16 +206,39 @@ int main(int argc, char *argv[])
else
{
g_print("Pipeline in playing state\n");
}
// Print out elements in playbin
log_bin_elements(GST_BIN(data.pipeline));
// Print out elements in playbin
g_print("Elements in pipeline 1\n");
log_bin_elements(GST_BIN(data.pipeline));
// Create pipeline diagram
if (g_create_dot)
// Create pipeline diagram
if (g_create_dot)
{
g_print("Creating pipeline.dot file\n");
GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN(data.pipeline), GST_DEBUG_GRAPH_SHOW_ALL, "pipeline");
}
}
if (data.pipeline_2)
{
g_print("Creating pipeline.dot file\n");
GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN(data.pipeline), GST_DEBUG_GRAPH_SHOW_ALL, "pipeline");
if (g_wait_secs > 0)
{
g_print("Sleeping %d secs prior to setting pipeline 2 in playing state\n", g_wait_secs);
g_usleep(g_wait_secs * 1000000L);
}
if (!set_pipeline_state(data.pipeline_2, GST_STATE_PLAYING, g_state_change_timeout_secs))
{
g_printerr ("Unable to set pipeline 2 to the playing state.\n");
return -1;
}
else
{
g_print("Pipeline 2 in playing state\n");
if (data.pipeline_2)
{
g_print("Elements in pipeline 2\n");
log_bin_elements(GST_BIN(data.pipeline_2));
}
}
}
// Perform requested testing
......@@ -241,6 +280,10 @@ static void handle_message (CustomData *data, GstMessage *msg)
}
break;
case GST_MESSAGE_BUFFERING:
g_print ("Got buffering msg.\n");
break;
case GST_MESSAGE_DURATION:
// The duration has changed, mark thdata.pipeline,e current one as invalid
data->duration = GST_CLOCK_TIME_NONE;
......@@ -355,6 +398,21 @@ static gboolean process_cmd_line_args(int argc, char *argv[])
g_use_simple_pipeline = TRUE;
g_print("Set to build simplest pipeline\n");
}
else if (strstr(argv[i], "two") != NULL)
{
g_use_two_pipelines = TRUE;
g_print("Set to build two pipelines\n");
}
else if (strstr(argv[i], "auto_audio") != NULL)
{
g_use_auto_audio = TRUE;
g_print("Set to use auto audio sink\n");
}
else if (strstr(argv[i], "download_buffering") != NULL)
{
g_download_buffering = TRUE;
g_print("Set to playbin to buffer download\n");
}
else if (strstr(argv[i], "switch") != NULL)
{
g_test_uri_switch = TRUE;
......@@ -415,13 +473,20 @@ static gboolean process_cmd_line_args(int argc, char *argv[])
g_positions = TRUE;
g_print("Set to test positioning\n");
}
else if (strstr(argv[i], "states") != NULL)
{
g_states = TRUE;
g_print("Set to test state changes\n");
}
else
{
g_printerr("Invalid option: %s\n", argv[i]);
g_printerr("Usage:\n");
g_printerr("\t auto_audio \t\t create and use auto audio sink in playbin pipeline\n");
g_printerr("\t byte \t\t use byte format for query and seek\n");
g_printerr("\t changes=x \t\t where x is number of 2x increase rate changes\n");
g_printerr("\t dot \t\t generate dot file of pipeline diagram\n");
g_printerr("\t download_buffering \t\t enable playbin pipeline to buffer download\n");
g_printerr("\t dtcp \t\t indicates content is dtcp/ip encrypted\n");
g_printerr("\t file=name \t\twhere name indicates file name using path from env var\n");
g_printerr("\t host=ip \t\t addr of server\n");
......@@ -433,7 +498,9 @@ static gboolean process_cmd_line_args(int argc, char *argv[])
g_printerr("\t rate=y \t\t where y is desired rate\n");
g_printerr("\t rrid=i \t\t where i is cds recording id\n");
g_printerr("\t simple \t\t create simple pipeline rather than playbin\n");
g_printerr("\t states \t\t test state changes\n");
g_printerr("\t switch \t\t play for wait secs then switch uri\n");
g_printerr("\t two \t\t create two playbin pipelines\n");
g_printerr("\t uri=l \t\t where l is uri of desired content\n");
g_printerr("\t wait=x \t\t where x is secs\n");
g_printerr("\t zero \t\t set start position of seek to zero\n");
......@@ -475,6 +542,7 @@ static GstElement* create_playbin_pipeline()
// Register to receive playbin source signal & call get property on sourc
// to get supported playspeeds just like webkit would do
g_signal_connect(pipeline, "notify::source", G_CALLBACK(on_source_changed), pipeline);
g_signal_connect(pipeline, "message", G_CALLBACK(handle_message), pipeline);
// Uncomment this line to limit the amount of downloaded data
// NOTE: Can't set ring buffer to anything besides zero otherwise queue will not forward events
......@@ -485,6 +553,32 @@ static GstElement* create_playbin_pipeline()
//GstElement* fake_sink = gst_element_factory_make ("fakesink", "fakesink");
//g_object_set (pipeline, "audio-sink", fake_sink, NULL);
if (g_use_auto_audio)
{
if (!create_auto_audio_sink(pipeline))
{
g_printerr ("Problems creating auto audio sink\n");
return NULL;
}
else
{
g_print("Created auto audio sink\n");
}
}
if (g_download_buffering)
{
if (!enable_download_buffering(pipeline))
{
g_printerr ("Problems enabling download buffering\n");
return NULL;
}
else
{
g_print("Playbin pipeline download buffering enabled\n");
}
}
return pipeline;
}
......@@ -1230,12 +1324,12 @@ static void perform_test(CustomData* data)
g_usleep(g_wait_secs * 1000000L);
g_print("%s - Pausing pipeline for %d secs\n", __FUNCTION__, g_wait_secs);
set_pipeline_state (data, GST_STATE_PAUSED, g_state_change_timeout_secs);
set_pipeline_state (data->pipeline, GST_STATE_PAUSED, g_state_change_timeout_secs);
g_usleep(g_wait_secs * 1000000L);
g_print("%s - Resuming pipeline after %d sec pause\n", __FUNCTION__, g_wait_secs);
set_pipeline_state (data, GST_STATE_PLAYING, g_state_change_timeout_secs);
set_pipeline_state (data->pipeline, GST_STATE_PLAYING, g_state_change_timeout_secs);
}
else if (g_test_uri_switch)
{
......@@ -1251,6 +1345,10 @@ static void perform_test(CustomData* data)
{
perform_test_position(data);
}
else if (g_states)
{
perform_test_states(data);
}
// Wait until error or EOS
bus = gst_element_get_bus (data->pipeline);
......@@ -1259,7 +1357,7 @@ static void perform_test(CustomData* data)
while (!done)
{
msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE,
GST_MESSAGE_ERROR | GST_MESSAGE_EOS);
GST_MESSAGE_ERROR | GST_MESSAGE_EOS | GST_MESSAGE_BUFFERING);
if (msg != NULL)
{
g_print("%s - Received msg type: %s\n", __FUNCTION__, GST_MESSAGE_TYPE_NAME(msg));
......@@ -1364,6 +1462,62 @@ static gboolean perform_test_position(CustomData* data)
return TRUE;
}
static gboolean perform_test_states(CustomData* data)
{
int i = 0;
GstState state = GST_STATE_PAUSED;
GstState current_state = GST_STATE_PAUSED;
GstState pending_state = GST_STATE_PAUSED;
g_print("%s - Performing 5 state changes\n", __FUNCTION__);
GstStateChangeReturn ret;
for (i = 0; i < 30; i++)
{
g_print("%s - Waiting %d secs prior to changing state to %s\n",
__FUNCTION__, g_wait_secs, gst_element_state_get_name(state));
g_usleep(g_wait_secs * 1000000L);
g_print("%s - Setting pipeline state to %s\n", __FUNCTION__, gst_element_state_get_name(state));
ret = gst_element_set_state(data->pipeline, state);
//ret = gst_element_set_state(data->pipeline_2, state);
if (ret == GST_STATE_CHANGE_ASYNC)
{
g_print("%s - Waiting for async state change\n", __FUNCTION__);
ret = gst_element_get_state(data->pipeline, &current_state, &pending_state, (10 * 1000000L));
g_print("%s - Got state for async pipeline state, status: %s, current: %s, pending: %s\n", __FUNCTION__,
gst_element_state_change_return_get_name(ret), gst_element_state_get_name(current_state),
gst_element_state_get_name(pending_state));
if (ret != GST_STATE_CHANGE_SUCCESS)
{
g_printerr("%s - Async state change failed to complete\n", __FUNCTION__);
return FALSE;
}
}
else if (ret == GST_STATE_CHANGE_FAILURE)
{
g_printerr("%s - Failed to change to state %s\n",
__FUNCTION__, gst_element_state_get_name(state));
return FALSE;
}
else
{
g_print("%s - Got successful pipeline state change\n", __FUNCTION__);
}
if (state == GST_STATE_PAUSED)
{
state = GST_STATE_PLAYING;
}
else
{
state = GST_STATE_PAUSED;
}
}
return TRUE;
}
static gboolean perform_test_query(CustomData* data, gint64* position, GstFormat format)
{
g_print("%s - Query position in format: %s\n",
......@@ -1477,10 +1631,10 @@ static gboolean perform_test_seek(CustomData* data, gint64 start_position, GstFo
return TRUE;
}
static gboolean set_pipeline_state(CustomData* data, GstState desired_state, gint timeoutSecs)
static gboolean set_pipeline_state(GstElement* pipeline, GstState desired_state, gint timeoutSecs)
{
GstStateChangeReturn ret = gst_element_set_state(GST_ELEMENT(data->pipeline), desired_state);
printf("Set state returned: %d\n", ret);
GstStateChangeReturn ret = gst_element_set_state(pipeline, desired_state);
printf("Set state of pipeline returned: %d\n", ret);
if (ret == GST_STATE_CHANGE_FAILURE)
{
......@@ -1497,7 +1651,7 @@ static gboolean set_pipeline_state(CustomData* data, GstState desired_state, gin
GstState state = GST_STATE_NULL;
do
{
ret = gst_element_get_state(GST_ELEMENT(data->pipeline), // element
ret = gst_element_get_state(pipeline, // element
&state, // state
NULL, // pending
100000000LL); // timeout(1 second = 10^9 nanoseconds)
......@@ -1569,3 +1723,54 @@ static gboolean set_new_uri(CustomData* data)
}
return TRUE;
}
static gboolean create_auto_audio_sink(GstElement* pipeline)
{
GstElement* scale = gst_element_factory_make("scaletempo", 0);
if (!scale) {
g_printerr("Failed to create scaletempo");
return FALSE;
}
GstElement* convert = gst_element_factory_make("audioconvert", 0);
GstElement* resample = gst_element_factory_make("audioresample", 0);
GstElement* sink = gst_element_factory_make("autoaudiosink", 0);
GstElement* audioSink = gst_bin_new("audio-sink");
gst_bin_add_many(GST_BIN(audioSink), scale, convert, resample, sink, NULL);
if (!gst_element_link_many(scale, convert, resample, sink, NULL)) {
g_printerr("Failed to link audio sink elements");
gst_object_unref(audioSink);
return FALSE;
}
// Setup audio sink bin's input pad to be scale's sink pad
GstPad* pad = gst_element_get_static_pad(scale, "sink");
gst_element_add_pad(audioSink, gst_ghost_pad_new("sink", pad));
g_object_set(pipeline, "audio-sink", audioSink, NULL);
return TRUE;
}
typedef enum {
GST_PLAY_FLAG_VIDEO = 0x00000001,
GST_PLAY_FLAG_AUDIO = 0x00000002,
GST_PLAY_FLAG_TEXT = 0x00000004,
GST_PLAY_FLAG_VIS = 0x00000008,
GST_PLAY_FLAG_SOFT_VOLUME = 0x00000010,
GST_PLAY_FLAG_NATIVE_AUDIO = 0x00000020,
GST_PLAY_FLAG_NATIVE_VIDEO = 0x00000040,
GST_PLAY_FLAG_DOWNLOAD = 0x00000080,
GST_PLAY_FLAG_BUFFERING = 0x000000100
} GstPlayFlags;
static gboolean enable_download_buffering(GstElement* pipeline)
{
GstPlayFlags flags;
g_object_get(pipeline, "flags", &flags, NULL);
g_object_set(pipeline, "flags", flags | 0x00000080, NULL);
return TRUE;
}
......@@ -20,7 +20,7 @@ RUIH_GST_DTCP_DLL=/media/RUIH_RI_2/dtcp_greg/dtcpip_test_nodebug.so
export RUIH_GST_DTCP_KEY_STORAGE
export RUIH_GST_DTCP_DLL
#
GST_DEBUG=*:1,dlnasrc:4,souphttpsrc:4,mpeg2dec:3,tsdemux:4,mpegtsbase:4,mpegtspacketizer:4,dtcpip:5,basesrc:4
GST_DEBUG=*:1,dlnasrc:4,souphttpsrc:4,mpeg2dec:3,tsdemux:4,mpegtsbase:4,mpegtspacketizer:4,dtcpip:5,basesrc:4,GST_STATES:1
#uridecodebin:3,filesrc:5,dtcpip:4,playbin:3,passthru:1,\
#basesrc:3,pushsrc:5,baseparse:1,task:1,queue2:2,multiqueue:2,bin:1,\
#mpegtsdemux:4,xvimagesink:3,fakesink:5,structure:1,\
......@@ -35,9 +35,9 @@ export GST_DEBUG_NO_COLOR
# This doesn't seem to work here - need to export in terminal window using ./tmp as value
#export GST_DEBUG_DUMP_DOT_DIR=tmp
#
gst-git ../general host=192.168.0.106 rrid=35 wait=10 rate=2
#gst-git ../general file=clock.mpg
#gst-git ../general uri=http://10.36.32.195:80/fxi/us.ts
#gst-git ../general host=192.168.0.106 rrid=35 wait=1 rate=2 dot
#gst-git ../general file=clock.mpg two
gst-git ../general uri=http://192.168.2.16:818/tests/test.m2t auto_audio wait=5 states
#gst-git ../general uri=http://10.36.32.195/fxi/Ultimate-Stream-1280x720-5Mb-mpeg2v-ac3_0100_CC_Trim.ts
#gst-git ../general uri=http://192.168.2.16:8895/resource/1/MEDIA_ITEM/MPEG_TS_SD_KO_ISO-0/ORIGINAL
#gst-git ../general uri=http://dveo.com/downloads/TS-sample-files/San_Diego_Clip.ts
......@@ -49,5 +49,5 @@ gst-git ../general host=192.168.0.106 rrid=35 wait=10 rate=2
#
# To debug with gdb debugger, use this line
#gst-git gdb --args ../general host=192.168.2.2 rrid=19
#gst-git gdb --args ../general file=0.mpg wait=10 rate=4
#gst-git gdb --args ../general uri=http://192.168.0.106:818/tests/test.m2t
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment