mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-20 15:27:07 +00:00
configure.ac: Bump libsoup requirement as libsoup does not support async client operation prior to version 2.2.104 an...
Original commit message from CVS: Patch by: Wouter Cloetens <wouter at mind dot be> * configure.ac: Bump libsoup requirement as libsoup does not support async client operation prior to version 2.2.104 and it has some leaks. * ext/soup/gstsouphttpsrc.c: (gst_souphttp_src_class_init), (gst_souphttp_src_init), (gst_souphttp_src_dispose), (gst_souphttp_src_set_property), (gst_souphttp_src_create), (gst_souphttp_src_start), (gst_souphttp_src_stop), (gst_souphttp_src_unlock), (gst_souphttp_src_unlock_stop), (gst_souphttp_src_get_size), (soup_got_headers), (soup_got_body), (soup_finished), (soup_got_chunk), (soup_response), (soup_session_close): * ext/soup/gstsouphttpsrc.h: Implement unlock(). Picks up the size from the Content-Length header and emit a duration message. Don't leak the GMainContext object. Fixes #500099.
This commit is contained in:
parent
e8af48c02b
commit
17cd697aa0
4 changed files with 129 additions and 16 deletions
23
ChangeLog
23
ChangeLog
|
@ -1,3 +1,26 @@
|
|||
2007-11-29 Wim Taymans <wim.taymans@gmail.com>
|
||||
|
||||
Patch by: Wouter Cloetens <wouter at mind dot be>
|
||||
|
||||
* configure.ac:
|
||||
Bump libsoup requirement as libsoup does not support async client
|
||||
operation prior to version 2.2.104 and it has some leaks.
|
||||
|
||||
* ext/soup/gstsouphttpsrc.c: (gst_souphttp_src_class_init),
|
||||
(gst_souphttp_src_init), (gst_souphttp_src_dispose),
|
||||
(gst_souphttp_src_set_property), (gst_souphttp_src_create),
|
||||
(gst_souphttp_src_start), (gst_souphttp_src_stop),
|
||||
(gst_souphttp_src_unlock), (gst_souphttp_src_unlock_stop),
|
||||
(gst_souphttp_src_get_size), (soup_got_headers), (soup_got_body),
|
||||
(soup_finished), (soup_got_chunk), (soup_response),
|
||||
(soup_session_close):
|
||||
* ext/soup/gstsouphttpsrc.h:
|
||||
Implement unlock().
|
||||
Picks up the size from the Content-Length header and emit a duration
|
||||
message.
|
||||
Don't leak the GMainContext object.
|
||||
Fixes #500099.
|
||||
|
||||
2007-11-29 Wim Taymans <wim.taymans@gmail.com>
|
||||
|
||||
* ext/alsaspdif/alsaspdifsink.c: (alsaspdifsink_set_caps),
|
||||
|
|
|
@ -790,7 +790,7 @@ AG_GST_CHECK_FEATURE(NEON, [neon http client plugins], neonhttpsrc, [
|
|||
dnl *** soup ***
|
||||
translit(dnm, m, l) AM_CONDITIONAL(USE_SOUP, true)
|
||||
AG_GST_CHECK_FEATURE(SOUP, [soup http client plugins], souphttpsrc, [
|
||||
PKG_CHECK_MODULES(SOUP, libsoup-2.2, HAVE_SOUP="yes", [
|
||||
PKG_CHECK_MODULES(SOUP, libsoup-2.2 >= 2.2.104, HAVE_SOUP="yes", [
|
||||
HAVE_SOUP="no"
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
|
|
|
@ -50,11 +50,16 @@ static GstFlowReturn gst_souphttp_src_create (GstPushSrc * psrc,
|
|||
GstBuffer ** outbuf);
|
||||
static gboolean gst_souphttp_src_start (GstBaseSrc * bsrc);
|
||||
static gboolean gst_souphttp_src_stop (GstBaseSrc * bsrc);
|
||||
static gboolean gst_souphttp_src_get_size (GstBaseSrc * bsrc, guint64 * size);
|
||||
static gboolean gst_souphttp_src_unlock (GstBaseSrc * bsrc);
|
||||
static gboolean gst_souphttp_src_unlock_stop (GstBaseSrc * bsrc);
|
||||
|
||||
static gboolean gst_souphttp_src_set_location (GstSouphttpSrc * src,
|
||||
const gchar * uri);
|
||||
|
||||
static void soup_got_headers (SoupMessage * msg, GstSouphttpSrc * src);
|
||||
static void soup_finished (SoupMessage * msg, GstSouphttpSrc * src);
|
||||
static void soup_got_body (SoupMessage * msg, GstSouphttpSrc * src);
|
||||
static void soup_got_chunk (SoupMessage * msg, GstSouphttpSrc * src);
|
||||
static void soup_response (SoupMessage * msg, gpointer user_data);
|
||||
static void soup_session_close (GstSouphttpSrc * src);
|
||||
|
@ -103,6 +108,9 @@ gst_souphttp_src_class_init (GstSouphttpSrcClass * klass)
|
|||
gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_souphttp_src_start);
|
||||
gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_souphttp_src_stop);
|
||||
gstbasesrc_class->unlock = GST_DEBUG_FUNCPTR (gst_souphttp_src_unlock);
|
||||
gstbasesrc_class->unlock_stop =
|
||||
GST_DEBUG_FUNCPTR (gst_souphttp_src_unlock_stop);
|
||||
gstbasesrc_class->get_size = GST_DEBUG_FUNCPTR (gst_souphttp_src_get_size);
|
||||
|
||||
gstpushsrc_class->create = GST_DEBUG_FUNCPTR (gst_souphttp_src_create);
|
||||
|
||||
|
@ -115,9 +123,11 @@ gst_souphttp_src_init (GstSouphttpSrc * src, GstSouphttpSrcClass * g_class)
|
|||
{
|
||||
src->location = NULL;
|
||||
src->loop = NULL;
|
||||
src->context = NULL;
|
||||
src->session = NULL;
|
||||
src->msg = NULL;
|
||||
src->interrupted = FALSE;
|
||||
src->have_size = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -129,7 +139,9 @@ gst_souphttp_src_dispose (GObject * gobject)
|
|||
soup_session_close (src);
|
||||
if (src->loop) {
|
||||
g_main_loop_unref (src->loop);
|
||||
g_main_context_unref (src->context);
|
||||
src->loop = NULL;
|
||||
src->context = NULL;
|
||||
}
|
||||
if (src->location) {
|
||||
g_free (src->location);
|
||||
|
@ -202,6 +214,7 @@ gst_souphttp_src_create (GstPushSrc * psrc, GstBuffer ** outbuf)
|
|||
}
|
||||
if (!src->session) {
|
||||
GST_DEBUG_OBJECT (src, "EOS reached");
|
||||
soup_session_close (src);
|
||||
src->ret = GST_FLOW_UNEXPECTED;
|
||||
break;
|
||||
}
|
||||
|
@ -231,12 +244,10 @@ gst_souphttp_src_create (GstPushSrc * psrc, GstBuffer ** outbuf)
|
|||
return src->ret;
|
||||
}
|
||||
|
||||
/* create a socket for connecting to remote server */
|
||||
static gboolean
|
||||
gst_souphttp_src_start (GstBaseSrc * bsrc)
|
||||
{
|
||||
GstSouphttpSrc *src = GST_SOUPHTTP_SRC (bsrc);
|
||||
GMainContext *context;
|
||||
|
||||
if (!src->location) {
|
||||
GST_ELEMENT_ERROR (src, LIBRARY, INIT,
|
||||
|
@ -244,18 +255,19 @@ gst_souphttp_src_start (GstBaseSrc * bsrc)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
context = g_main_context_new ();
|
||||
src->context = g_main_context_new ();
|
||||
|
||||
src->loop = g_main_loop_new (context, TRUE);
|
||||
src->loop = g_main_loop_new (src->context, TRUE);
|
||||
if (!src->loop) {
|
||||
GST_ELEMENT_ERROR (src, LIBRARY, INIT,
|
||||
(NULL), ("Failed to start GMainLoop"));
|
||||
g_main_context_unref (src->context);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
src->session =
|
||||
soup_session_async_new_with_options (SOUP_SESSION_ASYNC_CONTEXT, context,
|
||||
NULL);
|
||||
soup_session_async_new_with_options (SOUP_SESSION_ASYNC_CONTEXT,
|
||||
src->context, NULL);
|
||||
if (!src->session) {
|
||||
GST_ELEMENT_ERROR (src, LIBRARY, INIT,
|
||||
(NULL), ("Failed to create async session"));
|
||||
|
@ -267,7 +279,12 @@ gst_souphttp_src_start (GstBaseSrc * bsrc)
|
|||
GST_ELEMENT_ERROR (src, LIBRARY, INIT, (NULL), ("Error parsing URL"));
|
||||
return FALSE;
|
||||
}
|
||||
soup_message_add_header (src->msg->request_headers, "Connection", "close");
|
||||
|
||||
g_signal_connect (src->msg, "got_headers",
|
||||
G_CALLBACK (soup_got_headers), src);
|
||||
g_signal_connect (src->msg, "got_body", G_CALLBACK (soup_got_body), src);
|
||||
g_signal_connect (src->msg, "finished", G_CALLBACK (soup_finished), src);
|
||||
g_signal_connect (src->msg, "got_chunk", G_CALLBACK (soup_got_chunk), src);
|
||||
soup_message_set_flags (src->msg, SOUP_MESSAGE_OVERWRITE_CHUNKS);
|
||||
|
||||
|
@ -298,11 +315,40 @@ gst_souphttp_src_unlock (GstBaseSrc * bsrc)
|
|||
GST_DEBUG_OBJECT (src, "unlock()");
|
||||
|
||||
src->interrupted = TRUE;
|
||||
g_main_loop_quit (src->loop);
|
||||
|
||||
if (src->loop)
|
||||
g_main_loop_quit (src->loop);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Interrupt interrupt. */
|
||||
static gboolean
|
||||
gst_souphttp_src_unlock_stop (GstBaseSrc * bsrc)
|
||||
{
|
||||
GstSouphttpSrc *src;
|
||||
|
||||
src = GST_SOUPHTTP_SRC (bsrc);
|
||||
GST_DEBUG_OBJECT (src, "unlock_stop()");
|
||||
|
||||
src->interrupted = FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_souphttp_src_get_size (GstBaseSrc * bsrc, guint64 * size)
|
||||
{
|
||||
GstSouphttpSrc *src;
|
||||
|
||||
src = GST_SOUPHTTP_SRC (bsrc);
|
||||
|
||||
if (src->have_size) {
|
||||
GST_DEBUG_OBJECT (src, "get_size() = %llu", src->content_size);
|
||||
*size = src->content_size;
|
||||
return TRUE;
|
||||
}
|
||||
GST_DEBUG_OBJECT (src, "get_size() = FALSE");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_souphttp_src_set_location (GstSouphttpSrc * src, const gchar * uri)
|
||||
{
|
||||
|
@ -315,6 +361,47 @@ gst_souphttp_src_set_location (GstSouphttpSrc * src, const gchar * uri)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
soup_got_headers (SoupMessage * msg, GstSouphttpSrc * src)
|
||||
{
|
||||
const char *value;
|
||||
|
||||
GST_DEBUG_OBJECT (src, "got headers");
|
||||
|
||||
value = soup_message_get_header (msg->response_headers, "Content-Length");
|
||||
if (value != NULL) {
|
||||
src->content_size = g_ascii_strtoull (value, NULL, 10);
|
||||
src->have_size = TRUE;
|
||||
GST_DEBUG_OBJECT (src, "size = %llu", src->content_size);
|
||||
|
||||
gst_element_post_message (GST_ELEMENT (src),
|
||||
gst_message_new_duration (GST_OBJECT (src), GST_FORMAT_BYTES,
|
||||
src->content_size));
|
||||
}
|
||||
}
|
||||
|
||||
/* Have body. Signal EOS. */
|
||||
static void
|
||||
soup_got_body (SoupMessage * msg, GstSouphttpSrc * src)
|
||||
{
|
||||
GST_DEBUG_OBJECT (src, "got body");
|
||||
src->ret = GST_FLOW_UNEXPECTED;
|
||||
if (src->loop)
|
||||
g_main_loop_quit (src->loop);
|
||||
soup_message_io_pause (msg);
|
||||
}
|
||||
|
||||
/* Finished. Signal EOS. */
|
||||
static void
|
||||
soup_finished (SoupMessage * msg, GstSouphttpSrc * src)
|
||||
{
|
||||
GST_DEBUG_OBJECT (src, "finished");
|
||||
src->ret = GST_FLOW_UNEXPECTED;
|
||||
if (src->loop)
|
||||
g_main_loop_quit (src->loop);
|
||||
soup_message_io_pause (msg);
|
||||
}
|
||||
|
||||
static void
|
||||
soup_got_chunk (SoupMessage * msg, GstSouphttpSrc * src)
|
||||
{
|
||||
|
@ -327,9 +414,10 @@ soup_got_chunk (SoupMessage * msg, GstSouphttpSrc * src)
|
|||
src->ret = gst_pad_alloc_buffer (GST_BASE_SRC_PAD (basesrc),
|
||||
basesrc->segment.last_stop, msg->response.length,
|
||||
GST_PAD_CAPS (GST_BASE_SRC_PAD (basesrc)), src->outbuf);
|
||||
if (G_LIKELY (src->ret == GST_FLOW_OK))
|
||||
if (G_LIKELY (src->ret == GST_FLOW_OK)) {
|
||||
memcpy (GST_BUFFER_DATA (*src->outbuf), msg->response.body,
|
||||
msg->response.length);
|
||||
}
|
||||
|
||||
g_main_loop_quit (src->loop);
|
||||
soup_message_io_pause (msg);
|
||||
|
@ -348,7 +436,6 @@ soup_response (SoupMessage * msg, gpointer user_data)
|
|||
static void
|
||||
soup_session_close (GstSouphttpSrc * src)
|
||||
{
|
||||
GST_DEBUG_OBJECT (src, "Connection closed");
|
||||
if (src->session) {
|
||||
soup_session_abort (src->session); /* This unrefs the message. */
|
||||
g_object_unref (src->session);
|
||||
|
|
|
@ -40,13 +40,16 @@ typedef struct _GstSouphttpSrcClass GstSouphttpSrcClass;
|
|||
struct _GstSouphttpSrc {
|
||||
GstPushSrc element;
|
||||
|
||||
gchar *location; /* Full URI. */
|
||||
GMainLoop *loop; /* Event loop. */
|
||||
SoupSession *session; /* Async context. */
|
||||
SoupMessage *msg; /* Request message. */
|
||||
gchar * location; /* Full URI. */
|
||||
GMainContext * context; /* I/O context. */
|
||||
GMainLoop * loop; /* Event loop. */
|
||||
SoupSession * session; /* Async context. */
|
||||
SoupMessage * msg; /* Request message. */
|
||||
GstFlowReturn ret; /* Return code from callback. */
|
||||
GstBuffer **outbuf; /* Return buffer allocated by callback. */
|
||||
GstBuffer ** outbuf; /* Return buffer allocated by callback. */
|
||||
gboolean interrupted; /* Signal unlock(). */
|
||||
gboolean have_size; /* Received and parsed Content-Length header. */
|
||||
guint64 content_size; /* Value of Content-Length header. */
|
||||
};
|
||||
|
||||
struct _GstSouphttpSrcClass {
|
||||
|
|
Loading…
Reference in a new issue