Commit 9e51c7a6 authored by Brendan Long's avatar Brendan Long

Merge pull request #2 from cablelabs/buffering-test

Added another test option called "handle_buffering".  This simulates wha...
parents c2b0fd9c e65665af
...@@ -45,6 +45,7 @@ static gboolean g_use_simple_pipeline = FALSE; ...@@ -45,6 +45,7 @@ static gboolean g_use_simple_pipeline = FALSE;
static gboolean g_use_two_pipelines = FALSE; static gboolean g_use_two_pipelines = FALSE;
static gboolean g_use_auto_audio = FALSE; static gboolean g_use_auto_audio = FALSE;
static gboolean g_download_buffering = FALSE; static gboolean g_download_buffering = FALSE;
static gboolean g_handle_buffering = FALSE;
static gboolean g_use_dtcp = FALSE; static gboolean g_use_dtcp = FALSE;
static gboolean g_format_bytes = FALSE; static gboolean g_format_bytes = FALSE;
...@@ -89,6 +90,7 @@ typedef struct _CustomData { ...@@ -89,6 +90,7 @@ typedef struct _CustomData {
gdouble rate; /* current playspeed */ gdouble rate; /* current playspeed */
GstElement *pipeline_2; /* Optional second pipeline element */ GstElement *pipeline_2; /* Optional second pipeline element */
GMainLoop *loop; /* Main loop for testing with keyboard input */ GMainLoop *loop; /* Main loop for testing with keyboard input */
gboolean buffering; /* Indicates if buffering data */
} CustomData; } CustomData;
// Local method declarations // Local method declarations
...@@ -122,6 +124,7 @@ static gboolean set_new_uri(CustomData* data); ...@@ -122,6 +124,7 @@ static gboolean set_new_uri(CustomData* data);
static void handle_message (CustomData *data, GstMessage *msg); static void handle_message (CustomData *data, GstMessage *msg);
static gboolean handle_keyboard (GIOChannel *source, GIOCondition cond, CustomData *data); static gboolean handle_keyboard (GIOChannel *source, GIOCondition cond, CustomData *data);
static gboolean send_seek_event (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 void log_bin_elements(GstBin* bin);
static GstElement* log_element_links(GstElement* elem); static GstElement* log_element_links(GstElement* elem);
...@@ -140,6 +143,7 @@ int main(int argc, char *argv[]) ...@@ -140,6 +143,7 @@ int main(int argc, char *argv[])
data.seek_done = FALSE; data.seek_done = FALSE;
data.duration = GST_CLOCK_TIME_NONE; data.duration = GST_CLOCK_TIME_NONE;
data.pipeline_2 = NULL; data.pipeline_2 = NULL;
data.buffering = FALSE;
// Assign default values // Assign default values
strcpy(g_host, "192.168.2.2"); strcpy(g_host, "192.168.2.2");
...@@ -264,6 +268,7 @@ static void handle_message (CustomData *data, GstMessage *msg) ...@@ -264,6 +268,7 @@ static void handle_message (CustomData *data, GstMessage *msg)
GError *err; GError *err;
gchar *debug_info; gchar *debug_info;
GstState old_state, new_state, pending_state; GstState old_state, new_state, pending_state;
//g_print("Got message type: %s\n", GST_MESSAGE_TYPE_NAME (msg)); //g_print("Got message type: %s\n", GST_MESSAGE_TYPE_NAME (msg));
switch (GST_MESSAGE_TYPE (msg)) switch (GST_MESSAGE_TYPE (msg))
...@@ -289,7 +294,13 @@ static void handle_message (CustomData *data, GstMessage *msg) ...@@ -289,7 +294,13 @@ static void handle_message (CustomData *data, GstMessage *msg)
break; break;
case GST_MESSAGE_BUFFERING: 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; break;
case GST_MESSAGE_DURATION: case GST_MESSAGE_DURATION:
...@@ -317,6 +328,39 @@ static void handle_message (CustomData *data, GstMessage *msg) ...@@ -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 * Handle command line args
*/ */
...@@ -490,6 +534,11 @@ static gboolean process_cmd_line_args(int argc, char *argv[]) ...@@ -490,6 +534,11 @@ static gboolean process_cmd_line_args(int argc, char *argv[])
g_playspeeds = TRUE; g_playspeeds = TRUE;
g_print("Set to change playspeeds from keyboard\n"); 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 else
{ {
g_printerr("Invalid option: %s\n", argv[i]); g_printerr("Invalid option: %s\n", argv[i]);
...@@ -501,6 +550,7 @@ static gboolean process_cmd_line_args(int argc, char *argv[]) ...@@ -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 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 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 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 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_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"); 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) { ...@@ -1780,8 +1830,24 @@ static gboolean send_seek_event (CustomData *data) {
static gboolean set_pipeline_state(GstElement* pipeline, GstState desired_state, gint timeoutSecs) static gboolean set_pipeline_state(GstElement* pipeline, GstState desired_state, gint timeoutSecs)
{ {
GstStateChangeReturn ret = gst_element_set_state(pipeline, desired_state); GstState state = GST_STATE_PAUSED;
printf("Set state of pipeline returned: %d\n", ret); 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) if (ret == GST_STATE_CHANGE_FAILURE)
{ {
...@@ -1789,13 +1855,18 @@ static gboolean set_pipeline_state(GstElement* pipeline, GstState desired_state, ...@@ -1789,13 +1855,18 @@ static gboolean set_pipeline_state(GstElement* pipeline, GstState desired_state,
gst_element_state_get_name(desired_state)); gst_element_state_get_name(desired_state));
return FALSE; 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", printf("State change is async, calling get state to wait %d secs for state\n",
timeoutSecs); timeoutSecs);
int maxCnt = timeoutSecs; int maxCnt = timeoutSecs;
int curCnt = 0; int curCnt = 0;
GstState state = GST_STATE_NULL; state = GST_STATE_NULL;
do do
{ {
ret = gst_element_get_state(pipeline, // element 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