mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-10-02 00:32:43 +00:00
gst/rtsp/: Added README
Original commit message from CVS: * gst/rtsp/README: * gst/rtsp/gstrtspsrc.c: (gst_rtsp_proto_get_type), (gst_rtspsrc_class_init), (gst_rtspsrc_create_stream), (gst_rtspsrc_add_element), (gst_rtspsrc_set_state), (gst_rtspsrc_stream_setup_rtp), (gst_rtspsrc_stream_configure_transport), (find_stream), (gst_rtspsrc_loop), (gst_rtspsrc_open), (gst_rtspsrc_play): * gst/rtsp/rtsp.h: * gst/rtsp/rtspconnection.c: (rtsp_connection_create), (rtsp_connection_send), (read_line), (parse_request_line), (parse_line), (read_body), (rtsp_connection_receive), (rtsp_connection_free): * gst/rtsp/rtspconnection.h: * gst/rtsp/rtspdefs.c: (rtsp_find_method): * gst/rtsp/rtspdefs.h: * gst/rtsp/rtspmessage.c: (rtsp_message_set_body), (rtsp_message_take_body): * gst/rtsp/rtspmessage.h: * gst/rtsp/rtspstream.h: * gst/rtsp/sdpmessage.c: (sdp_parse_line): Added README Some cleanups.
This commit is contained in:
parent
91ce2b294e
commit
63177e0731
12 changed files with 368 additions and 124 deletions
25
ChangeLog
25
ChangeLog
|
@ -1,3 +1,28 @@
|
|||
2005-05-11 Wim Taymans <wim@fluendo.com>
|
||||
|
||||
* gst/rtsp/README:
|
||||
* gst/rtsp/gstrtspsrc.c: (gst_rtsp_proto_get_type),
|
||||
(gst_rtspsrc_class_init), (gst_rtspsrc_create_stream),
|
||||
(gst_rtspsrc_add_element), (gst_rtspsrc_set_state),
|
||||
(gst_rtspsrc_stream_setup_rtp),
|
||||
(gst_rtspsrc_stream_configure_transport), (find_stream),
|
||||
(gst_rtspsrc_loop), (gst_rtspsrc_open), (gst_rtspsrc_play):
|
||||
* gst/rtsp/rtsp.h:
|
||||
* gst/rtsp/rtspconnection.c: (rtsp_connection_create),
|
||||
(rtsp_connection_send), (read_line), (parse_request_line),
|
||||
(parse_line), (read_body), (rtsp_connection_receive),
|
||||
(rtsp_connection_free):
|
||||
* gst/rtsp/rtspconnection.h:
|
||||
* gst/rtsp/rtspdefs.c: (rtsp_find_method):
|
||||
* gst/rtsp/rtspdefs.h:
|
||||
* gst/rtsp/rtspmessage.c: (rtsp_message_set_body),
|
||||
(rtsp_message_take_body):
|
||||
* gst/rtsp/rtspmessage.h:
|
||||
* gst/rtsp/rtspstream.h:
|
||||
* gst/rtsp/sdpmessage.c: (sdp_parse_line):
|
||||
Added README
|
||||
Some cleanups.
|
||||
|
||||
2005-05-11 Wim Taymans <wim@fluendo.com>
|
||||
|
||||
* gst/rtsp/gstrtspsrc.c: (gst_rtsp_proto_get_type),
|
||||
|
|
156
gst/rtsp/README
Normal file
156
gst/rtsp/README
Normal file
|
@ -0,0 +1,156 @@
|
|||
RTSP source
|
||||
-----------
|
||||
|
||||
The RTSP source establishes a connection to an RTSP server and sets up
|
||||
the UDP sources and RTP session handlers.
|
||||
|
||||
An RTSP session is created as follows:
|
||||
|
||||
- Parse RTSP URL:
|
||||
|
||||
ex:
|
||||
rtsp://thread:5454/south-rtsp.mp3
|
||||
|
||||
- Open a connection to the server with the url. All further conversation with
|
||||
the server should be done with this connection. Each request/reply has
|
||||
a CSeq number added to the header.
|
||||
|
||||
- Send a DESCRIBE request for the url. We currently support a response in
|
||||
SDP.
|
||||
|
||||
ex:
|
||||
|
||||
>> DESCRIBE rtsp://thread:5454/south-rtsp.mp3 RTSP/1.0
|
||||
>> Accept: application/sdp
|
||||
>> CSeq: 0
|
||||
>>
|
||||
<< RTSP/1.0 200 OK
|
||||
<< Content-Length: 84
|
||||
<< Content-Type: application/sdp
|
||||
<< CSeq: 0
|
||||
<< Date: Wed May 11 13:09:37 2005 GMT
|
||||
<<
|
||||
<< v=0
|
||||
<< o=- 0 0 IN IP4 192.168.1.1
|
||||
<< s=No Title
|
||||
<< m=audio 0 RTP/AVP 14
|
||||
<< a=control:streamid=0
|
||||
|
||||
- Parse the SDP message, for each stream (m=) we create an GstRTPStream. We need
|
||||
to allocate two local UDP ports for receiving the RTP and RTCP data because we
|
||||
need to send the port numbers to the server in the next request.
|
||||
|
||||
In RTSPSrc we create two elements that can handle the udp://0.0.0.0:0 uri. This
|
||||
will create an udp source element. We get the port number by getting the "port"
|
||||
property of the element after setting the element to PAUSED.
|
||||
|
||||
+-----------------+
|
||||
| +------------+ |
|
||||
| | udpsrc0 | |
|
||||
| | port=5000 | |
|
||||
| +------------+ |
|
||||
| +------------+ |
|
||||
| | udpsrc1 | |
|
||||
| | port=5001 | |
|
||||
| +------------+ |
|
||||
+-----------------+
|
||||
|
||||
- Send a SETUP message to the server with the RTP ports. We get the setup URI from
|
||||
the a= attribute in the SDP message. This can be an absolute URL or a relative
|
||||
url.
|
||||
|
||||
ex:
|
||||
|
||||
>> SETUP rtsp://thread:5454/south-rtsp.mp3/streamid=0 RTSP/1.0
|
||||
>> CSeq: 1
|
||||
>> Transport: RTP/AVP/UDP;unicast;client_port=5000-5001,RTP/AVP/UDP;multicast,RTP/AVP/TCP
|
||||
>>
|
||||
<< RTSP/1.0 200 OK
|
||||
<< Transport: RTP/AVP/UDP;unicast;client_port=5000-5001;server_port=6000-6001
|
||||
<< CSeq: 1
|
||||
<< Date: Wed May 11 13:21:43 2005 GMT
|
||||
<< Session: 5d5cb94413288ccd
|
||||
<<
|
||||
|
||||
The client needs to send the local ports to the server along with the supported
|
||||
transport types. The server selects the final transport which it returns in the
|
||||
Transport header field. The server also includes its ports where RTP and RTCP
|
||||
messages can be sent to.
|
||||
|
||||
In the above example UDP was choosen as a transport. At this point the RTSPSrc element
|
||||
will furter configure its elements to process this stream.
|
||||
|
||||
The RTSPSrc will create and connect an RTP session manager element and will
|
||||
connect it to the src pads of the udp element. The data pad from the RTP session
|
||||
manager is ghostpadded to RTPSrc.
|
||||
The RTCP pad of the rtpdec is routed to a new udpsink that sends data to the RTCP
|
||||
port of the server as returned in the Transport: header field.
|
||||
|
||||
+---------------------------------------------+
|
||||
| +------------+ |
|
||||
| | udpsrc0 | +--------+ |
|
||||
| | port=5000 ----- rtpdec --------------------
|
||||
| +------------+ | | |
|
||||
| +------------+ | | +------------+ |
|
||||
| | udpsrc1 ----- RTCP ---- udpsink | |
|
||||
| | port=5001 | +--------+ | port=6001 | |
|
||||
| +------------+ +------------+ |
|
||||
+---------------------------------------------+
|
||||
|
||||
The output type of rtpdec is configured as the media type specified in the SDP
|
||||
message.
|
||||
|
||||
- All the elements are set to PAUSED/PLAYING and the PLAY RTSP message is
|
||||
sent.
|
||||
|
||||
>> PLAY rtsp://thread:5454/south-rtsp.mp3 RTSP/1.0
|
||||
>> CSeq: 2
|
||||
>>
|
||||
<< RTSP/1.0 200 OK
|
||||
<< CSeq: 2
|
||||
<< Date: Wed May 11 13:21:43 2005 GMT
|
||||
<< Session: 5d5cb94413288ccd
|
||||
<<
|
||||
|
||||
- The udp source elements receive data from that point and the RTP/RTCP messages
|
||||
are processed by the elements.
|
||||
|
||||
- In the case of interleaved mode, the SETUP method yields:
|
||||
|
||||
>> SETUP rtsp://thread:5454/south-rtsp.mp3/streamid=0 RTSP/1.0
|
||||
>> CSeq: 1
|
||||
>> Transport: RTP/AVP/UDP;unicast;client_port=5000-5001,RTP/AVP/UDP;multicast,RTP/AVP/TCP
|
||||
>>
|
||||
<< RTSP/1.0 200 OK
|
||||
<< Transport: RTP/AVP/TCP;interleaved=0-1
|
||||
<< CSeq: 1
|
||||
<< Date: Wed May 11 13:21:43 2005 GMT
|
||||
<< Session: 5d5cb94413288ccd
|
||||
<<
|
||||
|
||||
This means that RTP/RTCP messages will be send on channel 0/1 respectively and that
|
||||
the data will be received on the same connection as the RTSP connection.
|
||||
|
||||
At this point, we remove the UDP source elements as we don't need them anymore. We
|
||||
setup the rtpdec session manager element though as follows:
|
||||
|
||||
+---------------------------------------------+
|
||||
| +------------+ |
|
||||
| | _loop() | +--------+ |
|
||||
| | ----- rtpdec --------------------
|
||||
| | | | | |
|
||||
| | | | | +------------+ |
|
||||
| | ----- RTCP ---- udpsink | |
|
||||
| | | +--------+ | port=6001 | |
|
||||
| +------------+ +------------+ |
|
||||
+---------------------------------------------+
|
||||
|
||||
We start an interal task to start reading from the RTSP connection waiting
|
||||
for data. The received data is then pushed to the rtpdec element.
|
||||
|
||||
When reading from the RTSP connection we receive data packets in the
|
||||
following layout (see also RFC2326)
|
||||
|
||||
$<1 byte channel><2 bytes length, big endian><length bytes of data>
|
||||
|
||||
|
|
@ -637,7 +637,7 @@ gst_rtspsrc_open (GstRTSPSrc * src)
|
|||
|
||||
new =
|
||||
g_strconcat (transports, transports[0] ? "," : "",
|
||||
",RTP/AVP/UDP;multicast", NULL);
|
||||
"RTP/AVP/UDP;multicast", NULL);
|
||||
g_free (transports);
|
||||
transports = new;
|
||||
}
|
||||
|
@ -645,7 +645,7 @@ gst_rtspsrc_open (GstRTSPSrc * src)
|
|||
gchar *new;
|
||||
|
||||
new =
|
||||
g_strconcat (transports, transports[0] ? "," : "", ",RTP/AVP/TCP",
|
||||
g_strconcat (transports, transports[0] ? "," : "", "RTP/AVP/TCP",
|
||||
NULL);
|
||||
g_free (transports);
|
||||
transports = new;
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include <rtspconnection.h>
|
||||
#include <rtspdefs.h>
|
||||
#include <rtspmessage.h>
|
||||
#include <rtspstream.h>
|
||||
#include <rtsptransport.h>
|
||||
#include <rtspurl.h>
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -94,7 +95,7 @@ rtsp_connection_create (gint fd, RTSPConnection ** conn)
|
|||
{
|
||||
RTSPConnection *newconn;
|
||||
|
||||
/* FIXME check fd */
|
||||
/* FIXME check fd, must be connected SOCK_STREAM */
|
||||
|
||||
newconn = g_new (RTSPConnection, 1);
|
||||
|
||||
|
@ -120,30 +121,70 @@ RTSPResult
|
|||
rtsp_connection_send (RTSPConnection * conn, RTSPMessage * message)
|
||||
{
|
||||
GString *str;
|
||||
gint towrite;
|
||||
gchar *data;
|
||||
|
||||
if (conn == NULL || message == NULL)
|
||||
return RTSP_EINVAL;
|
||||
|
||||
str = g_string_new ("");
|
||||
|
||||
/* create request string, add CSeq */
|
||||
g_string_append_printf (str, "%s %s RTSP/1.0\r\n"
|
||||
"CSeq: %d\r\n",
|
||||
rtsp_method_as_text (message->type_data.request.method),
|
||||
message->type_data.request.uri, conn->cseq);
|
||||
|
||||
/* append session id if we have one */
|
||||
if (conn->session_id[0] != '\0') {
|
||||
rtsp_message_add_header (message, RTSP_HDR_SESSION, conn->session_id);
|
||||
}
|
||||
|
||||
/* append headers */
|
||||
g_hash_table_foreach (message->hdr_fields, (GHFunc) append_header, str);
|
||||
|
||||
/* append Content-Length and body if needed */
|
||||
if (message->body != NULL && message->body_size > 0) {
|
||||
gchar *len;
|
||||
|
||||
g_string_append (str, "\r\n");
|
||||
len = g_strdup_printf ("%d", message->body_size);
|
||||
append_header (RTSP_HDR_CONTENT_LENGTH, len, str);
|
||||
g_free (len);
|
||||
/* header ends here */
|
||||
g_string_append (str, "\r\n");
|
||||
str = g_string_append_len (str, message->body, message->body_size);
|
||||
} else {
|
||||
/* just end headers */
|
||||
g_string_append (str, "\r\n");
|
||||
}
|
||||
|
||||
write (conn->fd, str->str, str->len);
|
||||
/* write request */
|
||||
towrite = str->len;
|
||||
data = str->str;
|
||||
|
||||
while (towrite > 0) {
|
||||
gint written;
|
||||
|
||||
written = write (conn->fd, data, towrite);
|
||||
if (written < 0) {
|
||||
if (errno != EAGAIN && errno != EINTR)
|
||||
goto write_error;
|
||||
} else {
|
||||
towrite -= written;
|
||||
data += written;
|
||||
}
|
||||
}
|
||||
g_string_free (str, TRUE);
|
||||
|
||||
conn->cseq++;
|
||||
|
||||
return RTSP_OK;
|
||||
|
||||
write_error:
|
||||
{
|
||||
g_string_free (str, TRUE);
|
||||
return RTSP_ESYS;
|
||||
}
|
||||
}
|
||||
|
||||
static RTSPResult
|
||||
|
@ -151,29 +192,30 @@ read_line (gint fd, gchar * buffer, guint size)
|
|||
{
|
||||
gint idx;
|
||||
gchar c;
|
||||
gint ret;
|
||||
gint r;
|
||||
|
||||
idx = 0;
|
||||
while (TRUE) {
|
||||
ret = read (fd, &c, 1);
|
||||
if (ret < 1)
|
||||
goto error;
|
||||
r = read (fd, &c, 1);
|
||||
if (r < 1) {
|
||||
if (errno != EAGAIN && errno != EINTR)
|
||||
goto read_error;
|
||||
} else {
|
||||
if (c == '\n') /* end on \n */
|
||||
break;
|
||||
if (c == '\r') /* ignore \r */
|
||||
continue;
|
||||
|
||||
if (c == '\n') /* end on \n */
|
||||
break;
|
||||
if (c == '\r') /* ignore \r */
|
||||
continue;
|
||||
|
||||
if (idx < size - 1)
|
||||
buffer[idx++] = c;
|
||||
if (idx < size - 1)
|
||||
buffer[idx++] = c;
|
||||
}
|
||||
}
|
||||
buffer[idx] = '\0';
|
||||
|
||||
return RTSP_OK;
|
||||
|
||||
error:
|
||||
read_error:
|
||||
{
|
||||
perror ("read");
|
||||
return RTSP_ESYS;
|
||||
}
|
||||
}
|
||||
|
@ -242,6 +284,43 @@ wrong_version:
|
|||
}
|
||||
}
|
||||
|
||||
static RTSPResult
|
||||
parse_request_line (gchar * buffer, RTSPMessage * msg)
|
||||
{
|
||||
gchar versionstr[20];
|
||||
gchar methodstr[20];
|
||||
gchar urlstr[4096];
|
||||
gchar *bptr;
|
||||
RTSPMethod method;
|
||||
|
||||
bptr = buffer;
|
||||
|
||||
read_string (methodstr, sizeof (methodstr), &bptr);
|
||||
method = rtsp_find_method (methodstr);
|
||||
if (method == -1)
|
||||
goto wrong_method;
|
||||
|
||||
read_string (urlstr, sizeof (urlstr), &bptr);
|
||||
|
||||
read_string (versionstr, sizeof (versionstr), &bptr);
|
||||
if (strcmp (versionstr, "RTSP/1.0") != 0)
|
||||
goto wrong_version;
|
||||
|
||||
rtsp_message_init_request (method, urlstr, msg);
|
||||
|
||||
return RTSP_OK;
|
||||
|
||||
wrong_method:
|
||||
{
|
||||
return RTSP_EINVAL;
|
||||
}
|
||||
wrong_version:
|
||||
{
|
||||
return RTSP_EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/* parsing lines means reading a Key: Value pair */
|
||||
static RTSPResult
|
||||
parse_line (gchar * buffer, RTSPMessage * msg)
|
||||
{
|
||||
|
@ -251,6 +330,7 @@ parse_line (gchar * buffer, RTSPMessage * msg)
|
|||
|
||||
bptr = buffer;
|
||||
|
||||
/* read key */
|
||||
read_key (key, sizeof (key), &bptr);
|
||||
if (*bptr != ':')
|
||||
return RTSP_EINVAL;
|
||||
|
@ -259,7 +339,7 @@ parse_line (gchar * buffer, RTSPMessage * msg)
|
|||
|
||||
field = rtsp_find_header_field (key);
|
||||
if (field == -1) {
|
||||
g_warning ("unknown header field '%s'\n", key);
|
||||
g_warning ("ignoring unknown header field '%s'\n", key);
|
||||
} else {
|
||||
while (g_ascii_isspace (*bptr))
|
||||
bptr++;
|
||||
|
@ -276,8 +356,9 @@ read_body (gint fd, glong content_length, RTSPMessage * msg)
|
|||
gint to_read, r;
|
||||
|
||||
if (content_length <= 0) {
|
||||
rtsp_message_set_body (msg, NULL, 0);
|
||||
return RTSP_OK;
|
||||
body = NULL;
|
||||
content_length = 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
body = g_malloc (content_length);
|
||||
|
@ -285,14 +366,25 @@ read_body (gint fd, glong content_length, RTSPMessage * msg)
|
|||
to_read = content_length;
|
||||
while (to_read > 0) {
|
||||
r = read (fd, bodyptr, to_read);
|
||||
|
||||
to_read -= r;
|
||||
bodyptr += r;
|
||||
if (r < 0) {
|
||||
if (errno != EAGAIN && errno != EINTR)
|
||||
goto read_error;
|
||||
} else {
|
||||
to_read -= r;
|
||||
bodyptr += r;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
rtsp_message_set_body (msg, body, content_length);
|
||||
|
||||
return RTSP_OK;
|
||||
|
||||
read_error:
|
||||
{
|
||||
g_free (body);
|
||||
return RTSP_ESYS;
|
||||
}
|
||||
}
|
||||
|
||||
RTSPResult
|
||||
|
@ -312,30 +404,36 @@ rtsp_connection_receive (RTSPConnection * conn, RTSPMessage * msg)
|
|||
|
||||
need_body = TRUE;
|
||||
|
||||
res = RTSP_OK;
|
||||
/* parse first line and headers */
|
||||
while (TRUE) {
|
||||
while (res == RTSP_OK) {
|
||||
gchar c;
|
||||
gint ret;
|
||||
|
||||
/* read first character, this identifies data messages */
|
||||
ret = read (conn->fd, &c, 1);
|
||||
if (ret < 0)
|
||||
goto read_error;
|
||||
if (ret < 1)
|
||||
break;
|
||||
|
||||
/* check for data packet */
|
||||
/* check for data packet, first character is $ */
|
||||
if (c == '$') {
|
||||
guint16 size;
|
||||
|
||||
/* read channel */
|
||||
/* data packets are $<1 byte channel><2 bytes length,BE><data bytes> */
|
||||
|
||||
/* read channel, which is the next char */
|
||||
ret = read (conn->fd, &c, 1);
|
||||
if (ret < 0)
|
||||
goto read_error;
|
||||
if (ret < 1)
|
||||
goto error;
|
||||
|
||||
/* now we create a data message */
|
||||
rtsp_message_init_data ((gint) c, msg);
|
||||
|
||||
/* next two bytes are the length of the data */
|
||||
ret = read (conn->fd, &size, 2);
|
||||
if (ret < 0)
|
||||
goto read_error;
|
||||
|
@ -344,12 +442,14 @@ rtsp_connection_receive (RTSPConnection * conn, RTSPMessage * msg)
|
|||
|
||||
size = GUINT16_FROM_BE (size);
|
||||
|
||||
read_body (conn->fd, size, msg);
|
||||
/* and read the body */
|
||||
res = read_body (conn->fd, size, msg);
|
||||
need_body = FALSE;
|
||||
break;
|
||||
} else {
|
||||
gint offset = 0;
|
||||
|
||||
/* we have a regular response */
|
||||
if (c != '\r') {
|
||||
buffer[0] = c;
|
||||
offset = 1;
|
||||
|
@ -358,46 +458,54 @@ rtsp_connection_receive (RTSPConnection * conn, RTSPMessage * msg)
|
|||
if (c == '\n')
|
||||
break;
|
||||
|
||||
read_line (conn->fd, buffer + offset, sizeof (buffer) - offset);
|
||||
/* read lines */
|
||||
res = read_line (conn->fd, buffer + offset, sizeof (buffer) - offset);
|
||||
if (res != RTSP_OK)
|
||||
goto read_error;
|
||||
|
||||
if (buffer[0] == '\0')
|
||||
break;
|
||||
|
||||
if (line == 0) {
|
||||
/* first line, check for response status */
|
||||
if (g_str_has_prefix (buffer, "RTSP")) {
|
||||
parse_response_status (buffer, msg);
|
||||
res = parse_response_status (buffer, msg);
|
||||
} else {
|
||||
g_warning ("parsing request not implemented\n");
|
||||
goto error;
|
||||
res = parse_request_line (buffer, msg);
|
||||
}
|
||||
} else {
|
||||
/* else just parse the line */
|
||||
parse_line (buffer, msg);
|
||||
}
|
||||
}
|
||||
line++;
|
||||
}
|
||||
|
||||
/* read the rest of the body if needed */
|
||||
if (need_body) {
|
||||
/* parse body */
|
||||
res = rtsp_message_get_header (msg, RTSP_HDR_CONTENT_LENGTH, &hdrval);
|
||||
if (res == RTSP_OK) {
|
||||
/* see if there is a Content-Length header */
|
||||
if (rtsp_message_get_header (msg, RTSP_HDR_CONTENT_LENGTH,
|
||||
&hdrval) == RTSP_OK) {
|
||||
/* there is, read the body */
|
||||
content_length = atol (hdrval);
|
||||
read_body (conn->fd, content_length, msg);
|
||||
res = read_body (conn->fd, content_length, msg);
|
||||
}
|
||||
|
||||
/* save session id */
|
||||
/* save session id in the connection for further use */
|
||||
{
|
||||
gchar *session_id;
|
||||
|
||||
if (rtsp_message_get_header (msg, RTSP_HDR_SESSION,
|
||||
&session_id) == RTSP_OK) {
|
||||
strncpy (conn->session_id, session_id, sizeof (conn->session_id) - 1);
|
||||
conn->session_id[sizeof (conn->session_id) - 1] = '\0';
|
||||
gint maxlen = sizeof (conn->session_id) - 1;
|
||||
|
||||
/* make sure to not overflow */
|
||||
strncpy (conn->session_id, session_id, maxlen);
|
||||
conn->session_id[maxlen] = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return RTSP_OK;
|
||||
return res;
|
||||
|
||||
error:
|
||||
{
|
||||
|
@ -405,7 +513,6 @@ error:
|
|||
}
|
||||
read_error:
|
||||
{
|
||||
perror ("read");
|
||||
return RTSP_ESYS;
|
||||
}
|
||||
}
|
||||
|
@ -430,3 +537,12 @@ sys_error:
|
|||
return RTSP_ESYS;
|
||||
}
|
||||
}
|
||||
|
||||
RTSPResult
|
||||
rtsp_connection_free (RTSPConnection * conn)
|
||||
{
|
||||
if (conn == NULL)
|
||||
return RTSP_EINVAL;
|
||||
|
||||
g_free (conn);
|
||||
}
|
||||
|
|
|
@ -24,33 +24,30 @@
|
|||
|
||||
#include <rtspdefs.h>
|
||||
#include <rtspurl.h>
|
||||
#include <rtspstream.h>
|
||||
#include <rtspmessage.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _RTSPConnection
|
||||
{
|
||||
gint fd;
|
||||
gint fd; /* our socket */
|
||||
|
||||
gint cseq;
|
||||
gchar session_id[512];
|
||||
|
||||
RTSPState state;
|
||||
|
||||
int num_streams;
|
||||
RTSPStream **streams;
|
||||
gint cseq; /* sequence number */
|
||||
gchar session_id[512]; /* session id */
|
||||
|
||||
RTSPState state; /* state of the connection */
|
||||
} RTSPConnection;
|
||||
|
||||
/* opening/closing a connection */
|
||||
RTSPResult rtsp_connection_open (RTSPUrl *url, RTSPConnection **conn);
|
||||
RTSPResult rtsp_connection_create (gint fd, RTSPConnection **conn);
|
||||
RTSPResult rtsp_connection_close (RTSPConnection *conn);
|
||||
RTSPResult rtsp_connection_free (RTSPConnection *conn);
|
||||
|
||||
/* sending/receiving messages */
|
||||
RTSPResult rtsp_connection_send (RTSPConnection *conn, RTSPMessage *message);
|
||||
RTSPResult rtsp_connection_receive (RTSPConnection *conn, RTSPMessage *message);
|
||||
|
||||
RTSPResult rtsp_connection_close (RTSPConnection *conn);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __RTSP_CONNECTION_H__ */
|
||||
|
|
|
@ -169,3 +169,16 @@ rtsp_find_header_field (gchar * header)
|
|||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
RTSPMethod
|
||||
rtsp_find_method (gchar * method)
|
||||
{
|
||||
gint idx;
|
||||
|
||||
for (idx = 0; rtsp_methods[idx]; idx++) {
|
||||
if (g_ascii_strcasecmp (rtsp_headers[idx], method) == 0) {
|
||||
return idx;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -167,7 +167,9 @@ const gchar* rtsp_method_as_text (RTSPMethod method);
|
|||
const gchar* rtsp_header_as_text (RTSPHeaderField field);
|
||||
const gchar* rtsp_status_as_text (RTSPStatusCode code);
|
||||
const gchar* rtsp_status_to_string (RTSPStatusCode code);
|
||||
|
||||
RTSPHeaderField rtsp_find_header_field (gchar *header);
|
||||
RTSPMethod rtsp_find_method (gchar *method);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
|
@ -161,24 +161,16 @@ rtsp_message_get_header (RTSPMessage * msg, RTSPHeaderField field,
|
|||
}
|
||||
|
||||
RTSPResult
|
||||
rtsp_message_get_header_copy (RTSPMessage * msg, RTSPHeaderField field,
|
||||
gchar ** value)
|
||||
rtsp_message_set_body (RTSPMessage * msg, guint8 * data, guint size)
|
||||
{
|
||||
gchar *val;
|
||||
|
||||
if (msg == NULL || value == NULL)
|
||||
if (msg == NULL)
|
||||
return RTSP_EINVAL;
|
||||
|
||||
val = g_hash_table_lookup (msg->hdr_fields, GINT_TO_POINTER (field));
|
||||
|
||||
*value = g_strdup (val);
|
||||
|
||||
return RTSP_OK;
|
||||
return rtsp_message_take_body (msg, g_memdup (data, size), size);
|
||||
}
|
||||
|
||||
|
||||
RTSPResult
|
||||
rtsp_message_set_body (RTSPMessage * msg, guint8 * data, guint size)
|
||||
rtsp_message_take_body (RTSPMessage * msg, guint8 * data, guint size)
|
||||
{
|
||||
if (msg == NULL)
|
||||
return RTSP_EINVAL;
|
||||
|
@ -192,13 +184,6 @@ rtsp_message_set_body (RTSPMessage * msg, guint8 * data, guint size)
|
|||
return RTSP_OK;
|
||||
}
|
||||
|
||||
RTSPResult
|
||||
rtsp_message_set_body_copy (RTSPMessage * msg, guint8 * data, guint size)
|
||||
{
|
||||
return RTSP_ENOTIMPL;
|
||||
}
|
||||
|
||||
|
||||
RTSPResult
|
||||
rtsp_message_get_body (RTSPMessage * msg, guint8 ** data, guint * size)
|
||||
{
|
||||
|
@ -211,18 +196,6 @@ rtsp_message_get_body (RTSPMessage * msg, guint8 ** data, guint * size)
|
|||
return RTSP_OK;
|
||||
}
|
||||
|
||||
RTSPResult
|
||||
rtsp_message_get_body_copy (RTSPMessage * msg, guint8 ** data, guint * size)
|
||||
{
|
||||
if (msg == NULL || data == NULL || size == NULL)
|
||||
return RTSP_EINVAL;
|
||||
|
||||
*data = g_memdup (msg->body, msg->body_size);
|
||||
*size = msg->body_size;
|
||||
|
||||
return RTSP_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
dump_mem (guint8 * mem, gint size)
|
||||
{
|
||||
|
|
|
@ -73,13 +73,10 @@ RTSPResult rtsp_message_free (RTSPMessage *msg);
|
|||
RTSPResult rtsp_message_add_header (RTSPMessage *msg, RTSPHeaderField field, gchar *value);
|
||||
RTSPResult rtsp_message_remove_header (RTSPMessage *msg, RTSPHeaderField field);
|
||||
RTSPResult rtsp_message_get_header (RTSPMessage *msg, RTSPHeaderField field, gchar **value);
|
||||
RTSPResult rtsp_message_get_header_copy (RTSPMessage *msg, RTSPHeaderField field, gchar **value);
|
||||
|
||||
RTSPResult rtsp_message_set_body (RTSPMessage *msg, guint8 *data, guint size);
|
||||
RTSPResult rtsp_message_set_body_copy (RTSPMessage *msg, guint8 *data, guint size);
|
||||
|
||||
RTSPResult rtsp_message_take_body (RTSPMessage *msg, guint8 *data, guint size);
|
||||
RTSPResult rtsp_message_get_body (RTSPMessage *msg, guint8 **data, guint *size);
|
||||
RTSPResult rtsp_message_get_body_copy (RTSPMessage *msg, guint8 **data, guint *size);
|
||||
|
||||
RTSPResult rtsp_message_dump (RTSPMessage *msg);
|
||||
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
/* GStreamer
|
||||
* Copyright (C) <2005> Wim Taymans <wim@fluendo.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __RTSP_STREAM_H__
|
||||
#define __RTSP_STREAM_H__
|
||||
|
||||
#include <rtspdefs.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _RTSPStream {
|
||||
} RTSPStream;
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __RTSP_STREAM_H__ */
|
|
@ -462,7 +462,7 @@ sdp_parse_line (SDPContext * c, gchar type, guint8 * buffer)
|
|||
switch (type) {
|
||||
case 'v':
|
||||
if (buffer[0] != '0')
|
||||
g_print ("wrong SDP version\n");
|
||||
g_warning ("wrong SDP version");
|
||||
sdp_message_set_version (c->msg, buffer);
|
||||
break;
|
||||
case 'o':
|
||||
|
@ -550,11 +550,9 @@ sdp_parse_line (SDPContext * c, gchar type, guint8 * buffer)
|
|||
sdp_media_add_format (&nmedia, str);
|
||||
} while (*p != '\0');
|
||||
|
||||
g_print ("%p\n", &nmedia);
|
||||
sdp_message_add_media (c->msg, &nmedia);
|
||||
c->media =
|
||||
&g_array_index (c->msg->medias, SDPMedia, c->msg->medias->len - 1);
|
||||
g_print ("%p\n", c->media);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
Loading…
Reference in a new issue