gst/rtsp/gstrtspsrc.*: Small cleanups, added documentation.
Original commit message from CVS: * gst/rtsp/gstrtspsrc.c: (gst_rtspsrc_media_to_caps), (gst_rtspsrc_send), (gst_rtspsrc_parse_methods), (gst_rtspsrc_open), (gst_rtspsrc_close), (gst_rtspsrc_play), (gst_rtspsrc_pause), (gst_rtspsrc_change_state), (gst_rtspsrc_uri_get_uri), (gst_rtspsrc_uri_set_uri): * gst/rtsp/gstrtspsrc.h: Small cleanups, added documentation. Try to clean up the requests and responses. Refactor parsing the supported methods. * gst/rtsp/rtspconnection.c: (rtsp_connection_open), (rtsp_connection_create), (rtsp_connection_send), (parse_response_status), (parse_request_line), (rtsp_connection_receive), (rtsp_connection_close), (rtsp_connection_free): * gst/rtsp/rtsptransport.c: (rtsp_transport_new), (rtsp_transport_init), (rtsp_transport_parse), (rtsp_transport_free): * gst/rtsp/rtspurl.c: (rtsp_url_parse): * gst/rtsp/sdpmessage.c: (sdp_message_new), (sdp_message_init), (sdp_message_clean), (sdp_message_free), (sdp_media_new), (sdp_media_init), (sdp_message_parse_buffer), (sdp_message_dump): Use g_return_val some more. * gst/rtsp/rtspdefs.h: Add more enum values to track initial states. * gst/rtsp/rtspmessage.c: (rtsp_message_new_request), (rtsp_message_init_request), (rtsp_message_new_response), (rtsp_message_init_response), (rtsp_message_init_data), (rtsp_message_unset), (rtsp_message_free), (rtsp_message_add_header), (rtsp_message_remove_header), (rtsp_message_get_header), (rtsp_message_set_body), (rtsp_message_take_body), (rtsp_message_get_body), (rtsp_message_steal_body), (rtsp_message_dump): * gst/rtsp/rtspmessage.h: Reorder arguments, object goes as the first one. Use g_return_val some more.
This commit is contained in:
parent
ee58147b3d
commit
a437e9f0ed
41
ChangeLog
41
ChangeLog
@ -1,3 +1,44 @@
|
||||
2006-09-18 Wim Taymans <wim@fluendo.com>
|
||||
|
||||
* gst/rtsp/gstrtspsrc.c: (gst_rtspsrc_media_to_caps),
|
||||
(gst_rtspsrc_send), (gst_rtspsrc_parse_methods),
|
||||
(gst_rtspsrc_open), (gst_rtspsrc_close), (gst_rtspsrc_play),
|
||||
(gst_rtspsrc_pause), (gst_rtspsrc_change_state),
|
||||
(gst_rtspsrc_uri_get_uri), (gst_rtspsrc_uri_set_uri):
|
||||
* gst/rtsp/gstrtspsrc.h:
|
||||
Small cleanups, added documentation.
|
||||
Try to clean up the requests and responses.
|
||||
Refactor parsing the supported methods.
|
||||
|
||||
* gst/rtsp/rtspconnection.c: (rtsp_connection_open),
|
||||
(rtsp_connection_create), (rtsp_connection_send),
|
||||
(parse_response_status), (parse_request_line),
|
||||
(rtsp_connection_receive), (rtsp_connection_close),
|
||||
(rtsp_connection_free):
|
||||
* gst/rtsp/rtsptransport.c: (rtsp_transport_new),
|
||||
(rtsp_transport_init), (rtsp_transport_parse),
|
||||
(rtsp_transport_free):
|
||||
* gst/rtsp/rtspurl.c: (rtsp_url_parse):
|
||||
* gst/rtsp/sdpmessage.c: (sdp_message_new), (sdp_message_init),
|
||||
(sdp_message_clean), (sdp_message_free), (sdp_media_new),
|
||||
(sdp_media_init), (sdp_message_parse_buffer), (sdp_message_dump):
|
||||
Use g_return_val some more.
|
||||
|
||||
* gst/rtsp/rtspdefs.h:
|
||||
Add more enum values to track initial states.
|
||||
|
||||
* gst/rtsp/rtspmessage.c: (rtsp_message_new_request),
|
||||
(rtsp_message_init_request), (rtsp_message_new_response),
|
||||
(rtsp_message_init_response), (rtsp_message_init_data),
|
||||
(rtsp_message_unset), (rtsp_message_free),
|
||||
(rtsp_message_add_header), (rtsp_message_remove_header),
|
||||
(rtsp_message_get_header), (rtsp_message_set_body),
|
||||
(rtsp_message_take_body), (rtsp_message_get_body),
|
||||
(rtsp_message_steal_body), (rtsp_message_dump):
|
||||
* gst/rtsp/rtspmessage.h:
|
||||
Reorder arguments, object goes as the first one.
|
||||
Use g_return_val some more.
|
||||
|
||||
2006-09-18 Wim Taymans <wim@fluendo.com>
|
||||
|
||||
* gst/rtsp/gstrtspsrc.c: (gst_rtspsrc_base_init),
|
||||
|
@ -354,6 +354,10 @@ G_STMT_START { \
|
||||
while (*p && g_ascii_isspace (*p)) \
|
||||
p++;
|
||||
|
||||
/* rtpmap contains:
|
||||
*
|
||||
* <payload> <encoding_name>/<clock_rate>[/<encoding_params>]
|
||||
*/
|
||||
static gboolean
|
||||
gst_rtspsrc_parse_rtpmap (gchar * rtpmap, gint * payload, gchar ** name,
|
||||
gint * rate, gchar ** params)
|
||||
@ -413,10 +417,9 @@ gst_rtspsrc_media_to_caps (SDPMedia * media)
|
||||
GstStructure *s;
|
||||
|
||||
payload = sdp_media_get_format (media, 0);
|
||||
if (payload == NULL) {
|
||||
g_warning ("payload type not given");
|
||||
return NULL;
|
||||
}
|
||||
if (payload == NULL)
|
||||
goto no_payload;
|
||||
|
||||
pt = atoi (payload);
|
||||
|
||||
/* dynamic payloads need rtpmap */
|
||||
@ -428,18 +431,18 @@ gst_rtspsrc_media_to_caps (SDPMedia * media)
|
||||
ret = gst_rtspsrc_parse_rtpmap (rtpmap, &payload, &name, &rate, ¶ms);
|
||||
if (ret) {
|
||||
if (payload != pt) {
|
||||
/* FIXME, not fatal? */
|
||||
g_warning ("rtpmap of wrong payload type");
|
||||
name = NULL;
|
||||
rate = -1;
|
||||
params = NULL;
|
||||
}
|
||||
} else {
|
||||
/* FIXME, not fatal? */
|
||||
g_warning ("error parsing rtpmap");
|
||||
}
|
||||
} else {
|
||||
g_warning ("rtpmap type not given for dynamic payload %d", pt);
|
||||
return NULL;
|
||||
}
|
||||
} else
|
||||
goto no_rtpmap;
|
||||
}
|
||||
|
||||
caps = gst_caps_new_simple ("application/x-rtp",
|
||||
@ -494,6 +497,18 @@ gst_rtspsrc_media_to_caps (SDPMedia * media)
|
||||
}
|
||||
}
|
||||
return caps;
|
||||
|
||||
/* ERRORS */
|
||||
no_payload:
|
||||
{
|
||||
g_warning ("payload type not given");
|
||||
return NULL;
|
||||
}
|
||||
no_rtpmap:
|
||||
{
|
||||
g_warning ("rtpmap type not given for dynamic payload %d", pt);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -948,29 +963,48 @@ need_pause:
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_rtspsrc_send:
|
||||
* @src: the rtsp source
|
||||
* @request: must point to a valid request
|
||||
* @response: must point to an empty #RTSPMessage
|
||||
*
|
||||
* send @request and retrieve the response in @response. optionally @code can be
|
||||
* non-NULL in which case it will contain the status code of the response.
|
||||
*
|
||||
* If This function returns TRUE, @response will contain a valid response
|
||||
* message that should be cleaned with rtsp_message_unset() after usage.
|
||||
*
|
||||
* If @code is NULL, this function will return FALSE (with an invalid @response
|
||||
* message) if the response code was not 200 (OK).
|
||||
*
|
||||
* Returns: TRUE if the processing was successful.
|
||||
*/
|
||||
static gboolean
|
||||
gst_rtspsrc_send (GstRTSPSrc * src, RTSPMessage * request,
|
||||
RTSPMessage * response, RTSPStatusCode * code)
|
||||
{
|
||||
RTSPResult res;
|
||||
RTSPStatusCode thecode;
|
||||
|
||||
if (src->debug) {
|
||||
if (src->debug)
|
||||
rtsp_message_dump (request);
|
||||
}
|
||||
|
||||
if ((res = rtsp_connection_send (src->connection, request)) < 0)
|
||||
goto send_error;
|
||||
|
||||
if ((res = rtsp_connection_receive (src->connection, response)) < 0)
|
||||
goto receive_error;
|
||||
|
||||
if (code) {
|
||||
*code = response->type_data.response.code;
|
||||
}
|
||||
|
||||
if (src->debug) {
|
||||
if (src->debug)
|
||||
rtsp_message_dump (response);
|
||||
}
|
||||
if (response->type_data.response.code != RTSP_STS_OK)
|
||||
|
||||
thecode = response->type_data.response.code;
|
||||
/* if the caller wanted the result code, we store it. Else we check if it's
|
||||
* OK. */
|
||||
if (code)
|
||||
*code = thecode;
|
||||
else if (thecode != RTSP_STS_OK)
|
||||
goto error_response;
|
||||
|
||||
return TRUE;
|
||||
@ -990,9 +1024,92 @@ receive_error:
|
||||
}
|
||||
error_response:
|
||||
{
|
||||
GST_ELEMENT_ERROR (src, RESOURCE, READ, ("Got error response: %d (%s).",
|
||||
response->type_data.response.code,
|
||||
response->type_data.response.reason), (NULL));
|
||||
switch (response->type_data.response.code) {
|
||||
case RTSP_STS_NOT_FOUND:
|
||||
GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, ("%s",
|
||||
response->type_data.response.reason), (NULL));
|
||||
break;
|
||||
default:
|
||||
GST_ELEMENT_ERROR (src, RESOURCE, READ, ("Got error response: %d (%s).",
|
||||
response->type_data.response.code,
|
||||
response->type_data.response.reason), (NULL));
|
||||
break;
|
||||
}
|
||||
/* we return FALSE so we should unset the response ourselves */
|
||||
rtsp_message_unset (response);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* parse the response and collect all the supported methods. We need this
|
||||
* information so that we don't try to send an unsupported request to the
|
||||
* server.
|
||||
*/
|
||||
static gboolean
|
||||
gst_rtspsrc_parse_methods (GstRTSPSrc * src, RTSPMessage * response)
|
||||
{
|
||||
gchar *respoptions = NULL;
|
||||
gchar **options;
|
||||
gint i;
|
||||
|
||||
/* clear supported methods */
|
||||
src->methods = 0;
|
||||
|
||||
/* Try Allow Header first */
|
||||
rtsp_message_get_header (response, RTSP_HDR_ALLOW, &respoptions);
|
||||
if (!respoptions)
|
||||
/* Then maybe Public Header... */
|
||||
rtsp_message_get_header (response, RTSP_HDR_PUBLIC, &respoptions);
|
||||
if (!respoptions) {
|
||||
/* this field is not required, assume the server supports
|
||||
* DESCRIBE and SETUP*/
|
||||
GST_DEBUG_OBJECT (src, "could not get OPTIONS");
|
||||
src->methods = RTSP_DESCRIBE | RTSP_SETUP;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* If we get here, the server gave a list of supported methods, parse
|
||||
* them here. The string is like:
|
||||
*
|
||||
* OPTIONS, DESCRIBE, ANNOUNCE, PLAY, SETUP, ...
|
||||
*/
|
||||
options = g_strsplit (respoptions, ",", 0);
|
||||
|
||||
i = 0;
|
||||
while (options[i]) {
|
||||
gchar *stripped;
|
||||
gint method;
|
||||
|
||||
stripped = g_strstrip (options[i]);
|
||||
method = rtsp_find_method (stripped);
|
||||
|
||||
/* keep bitfield of supported methods */
|
||||
if (method != -1)
|
||||
src->methods |= method;
|
||||
i++;
|
||||
}
|
||||
g_strfreev (options);
|
||||
|
||||
/* we need describe and setup */
|
||||
if (!(src->methods & RTSP_DESCRIBE))
|
||||
goto no_describe;
|
||||
if (!(src->methods & RTSP_SETUP))
|
||||
goto no_setup;
|
||||
|
||||
done:
|
||||
return TRUE;
|
||||
|
||||
/* ERRORS */
|
||||
no_describe:
|
||||
{
|
||||
GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ,
|
||||
("Server does not support DESCRIBE."), (NULL));
|
||||
return FALSE;
|
||||
}
|
||||
no_setup:
|
||||
{
|
||||
GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ,
|
||||
("Server does not support SETUP."), (NULL));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
@ -1005,11 +1122,13 @@ gst_rtspsrc_open (GstRTSPSrc * src)
|
||||
RTSPMessage response = { 0 };
|
||||
guint8 *data;
|
||||
guint size;
|
||||
gint i, n_streams;
|
||||
SDPMessage sdp = { 0 };
|
||||
GstRTSPProto protocols;
|
||||
GstRTSPStream *stream = NULL;
|
||||
|
||||
/* can't continue without a valid url */
|
||||
if (src->url == NULL)
|
||||
if (G_UNLIKELY (src->url == NULL))
|
||||
goto no_url;
|
||||
|
||||
/* open connection */
|
||||
@ -1019,7 +1138,7 @@ gst_rtspsrc_open (GstRTSPSrc * src)
|
||||
|
||||
/* create OPTIONS */
|
||||
GST_DEBUG_OBJECT (src, "create options...");
|
||||
res = rtsp_message_init_request (RTSP_OPTIONS, src->location, &request);
|
||||
res = rtsp_message_init_request (&request, RTSP_OPTIONS, src->location);
|
||||
if (res < 0)
|
||||
goto create_request_failed;
|
||||
|
||||
@ -1028,56 +1147,13 @@ gst_rtspsrc_open (GstRTSPSrc * src)
|
||||
if (!gst_rtspsrc_send (src, &request, &response, NULL))
|
||||
goto send_error;
|
||||
|
||||
{
|
||||
gchar *respoptions = NULL;
|
||||
gchar **options;
|
||||
gint i;
|
||||
|
||||
/* Try Allow Header first */
|
||||
rtsp_message_get_header (&response, RTSP_HDR_ALLOW, &respoptions);
|
||||
if (!respoptions) {
|
||||
/* Then maybe Public Header... */
|
||||
rtsp_message_get_header (&response, RTSP_HDR_PUBLIC, &respoptions);
|
||||
if (!respoptions) {
|
||||
/* this field is not required, assume the server supports
|
||||
* DESCRIBE and SETUP*/
|
||||
GST_DEBUG_OBJECT (src, "could not get OPTIONS");
|
||||
src->options = RTSP_DESCRIBE | RTSP_SETUP;
|
||||
goto no_options;
|
||||
}
|
||||
}
|
||||
|
||||
/* parse options */
|
||||
options = g_strsplit (respoptions, ",", 0);
|
||||
|
||||
i = 0;
|
||||
while (options[i]) {
|
||||
gchar *stripped;
|
||||
gint method;
|
||||
|
||||
stripped = g_strdup (options[i]);
|
||||
stripped = g_strstrip (stripped);
|
||||
method = rtsp_find_method (stripped);
|
||||
g_free (stripped);
|
||||
|
||||
/* keep bitfield of supported methods */
|
||||
if (method != -1)
|
||||
src->options |= method;
|
||||
i++;
|
||||
}
|
||||
g_strfreev (options);
|
||||
|
||||
no_options:
|
||||
/* we need describe and setup */
|
||||
if (!(src->options & RTSP_DESCRIBE))
|
||||
goto no_describe;
|
||||
if (!(src->options & RTSP_SETUP))
|
||||
goto no_setup;
|
||||
}
|
||||
/* parse OPTIONS */
|
||||
if (!gst_rtspsrc_parse_methods (src, &response))
|
||||
goto methods_error;
|
||||
|
||||
/* create DESCRIBE */
|
||||
GST_DEBUG_OBJECT (src, "create describe...");
|
||||
res = rtsp_message_init_request (RTSP_DESCRIBE, src->location, &request);
|
||||
res = rtsp_message_init_request (&request, RTSP_DESCRIBE, src->location);
|
||||
if (res < 0)
|
||||
goto create_request_failed;
|
||||
|
||||
@ -1117,134 +1193,138 @@ gst_rtspsrc_open (GstRTSPSrc * src)
|
||||
protocols = src->protocols;
|
||||
|
||||
/* setup streams */
|
||||
{
|
||||
gint i;
|
||||
n_streams = sdp_message_medias_len (&sdp);
|
||||
for (i = 0; i < n_streams; i++) {
|
||||
SDPMedia *media;
|
||||
gchar *setup_url;
|
||||
gchar *control_url;
|
||||
gchar *transports;
|
||||
|
||||
for (i = 0; i < sdp_message_medias_len (&sdp); i++) {
|
||||
SDPMedia *media;
|
||||
gchar *setup_url;
|
||||
gchar *control_url;
|
||||
gchar *transports;
|
||||
GstRTSPStream *stream;
|
||||
media = sdp_message_get_media (&sdp, i);
|
||||
|
||||
media = sdp_message_get_media (&sdp, i);
|
||||
GST_DEBUG_OBJECT (src, "setup media %d", i);
|
||||
control_url = sdp_media_get_attribute_val (media, "control");
|
||||
if (control_url == NULL) {
|
||||
GST_DEBUG_OBJECT (src, "no control url found, skipping stream %d", i);
|
||||
continue;
|
||||
}
|
||||
|
||||
stream = gst_rtspsrc_create_stream (src);
|
||||
/* check absolute/relative URL */
|
||||
/* FIXME, what if the control_url starts with a '/' or a non rtsp: protocol? */
|
||||
if (g_str_has_prefix (control_url, "rtsp://")) {
|
||||
setup_url = g_strdup (control_url);
|
||||
} else {
|
||||
setup_url = g_strdup_printf ("%s/%s", src->location, control_url);
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (src, "setup media %d", i);
|
||||
control_url = sdp_media_get_attribute_val (media, "control");
|
||||
if (control_url == NULL) {
|
||||
GST_DEBUG_OBJECT (src, "no control url found, skipping stream");
|
||||
continue;
|
||||
}
|
||||
GST_DEBUG_OBJECT (src, "setup %s", setup_url);
|
||||
|
||||
/* check absolute/relative URL */
|
||||
/* FIXME, what if the control_url starts with a '/' or a non rtsp: protocol? */
|
||||
if (g_str_has_prefix (control_url, "rtsp://")) {
|
||||
setup_url = g_strdup (control_url);
|
||||
} else {
|
||||
setup_url = g_strdup_printf ("%s/%s", src->location, control_url);
|
||||
}
|
||||
/* create SETUP request */
|
||||
res = rtsp_message_init_request (&request, RTSP_SETUP, setup_url);
|
||||
g_free (setup_url);
|
||||
if (res < 0)
|
||||
goto create_request_failed;
|
||||
|
||||
GST_DEBUG_OBJECT (src, "setup %s", setup_url);
|
||||
stream = gst_rtspsrc_create_stream (src);
|
||||
|
||||
/* create SETUP request */
|
||||
res = rtsp_message_init_request (RTSP_SETUP, setup_url, &request);
|
||||
g_free (setup_url);
|
||||
if (res < 0)
|
||||
goto create_request_failed;
|
||||
transports = g_strdup ("");
|
||||
if (protocols & GST_RTSP_PROTO_UDP_UNICAST) {
|
||||
gchar *new;
|
||||
gint rtpport, rtcpport;
|
||||
gchar *trxparams;
|
||||
|
||||
transports = g_strdup ("");
|
||||
if (protocols & GST_RTSP_PROTO_UDP_UNICAST) {
|
||||
gchar *new;
|
||||
gint rtpport, rtcpport;
|
||||
gchar *trxparams;
|
||||
/* allocate two UDP ports */
|
||||
if (!gst_rtspsrc_stream_setup_rtp (stream, media, &rtpport, &rtcpport))
|
||||
goto setup_rtp_failed;
|
||||
|
||||
/* allocate two UDP ports */
|
||||
if (!gst_rtspsrc_stream_setup_rtp (stream, media, &rtpport, &rtcpport))
|
||||
goto setup_rtp_failed;
|
||||
GST_DEBUG_OBJECT (src, "setting up RTP ports %d-%d", rtpport, rtcpport);
|
||||
|
||||
GST_DEBUG_OBJECT (src, "setting up RTP ports %d-%d", rtpport, rtcpport);
|
||||
|
||||
trxparams = g_strdup_printf ("client_port=%d-%d", rtpport, rtcpport);
|
||||
new = g_strconcat (transports, "RTP/AVP/UDP;unicast;", trxparams, NULL);
|
||||
g_free (trxparams);
|
||||
g_free (transports);
|
||||
transports = new;
|
||||
}
|
||||
if (protocols & GST_RTSP_PROTO_UDP_MULTICAST) {
|
||||
gchar *new;
|
||||
|
||||
GST_DEBUG_OBJECT (src, "setting up MULTICAST");
|
||||
|
||||
/* we don't hav to allocate any UDP ports yet, if the selected transport
|
||||
* turns out to be multicast we can create them and join the multicast
|
||||
* group indicated in the transport reply */
|
||||
new =
|
||||
g_strconcat (transports, transports[0] ? "," : "",
|
||||
"RTP/AVP/UDP;multicast", NULL);
|
||||
g_free (transports);
|
||||
transports = new;
|
||||
}
|
||||
if (protocols & GST_RTSP_PROTO_TCP) {
|
||||
gchar *new;
|
||||
|
||||
GST_DEBUG_OBJECT (src, "setting up TCP");
|
||||
|
||||
new =
|
||||
g_strconcat (transports, transports[0] ? "," : "", "RTP/AVP/TCP",
|
||||
NULL);
|
||||
g_free (transports);
|
||||
transports = new;
|
||||
}
|
||||
|
||||
/* select transport, copy is made when adding to header */
|
||||
rtsp_message_add_header (&request, RTSP_HDR_TRANSPORT, transports);
|
||||
trxparams = g_strdup_printf ("client_port=%d-%d", rtpport, rtcpport);
|
||||
new = g_strconcat (transports, "RTP/AVP/UDP;unicast;", trxparams, NULL);
|
||||
g_free (trxparams);
|
||||
g_free (transports);
|
||||
transports = new;
|
||||
}
|
||||
if (protocols & GST_RTSP_PROTO_UDP_MULTICAST) {
|
||||
gchar *new;
|
||||
|
||||
if (!gst_rtspsrc_send (src, &request, &response, NULL))
|
||||
goto send_error;
|
||||
GST_DEBUG_OBJECT (src, "setting up MULTICAST");
|
||||
|
||||
/* parse response transport */
|
||||
{
|
||||
gchar *resptrans = NULL;
|
||||
RTSPTransport transport = { 0 };
|
||||
/* we don't hav to allocate any UDP ports yet, if the selected transport
|
||||
* turns out to be multicast we can create them and join the multicast
|
||||
* group indicated in the transport reply */
|
||||
new =
|
||||
g_strconcat (transports, transports[0] ? "," : "",
|
||||
"RTP/AVP/UDP;multicast", NULL);
|
||||
g_free (transports);
|
||||
transports = new;
|
||||
}
|
||||
if (protocols & GST_RTSP_PROTO_TCP) {
|
||||
gchar *new;
|
||||
|
||||
rtsp_message_get_header (&response, RTSP_HDR_TRANSPORT, &resptrans);
|
||||
if (!resptrans)
|
||||
goto no_transport;
|
||||
GST_DEBUG_OBJECT (src, "setting up TCP");
|
||||
|
||||
/* parse transport */
|
||||
rtsp_transport_parse (resptrans, &transport);
|
||||
new =
|
||||
g_strconcat (transports, transports[0] ? "," : "", "RTP/AVP/TCP",
|
||||
NULL);
|
||||
g_free (transports);
|
||||
transports = new;
|
||||
}
|
||||
|
||||
/* update allowed transports for other streams. once the transport of
|
||||
* one stream has been determined, we make sure that all other streams
|
||||
* are configured in the same way */
|
||||
if (transport.lower_transport == RTSP_LOWER_TRANS_TCP) {
|
||||
GST_DEBUG_OBJECT (src, "stream %d as TCP", i);
|
||||
protocols = GST_RTSP_PROTO_TCP;
|
||||
src->interleaved = TRUE;
|
||||
/* select transport, copy is made when adding to header */
|
||||
rtsp_message_add_header (&request, RTSP_HDR_TRANSPORT, transports);
|
||||
g_free (transports);
|
||||
|
||||
if (!gst_rtspsrc_send (src, &request, &response, NULL))
|
||||
goto send_error;
|
||||
|
||||
/* parse response transport */
|
||||
{
|
||||
gchar *resptrans = NULL;
|
||||
RTSPTransport transport = { 0 };
|
||||
|
||||
rtsp_message_get_header (&response, RTSP_HDR_TRANSPORT, &resptrans);
|
||||
if (!resptrans)
|
||||
goto no_transport;
|
||||
|
||||
/* parse transport */
|
||||
rtsp_transport_parse (resptrans, &transport);
|
||||
|
||||
/* update allowed transports for other streams. once the transport of
|
||||
* one stream has been determined, we make sure that all other streams
|
||||
* are configured in the same way */
|
||||
if (transport.lower_transport == RTSP_LOWER_TRANS_TCP) {
|
||||
GST_DEBUG_OBJECT (src, "stream %d as TCP", i);
|
||||
protocols = GST_RTSP_PROTO_TCP;
|
||||
src->interleaved = TRUE;
|
||||
} else {
|
||||
if (transport.multicast) {
|
||||
/* only allow multicast for other streams */
|
||||
GST_DEBUG_OBJECT (src, "stream %d as MULTICAST", i);
|
||||
protocols = GST_RTSP_PROTO_UDP_MULTICAST;
|
||||
} else {
|
||||
if (transport.multicast) {
|
||||
/* only allow multicast for other streams */
|
||||
GST_DEBUG_OBJECT (src, "stream %d as MULTICAST", i);
|
||||
protocols = GST_RTSP_PROTO_UDP_MULTICAST;
|
||||
} else {
|
||||
/* only allow unicast for other streams */
|
||||
GST_DEBUG_OBJECT (src, "stream %d as UNICAST", i);
|
||||
protocols = GST_RTSP_PROTO_UDP_UNICAST;
|
||||
}
|
||||
/* only allow unicast for other streams */
|
||||
GST_DEBUG_OBJECT (src, "stream %d as UNICAST", i);
|
||||
protocols = GST_RTSP_PROTO_UDP_UNICAST;
|
||||
}
|
||||
/* now configure the stream with the transport */
|
||||
if (!gst_rtspsrc_stream_configure_transport (stream, media, &transport)) {
|
||||
GST_DEBUG_OBJECT (src,
|
||||
"could not configure stream transport, skipping stream");
|
||||
}
|
||||
/* clean up our transport struct */
|
||||
rtsp_transport_init (&transport);
|
||||
}
|
||||
/* now configure the stream with the transport */
|
||||
if (!gst_rtspsrc_stream_configure_transport (stream, media, &transport)) {
|
||||
GST_DEBUG_OBJECT (src,
|
||||
"could not configure stream %d transport, skipping stream", i);
|
||||
}
|
||||
/* clean up our transport struct */
|
||||
rtsp_transport_init (&transport);
|
||||
}
|
||||
}
|
||||
/* if we got here all was configured. We have dynamic pads so we notify that
|
||||
* we are done */
|
||||
gst_element_no_more_pads (GST_ELEMENT_CAST (src));
|
||||
|
||||
/* clean up any messages */
|
||||
rtsp_message_unset (&request);
|
||||
rtsp_message_unset (&response);
|
||||
|
||||
return TRUE;
|
||||
|
||||
/* ERRORS */
|
||||
@ -1252,53 +1332,53 @@ no_url:
|
||||
{
|
||||
GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND,
|
||||
("No valid RTSP url was provided"), (NULL));
|
||||
return FALSE;
|
||||
goto cleanup_error;
|
||||
}
|
||||
could_not_open:
|
||||
{
|
||||
GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ_WRITE,
|
||||
("Could not open connection."), (NULL));
|
||||
return FALSE;
|
||||
goto cleanup_error;
|
||||
}
|
||||
create_request_failed:
|
||||
{
|
||||
GST_ELEMENT_ERROR (src, LIBRARY, INIT,
|
||||
("Could not create request."), (NULL));
|
||||
return FALSE;
|
||||
goto cleanup_error;
|
||||
}
|
||||
send_error:
|
||||
{
|
||||
GST_ELEMENT_ERROR (src, RESOURCE, WRITE,
|
||||
("Could not send message."), (NULL));
|
||||
return FALSE;
|
||||
goto cleanup_error;
|
||||
}
|
||||
no_describe:
|
||||
methods_error:
|
||||
{
|
||||
GST_ELEMENT_ERROR (src, RESOURCE, WRITE,
|
||||
("Server does not support DESCRIBE."), (NULL));
|
||||
return FALSE;
|
||||
}
|
||||
no_setup:
|
||||
{
|
||||
GST_ELEMENT_ERROR (src, RESOURCE, WRITE,
|
||||
("Server does not support SETUP."), (NULL));
|
||||
return FALSE;
|
||||
/* error was posted */
|
||||
goto cleanup_error;
|
||||
}
|
||||
wrong_content_type:
|
||||
{
|
||||
GST_ELEMENT_ERROR (src, RESOURCE, WRITE,
|
||||
GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS,
|
||||
("Server does not support SDP."), (NULL));
|
||||
return FALSE;
|
||||
goto cleanup_error;
|
||||
}
|
||||
setup_rtp_failed:
|
||||
{
|
||||
GST_ELEMENT_ERROR (src, RESOURCE, WRITE, ("Could not setup rtp."), (NULL));
|
||||
return FALSE;
|
||||
GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS, ("Could not setup rtp."),
|
||||
(NULL));
|
||||
goto cleanup_error;
|
||||
}
|
||||
no_transport:
|
||||
{
|
||||
GST_ELEMENT_ERROR (src, RESOURCE, WRITE,
|
||||
GST_ELEMENT_ERROR (src, RESOURCE, SETTINGS,
|
||||
("Server did not select transport."), (NULL));
|
||||
goto cleanup_error;
|
||||
}
|
||||
cleanup_error:
|
||||
{
|
||||
rtsp_message_unset (&request);
|
||||
rtsp_message_unset (&response);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
@ -1328,14 +1408,18 @@ gst_rtspsrc_close (GstRTSPSrc * src)
|
||||
src->task = NULL;
|
||||
}
|
||||
|
||||
if (src->options & RTSP_PLAY) {
|
||||
if (src->methods & RTSP_PLAY) {
|
||||
/* do TEARDOWN */
|
||||
res = rtsp_message_init_request (RTSP_TEARDOWN, src->location, &request);
|
||||
res = rtsp_message_init_request (&request, RTSP_TEARDOWN, src->location);
|
||||
if (res < 0)
|
||||
goto create_request_failed;
|
||||
|
||||
if (!gst_rtspsrc_send (src, &request, &response, NULL))
|
||||
goto send_error;
|
||||
|
||||
/* FIXME, parse result? */
|
||||
rtsp_message_unset (&request);
|
||||
rtsp_message_unset (&response);
|
||||
}
|
||||
|
||||
/* close connection */
|
||||
@ -1354,6 +1438,7 @@ create_request_failed:
|
||||
}
|
||||
send_error:
|
||||
{
|
||||
rtsp_message_unset (&request);
|
||||
GST_ELEMENT_ERROR (src, RESOURCE, WRITE,
|
||||
("Could not send message."), (NULL));
|
||||
return FALSE;
|
||||
@ -1372,13 +1457,13 @@ gst_rtspsrc_play (GstRTSPSrc * src)
|
||||
RTSPMessage response = { 0 };
|
||||
RTSPResult res;
|
||||
|
||||
if (!(src->options & RTSP_PLAY))
|
||||
if (!(src->methods & RTSP_PLAY))
|
||||
return TRUE;
|
||||
|
||||
GST_DEBUG_OBJECT (src, "PLAY...");
|
||||
|
||||
/* do play */
|
||||
res = rtsp_message_init_request (RTSP_PLAY, src->location, &request);
|
||||
res = rtsp_message_init_request (&request, RTSP_PLAY, src->location);
|
||||
if (res < 0)
|
||||
goto create_request_failed;
|
||||
|
||||
@ -1387,10 +1472,16 @@ gst_rtspsrc_play (GstRTSPSrc * src)
|
||||
if (!gst_rtspsrc_send (src, &request, &response, NULL))
|
||||
goto send_error;
|
||||
|
||||
rtsp_message_unset (&request);
|
||||
rtsp_message_unset (&response);
|
||||
|
||||
/* for interleaved transport, we receive the data on the RTSP connection
|
||||
* instead of UDP. We start a task to select and read from that connection. */
|
||||
if (src->interleaved) {
|
||||
src->task = gst_task_create ((GstTaskFunction) gst_rtspsrc_loop, src);
|
||||
|
||||
gst_task_set_lock (src->task, src->stream_rec_lock);
|
||||
src->running = TRUE;
|
||||
gst_task_start (src->task);
|
||||
}
|
||||
|
||||
@ -1405,6 +1496,7 @@ create_request_failed:
|
||||
}
|
||||
send_error:
|
||||
{
|
||||
rtsp_message_unset (&request);
|
||||
GST_ELEMENT_ERROR (src, RESOURCE, WRITE,
|
||||
("Could not send message."), (NULL));
|
||||
return FALSE;
|
||||
@ -1418,18 +1510,21 @@ gst_rtspsrc_pause (GstRTSPSrc * src)
|
||||
RTSPMessage response = { 0 };
|
||||
RTSPResult res;
|
||||
|
||||
if (!(src->options & RTSP_PAUSE))
|
||||
if (!(src->methods & RTSP_PAUSE))
|
||||
return TRUE;
|
||||
|
||||
GST_DEBUG_OBJECT (src, "PAUSE...");
|
||||
/* do pause */
|
||||
res = rtsp_message_init_request (RTSP_PAUSE, src->location, &request);
|
||||
res = rtsp_message_init_request (&request, RTSP_PAUSE, src->location);
|
||||
if (res < 0)
|
||||
goto create_request_failed;
|
||||
|
||||
if (!gst_rtspsrc_send (src, &request, &response, NULL))
|
||||
goto send_error;
|
||||
|
||||
rtsp_message_unset (&request);
|
||||
rtsp_message_unset (&response);
|
||||
|
||||
return TRUE;
|
||||
|
||||
/* ERRORS */
|
||||
@ -1441,6 +1536,7 @@ create_request_failed:
|
||||
}
|
||||
send_error:
|
||||
{
|
||||
rtsp_message_unset (&request);
|
||||
GST_ELEMENT_ERROR (src, RESOURCE, WRITE,
|
||||
("Could not send message."), (NULL));
|
||||
return FALSE;
|
||||
@ -1461,7 +1557,7 @@ gst_rtspsrc_change_state (GstElement * element, GstStateChange transition)
|
||||
break;
|
||||
case GST_STATE_CHANGE_READY_TO_PAUSED:
|
||||
rtspsrc->interleaved = FALSE;
|
||||
rtspsrc->options = 0;
|
||||
gst_segment_init (&rtspsrc->segment, GST_FORMAT_TIME);
|
||||
if (!gst_rtspsrc_open (rtspsrc))
|
||||
goto open_failed;
|
||||
break;
|
||||
@ -1521,6 +1617,7 @@ gst_rtspsrc_uri_get_uri (GstURIHandler * handler)
|
||||
{
|
||||
GstRTSPSrc *src = GST_RTSPSRC (handler);
|
||||
|
||||
/* should not dup */
|
||||
return src->location;
|
||||
}
|
||||
|
||||
@ -1560,8 +1657,8 @@ was_ok:
|
||||
}
|
||||
parse_error:
|
||||
{
|
||||
GST_ERROR_OBJECT (src, "Not a valid RTSP url '%s' (%d)", GST_STR_NULL (uri),
|
||||
res);
|
||||
GST_ERROR_OBJECT (src, "Not a valid RTSP url '%s' (%d)",
|
||||
GST_STR_NULL (uri), res);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -103,8 +103,8 @@ struct _GstRTSPSrc {
|
||||
guint retry;
|
||||
|
||||
GstRTSPProto protocols;
|
||||
/* supported options */
|
||||
gint options;
|
||||
/* supported methods */
|
||||
gint methods;
|
||||
|
||||
RTSPConnection *connection;
|
||||
RTSPMessage *request;
|
||||
|
@ -71,8 +71,8 @@ rtsp_connection_open (RTSPUrl * url, RTSPConnection ** conn)
|
||||
struct in_addr addr;
|
||||
gint ret;
|
||||
|
||||
if (url == NULL || conn == NULL)
|
||||
return RTSP_EINVAL;
|
||||
g_return_val_if_fail (url != NULL, RTSP_EINVAL);
|
||||
g_return_val_if_fail (conn != NULL, RTSP_EINVAL);
|
||||
|
||||
if (url->protocol != RTSP_PROTO_TCP)
|
||||
return RTSP_ENOTIMPL;
|
||||
@ -128,6 +128,8 @@ rtsp_connection_create (gint fd, RTSPConnection ** conn)
|
||||
{
|
||||
RTSPConnection *newconn;
|
||||
|
||||
g_return_val_if_fail (conn != NULL, RTSP_EINVAL);
|
||||
|
||||
/* FIXME check fd, must be connected SOCK_STREAM */
|
||||
|
||||
newconn = g_new (RTSPConnection, 1);
|
||||
@ -157,8 +159,8 @@ rtsp_connection_send (RTSPConnection * conn, RTSPMessage * message)
|
||||
gint towrite;
|
||||
gchar *data;
|
||||
|
||||
if (conn == NULL || message == NULL)
|
||||
return RTSP_EINVAL;
|
||||
g_return_val_if_fail (conn != NULL, RTSP_EINVAL);
|
||||
g_return_val_if_fail (message != NULL, RTSP_EINVAL);
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
WSADATA w;
|
||||
@ -333,7 +335,7 @@ parse_response_status (gchar * buffer, RTSPMessage * msg)
|
||||
while (g_ascii_isspace (*bptr))
|
||||
bptr++;
|
||||
|
||||
rtsp_message_init_response (code, bptr, NULL, msg);
|
||||
rtsp_message_init_response (msg, code, bptr, NULL);
|
||||
|
||||
return RTSP_OK;
|
||||
|
||||
@ -365,7 +367,7 @@ parse_request_line (gchar * buffer, RTSPMessage * msg)
|
||||
if (strcmp (versionstr, "RTSP/1.0") != 0)
|
||||
goto wrong_version;
|
||||
|
||||
rtsp_message_init_request (method, urlstr, msg);
|
||||
rtsp_message_init_request (msg, method, urlstr);
|
||||
|
||||
return RTSP_OK;
|
||||
|
||||
@ -456,8 +458,8 @@ rtsp_connection_receive (RTSPConnection * conn, RTSPMessage * msg)
|
||||
RTSPResult res;
|
||||
gboolean need_body;
|
||||
|
||||
if (conn == NULL || msg == NULL)
|
||||
return RTSP_EINVAL;
|
||||
g_return_val_if_fail (conn != NULL, RTSP_EINVAL);
|
||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||
|
||||
line = 0;
|
||||
|
||||
@ -490,7 +492,7 @@ rtsp_connection_receive (RTSPConnection * conn, RTSPMessage * msg)
|
||||
goto error;
|
||||
|
||||
/* now we create a data message */
|
||||
rtsp_message_init_data ((gint) c, msg);
|
||||
rtsp_message_init_data (msg, (gint) c);
|
||||
|
||||
/* next two bytes are the length of the data */
|
||||
ret = read (conn->fd, &size, 2);
|
||||
@ -590,8 +592,7 @@ rtsp_connection_close (RTSPConnection * conn)
|
||||
{
|
||||
gint res;
|
||||
|
||||
if (conn == NULL)
|
||||
return RTSP_EINVAL;
|
||||
g_return_val_if_fail (conn != NULL, RTSP_EINVAL);
|
||||
|
||||
res = CLOSE_SOCKET (conn->fd);
|
||||
#ifdef G_OS_WIN32
|
||||
@ -612,8 +613,7 @@ sys_error:
|
||||
RTSPResult
|
||||
rtsp_connection_free (RTSPConnection * conn)
|
||||
{
|
||||
if (conn == NULL)
|
||||
return RTSP_EINVAL;
|
||||
g_return_val_if_fail (conn != NULL, RTSP_EINVAL);
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
WSACleanup ();
|
||||
|
@ -50,6 +50,7 @@ typedef enum {
|
||||
} RTSPFamily;
|
||||
|
||||
typedef enum {
|
||||
RTSP_STATE_INVALID,
|
||||
RTSP_STATE_INIT,
|
||||
RTSP_STATE_READY,
|
||||
RTSP_STATE_PLAYING,
|
||||
@ -57,6 +58,7 @@ typedef enum {
|
||||
} RTSPState;
|
||||
|
||||
typedef enum {
|
||||
RTSP_INVALID = 0,
|
||||
RTSP_DESCRIBE = (1 << 0),
|
||||
RTSP_ANNOUNCE = (1 << 1),
|
||||
RTSP_GET_PARAMETER = (1 << 2),
|
||||
@ -120,6 +122,7 @@ typedef enum {
|
||||
} RTSPHeaderField;
|
||||
|
||||
typedef enum {
|
||||
RTSP_STS_INVALID = 0,
|
||||
RTSP_STS_CONTINUE = 100,
|
||||
RTSP_STS_OK = 200,
|
||||
RTSP_STS_CREATED = 201,
|
||||
|
@ -20,84 +20,69 @@
|
||||
#include "rtspmessage.h"
|
||||
|
||||
RTSPResult
|
||||
rtsp_message_new_request (RTSPMethod method, gchar * uri, RTSPMessage ** msg)
|
||||
rtsp_message_new_request (RTSPMessage ** msg, RTSPMethod method, gchar * uri)
|
||||
{
|
||||
RTSPMessage *newmsg;
|
||||
|
||||
if (msg == NULL || uri == NULL)
|
||||
return RTSP_EINVAL;
|
||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||
g_return_val_if_fail (uri != NULL, RTSP_EINVAL);
|
||||
|
||||
newmsg = g_new0 (RTSPMessage, 1);
|
||||
|
||||
*msg = newmsg;
|
||||
|
||||
return rtsp_message_init_request (method, uri, newmsg);
|
||||
return rtsp_message_init_request (newmsg, method, uri);
|
||||
}
|
||||
|
||||
RTSPResult
|
||||
rtsp_message_init_request (RTSPMethod method, gchar * uri, RTSPMessage * msg)
|
||||
rtsp_message_init_request (RTSPMessage * msg, RTSPMethod method, gchar * uri)
|
||||
{
|
||||
if (msg == NULL || uri == NULL)
|
||||
return RTSP_EINVAL;
|
||||
g_return_val_if_fail (uri != NULL, RTSP_EINVAL);
|
||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||
|
||||
rtsp_message_unset (msg);
|
||||
|
||||
msg->type = RTSP_MESSAGE_REQUEST;
|
||||
msg->type_data.request.method = method;
|
||||
g_free (msg->type_data.request.uri);
|
||||
msg->type_data.request.uri = g_strdup (uri);
|
||||
|
||||
if (msg->hdr_fields != NULL)
|
||||
g_hash_table_destroy (msg->hdr_fields);
|
||||
msg->hdr_fields =
|
||||
g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free);
|
||||
|
||||
if (msg->body) {
|
||||
g_free (msg->body);
|
||||
msg->body = NULL;
|
||||
}
|
||||
msg->body_size = 0;
|
||||
|
||||
return RTSP_OK;
|
||||
}
|
||||
|
||||
RTSPResult
|
||||
rtsp_message_new_response (RTSPStatusCode code, gchar * reason,
|
||||
RTSPMessage * request, RTSPMessage ** msg)
|
||||
rtsp_message_new_response (RTSPMessage ** msg, RTSPStatusCode code,
|
||||
gchar * reason, RTSPMessage * request)
|
||||
{
|
||||
RTSPMessage *newmsg;
|
||||
|
||||
if (msg == NULL || reason == NULL || request == NULL)
|
||||
return RTSP_EINVAL;
|
||||
g_return_val_if_fail (reason != NULL, RTSP_EINVAL);
|
||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||
g_return_val_if_fail (request != NULL, RTSP_EINVAL);
|
||||
|
||||
newmsg = g_new0 (RTSPMessage, 1);
|
||||
|
||||
*msg = newmsg;
|
||||
|
||||
return rtsp_message_init_response (code, reason, request, newmsg);
|
||||
return rtsp_message_init_response (newmsg, code, reason, request);
|
||||
}
|
||||
|
||||
RTSPResult
|
||||
rtsp_message_init_response (RTSPStatusCode code, gchar * reason,
|
||||
RTSPMessage * request, RTSPMessage * msg)
|
||||
rtsp_message_init_response (RTSPMessage * msg, RTSPStatusCode code,
|
||||
gchar * reason, RTSPMessage * request)
|
||||
{
|
||||
if (reason == NULL || msg == NULL)
|
||||
return RTSP_EINVAL;
|
||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||
g_return_val_if_fail (reason != NULL, RTSP_EINVAL);
|
||||
|
||||
rtsp_message_unset (msg);
|
||||
|
||||
msg->type = RTSP_MESSAGE_RESPONSE;
|
||||
msg->type_data.response.code = code;
|
||||
g_free (msg->type_data.response.reason);
|
||||
msg->type_data.response.reason = g_strdup (reason);
|
||||
|
||||
if (msg->hdr_fields != NULL)
|
||||
g_hash_table_destroy (msg->hdr_fields);
|
||||
msg->hdr_fields =
|
||||
g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free);
|
||||
|
||||
if (msg->body) {
|
||||
g_free (msg->body);
|
||||
msg->body = NULL;
|
||||
}
|
||||
msg->body_size = 0;
|
||||
|
||||
if (request) {
|
||||
/* FIXME copy headers */
|
||||
}
|
||||
@ -106,10 +91,11 @@ rtsp_message_init_response (RTSPStatusCode code, gchar * reason,
|
||||
}
|
||||
|
||||
RTSPResult
|
||||
rtsp_message_init_data (gint channel, RTSPMessage * msg)
|
||||
rtsp_message_init_data (RTSPMessage * msg, gint channel)
|
||||
{
|
||||
if (msg == NULL)
|
||||
return RTSP_EINVAL;
|
||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||
|
||||
rtsp_message_unset (msg);
|
||||
|
||||
msg->type = RTSP_MESSAGE_DATA;
|
||||
msg->type_data.data.channel = channel;
|
||||
@ -117,13 +103,51 @@ rtsp_message_init_data (gint channel, RTSPMessage * msg)
|
||||
return RTSP_OK;
|
||||
}
|
||||
|
||||
RTSPResult
|
||||
rtsp_message_unset (RTSPMessage * msg)
|
||||
{
|
||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||
|
||||
msg->type = RTSP_MESSAGE_INVALID;
|
||||
msg->type_data.request.method = RTSP_INVALID;
|
||||
g_free (msg->type_data.request.uri);
|
||||
msg->type_data.request.uri = NULL;
|
||||
|
||||
msg->type_data.response.code = RTSP_STS_INVALID;
|
||||
g_free (msg->type_data.response.reason);
|
||||
msg->type_data.response.reason = NULL;
|
||||
|
||||
if (msg->hdr_fields != NULL)
|
||||
g_hash_table_destroy (msg->hdr_fields);
|
||||
msg->hdr_fields = NULL;
|
||||
|
||||
g_free (msg->body);
|
||||
msg->body = NULL;
|
||||
msg->body_size = 0;
|
||||
|
||||
return RTSP_OK;
|
||||
}
|
||||
|
||||
RTSPResult
|
||||
rtsp_message_free (RTSPMessage * msg)
|
||||
{
|
||||
RTSPResult res;
|
||||
|
||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||
|
||||
res = rtsp_message_unset (msg);
|
||||
if (res == RTSP_OK)
|
||||
g_free (msg);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
RTSPResult
|
||||
rtsp_message_add_header (RTSPMessage * msg, RTSPHeaderField field,
|
||||
gchar * value)
|
||||
{
|
||||
if (msg == NULL || value == NULL)
|
||||
return RTSP_EINVAL;
|
||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||
g_return_val_if_fail (value != NULL, RTSP_EINVAL);
|
||||
|
||||
g_hash_table_insert (msg->hdr_fields, GINT_TO_POINTER (field),
|
||||
g_strdup (value));
|
||||
@ -134,8 +158,7 @@ rtsp_message_add_header (RTSPMessage * msg, RTSPHeaderField field,
|
||||
RTSPResult
|
||||
rtsp_message_remove_header (RTSPMessage * msg, RTSPHeaderField field)
|
||||
{
|
||||
if (msg == NULL)
|
||||
return RTSP_EINVAL;
|
||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||
|
||||
g_hash_table_remove (msg->hdr_fields, GINT_TO_POINTER (field));
|
||||
|
||||
@ -148,8 +171,8 @@ rtsp_message_get_header (RTSPMessage * msg, RTSPHeaderField field,
|
||||
{
|
||||
gchar *val;
|
||||
|
||||
if (msg == NULL || value == NULL)
|
||||
return RTSP_EINVAL;
|
||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||
g_return_val_if_fail (value != NULL, RTSP_EINVAL);
|
||||
|
||||
val = g_hash_table_lookup (msg->hdr_fields, GINT_TO_POINTER (field));
|
||||
if (val == NULL)
|
||||
@ -163,8 +186,7 @@ rtsp_message_get_header (RTSPMessage * msg, RTSPHeaderField field,
|
||||
RTSPResult
|
||||
rtsp_message_set_body (RTSPMessage * msg, guint8 * data, guint size)
|
||||
{
|
||||
if (msg == NULL)
|
||||
return RTSP_EINVAL;
|
||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||
|
||||
return rtsp_message_take_body (msg, g_memdup (data, size), size);
|
||||
}
|
||||
@ -172,8 +194,7 @@ rtsp_message_set_body (RTSPMessage * msg, guint8 * data, guint size)
|
||||
RTSPResult
|
||||
rtsp_message_take_body (RTSPMessage * msg, guint8 * data, guint size)
|
||||
{
|
||||
if (msg == NULL)
|
||||
return RTSP_EINVAL;
|
||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||
|
||||
if (msg->body)
|
||||
g_free (msg->body);
|
||||
@ -187,8 +208,9 @@ rtsp_message_take_body (RTSPMessage * msg, guint8 * data, guint size)
|
||||
RTSPResult
|
||||
rtsp_message_get_body (RTSPMessage * msg, guint8 ** data, guint * size)
|
||||
{
|
||||
if (msg == NULL || data == NULL || size == NULL)
|
||||
return RTSP_EINVAL;
|
||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||
g_return_val_if_fail (data != NULL, RTSP_EINVAL);
|
||||
g_return_val_if_fail (size != NULL, RTSP_EINVAL);
|
||||
|
||||
*data = msg->body;
|
||||
*size = msg->body_size;
|
||||
@ -199,8 +221,9 @@ rtsp_message_get_body (RTSPMessage * msg, guint8 ** data, guint * size)
|
||||
RTSPResult
|
||||
rtsp_message_steal_body (RTSPMessage * msg, guint8 ** data, guint * size)
|
||||
{
|
||||
if (msg == NULL || data == NULL || size == NULL)
|
||||
return RTSP_EINVAL;
|
||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||
g_return_val_if_fail (data != NULL, RTSP_EINVAL);
|
||||
g_return_val_if_fail (size != NULL, RTSP_EINVAL);
|
||||
|
||||
*data = msg->body;
|
||||
*size = msg->body_size;
|
||||
@ -257,8 +280,7 @@ rtsp_message_dump (RTSPMessage * msg)
|
||||
guint8 *data;
|
||||
guint size;
|
||||
|
||||
if (msg == NULL)
|
||||
return RTSP_EINVAL;
|
||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||
|
||||
if (msg->type == RTSP_MESSAGE_REQUEST) {
|
||||
g_print ("request message %p\n", msg);
|
||||
|
@ -28,6 +28,7 @@ G_BEGIN_DECLS
|
||||
|
||||
typedef enum
|
||||
{
|
||||
RTSP_MESSAGE_INVALID,
|
||||
RTSP_MESSAGE_REQUEST,
|
||||
RTSP_MESSAGE_RESPONSE,
|
||||
RTSP_MESSAGE_DATA,
|
||||
@ -58,15 +59,16 @@ typedef struct _RTSPMessage
|
||||
|
||||
} RTSPMessage;
|
||||
|
||||
RTSPResult rtsp_message_new_request (RTSPMethod method, gchar *uri, RTSPMessage **msg);
|
||||
RTSPResult rtsp_message_init_request (RTSPMethod method, gchar *uri, RTSPMessage *msg);
|
||||
RTSPResult rtsp_message_new_request (RTSPMessage **msg, RTSPMethod method, gchar *uri);
|
||||
RTSPResult rtsp_message_init_request (RTSPMessage *msg, RTSPMethod method, gchar *uri);
|
||||
|
||||
RTSPResult rtsp_message_new_response (RTSPStatusCode code, gchar *reason,
|
||||
RTSPMessage *request, RTSPMessage **msg);
|
||||
RTSPResult rtsp_message_init_response (RTSPStatusCode code, gchar *reason,
|
||||
RTSPMessage *request, RTSPMessage *msg);
|
||||
RTSPResult rtsp_message_init_data (gint channel, RTSPMessage *msg);
|
||||
RTSPResult rtsp_message_new_response (RTSPMessage **msg, RTSPStatusCode code, gchar *reason,
|
||||
RTSPMessage *request);
|
||||
RTSPResult rtsp_message_init_response (RTSPMessage *msg, RTSPStatusCode code, gchar *reason,
|
||||
RTSPMessage *request);
|
||||
RTSPResult rtsp_message_init_data (RTSPMessage *msg, gint channel);
|
||||
|
||||
RTSPResult rtsp_message_unset (RTSPMessage *msg);
|
||||
RTSPResult rtsp_message_free (RTSPMessage *msg);
|
||||
|
||||
|
||||
|
@ -27,8 +27,7 @@ rtsp_transport_new (RTSPTransport ** transport)
|
||||
{
|
||||
RTSPTransport *trans;
|
||||
|
||||
if (transport == NULL)
|
||||
return RTSP_EINVAL;
|
||||
g_return_val_if_fail (transport != NULL, RTSP_EINVAL);
|
||||
|
||||
trans = g_new0 (RTSPTransport, 1);
|
||||
|
||||
@ -40,6 +39,8 @@ rtsp_transport_new (RTSPTransport ** transport)
|
||||
RTSPResult
|
||||
rtsp_transport_init (RTSPTransport * transport)
|
||||
{
|
||||
g_return_val_if_fail (transport != NULL, RTSP_EINVAL);
|
||||
|
||||
g_free (transport->destination);
|
||||
g_free (transport->source);
|
||||
g_free (transport->ssrc);
|
||||
@ -83,8 +84,8 @@ rtsp_transport_parse (gchar * str, RTSPTransport * transport)
|
||||
gchar **split, *down;
|
||||
gint i;
|
||||
|
||||
if (str == NULL || transport == NULL)
|
||||
return RTSP_EINVAL;
|
||||
g_return_val_if_fail (transport != NULL, RTSP_EINVAL);
|
||||
g_return_val_if_fail (str != NULL, RTSP_EINVAL);
|
||||
|
||||
rtsp_transport_init (transport);
|
||||
|
||||
@ -141,6 +142,8 @@ rtsp_transport_parse (gchar * str, RTSPTransport * transport)
|
||||
RTSPResult
|
||||
rtsp_transport_free (RTSPTransport * transport)
|
||||
{
|
||||
g_return_val_if_fail (transport != NULL, RTSP_EINVAL);
|
||||
|
||||
rtsp_transport_init (transport);
|
||||
g_free (transport);
|
||||
return RTSP_OK;
|
||||
|
@ -34,10 +34,10 @@ rtsp_url_parse (const gchar * urlstr, RTSPUrl ** url)
|
||||
RTSPUrl *res;
|
||||
gchar *p, *slash, *at, *col;
|
||||
|
||||
res = g_new0 (RTSPUrl, 1);
|
||||
g_return_val_if_fail (urlstr != NULL, RTSP_EINVAL);
|
||||
g_return_val_if_fail (url != NULL, RTSP_EINVAL);
|
||||
|
||||
if (urlstr == NULL)
|
||||
goto invalid;
|
||||
res = g_new0 (RTSPUrl, 1);
|
||||
|
||||
p = (gchar *) urlstr;
|
||||
if (g_str_has_prefix (p, RTSP_PROTO)) {
|
||||
|
@ -76,8 +76,7 @@ sdp_message_new (SDPMessage ** msg)
|
||||
{
|
||||
SDPMessage *newmsg;
|
||||
|
||||
if (msg == NULL)
|
||||
return RTSP_EINVAL;
|
||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||
|
||||
newmsg = g_new0 (SDPMessage, 1);
|
||||
|
||||
@ -89,8 +88,7 @@ sdp_message_new (SDPMessage ** msg)
|
||||
RTSPResult
|
||||
sdp_message_init (SDPMessage * msg)
|
||||
{
|
||||
if (msg == NULL)
|
||||
return RTSP_EINVAL;
|
||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||
|
||||
FREE_STRING (msg->version);
|
||||
FREE_STRING (msg->origin.username);
|
||||
@ -123,8 +121,7 @@ sdp_message_init (SDPMessage * msg)
|
||||
RTSPResult
|
||||
sdp_message_clean (SDPMessage * msg)
|
||||
{
|
||||
if (msg == NULL)
|
||||
return RTSP_EINVAL;
|
||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||
|
||||
FREE_ARRAY (msg->emails);
|
||||
FREE_ARRAY (msg->phones);
|
||||
@ -140,8 +137,7 @@ sdp_message_clean (SDPMessage * msg)
|
||||
RTSPResult
|
||||
sdp_message_free (SDPMessage * msg)
|
||||
{
|
||||
if (msg == NULL)
|
||||
return RTSP_EINVAL;
|
||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||
|
||||
sdp_message_clean (msg);
|
||||
|
||||
@ -156,8 +152,7 @@ sdp_media_new (SDPMedia ** media)
|
||||
{
|
||||
SDPMedia *newmedia;
|
||||
|
||||
if (media == NULL)
|
||||
return RTSP_EINVAL;
|
||||
g_return_val_if_fail (media != NULL, RTSP_EINVAL);
|
||||
|
||||
newmedia = g_new0 (SDPMedia, 1);
|
||||
|
||||
@ -169,8 +164,7 @@ sdp_media_new (SDPMedia ** media)
|
||||
RTSPResult
|
||||
sdp_media_init (SDPMedia * media)
|
||||
{
|
||||
if (media == NULL)
|
||||
return RTSP_EINVAL;
|
||||
g_return_val_if_fail (media != NULL, RTSP_EINVAL);
|
||||
|
||||
FREE_STRING (media->media);
|
||||
media->port = 0;
|
||||
@ -578,8 +572,9 @@ sdp_message_parse_buffer (guint8 * data, guint size, SDPMessage * msg)
|
||||
gchar buffer[4096];
|
||||
gint idx = 0;
|
||||
|
||||
if (msg == NULL || data == NULL || size == 0)
|
||||
return RTSP_EINVAL;
|
||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||
g_return_val_if_fail (data != NULL, RTSP_EINVAL);
|
||||
g_return_val_if_fail (size != 0, RTSP_EINVAL);
|
||||
|
||||
c.state = SDP_SESSION;
|
||||
c.msg = msg;
|
||||
@ -651,8 +646,7 @@ print_media (SDPMedia * media)
|
||||
RTSPResult
|
||||
sdp_message_dump (SDPMessage * msg)
|
||||
{
|
||||
if (msg == NULL)
|
||||
return RTSP_EINVAL;
|
||||
g_return_val_if_fail (msg != NULL, RTSP_EINVAL);
|
||||
|
||||
g_print ("sdp packet %p:\n", msg);
|
||||
g_print (" version: '%s'\n", msg->version);
|
||||
@ -666,6 +660,7 @@ sdp_message_dump (SDPMessage * msg)
|
||||
g_print (" session_name: '%s'\n", msg->session_name);
|
||||
g_print (" information: '%s'\n", msg->information);
|
||||
g_print (" uri: '%s'\n", msg->uri);
|
||||
|
||||
if (msg->emails->len > 0) {
|
||||
gint i;
|
||||
|
||||
@ -710,7 +705,5 @@ sdp_message_dump (SDPMessage * msg)
|
||||
print_media (&g_array_index (msg->medias, SDPMedia, i));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return RTSP_OK;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user