mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-11 01:45:33 +00:00
gst/rtsp/URLS: Added some other URL.
Original commit message from CVS: * gst/rtsp/URLS: Added some other URL. * gst/rtsp/gstrtspsrc.c: (gst_rtspsrc_loop_udp), (gst_rtspsrc_handle_request), (gst_rtspsrc_send), (gst_rtspsrc_open), (gst_rtspsrc_play), (gst_rtspsrc_handle_message), (gst_rtspsrc_change_state): * gst/rtsp/gstrtspsrc.h: Work on fallback to TCP connection when the UDP socket times out. Handler server requests, just reply with OK for now. * gst/rtsp/rtspdefs.c: (rtsp_strresult): * gst/rtsp/rtspdefs.h: Added some more Real extension headers. * gst/rtsp/rtspurl.c: (rtsp_url_parse): Fix parsing of urls with a ':' that is not part of the hostname:port part of the url.
This commit is contained in:
parent
7cb2c5f8a0
commit
7accf76da8
7 changed files with 156 additions and 14 deletions
21
ChangeLog
21
ChangeLog
|
@ -1,3 +1,24 @@
|
|||
2006-10-11 Wim Taymans <wim@fluendo.com>
|
||||
|
||||
* gst/rtsp/URLS:
|
||||
Added some other URL.
|
||||
|
||||
* gst/rtsp/gstrtspsrc.c: (gst_rtspsrc_loop_udp),
|
||||
(gst_rtspsrc_handle_request), (gst_rtspsrc_send),
|
||||
(gst_rtspsrc_open), (gst_rtspsrc_play),
|
||||
(gst_rtspsrc_handle_message), (gst_rtspsrc_change_state):
|
||||
* gst/rtsp/gstrtspsrc.h:
|
||||
Work on fallback to TCP connection when the UDP socket times out.
|
||||
Handler server requests, just reply with OK for now.
|
||||
|
||||
* gst/rtsp/rtspdefs.c: (rtsp_strresult):
|
||||
* gst/rtsp/rtspdefs.h:
|
||||
Added some more Real extension headers.
|
||||
|
||||
* gst/rtsp/rtspurl.c: (rtsp_url_parse):
|
||||
Fix parsing of urls with a ':' that is not part of the hostname:port
|
||||
part of the url.
|
||||
|
||||
2006-10-11 Tim-Philipp Müller <tim at centricular dot net>
|
||||
|
||||
* gst/apetag/gsttagdemux.c: (gst_tag_demux_add_srcpad):
|
||||
|
|
|
@ -16,3 +16,4 @@ MP4V-ES/mpeg4-generic(ACC):
|
|||
|
||||
REAL:
|
||||
rtsp://213.254.239.61/farm/*/encoder/tagesschau/live1high.rm
|
||||
rtsp://64.192.137.105:554/real.amazon-de.eu2/phononet/B/0/0/0/H/W/Y/4/K/S/01.01.rm?cloakport=80,554,7070
|
||||
|
|
|
@ -95,6 +95,10 @@
|
|||
#include "gstrtspsrc.h"
|
||||
#include "sdp.h"
|
||||
|
||||
#if 0
|
||||
#define WITH_EXT_REAL
|
||||
#endif
|
||||
|
||||
#include "rtspextwms.h"
|
||||
#ifdef WITH_EXT_REAL
|
||||
#include "rtspextreal.h"
|
||||
|
@ -173,6 +177,11 @@ static void gst_rtspsrc_set_property (GObject * object, guint prop_id,
|
|||
static void gst_rtspsrc_get_property (GObject * object, guint prop_id,
|
||||
GValue * value, GParamSpec * pspec);
|
||||
|
||||
static gboolean gst_rtspsrc_open (GstRTSPSrc * src);
|
||||
static gboolean gst_rtspsrc_play (GstRTSPSrc * src);
|
||||
static gboolean gst_rtspsrc_pause (GstRTSPSrc * src);
|
||||
static gboolean gst_rtspsrc_close (GstRTSPSrc * src);
|
||||
|
||||
static gboolean gst_rtspsrc_uri_set_uri (GstURIHandler * handler,
|
||||
const gchar * uri);
|
||||
|
||||
|
@ -1207,9 +1216,12 @@ need_pause:
|
|||
static void
|
||||
gst_rtspsrc_loop_udp (GstRTSPSrc * src)
|
||||
{
|
||||
gboolean restart = FALSE;
|
||||
|
||||
GST_OBJECT_LOCK (src);
|
||||
if (src->loop_cmd == CMD_STOP)
|
||||
goto stopping;
|
||||
|
||||
while (src->loop_cmd == CMD_WAIT) {
|
||||
GST_DEBUG_OBJECT (src, "waiting");
|
||||
GST_RTSP_LOOP_WAIT (src);
|
||||
|
@ -1220,9 +1232,42 @@ gst_rtspsrc_loop_udp (GstRTSPSrc * src)
|
|||
if (src->loop_cmd == CMD_RECONNECT) {
|
||||
/* FIXME, when we get here we have to reconnect using tcp */
|
||||
src->loop_cmd = CMD_WAIT;
|
||||
restart = TRUE;
|
||||
}
|
||||
GST_OBJECT_UNLOCK (src);
|
||||
|
||||
if (restart) {
|
||||
gst_rtspsrc_pause (src);
|
||||
|
||||
if (src->task) {
|
||||
/* stop task, we cannot join as this would deadlock */
|
||||
gst_task_stop (src->task);
|
||||
/* and free the task so that _close will not stop/join it again. */
|
||||
gst_object_unref (GST_OBJECT (src->task));
|
||||
src->task = NULL;
|
||||
}
|
||||
gst_rtspsrc_close (src);
|
||||
|
||||
/* see if we have TCP left to try */
|
||||
if (src->cur_protocols & RTSP_LOWER_TRANS_TCP) {
|
||||
/* We post a warning message now to inform the user
|
||||
* that nothing happened. It's most likely a firewall thing. */
|
||||
GST_ELEMENT_WARNING (src, RESOURCE, READ, (NULL),
|
||||
("Could not receive any UDP packets for %.4f seconds, maybe your "
|
||||
"firewall is blocking it. Retrying using a TCP connection.",
|
||||
(gdouble) src->timeout / 1000000));
|
||||
/* we can try only TCP now */
|
||||
src->cur_protocols = RTSP_LOWER_TRANS_TCP;
|
||||
gst_rtspsrc_open (src);
|
||||
gst_rtspsrc_play (src);
|
||||
} else {
|
||||
src->cur_protocols = 0;
|
||||
/* no transport possible, post an error */
|
||||
GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
|
||||
("Could not receive any UDP packets for %.4f seconds, maybe your "
|
||||
"firewall is blocking it.", (gdouble) src->timeout / 1000000));
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
||||
/* ERRORS */
|
||||
|
@ -1253,6 +1298,36 @@ gst_rtspsrc_loop (GstRTSPSrc * src)
|
|||
gst_rtspsrc_loop_udp (src);
|
||||
}
|
||||
|
||||
static RTSPResult
|
||||
gst_rtspsrc_handle_request (GstRTSPSrc * src, RTSPMessage * request)
|
||||
{
|
||||
RTSPMessage response = { 0 };
|
||||
RTSPResult res;
|
||||
|
||||
res = rtsp_message_init_response (&response, RTSP_STS_OK, "OK", request);
|
||||
if (res < 0)
|
||||
goto send_error;
|
||||
|
||||
if (src->debug)
|
||||
rtsp_message_dump (&response);
|
||||
|
||||
if ((res = rtsp_connection_send (src->connection, &response)) < 0)
|
||||
goto send_error;
|
||||
|
||||
return RTSP_OK;
|
||||
|
||||
/* ERRORS */
|
||||
send_error:
|
||||
{
|
||||
gchar *str = rtsp_strresult (res);
|
||||
|
||||
GST_ELEMENT_ERROR (src, RESOURCE, WRITE, (NULL),
|
||||
("Could not send message. (%s)", str));
|
||||
g_free (str);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_rtspsrc_send:
|
||||
* @src: the rtsp source
|
||||
|
@ -1287,12 +1362,28 @@ gst_rtspsrc_send (GstRTSPSrc * src, RTSPMessage * request,
|
|||
if ((res = rtsp_connection_send (src->connection, request)) < 0)
|
||||
goto send_error;
|
||||
|
||||
next:
|
||||
if ((res = rtsp_connection_receive (src->connection, response)) < 0)
|
||||
goto receive_error;
|
||||
|
||||
if (src->debug)
|
||||
rtsp_message_dump (response);
|
||||
|
||||
switch (response->type) {
|
||||
case RTSP_MESSAGE_REQUEST:
|
||||
/* FIXME, handle server request, reply with OK, for now */
|
||||
if ((res = gst_rtspsrc_handle_request (src, response)) < 0)
|
||||
goto handle_request_failed;
|
||||
goto next;
|
||||
case RTSP_MESSAGE_RESPONSE:
|
||||
/* ok, a response is good */
|
||||
break;
|
||||
default:
|
||||
case RTSP_MESSAGE_DATA:
|
||||
/* get next response */
|
||||
goto next;
|
||||
}
|
||||
|
||||
thecode = response->type_data.response.code;
|
||||
/* if the caller wanted the result code, we store it. Else we check if it's
|
||||
* OK. */
|
||||
|
@ -1332,6 +1423,11 @@ receive_error:
|
|||
g_free (str);
|
||||
return FALSE;
|
||||
}
|
||||
handle_request_failed:
|
||||
{
|
||||
/* ERROR was posted */
|
||||
return FALSE;
|
||||
}
|
||||
error_response:
|
||||
{
|
||||
switch (response->type_data.response.code) {
|
||||
|
@ -1566,6 +1662,11 @@ gst_rtspsrc_open (GstRTSPSrc * src)
|
|||
GstRTSPStream *stream = NULL;
|
||||
gchar *respcont = NULL;
|
||||
|
||||
/* reset our state */
|
||||
src->free_channel = 0;
|
||||
src->interleaved = FALSE;
|
||||
gst_segment_init (&src->segment, GST_FORMAT_TIME);
|
||||
|
||||
/* can't continue without a valid url */
|
||||
if (G_UNLIKELY (src->url == NULL))
|
||||
goto no_url;
|
||||
|
@ -1639,7 +1740,7 @@ gst_rtspsrc_open (GstRTSPSrc * src)
|
|||
|
||||
/* we initially allow all configured lower transports. based on the
|
||||
* replies from the server we narrow them down. */
|
||||
protocols = src->protocols;
|
||||
protocols = src->cur_protocols;
|
||||
|
||||
/* setup streams */
|
||||
n_streams = sdp_message_medias_len (&sdp);
|
||||
|
@ -1952,7 +2053,7 @@ gst_rtspsrc_play (GstRTSPSrc * src)
|
|||
if (res < 0)
|
||||
goto create_request_failed;
|
||||
|
||||
rtsp_message_add_header (&request, RTSP_HDR_RANGE, "npt=0.000-");
|
||||
rtsp_message_add_header (&request, RTSP_HDR_RANGE, "npt=0-");
|
||||
|
||||
if (!gst_rtspsrc_send (src, &request, &response, NULL))
|
||||
goto send_error;
|
||||
|
@ -2051,13 +2152,6 @@ gst_rtspsrc_handle_message (GstBin * bin, GstMessage * message)
|
|||
if (gst_structure_has_name (s, "GstUDPSrcTimeout")) {
|
||||
GST_DEBUG_OBJECT (bin, "timeout on UDP port");
|
||||
gst_rtspsrc_loop_send_cmd (rtspsrc, CMD_RECONNECT);
|
||||
/* FIXME, we post an error message now to inform the user
|
||||
* that nothing happened. It's most likely a firewall thing. Ideally we
|
||||
* notify the thread and redo the setup with only TCP. */
|
||||
GST_ELEMENT_ERROR (rtspsrc, RESOURCE, READ, (NULL),
|
||||
("Could not receive any UDP packets for %.4f seconds, maybe your "
|
||||
"firewall is blocking it.",
|
||||
(gdouble) rtspsrc->timeout / 1000000));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -2080,15 +2174,13 @@ gst_rtspsrc_change_state (GstElement * element, GstStateChange transition)
|
|||
case GST_STATE_CHANGE_NULL_TO_READY:
|
||||
break;
|
||||
case GST_STATE_CHANGE_READY_TO_PAUSED:
|
||||
/* the first free channel for interleaved mode */
|
||||
rtspsrc->free_channel = 0;
|
||||
rtspsrc->interleaved = FALSE;
|
||||
gst_segment_init (&rtspsrc->segment, GST_FORMAT_TIME);
|
||||
rtspsrc->cur_protocols = rtspsrc->protocols;
|
||||
if (!gst_rtspsrc_open (rtspsrc))
|
||||
goto open_failed;
|
||||
break;
|
||||
case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
|
||||
rtsp_connection_flush (rtspsrc->connection, FALSE);
|
||||
/* copy configuerd protocols */
|
||||
gst_rtspsrc_play (rtspsrc);
|
||||
break;
|
||||
case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
|
||||
|
|
|
@ -124,14 +124,18 @@ struct _GstRTSPSrc {
|
|||
GList *streams;
|
||||
GstStructure *props;
|
||||
|
||||
/* properties */
|
||||
gchar *location;
|
||||
RTSPUrl *url;
|
||||
gchar *content_base;
|
||||
RTSPLowerTrans protocols;
|
||||
gboolean debug;
|
||||
guint retry;
|
||||
guint64 timeout;
|
||||
|
||||
/* state */
|
||||
gchar *content_base;
|
||||
RTSPLowerTrans cur_protocols;
|
||||
|
||||
/* supported methods */
|
||||
gint methods;
|
||||
|
||||
|
|
|
@ -128,7 +128,16 @@ static const gchar *rtsp_headers[] = {
|
|||
"ClientChallenge", /* ClientChallenge */
|
||||
"RealChallenge1", /* RealChallenge1 */
|
||||
"RealChallenge2", /* RealChallenge2 */
|
||||
"RealChallenge3", /* RealChallenge3 */
|
||||
"Subscribe", /* Subscribe */
|
||||
"Alert", /* Alert */
|
||||
"ClientID", /* ClientID */
|
||||
"CompanyID", /* CompanyID */
|
||||
"GUID", /* GUID */
|
||||
"RegionData", /* RegionData */
|
||||
"SupportsMaximumASMBandwidth", /* SupportsMaximumASMBandwidth */
|
||||
"Language", /* Language */
|
||||
"PlayerStarttime", /* PlayerStarttime */
|
||||
|
||||
NULL
|
||||
};
|
||||
|
|
|
@ -155,7 +155,17 @@ typedef enum {
|
|||
RTSP_HDR_CLIENT_CHALLENGE, /* ClientChallenge */
|
||||
RTSP_HDR_REAL_CHALLENGE1, /* RealChallenge1 */
|
||||
RTSP_HDR_REAL_CHALLENGE2, /* RealChallenge2 */
|
||||
RTSP_HDR_REAL_CHALLENGE3, /* RealChallenge3 */
|
||||
RTSP_HDR_SUBSCRIBE, /* Subscribe */
|
||||
RTSP_HDR_ALERT, /* Alert */
|
||||
RTSP_HDR_CLIENT_ID, /* ClientID */
|
||||
RTSP_HDR_COMPANY_ID, /* CompanyID */
|
||||
RTSP_HDR_GUID, /* GUID */
|
||||
RTSP_HDR_REGION_DATA, /* RegionData */
|
||||
RTSP_HDR_MAX_ASM_WIDTH, /* SupportsMaximumASMBandwidth */
|
||||
RTSP_HDR_LANGUAGE, /* Language */
|
||||
RTSP_HDR_PLAYER_START_TIME, /* PlayerStarttime */
|
||||
|
||||
|
||||
} RTSPHeaderField;
|
||||
|
||||
|
|
|
@ -95,6 +95,11 @@ rtsp_url_parse (const gchar * urlstr, RTSPUrl ** url)
|
|||
}
|
||||
|
||||
col = strstr (p, ":");
|
||||
/* we have a ':' and a slash but the ':' is after the slash, it's not really
|
||||
* part of the hostname */
|
||||
if (col && slash && col >= slash)
|
||||
col = NULL;
|
||||
|
||||
if (col) {
|
||||
res->host = g_strndup (p, col - p);
|
||||
p = col + 1;
|
||||
|
|
Loading…
Reference in a new issue