Implement rest of redirection support and remove unnecessary internal buffering.
authorIlpo Ruotsalainen <ilpo.ruotsalainen@movial.fi>
Mon, 1 Dec 2008 13:48:17 +0000 (15:48 +0200)
committerIlpo Ruotsalainen <ilpo.ruotsalainen@movial.fi>
Mon, 1 Dec 2008 13:48:17 +0000 (15:48 +0200)
isatis-player/isatissrc.c
isatis-player/isatissrc.h
isatis-player/player.c
isatis-plugin/plugin.c

index 51cbfb6..fcbb5c5 100644 (file)
@@ -130,7 +130,7 @@ static gboolean gst_isatis_src_start(GstBaseSrc *bsrc)
 
        GST_DEBUG_OBJECT(src, "starting");
 
-       if (isatis_socket_send(src->socket, ISATIS_CMD_START, NULL, 0) < 0)
+       if (isatis_socket_send(src->socket, ISATIS_CMD_START, src->uri, strlen(src->uri)) < 0)
        {
                GST_ELEMENT_ERROR(src, RESOURCE, WRITE, ("Error communicating with plugin"), GST_ERROR_SYSTEM);
                return FALSE;
@@ -155,10 +155,6 @@ static gboolean gst_isatis_src_stop(GstBaseSrc *bsrc)
                return FALSE;
        }
 
-       /* Empty the buffer queue */
-       while (!g_queue_is_empty(src->buffer_queue))
-               gst_buffer_unref(g_queue_pop_head(src->buffer_queue));
-
        /* Drain messages until stopped */
        do
        {
@@ -172,84 +168,54 @@ static gboolean gst_isatis_src_stop(GstBaseSrc *bsrc)
        return TRUE;
 }
 
-static GstFlowReturn gst_isatis_src_handle_messages(GstIsatisSrc *src)
+static GstFlowReturn gst_isatis_src_create(GstPushSrc *psrc, GstBuffer **outbuf)
 {
+       GstIsatisSrc *src = GST_ISATIS_SRC(psrc);
        uint8_t msg;
        size_t datalen;
-       int i = 0;
-       gboolean got_data = FALSE;
 
-       do
+       if (src->eos)
+               return GST_FLOW_UNEXPECTED;
+
+       /* XXX Should really provide unlock method XXX */
+
+       if (isatis_socket_receive_header(src->socket, &msg, &datalen) < 0)
        {
-               if (isatis_socket_receive_header(src->socket, &msg, &datalen) < 0)
-                       goto error;
+               GST_ELEMENT_ERROR(src, RESOURCE, READ, ("Error communicating with plugin"), GST_ERROR_SYSTEM);
+               return GST_FLOW_ERROR;
+       }
 
 #ifdef SPAMMY_DEBUG
-               GST_DEBUG_OBJECT(src, "received message '%c' with %d bytes of data", msg, datalen);
+       GST_DEBUG_OBJECT(src, "received message '%c' with %d bytes of data", msg, datalen);
 #endif
 
-               switch (msg)
-               {
-                       case ISATIS_CMD_DATA:
-                               {
-                                       GstBuffer *buf = gst_buffer_new_and_alloc(datalen);
-
-                                       if (isatis_socket_receive_data(src->socket, GST_BUFFER_DATA(buf), datalen) < 0)
-                                       {
-                                               gst_buffer_unref(buf);
-                                               goto error;
-                                       }
-
-                                       g_queue_push_head(src->buffer_queue, buf);
+       switch (msg)
+       {
+               case ISATIS_CMD_DATA:
+                       {
+                               GstBuffer *buf = gst_buffer_new_and_alloc(datalen);
 
-                                       got_data = TRUE;
+                               if (isatis_socket_receive_data(src->socket, GST_BUFFER_DATA(buf), datalen) < 0)
+                               {
+                                       gst_buffer_unref(buf);
+                                       GST_ELEMENT_ERROR(src, RESOURCE, READ, ("Error communicating with plugin"), GST_ERROR_SYSTEM);
+                                       return GST_FLOW_ERROR;
                                }
-                               break;
-
-                       case ISATIS_CMD_EOS:
-                               src->eos = TRUE;
-
-                               if (got_data)
-                                       return GST_FLOW_OK;
-                               else
-                                       return GST_FLOW_UNEXPECTED;
-
-                       default:
-                               isatis_socket_receive_discard(src->socket, datalen);
 
-                               GST_ELEMENT_ERROR(src, RESOURCE, READ, ("Unexpected command from plugin"), (NULL));
-                               return GST_FLOW_ERROR;
-               }
-       }
-       while (isatis_socket_can_receive(src->socket) && i++ < 100);
-
-       return GST_FLOW_OK;
-
-error:
-       GST_ELEMENT_ERROR(src, RESOURCE, READ, ("Error communicating with plugin"), GST_ERROR_SYSTEM);
-
-       return GST_FLOW_ERROR;
-}
-
-static GstFlowReturn gst_isatis_src_create(GstPushSrc *psrc, GstBuffer **outbuf)
-{
-       GstIsatisSrc *src = GST_ISATIS_SRC(psrc);
-       GstFlowReturn ret = GST_FLOW_OK;
+                               *outbuf = buf;
+                       }
+                       break;
 
-       while (g_queue_is_empty(src->buffer_queue))
-       {
-               if (src->eos)
+               case ISATIS_CMD_EOS:
+                       src->eos = TRUE;
                        return GST_FLOW_UNEXPECTED;
 
-               GST_DEBUG_OBJECT(src, "buffer queue is empty, trying to get more");
-
-               ret = gst_isatis_src_handle_messages(src);
-               if (ret != GST_FLOW_OK)
-                       return ret;
+               default:
+                       isatis_socket_receive_discard(src->socket, datalen);
+                       GST_ELEMENT_ERROR(src, RESOURCE, READ, ("Unexpected command from plugin"), (NULL));
+                       return GST_FLOW_ERROR;
        }
 
-       *outbuf = g_queue_pop_tail(src->buffer_queue);
-
        return GST_FLOW_OK;
 }
 
@@ -260,7 +226,6 @@ static void gst_isatis_src_init(GstIsatisSrc *src, GstIsatisSrcClass *klass)
        src->socket = NULL;
        src->uri = g_strdup("");
        src->eos = FALSE;
-       src->buffer_queue = g_queue_new();
 }
 
 static void gst_isatis_src_dispose(GObject *obj)
