]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/rtsp.c
Add support for track numbers when they are set via strings
[ffmpeg] / libavformat / rtsp.c
index 6c01f5e673dd0ca989a8f256ac05c45b05a6a232..a931e62bdabce9610c38ee36b1c69af6c669f927 100644 (file)
  */
 #include "avformat.h"
 
-#include <unistd.h> /* for select() prototype */
 #include <sys/time.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#ifndef __BEOS__
-# include <arpa/inet.h>
-#else
-# include "barpainet.h"
-#endif
+#include <unistd.h> /* for select() prototype */
+#include "network.h"
 
 #include "rtp_internal.h"
 
@@ -83,8 +77,6 @@ static int rtsp_read_play(AVFormatContext *s);
 
 int rtsp_default_protocols = (1 << RTSP_PROTOCOL_RTP_UDP);
 
-FFRTSPCallback *ff_rtsp_callback = NULL;
-
 static int rtsp_probe(AVProbeData *p)
 {
     if (strstart(p->filename, "rtsp:", NULL))
@@ -251,7 +243,7 @@ static void sdp_parse_fmtp_config(AVCodecContext *codec, char *attr, char *value
 {
     switch (codec->codec_id) {
         case CODEC_ID_MPEG4:
-        case CODEC_ID_MPEG4AAC:
+        case CODEC_ID_AAC:
             if (!strcmp(attr, "config")) {
                 /* decode the hexa encoded parameter */
                 int len = hex_to_data(NULL, value);
@@ -319,18 +311,9 @@ static void sdp_parse_fmtp(AVStream *st, const char *p)
     AVCodecContext *codec = st->codec;
     rtp_payload_data_t *rtp_payload_data = &rtsp_st->rtp_payload_data;
 
-    // TODO (Replace with rtsp_next_attr_and_value)
     /* loop on each attribute */
-    for(;;) {
-        skip_spaces(&p);
-        if (*p == '\0')
-            break;
-        get_word_sep(attr, sizeof(attr), "=", &p);
-        if (*p == '=')
-            p++;
-        get_word_sep(value, sizeof(value), ";", &p);
-        if (*p == ';')
-            p++;
+    while(rtsp_next_attr_and_value(&p, attr, sizeof(attr), value, sizeof(value)))
+    {
         /* grab the codec extra_data from the config parameter of the fmtp line */
         sdp_parse_fmtp_config(codec, attr, value);
         /* Looking for a known attribute */
@@ -832,13 +815,6 @@ static void rtsp_send_cmd(AVFormatContext *s,
         *content_ptr = content;
 }
 
-/* useful for modules: set RTSP callback function */
-
-void rtsp_set_callback(FFRTSPCallback *rtsp_cb)
-{
-    ff_rtsp_callback = rtsp_cb;
-}
-
 
 /* close and free RTSP streams */
 static void rtsp_close_streams(RTSPState *rt)
@@ -865,13 +841,13 @@ static int rtsp_read_header(AVFormatContext *s,
                             AVFormatParameters *ap)
 {
     RTSPState *rt = s->priv_data;
-    char host[1024], path[1024], tcpname[1024], cmd[2048];
+    char host[1024], path[1024], tcpname[1024], cmd[2048], *option_list, *option;
     URLContext *rtsp_hd;
     int port, i, j, ret, err;
     RTSPHeader reply1, *reply = &reply1;
     unsigned char *content = NULL;
     RTSPStream *rtsp_st;
-    int protocol_mask;
+    int protocol_mask = 0;
     AVStream *st;
 
     /* extract hostname and port */
@@ -880,6 +856,30 @@ static int rtsp_read_header(AVFormatContext *s,
     if (port < 0)
         port = RTSP_DEFAULT_PORT;
 
+    /* search for options */
+    option_list = strchr(path, '?');
+    if (option_list) {
+        /* remove the options from the path */
+        *option_list++ = 0;
+        while(option_list) {
+            /* move the option pointer */
+            option = option_list;
+            option_list = strchr(option_list, '&');
+            if (option_list)
+                *(option_list++) = 0;
+            /* handle the options */
+            if (strcmp(option, "udp") == 0)
+                protocol_mask = (1<< RTSP_PROTOCOL_RTP_UDP);
+            else if (strcmp(option, "multicast") == 0)
+                protocol_mask = (1<< RTSP_PROTOCOL_RTP_UDP_MULTICAST);
+            else if (strcmp(option, "tcp") == 0)
+                protocol_mask = (1<< RTSP_PROTOCOL_RTP_TCP);
+        }
+    }
+
+    if (!protocol_mask)
+        protocol_mask = rtsp_default_protocols;
+
     /* open the tcp connexion */
     snprintf(tcpname, sizeof(tcpname), "tcp://%s:%d", host, port);
     if (url_open(&rtsp_hd, tcpname, URL_RDWR) < 0)
@@ -910,8 +910,6 @@ static int rtsp_read_header(AVFormatContext *s,
         goto fail;
     }
 
-    protocol_mask = rtsp_default_protocols;
-
     /* for each stream, make the setup request */
     /* XXX: we assume the same server is used for the control of each
        RTSP stream */
@@ -1055,16 +1053,6 @@ static int rtsp_read_header(AVFormatContext *s,
         }
     }
 
-    /* use callback if available to extend setup */
-    if (ff_rtsp_callback) {
-        if (ff_rtsp_callback(RTSP_ACTION_CLIENT_SETUP, rt->session_id,
-                             NULL, 0, rt->last_reply) < 0) {
-            err = AVERROR_INVALIDDATA;
-            goto fail;
-        }
-    }
-
-
     rt->state = RTSP_STATE_IDLE;
     rt->seek_timestamp = 0; /* default is to start stream at position
                                zero */
@@ -1311,16 +1299,12 @@ static int rtsp_read_close(AVFormatContext *s)
              s->filename);
     rtsp_send_cmd(s, cmd, reply, NULL);
 
-    if (ff_rtsp_callback) {
-        ff_rtsp_callback(RTSP_ACTION_CLIENT_TEARDOWN, rt->session_id,
-                         NULL, 0, NULL);
-    }
-
     rtsp_close_streams(rt);
     url_close(rt->rtsp_hd);
     return 0;
 }
 
+#ifdef CONFIG_RTSP_DEMUXER
 AVInputFormat rtsp_demuxer = {
     "rtsp",
     "RTSP input format",
@@ -1334,6 +1318,7 @@ AVInputFormat rtsp_demuxer = {
     .read_play = rtsp_read_play,
     .read_pause = rtsp_read_pause,
 };
+#endif
 
 static int sdp_probe(AVProbeData *p1)
 {
@@ -1438,6 +1423,7 @@ AVInputFormat sdp_demuxer = {
 };
 #endif
 
+#ifdef CONFIG_REDIR_DEMUXER
 /* dummy redirector format (used directly in av_open_input_file now) */
 static int redir_probe(AVProbeData *pd)
 {
@@ -1500,3 +1486,4 @@ AVInputFormat redir_demuxer = {
     NULL,
     NULL,
 };
+#endif