Commit e65665af authored by lori@rkymtnhi.com's avatar lori@rkymtnhi.com

Added another test option called "handle_buffering". This simulates what it...

Added another test option called "handle_buffering".  This simulates what it done by WebKit where it will pause the pipeline when queues drop below the lower threshold to allow enough data to get buffered.  It will resume playback when data reaches the upper threshold limit for queue.
parent c2b0fd9c
......@@ -45,6 +45,7 @@ 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_handle_buffering = FALSE;
static gboolean g_use_dtcp = FALSE;
static gboolean g_format_bytes = FALSE;
......@@ -89,6 +90,7 @@ typedef struct _CustomData {
gdouble rate; /* current playspeed */
GstElement *pipeline_2; /* Optional second pipeline element */
GMainLoop *loop; /* Main loop for testing with keyboard input */
gboolean buffering; /* Indicates if buffering data */
} CustomData;
// Local method declarations
......@@ -122,6 +124,7 @@ static gboolean set_new_uri(CustomData* data);
static void handle_message (CustomData *data, GstMessage *msg);
static gboolean handle_keyboard (GIOChannel *source, GIOCondition cond, CustomData *data);
static gboolean send_seek_event (CustomData *data);
static gboolean handle_buffering_message(CustomData *data, GstMessage *msg);
static void log_bin_elements(GstBin* bin);
static GstElement* log_element_links(GstElement* elem);
......@@ -140,6 +143,7 @@ int main(int argc, char *argv[])
data.seek_done = FALSE;
data.duration = GST_CLOCK_TIME_NONE;
data.pipeline_2 = NULL;
data.buffering = FALSE;
// Assign default values
strcpy(g_host, "192.168.2.2");
......@@ -264,6 +268,7 @@ static void handle_message (CustomData *data, GstMessage *msg)
GError *err;
gchar *debug_info;
GstState old_state, new_state, pending_state;
//g_print("Got message type: %s\n", GST_MESSAGE_TYPE_NAME (msg));
switch (GST_MESSAGE_TYPE (msg))
......@@ -289,7 +294,13 @@ static void handle_message (CustomData *data, GstMessage *msg)
break;
case GST_MESSAGE_BUFFERING:
//g_print ("Got buffering msg.\n");
if (g_handle_buffering)
{
if (!handle_buffering_message(data, msg)) {
g_printerr ("Error handling buffering message");
data->terminate = TRUE;
}
}
break;
case GST_MESSAGE_DURATION:
......@@ -317,6 +328,39 @@ static void handle_message (CustomData *data, GstMessage *msg)
}
}
static gboolean handle_buffering_message(CustomData *data, GstMessage *msg)
{
int buffering_percentage;
const GstStructure *structure;
structure = gst_message_get_structure(msg);
gst_structure_get_int(structure, "buffer-percent", &buffering_percentage);
g_print("[Buffering] Buffering: %d%%.\n", buffering_percentage);
if ((!data->buffering) && (buffering_percentage < 10)) {
g_print("[Buffering] Pausing playback to give buffering chance to catch\n");
// Change state to paused to give buffering a chance
if (!set_pipeline_state(data->pipeline, GST_STATE_PAUSED, g_state_change_timeout_secs))
{
g_printerr ("Unable to set the pipeline to the paused state.\n");
return FALSE;
}
data->buffering = TRUE;
} else if ((data->buffering) && (buffering_percentage > 90)) {
// Resume playback
g_print("[Buffering] Resuming playback since buffering caught up\n");
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 FALSE;
}
data->buffering = FALSE;
}
return TRUE;
}
/**
* Handle command line args
*/
......@@ -490,6 +534,11 @@ static gboolean process_cmd_line_args(int argc, char *argv[])
g_playspeeds = TRUE;
g_print("Set to change playspeeds from keyboard\n");
}
else if (strstr(argv[i], "handle_buffering") != NULL)
{
g_handle_buffering = TRUE;
g_print("Set to handle buffering\n");
}
else
{
g_printerr("Invalid option: %s\n", argv[i]);
......@@ -501,6 +550,7 @@ static gboolean process_cmd_line_args(int argc, char *argv[])
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 handle_buffering \t\t listen for buffering messages, changing playback state accordingly\n");
g_printerr("\t host=ip \t\t addr of server\n");
g_printerr("\t manual_uri_bin \t\t build manual pipeline using uri decode bin\n");
g_printerr("\t manual_decode_bin \t\t build manual pipeline using decode bin\n");
......@@ -1780,8 +1830,24 @@ static gboolean send_seek_event (CustomData *data) {
static gboolean set_pipeline_state(GstElement* pipeline, GstState desired_state, gint timeoutSecs)
{
GstStateChangeReturn ret = gst_element_set_state(pipeline, desired_state);
printf("Set state of pipeline returned: %d\n", ret);
GstState state = GST_STATE_PAUSED;
GstState current_state = GST_STATE_PAUSED;
GstState pending_state = GST_STATE_PAUSED;
printf("set_pipeline_state() called with state: %s\n",
gst_element_state_get_name(desired_state));
// Determine current state
GstStateChangeReturn ret = gst_element_get_state(pipeline, &current_state, &pending_state, (10 * 1000000L));
if ((desired_state == current_state ) || (desired_state == pending_state)) {
// Nothing to do already in desired state, just return
// *TODO* - what about async change???
printf("already in desired state: %s\n", gst_element_state_get_name(desired_state));
return TRUE;
}
ret = gst_element_set_state(pipeline, desired_state);
if (ret == GST_STATE_CHANGE_FAILURE)
{
......@@ -1789,13 +1855,18 @@ static gboolean set_pipeline_state(GstElement* pipeline, GstState desired_state,
gst_element_state_get_name(desired_state));
return FALSE;
}
if (ret == GST_STATE_CHANGE_ASYNC)
else if (ret == GST_STATE_CHANGE_SUCCESS)
{
printf("Successfully changed to state: %s\n", gst_element_state_get_name(desired_state));
return TRUE;
}
else if (ret == GST_STATE_CHANGE_ASYNC)
{
printf("State change is async, calling get state to wait %d secs for state\n",
timeoutSecs);
int maxCnt = timeoutSecs;
int curCnt = 0;
GstState state = GST_STATE_NULL;
state = GST_STATE_NULL;
do
{
ret = gst_element_get_state(pipeline, // element
......
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