Remove the inclusion of rtsp.h and rtp.h from avformat.h, and
[ffmpeg.git] / ffserver.c
index f8ccfcb..96b2987 100644 (file)
@@ -26,6 +26,8 @@
 #include <string.h>
 #include <stdlib.h>
 #include "avformat.h"
+#include "rtsp.h"
+#include "rtp.h"
 
 #include <stdarg.h>
 #include <unistd.h>
 #include "ffserver.h"
 #include "random.h"
 #include "avstring.h"
+#include "cmdutils.h"
 
 #undef exit
 
+static const char program_name[] = "FFserver";
+static const int program_birth_year = 2000;
+
 /* maximum number of simultaneous HTTP connections */
 #define HTTP_MAX_CONNECTIONS 2000
 
@@ -1626,7 +1632,7 @@ static void compute_stats(HTTPContext *c)
                     strcpy(eosf - 4, ".asx");
                 else if (strcmp(eosf - 3, ".rm") == 0)
                     strcpy(eosf - 3, ".ram");
-                else if (stream->fmt == &rtp_muxer) {
+                else if (stream->fmt && !strcmp(stream->fmt->name, "rtp")) {
                     /* generate a sample RTSP director if
                        unicast. Generate an SDP redirector if
                        multicast */
@@ -1886,7 +1892,11 @@ static int open_input_stream(HTTPContext *c, const char *info)
         buf_size = FFM_PACKET_SIZE;
         /* compute position (absolute time) */
         if (find_info_tag(buf, sizeof(buf), "date", info))
+        {
             stream_pos = parse_date(buf, 0);
+            if (stream_pos == INT64_MIN)
+                return -1;
+        }
         else if (find_info_tag(buf, sizeof(buf), "buffer", info)) {
             int prebuffer = strtol(buf, 0, 10);
             stream_pos = av_gettime() - prebuffer * (int64_t)1000000;
@@ -1897,7 +1907,11 @@ static int open_input_stream(HTTPContext *c, const char *info)
         buf_size = 0;
         /* compute position (relative time) */
         if (find_info_tag(buf, sizeof(buf), "date", info))
+        {
             stream_pos = parse_date(buf, 1);
+            if (stream_pos == INT64_MIN)
+                return -1;
+        }
         else
             stream_pos = 0;
     }
@@ -1916,7 +1930,9 @@ static int open_input_stream(HTTPContext *c, const char *info)
         http_log("%s not found", input_filename);
         return -1;
     }
+    s->flags |= AVFMT_FLAG_GENPTS;
     c->fmt_in = s;
+    av_find_stream_info(c->fmt_in);
 
     /* open each parser */
     for(i=0;i<s->nb_streams;i++)
@@ -2622,94 +2638,38 @@ static int rtsp_parse_request(HTTPContext *c)
     return 0;
 }
 
-/* XXX: move that to rtsp.c, but would need to replace FFStream by
-   AVFormatContext */
 static int prepare_sdp_description(FFStream *stream, uint8_t **pbuffer,
                                    struct in_addr my_ip)
 {
-    ByteIOContext pb1, *pb = &pb1;
-    int i, payload_type, port, private_payload_type, j;
-    const char *ipstr, *title, *mediatype;
-    AVStream *st;
+    AVFormatContext *avc;
+    AVStream avs[MAX_STREAMS];
+    int i;
 
-    if (url_open_dyn_buf(pb) < 0)
+    avc =  av_alloc_format_context();
+    if (avc == NULL) {
         return -1;
+    }
+    if (stream->title[0] != 0) {
+        av_strlcpy(avc->title, stream->title, sizeof(avc->title));
+    } else {
+        av_strlcpy(avc->title, "No Title", sizeof(avc->title));
+    }
+    avc->nb_streams = stream->nb_streams;
+    if (stream->is_multicast) {
+        snprintf(avc->filename, 1024, "rtp://%s:%d?multicast=1?ttl=%d",
+                 inet_ntoa(stream->multicast_ip),
+                 stream->multicast_port, stream->multicast_ttl);
+    }
 
-    /* general media info */
-
-    url_fprintf(pb, "v=0\n");
-    ipstr = inet_ntoa(my_ip);
-    url_fprintf(pb, "o=- 0 0 IN IP4 %s\n", ipstr);
-    title = stream->title;
-    if (title[0] == '\0')
-        title = "No Title";
-    url_fprintf(pb, "s=%s\n", title);
-    if (stream->comment[0] != '\0')
-        url_fprintf(pb, "i=%s\n", stream->comment);
-    if (stream->is_multicast)
-        url_fprintf(pb, "c=IN IP4 %s\n", inet_ntoa(stream->multicast_ip));
-
-    /* for each stream, we output the necessary info */
-    private_payload_type = RTP_PT_PRIVATE;
     for(i = 0; i < stream->nb_streams; i++) {
-        st = stream->streams[i];
-        if (st->codec->codec_id == CODEC_ID_MPEG2TS)
-            mediatype = "video";
-        else {
-            switch(st->codec->codec_type) {
-            case CODEC_TYPE_AUDIO:
-                mediatype = "audio";
-                break;
-            case CODEC_TYPE_VIDEO:
-                mediatype = "video";
-                break;
-            default:
-                mediatype = "application";
-                break;
-            }
-        }
-        /* NOTE: the port indication is not correct in case of
-           unicast. It is not an issue because RTSP gives it */
-        payload_type = rtp_get_payload_type(st->codec);
-        if (payload_type < 0)
-            payload_type = private_payload_type++;
-        if (stream->is_multicast)
-            port = stream->multicast_port + 2 * i;
-        else
-            port = 0;
-
-        url_fprintf(pb, "m=%s %d RTP/AVP %d\n",
-                    mediatype, port, payload_type);
-        if (payload_type >= RTP_PT_PRIVATE) {
-            /* for private payload type, we need to give more info */
-            switch(st->codec->codec_id) {
-            case CODEC_ID_MPEG4:
-                {
-                    uint8_t *data;
-                    url_fprintf(pb, "a=rtpmap:%d MP4V-ES/%d\n",
-                                payload_type, 90000);
-                    /* we must also add the mpeg4 header */
-                    data = st->codec->extradata;
-                    if (data) {
-                        url_fprintf(pb, "a=fmtp:%d config=", payload_type);
-                        for(j=0;j<st->codec->extradata_size;j++)
-                            url_fprintf(pb, "%02x", data[j]);
-                        url_fprintf(pb, "\n");
-                    }
-                }
-                break;
-            default:
-                /* XXX: add other codecs ? */
-                goto fail;
-            }
-        }
-        url_fprintf(pb, "a=control:streamid=%d\n", i);
+        avc->streams[i] = &avs[i];
+        avc->streams[i]->codec = stream->streams[i]->codec;
     }
-    return url_close_dyn_buf(pb, pbuffer);
- fail:
-    url_close_dyn_buf(pb, pbuffer);
-    av_free(*pbuffer);
-    return -1;
+    *pbuffer = av_mallocz(2048);
+    avf_sdp_create(&avc, 1, *pbuffer, 2048);
+    av_free(avc);
+
+    return strlen(*pbuffer);
 }
 
 static void rtsp_cmd_options(HTTPContext *c, const char *url)