@@ -272,10 +237,6 @@ static void gst_isatis_src_dispose(GObject *obj)
        g_free(src->uri);
        src->uri = NULL;
 
-       g_assert(g_queue_is_empty(src->buffer_queue));
-       g_queue_free(src->buffer_queue);
-       src->buffer_queue = NULL;
-
        if (src->socket)
                isatis_socket_free(src->socket);
        src->socket = NULL;
index e9780a9..61790d9 100644 (file)
@@ -49,8 +49,6 @@ struct _GstIsatisSrc
        isatis_socket *socket;
        gchar *uri;
        gboolean eos;
-
-       GQueue *buffer_queue;
 };
 
 struct _GstIsatisSrcClass
index 5946da6..826eb81 100644 (file)
@@ -23,6 +23,7 @@
 #include <gtk/gtk.h>
 #include <gdk/gdkx.h>
 #include <glib.h>
+#include <string.h>
 
 #include "isatissrc.h"
 
@@ -236,16 +237,37 @@ static void element_callback(GstBus *bus, GstMessage *message, PlayerInternal *p
        if (gst_structure_has_name(message->structure, "redirect"))
        {
                const gchar *uri;
+               gchar *new_uri = NULL;
 
                uri = gst_structure_get_string(message->structure, "new-location");
 
-               if (uri == NULL)
-               {
-                       g_debug("redirect did not contain a new location");
+               if (!uri)
                        return;
+
+               if (!gst_uri_is_valid(uri))
+               {
+                       const gchar *old_uri;
+                       gchar *sep;
+
+                       g_object_get(priv->playbin, "uri", &old_uri, NULL);
+
+                       /* Wastes a few bytes of memory but is definitely enough to contain the new URI */
+                       new_uri = malloc(strlen(old_uri) + strlen(uri) + 1);
+                       strcpy(new_uri, old_uri);
+                       sep = strrchr(new_uri, '/');
+                       strcpy(sep + 1, uri);
+
+                       uri = new_uri;
                }
 
                g_debug("redirecting to %s", uri);
+
+               stop_playback(priv);
+               g_object_set(G_OBJECT(priv->playbin), "uri", uri, NULL);
+               start_playback(priv);
+
+               if (new_uri)
+                       free(new_uri);
        }
 }
 
index 968787c..725ba9f 100644 (file)
@@ -92,7 +92,14 @@ static gboolean NPP_OnDataReady(GIOChannel *channel, GIOCondition cond, NPP inst
        {
                case ISATIS_CMD_START:
                        if (!priv->stream)
+                       {
+                               free(priv->uri);
+                               priv->uri = malloc(datalen + 1);
+                               isatis_socket_receive_data(priv->socket, priv->uri, datalen);
+                               priv->uri[datalen] = '\0';
+
                                CallNPN_GetURLProc(host_funcs.geturl, instance, priv->uri, NULL);
+                       }
                        break;
 
                case ISATIS_CMD_STOP: