Merge commit '7c5012127fb7e18f0616011257bb4248f6a8b608'
[ffmpeg.git] / ffserver.c
similarity index 98%
rename from avserver.c
rename to ffserver.c
index de050a6..c03278c 100644 (file)
@@ -1,24 +1,28 @@
 /*
- * Multiple format streaming server
  * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
  *
- * This file is part of Libav.
+ * This file is part of FFmpeg.
  *
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg 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
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
+/**
+ * @file
+ * multiple format streaming server based on the FFmpeg libraries
+ */
+
 #include "config.h"
 #if !HAVE_CLOSESOCKET
 #define closesocket close
@@ -26,7 +30,7 @@
 #include <string.h>
 #include <stdlib.h>
 #include "libavformat/avformat.h"
-// FIXME those are internal headers, avserver _really_ shouldn't use them
+// FIXME those are internal headers, ffserver _really_ shouldn't use them
 #include "libavformat/ffm.h"
 #include "libavformat/network.h"
 #include "libavformat/os_support.h"
@@ -60,7 +64,7 @@
 
 #include "cmdutils.h"
 
-const char program_name[] = "avserver";
+const char program_name[] = "ffserver";
 const int program_birth_year = 2000;
 
 static const OptionDef options[];
@@ -201,7 +205,7 @@ typedef struct IPAddressACL {
     struct in_addr last;
 } IPAddressACL;
 
-/* description of each stream of the avserver.conf file */
+/* description of each stream of the ffserver.conf file */
 typedef struct FFStream {
     enum StreamType stream_type;
     char filename[1024];     /* stream filename */
@@ -224,8 +228,8 @@ typedef struct FFStream {
     char title[512];
     char copyright[512];
     char comment[512];
-    pid_t pid;  /* of avconv process */
-    time_t pid_start;  /* of avconv process */
+    pid_t pid;  /* Of ffmpeg process */
+    time_t pid_start;  /* Of ffmpeg process */
     char **child_argv;
     struct FFStream *next;
     unsigned bandwidth; /* bandwidth, in kbits/s */
@@ -300,10 +304,10 @@ static int rtp_new_av_stream(HTTPContext *c,
 static const char *my_program_name;
 static const char *my_program_dir;
 
-static const char *config_filename = "/etc/avserver.conf";
+static const char *config_filename = "/etc/ffserver.conf";
 
-static int avserver_debug;
-static int avserver_daemon;
+static int ffserver_debug;
+static int ffserver_daemon;
 static int no_launch;
 static int need_to_start_children;
 
@@ -321,12 +325,12 @@ static AVLFG random_state;
 
 static FILE *logfile = NULL;
 
-void exit_program(int ret)
+/* FIXME: make ffserver work with IPv6 */
+void av_noreturn exit_program(int ret)
 {
     exit(ret);
 }
 
-/* FIXME: make avserver work with IPv6 */
 /* resolve host with also IP address parsing */
 static int resolve_host(struct in_addr *sin_addr, const char *hostname)
 {
@@ -474,7 +478,7 @@ static void start_children(FFStream *feed)
                     slash = pathname;
                 else
                     slash++;
-                strcpy(slash, "avconv");
+                strcpy(slash, "ffmpeg");
 
                 http_log("Launch command line: ");
                 http_log("%s ", pathname);
@@ -485,7 +489,7 @@ static void start_children(FFStream *feed)
                 for (i = 3; i < 256; i++)
                     close(i);
 
-                if (!avserver_debug) {
+                if (!ffserver_debug) {
                     i = open("/dev/null", O_RDWR);
                     if (i != -1) {
                         dup2(i, 0);
@@ -496,7 +500,10 @@ static void start_children(FFStream *feed)
                 }
 
                 /* This is needed to make relative pathnames work */
-                chdir(my_program_dir);
+                if (chdir(my_program_dir) < 0) {
+                    http_log("chdir failed\n");
+                    exit(1);
+                }
 
                 signal(SIGPIPE, SIG_DFL);
 
@@ -626,7 +633,7 @@ static int http_server(void)
         return -1;
     }
 
-    http_log("AVserver started.\n");
+    http_log("FFserver started.\n");
 
     start_children(first_feed);
 
@@ -670,7 +677,7 @@ static int http_server(void)
                     poll_entry->events = POLLOUT;
                     poll_entry++;
                 } else {
-                    /* when avserver is doing the timing, we work by
+                    /* when ffserver is doing the timing, we work by
                        looking at which packet need to be sent every
                        10 ms */
                     delay1 = 10; /* one tick wait XXX: 10 ms assumed */
@@ -1486,7 +1493,7 @@ static int http_parse_request(HTTPContext *c)
 
     av_strlcpy(c->protocol, protocol, sizeof(c->protocol));
 
-    if (avserver_debug)
+    if (ffserver_debug)
         http_log("%s - - New connection: %s %s\n", inet_ntoa(c->from_addr.sin_addr), cmd, url);
 
     /* find the filename and the optional info string in the request */
@@ -1649,7 +1656,7 @@ static int http_parse_request(HTTPContext *c)
                                       "Content-type: video/x-ms-asf\r\n"
                                       "\r\n"
                                       "<ASX Version=\"3\">\r\n"
-                                      //"<!-- Autogenerated by avserver -->\r\n"
+                                      //"<!-- Autogenerated by ffserver -->\r\n"
                                       "<ENTRY><REF HREF=\"http://%s/%s%s\"/></ENTRY>\r\n"
                                       "</ASX>\r\n", hostbuf, filename, info);
                         break;
@@ -1658,7 +1665,7 @@ static int http_parse_request(HTTPContext *c)
                                       "HTTP/1.0 200 RAM Follows\r\n"
                                       "Content-type: audio/x-pn-realaudio\r\n"
                                       "\r\n"
-                                      "# Autogenerated by avserver\r\n"
+                                      "# Autogenerated by ffserver\r\n"
                                       "http://%s/%s%s\r\n", hostbuf, filename, info);
                         break;
                     case REDIR_ASF:
@@ -2118,12 +2125,13 @@ static int open_input_stream(HTTPContext *c, const char *info)
     char buf[128];
     char input_filename[1024];
     AVFormatContext *s = NULL;
-    int i, ret;
+    int buf_size, i, ret;
     int64_t stream_pos;
 
     /* find file name */
     if (c->stream->feed) {
         strcpy(input_filename, c->stream->feed->feed_filename);
+        buf_size = FFM_PACKET_SIZE;
         /* compute position (absolute time) */
         if (av_find_info_tag(buf, sizeof(buf), "date", info)) {
             if ((ret = av_parse_time(&stream_pos, buf, 0)) < 0)
@@ -2135,6 +2143,7 @@ static int open_input_stream(HTTPContext *c, const char *info)
             stream_pos = av_gettime() - c->stream->prebuffer * (int64_t)1000;
     } else {
         strcpy(input_filename, c->stream->feed_filename);
+        buf_size = 0;
         /* compute position (relative time) */
         if (av_find_info_tag(buf, sizeof(buf), "date", info)) {
             if ((ret = av_parse_time(&stream_pos, buf, 1)) < 0)
@@ -2150,6 +2159,10 @@ static int open_input_stream(HTTPContext *c, const char *info)
         http_log("could not open %s: %d\n", input_filename, ret);
         return -1;
     }
+
+    /* set buffer size */
+    if (buf_size > 0) ffio_set_buf_size(s->pb, buf_size);
+
     s->flags |= AVFMT_FLAG_GENPTS;
     c->fmt_in = s;
     if (strcmp(s->iformat->name, "ffm") && avformat_find_stream_info(c->fmt_in, NULL) < 0) {
@@ -2246,7 +2259,7 @@ static int http_prepare_data(HTTPContext *c)
 
         /*
          * HACK to avoid mpeg ps muxer to spit many underflow errors
-         * Default value from Libav
+         * Default value from FFmpeg
          * Try to set it use configuration option
          */
         c->fmt_ctx.max_delay = (int)(0.7*AV_TIME_BASE);
@@ -3444,7 +3457,7 @@ static int rtp_new_av_stream(HTTPContext *c,
 }
 
 /********************************************************************/
-/* avserver initialization */
+/* ffserver initialization */
 
 static AVStream *add_av_stream1(FFStream *stream, AVCodecContext *codec, int copy)
 {
@@ -3655,6 +3668,8 @@ static void build_feed_streams(void)
             int matches = 0;
 
             if (avformat_open_input(&s, feed->feed_filename, NULL, NULL) >= 0) {
+                /* set buffer size */
+                ffio_set_buf_size(s->pb, FFM_PACKET_SIZE);
                 /* Now see if it matches */
                 if (s->nb_streams == feed->nb_streams) {
                     matches = 1;
@@ -3900,10 +3915,10 @@ static void load_module(const char *filename)
         return;
     }
 
-    init_func = dlsym(dll, "avserver_module_init");
+    init_func = dlsym(dll, "ffserver_module_init");
     if (!init_func) {
         fprintf(stderr,
-                "%s: init function 'avserver_module_init()' not found\n",
+                "%s: init function 'ffserver_module_init()' not found\n",
                 filename);
         dlclose(dll);
     }
@@ -3912,7 +3927,7 @@ static void load_module(const char *filename)
 }
 #endif
 
-static int avserver_opt_default(const char *opt, const char *arg,
+static int ffserver_opt_default(const char *opt, const char *arg,
                        AVCodecContext *avctx, int type)
 {
     int ret = 0;
@@ -3922,7 +3937,7 @@ static int avserver_opt_default(const char *opt, const char *arg,
     return ret;
 }
 
-static int avserver_opt_preset(const char *arg,
+static int ffserver_opt_preset(const char *arg,
                        AVCodecContext *avctx, int type,
                        enum AVCodecID *audio_id, enum AVCodecID *video_id)
 {
@@ -3953,7 +3968,7 @@ static int avserver_opt_preset(const char *arg,
             *video_id = opt_video_codec(tmp2);
         }else if(!strcmp(tmp, "scodec")){
             /* opt_subtitle_codec(tmp2); */
-        }else if(avserver_opt_default(tmp, tmp2, avctx, type) < 0){
+        }else if(ffserver_opt_default(tmp, tmp2, avctx, type) < 0){
             fprintf(stderr, "%s: Invalid option or argument: '%s', parsed as '%s' = '%s'\n", filename, line, tmp, tmp2);
             ret = 1;
             break;
@@ -3965,7 +3980,7 @@ static int avserver_opt_preset(const char *arg,
     return ret;
 }
 
-static AVOutputFormat *avserver_guess_format(const char *short_name, const char *filename,
+static AVOutputFormat *ffserver_guess_format(const char *short_name, const char *filename,
                                              const char *mime_type)
 {
     AVOutputFormat *fmt = av_guess_format(short_name, filename, mime_type);
@@ -4052,7 +4067,7 @@ static int parse_ffconfig(const char *filename)
                 ERROR("%s:%d: Invalid host/IP address: %s\n", arg);
             }
         } else if (!av_strcasecmp(cmd, "NoDaemon")) {
-            avserver_daemon = 0;
+            ffserver_daemon = 0;
         } else if (!av_strcasecmp(cmd, "RTSPPort")) {
             get_arg(arg, sizeof(arg), &p);
             val = atoi(arg);
@@ -4089,7 +4104,7 @@ static int parse_ffconfig(const char *filename)
             } else
                 max_bandwidth = llval;
         } else if (!av_strcasecmp(cmd, "CustomLog")) {
-            if (!avserver_debug)
+            if (!ffserver_debug)
                 get_arg(logfilename, sizeof(logfilename), &p);
         } else if (!av_strcasecmp(cmd, "<Feed")) {
             /*********************************************/
@@ -4213,9 +4228,10 @@ static int parse_ffconfig(const char *filename)
                     }
                 }
 
-                stream->fmt = avserver_guess_format(NULL, stream->filename, NULL);
+                stream->fmt = ffserver_guess_format(NULL, stream->filename, NULL);
                 avcodec_get_context_defaults3(&video_enc, NULL);
                 avcodec_get_context_defaults3(&audio_enc, NULL);
+
                 audio_id = AV_CODEC_ID_NONE;
                 video_id = AV_CODEC_ID_NONE;
                 if (stream->fmt) {
@@ -4253,7 +4269,7 @@ static int parse_ffconfig(const char *filename)
                     /* jpeg cannot be used here, so use single frame jpeg */
                     if (!strcmp(arg, "jpeg"))
                         strcpy(arg, "mjpeg");
-                    stream->fmt = avserver_guess_format(arg, NULL, NULL);
+                    stream->fmt = ffserver_guess_format(arg, NULL, NULL);
                     if (!stream->fmt) {
                         ERROR("Unknown Format: %s\n", arg);
                     }
@@ -4416,7 +4432,7 @@ static int parse_ffconfig(const char *filename)
                 avctx = &audio_enc;
                 type = AV_OPT_FLAG_AUDIO_PARAM;
             }
-            if (avserver_opt_default(arg, arg2, avctx, type|AV_OPT_FLAG_ENCODING_PARAM)) {
+            if (ffserver_opt_default(arg, arg2, avctx, type|AV_OPT_FLAG_ENCODING_PARAM)) {
                 ERROR("AVOption error: %s %s\n", arg, arg2);
             }
         } else if (!av_strcasecmp(cmd, "AVPresetVideo") ||
@@ -4433,7 +4449,7 @@ static int parse_ffconfig(const char *filename)
                 audio_enc.codec_id = audio_id;
                 type = AV_OPT_FLAG_AUDIO_PARAM;
             }
-            if (avserver_opt_preset(arg, avctx, type|AV_OPT_FLAG_ENCODING_PARAM, &audio_id, &video_id)) {
+            if (ffserver_opt_preset(arg, avctx, type|AV_OPT_FLAG_ENCODING_PARAM, &audio_id, &video_id)) {
                 ERROR("AVPreset error: %s\n", arg);
             }
         } else if (!av_strcasecmp(cmd, "VideoTag")) {
@@ -4624,24 +4640,25 @@ static void handle_child_exit(int sig)
 
 static void opt_debug(void)
 {
-    avserver_debug = 1;
-    avserver_daemon = 0;
+    ffserver_debug = 1;
+    ffserver_daemon = 0;
     logfilename[0] = '-';
 }
 
-static void show_help(void)
+static int show_help(const char *opt, const char *arg)
 {
-    printf("usage: avserver [options]\n"
+    printf("usage: ffserver [options]\n"
            "Hyper fast multi format Audio/Video streaming server\n");
     printf("\n");
     show_help_options(options, "Main options:", 0, 0);
+    return 0;
 }
 
 static const OptionDef options[] = {
 #include "cmdutils_common_opts.h"
     { "n", OPT_BOOL, {(void *)&no_launch }, "enable no-launch mode" },
     { "d", 0, {(void*)opt_debug}, "enable debug mode" },
-    { "f", HAS_ARG | OPT_STRING, {(void*)&config_filename }, "use configfile instead of /etc/avserver.conf", "configfile" },
+    { "f", HAS_ARG | OPT_STRING, {(void*)&config_filename }, "use configfile instead of /etc/ffserver.conf", "configfile" },
     { NULL },
 };
 
@@ -4653,11 +4670,11 @@ int main(int argc, char **argv)
     av_register_all();
     avformat_network_init();
 
-    show_banner();
+    show_banner(argc, argv, options);
 
     my_program_name = argv[0];
     my_program_dir = getcwd(0, 0);
-    avserver_daemon = 1;
+    ffserver_daemon = 1;
 
     parse_options(NULL, argc, argv, options, NULL);
 
@@ -4690,7 +4707,7 @@ int main(int argc, char **argv)
     compute_bandwidth();
 
     /* put the process in background and detach it from its TTY */
-    if (avserver_daemon) {
+    if (ffserver_daemon) {
         int pid;
 
         pid = fork();
@@ -4717,7 +4734,7 @@ int main(int argc, char **argv)
     /* signal init */
     signal(SIGPIPE, SIG_IGN);
 
-    if (avserver_daemon)
+    if (ffserver_daemon)
         chdir("/");
 
     if (http_server() < 0) {