@@ -2737,7 +2697,8 @@ static void rtsp_cmd_describe(HTTPContext *c, const char *url)
         path++;
 
     for(stream = first_stream; stream != NULL; stream = stream->next) {
-        if (!stream->is_feed && stream->fmt == &rtp_muxer &&
+        if (!stream->is_feed &&
+            stream->fmt && !strcmp(stream->fmt->name, "rtp") &&
             !strcmp(path, stream->filename)) {
             goto found;
         }
@@ -2812,7 +2773,8 @@ static void rtsp_cmd_setup(HTTPContext *c, const char *url,
 
     /* now check each stream */
     for(stream = first_stream; stream != NULL; stream = stream->next) {
-        if (!stream->is_feed && stream->fmt == &rtp_muxer) {
+        if (!stream->is_feed &&
+            stream->fmt && !strcmp(stream->fmt->name, "rtp")) {
             /* accept aggregate filenames only if single stream */
             if (!strcmp(path, stream->filename)) {
                 if (stream->nb_streams != 1) {
@@ -3130,7 +3092,7 @@ static int rtp_new_av_stream(HTTPContext *c,
     ctx = av_alloc_format_context();
     if (!ctx)
         return -1;
-    ctx->oformat = &rtp_muxer;
+    ctx->oformat = guess_format("rtp", NULL, NULL);
 
     st = av_mallocz(sizeof(AVStream));
     if (!st)
@@ -3349,7 +3311,7 @@ static void build_file_streams(void)
             /* try to open the file */
             /* open stream */
             stream->ap_in = av_mallocz(sizeof(AVFormatParameters));
-            if (stream->fmt == &rtp_muxer) {
+            if (stream->fmt && !strcmp(stream->fmt->name, "rtp")) {
                 /* specific case : if transport stream output to RTP,
                    we use a raw transport stream reader */
                 stream->ap_in->mpeg2ts_raw = 1;
@@ -4356,14 +4318,8 @@ static int parse_ffconfig(const char *filename)
         return 0;
 }
 
-static void show_banner(void)
-{
-    printf("ffserver version " FFMPEG_VERSION ", Copyright (c) 2000-2006 Fabrice Bellard, et al.\n");
-}
-
 static void show_help(void)
 {
-    show_banner();
     printf("usage: ffserver [-L] [-h] [-f configfile]\n"
            "Hyper fast multi format Audio/Video streaming server\n"
            "\n"
@@ -4373,26 +4329,6 @@ static void show_help(void)
            );
 }
 
-static void show_license(void)
-{
-    show_banner();
-    printf(
-    "FFmpeg is free software; you can redistribute it and/or\n"
-    "modify it under the terms of the GNU Lesser General Public\n"
-    "License as published by the Free Software Foundation; either\n"
-    "version 2.1 of the License, or (at your option) any later version.\n"
-    "\n"
-    "FFmpeg is distributed in the hope that it will be useful,\n"
-    "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
-    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n"
-    "Lesser General Public License for more details.\n"
-    "\n"
-    "You should have received a copy of the GNU Lesser General Public\n"
-    "License along with FFmpeg; if not, write to the Free Software\n"
-    "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n"
-    );
-}
-
 static void handle_child_exit(int sig)
 {
     pid_t pid;
@@ -4426,6 +4362,8 @@ int main(int argc, char **argv)
 
     av_register_all();
 
+    show_banner(program_name, program_birth_year);
+
     config_filename = "/etc/ffserver.conf";
 
     my_program_name = argv[0];