mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-30 04:00:37 +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>
|
2007-11-29 Wim Taymans <wim.taymans@gmail.com>
|
||||||
|
|
||||||
* ext/alsaspdif/alsaspdifsink.c: (alsaspdifsink_set_caps),
|
* ext/alsaspdif/alsaspdifsink.c: (alsaspdifsink_set_caps),
|
||||||
|
|
|
@ -790,7 +790,7 @@ AG_GST_CHECK_FEATURE(NEON, [neon http client plugins], neonhttpsrc, [
|
||||||
dnl *** soup ***
|
dnl *** soup ***
|
||||||
translit(dnm, m, l) AM_CONDITIONAL(USE_SOUP, true)
|
translit(dnm, m, l) AM_CONDITIONAL(USE_SOUP, true)
|
||||||
AG_GST_CHECK_FEATURE(SOUP, [soup http client plugins], souphttpsrc, [
|
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"
|
HAVE_SOUP="no"
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
])
|
])
|
||||||
|
|
|
@ -50,11 +50,16 @@ static GstFlowReturn gst_souphttp_src_create (GstPushSrc * psrc,
|
||||||
GstBuffer ** outbuf);
|
GstBuffer ** outbuf);
|
||||||
static gboolean gst_souphttp_src_start (GstBaseSrc * bsrc);
|
static gboolean gst_souphttp_src_start (GstBaseSrc * bsrc);
|
||||||
static gboolean gst_souphttp_src_stop (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 (GstBaseSrc * bsrc);
|
||||||
|
static gboolean gst_souphttp_src_unlock_stop (GstBaseSrc * bsrc);
|
||||||
|
|
||||||
static gboolean gst_souphttp_src_set_location (GstSouphttpSrc * src,
|
static gboolean gst_souphttp_src_set_location (GstSouphttpSrc * src,
|
||||||
const gchar * uri);
|
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_got_chunk (SoupMessage * msg, GstSouphttpSrc * src);
|
||||||
static void soup_response (SoupMessage * msg, gpointer user_data);
|
static void soup_response (SoupMessage * msg, gpointer user_data);
|
||||||
static void soup_session_close (GstSouphttpSrc * src);
|
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->start = GST_DEBUG_FUNCPTR (gst_souphttp_src_start);
|
||||||
gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_souphttp_src_stop);
|
gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_souphttp_src_stop);
|
||||||
gstbasesrc_class->unlock = GST_DEBUG_FUNCPTR (gst_souphttp_src_unlock);
|
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);
|
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->location = NULL;
|
||||||
src->loop = NULL;
|
src->loop = NULL;
|
||||||
|
src->context = NULL;
|
||||||
src->session = NULL;
|
src->session = NULL;
|
||||||
src->msg = NULL;
|
src->msg = NULL;
|
||||||
src->interrupted = FALSE;
|
src->interrupted = FALSE;
|
||||||
|
src->have_size = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -129,7 +139,9 @@ gst_souphttp_src_dispose (GObject * gobject)
|
||||||
soup_session_close (src);
|
soup_session_close (src);
|
||||||
if (src->loop) {
|
if (src->loop) {
|
||||||
g_main_loop_unref (src->loop);
|
g_main_loop_unref (src->loop);
|
||||||
|
g_main_context_unref (src->context);
|
||||||
src->loop = NULL;
|
src->loop = NULL;
|
||||||
|
src->context = NULL;
|
||||||
}
|
}
|
||||||
if (src->location) {
|
if (src->location) {
|
||||||
g_free (src->location);
|
g_free (src->location);
|
||||||
|
@ -202,6 +214,7 @@ gst_souphttp_src_create (GstPushSrc * psrc, GstBuffer ** outbuf)
|
||||||
}
|
}
|
||||||
if (!src->session) {
|
if (!src->session) {
|
||||||
GST_DEBUG_OBJECT (src, "EOS reached");
|
GST_DEBUG_OBJECT (src, "EOS reached");
|
||||||
|
soup_session_close (src);
|
||||||
src->ret = GST_FLOW_UNEXPECTED;
|
src->ret = GST_FLOW_UNEXPECTED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -231,12 +244,10 @@ gst_souphttp_src_create (GstPushSrc * psrc, GstBuffer ** outbuf)
|
||||||
return src->ret;
|
return src->ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create a socket for connecting to remote server */
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_souphttp_src_start (GstBaseSrc * bsrc)
|
gst_souphttp_src_start (GstBaseSrc * bsrc)
|
||||||
{
|
{
|
||||||
GstSouphttpSrc *src = GST_SOUPHTTP_SRC (bsrc);
|
GstSouphttpSrc *src = GST_SOUPHTTP_SRC (bsrc);
|
||||||
GMainContext *context;
|
|
||||||
|
|
||||||
if (!src->location) {
|
if (!src->location) {
|
||||||
GST_ELEMENT_ERROR (src, LIBRARY, INIT,
|
GST_ELEMENT_ERROR (src, LIBRARY, INIT,
|
||||||
|
@ -244,18 +255,19 @@ gst_souphttp_src_start (GstBaseSrc * bsrc)
|
||||||
return FALSE;
|
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) {
|
if (!src->loop) {
|
||||||
GST_ELEMENT_ERROR (src, LIBRARY, INIT,
|
GST_ELEMENT_ERROR (src, LIBRARY, INIT,
|
||||||
(NULL), ("Failed to start GMainLoop"));
|
(NULL), ("Failed to start GMainLoop"));
|
||||||
|
g_main_context_unref (src->context);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
src->session =
|
src->session =
|
||||||
soup_session_async_new_with_options (SOUP_SESSION_ASYNC_CONTEXT, context,
|
soup_session_async_new_with_options (SOUP_SESSION_ASYNC_CONTEXT,
|
||||||
NULL);
|
src->context, NULL);
|
||||||
if (!src->session) {
|
if (!src->session) {
|
||||||
GST_ELEMENT_ERROR (src, LIBRARY, INIT,
|
GST_ELEMENT_ERROR (src, LIBRARY, INIT,
|
||||||
(NULL), ("Failed to create async session"));
|
(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"));
|
GST_ELEMENT_ERROR (src, LIBRARY, INIT, (NULL), ("Error parsing URL"));
|
||||||
return FALSE;
|
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);
|
g_signal_connect (src->msg, "got_chunk", G_CALLBACK (soup_got_chunk), src);
|
||||||
soup_message_set_flags (src->msg, SOUP_MESSAGE_OVERWRITE_CHUNKS);
|
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()");
|
GST_DEBUG_OBJECT (src, "unlock()");
|
||||||
|
|
||||||
src->interrupted = TRUE;
|
src->interrupted = TRUE;
|
||||||
|
if (src->loop)
|
||||||
g_main_loop_quit (src->loop);
|
g_main_loop_quit (src->loop);
|
||||||
|
|
||||||
return TRUE;
|
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
|
static gboolean
|
||||||
gst_souphttp_src_set_location (GstSouphttpSrc * src, const gchar * uri)
|
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;
|
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
|
static void
|
||||||
soup_got_chunk (SoupMessage * msg, GstSouphttpSrc * src)
|
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),
|
src->ret = gst_pad_alloc_buffer (GST_BASE_SRC_PAD (basesrc),
|
||||||
basesrc->segment.last_stop, msg->response.length,
|
basesrc->segment.last_stop, msg->response.length,
|
||||||
GST_PAD_CAPS (GST_BASE_SRC_PAD (basesrc)), src->outbuf);
|
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,
|
memcpy (GST_BUFFER_DATA (*src->outbuf), msg->response.body,
|
||||||
msg->response.length);
|
msg->response.length);
|
||||||
|
}
|
||||||
|
|
||||||
g_main_loop_quit (src->loop);
|
g_main_loop_quit (src->loop);
|
||||||
soup_message_io_pause (msg);
|
soup_message_io_pause (msg);
|
||||||
|
@ -348,7 +436,6 @@ soup_response (SoupMessage * msg, gpointer user_data)
|
||||||
static void
|
static void
|
||||||
soup_session_close (GstSouphttpSrc * src)
|
soup_session_close (GstSouphttpSrc * src)
|
||||||
{
|
{
|
||||||
GST_DEBUG_OBJECT (src, "Connection closed");
|
|
||||||
if (src->session) {
|
if (src->session) {
|
||||||
soup_session_abort (src->session); /* This unrefs the message. */
|
soup_session_abort (src->session); /* This unrefs the message. */
|
||||||
g_object_unref (src->session);
|
g_object_unref (src->session);
|
||||||
|
|
|
@ -41,12 +41,15 @@ struct _GstSouphttpSrc {
|
||||||
GstPushSrc element;
|
GstPushSrc element;
|
||||||
|
|
||||||
gchar * location; /* Full URI. */
|
gchar * location; /* Full URI. */
|
||||||
|
GMainContext * context; /* I/O context. */
|
||||||
GMainLoop * loop; /* Event loop. */
|
GMainLoop * loop; /* Event loop. */
|
||||||
SoupSession * session; /* Async context. */
|
SoupSession * session; /* Async context. */
|
||||||
SoupMessage * msg; /* Request message. */
|
SoupMessage * msg; /* Request message. */
|
||||||
GstFlowReturn ret; /* Return code from callback. */
|
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 interrupted; /* Signal unlock(). */
|
||||||
|
gboolean have_size; /* Received and parsed Content-Length header. */
|
||||||
|
guint64 content_size; /* Value of Content-Length header. */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstSouphttpSrcClass {
|
struct _GstSouphttpSrcClass {
|
||||||
|
|
Loading…
Reference in a new issue