X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=avserver.c;h=ad7bc78f0cdeb8da927053db11d122b449332b6e;hb=54cb096ee4558b3bfc28c2fcd6418ce82dc39fe1;hp=7b8bf1397a094656852ded96fc199599dfd4a25a;hpb=f5e717f3c735af5c941b458d42615c97028aa916;p=ffmpeg diff --git a/avserver.c b/avserver.c index 7b8bf1397a0..ad7bc78f0cd 100644 --- a/avserver.c +++ b/avserver.c @@ -24,23 +24,29 @@ #define closesocket close #endif #include -#include #include +#include #include "libavformat/avformat.h" +// FIXME those are internal headers, avserver _really_ shouldn't use them #include "libavformat/ffm.h" #include "libavformat/network.h" #include "libavformat/os_support.h" #include "libavformat/rtpdec.h" #include "libavformat/rtsp.h" -// XXX for ffio_open_dyn_packet_buffer, to be removed #include "libavformat/avio_internal.h" +#include "libavformat/internal.h" +#include "libavformat/url.h" + #include "libavutil/avstring.h" #include "libavutil/lfg.h" #include "libavutil/dict.h" +#include "libavutil/intreadwrite.h" #include "libavutil/mathematics.h" #include "libavutil/random_seed.h" #include "libavutil/parseutils.h" #include "libavutil/opt.h" +#include "libavutil/time.h" + #include #include #include @@ -49,7 +55,6 @@ #include #endif #include -#include #include #include #include @@ -223,8 +228,8 @@ typedef struct FFStream { char title[512]; char copyright[512]; char comment[512]; - pid_t pid; /* Of ffmpeg process */ - time_t pid_start; /* Of ffmpeg process */ + pid_t pid; /* of avconv process */ + time_t pid_start; /* of avconv process */ char **child_argv; struct FFStream *next; unsigned bandwidth; /* bandwidth, in kbits/s */ @@ -297,12 +302,10 @@ static int rtp_new_av_stream(HTTPContext *c, HTTPContext *rtsp_c); static const char *my_program_name; -static const char *my_program_dir; static const char *config_filename = "/etc/avserver.conf"; static int avserver_debug; -static int avserver_daemon; static int no_launch; static int need_to_start_children; @@ -320,9 +323,35 @@ static AVLFG random_state; static FILE *logfile = NULL; -void exit_program(int ret) +static int64_t ffm_read_write_index(int fd) +{ + uint8_t buf[8]; + + lseek(fd, 8, SEEK_SET); + if (read(fd, buf, 8) != 8) + return AVERROR(EIO); + return AV_RB64(buf); +} + +static int ffm_write_write_index(int fd, int64_t pos) { - exit(ret); + uint8_t buf[8]; + int i; + + for(i=0;i<8;i++) + buf[i] = (pos >> (56 - i * 8)) & 0xff; + lseek(fd, 8, SEEK_SET); + if (write(fd, buf, 8) != 8) + return AVERROR(EIO); + return 8; +} + +static void ffm_set_write_index(AVFormatContext *s, int64_t pos, + int64_t file_size) +{ + FFMContext *ffm = s->priv_data; + ffm->write_index = pos; + ffm->file_size = file_size; } /* FIXME: make avserver work with IPv6 */ @@ -333,8 +362,7 @@ static int resolve_host(struct in_addr *sin_addr, const char *hostname) if (!ff_inet_aton(hostname, sin_addr)) { #if HAVE_GETADDRINFO struct addrinfo *ai, *cur; - struct addrinfo hints; - memset(&hints, 0, sizeof(hints)); + struct addrinfo hints = { 0 }; hints.ai_family = AF_INET; if (getaddrinfo(hostname, NULL, &hints, &ai)) return -1; @@ -474,9 +502,9 @@ static void start_children(FFStream *feed) slash = pathname; else slash++; - strcpy(slash, "ffmpeg"); + strcpy(slash, "avconv"); - http_log("Launch commandline: "); + http_log("Launch command line: "); http_log("%s ", pathname); for (i = 1; feed->child_argv[i] && feed->child_argv[i][0]; i++) http_log("%s ", feed->child_argv[i]); @@ -486,18 +514,14 @@ static void start_children(FFStream *feed) close(i); if (!avserver_debug) { - i = open("/dev/null", O_RDWR); - if (i != -1) { - dup2(i, 0); - dup2(i, 1); - dup2(i, 2); - close(i); - } + if (!freopen("/dev/null", "r", stdin)) + http_log("failed to redirect STDIN to /dev/null\n;"); + if (!freopen("/dev/null", "w", stdout)) + http_log("failed to redirect STDOUT to /dev/null\n;"); + if (!freopen("/dev/null", "w", stderr)) + http_log("failed to redirect STDERR to /dev/null\n;"); } - /* This is needed to make relative pathnames work */ - chdir(my_program_dir); - signal(SIGPIPE, SIG_DFL); execvp(pathname, feed->child_argv); @@ -770,7 +794,8 @@ static void http_send_too_busy_reply(int fd) static void new_connection(int server_fd, int is_rtsp) { struct sockaddr_in from_addr; - int fd, len; + socklen_t len; + int fd; HTTPContext *c = NULL; len = sizeof(from_addr); @@ -850,7 +875,7 @@ static void close_connection(HTTPContext *c) if (st->codec->codec) avcodec_close(st->codec); } - av_close_input_file(c->fmt_in); + avformat_close_input(&c->fmt_in); } /* free RTP output streams if any */ @@ -868,7 +893,7 @@ static void close_connection(HTTPContext *c) } h = c->rtp_handles[i]; if (h) - url_close(h); + ffurl_close(h); } ctx = &c->fmt_ctx; @@ -1085,13 +1110,13 @@ static int extract_rates(char *rates, int ratelen, const char *request) const char *p; for (p = request; *p && *p != '\r' && *p != '\n'; ) { - if (strncasecmp(p, "Pragma:", 7) == 0) { + if (av_strncasecmp(p, "Pragma:", 7) == 0) { const char *q = p + 7; while (*q && *q != '\n' && isspace(*q)) q++; - if (strncasecmp(q, "stream-switch-entry=", 20) == 0) { + if (av_strncasecmp(q, "stream-switch-entry=", 20) == 0) { int stream_no; int rate_no; @@ -1271,9 +1296,9 @@ static void parse_acl_row(FFStream *stream, FFStream* feed, IPAddressACL *ext_ac int errors = 0; get_arg(arg, sizeof(arg), &p); - if (strcasecmp(arg, "allow") == 0) + if (av_strcasecmp(arg, "allow") == 0) acl.action = IP_ALLOW; - else if (strcasecmp(arg, "deny") == 0) + else if (av_strcasecmp(arg, "deny") == 0) acl.action = IP_DENY; else { fprintf(stderr, "%s:%d: ACL action '%s' is not ALLOW or DENY\n", @@ -1358,7 +1383,7 @@ static IPAddressACL* parse_dynamic_acl(FFStream *stream, HTTPContext *c) continue; get_arg(cmd, sizeof(cmd), &p); - if (!strcasecmp(cmd, "ACL")) + if (!av_strcasecmp(cmd, "ACL")) parse_acl_row(NULL, NULL, acl, p, stream->dynamic_acl, line_num); } fclose(f); @@ -1453,7 +1478,8 @@ enum RedirType { /* parse http request and prepare header */ static int http_parse_request(HTTPContext *c) { - char *p; + const char *p; + char *p1; enum RedirType redir_type; char cmd[32]; char info[1024], filename[1024]; @@ -1464,10 +1490,10 @@ static int http_parse_request(HTTPContext *c) FFStream *stream; int i; char ratebuf[32]; - char *useragent = 0; + const char *useragent = 0; p = c->buffer; - get_word(cmd, sizeof(cmd), (const char **)&p); + get_word(cmd, sizeof(cmd), &p); av_strlcpy(c->method, cmd, sizeof(c->method)); if (!strcmp(cmd, "GET")) @@ -1477,7 +1503,7 @@ static int http_parse_request(HTTPContext *c) else return -1; - get_word(url, sizeof(url), (const char **)&p); + get_word(url, sizeof(url), &p); av_strlcpy(c->url, url, sizeof(c->url)); get_word(protocol, sizeof(protocol), (const char **)&p); @@ -1490,17 +1516,17 @@ static int http_parse_request(HTTPContext *c) 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 */ - p = strchr(url, '?'); - if (p) { - av_strlcpy(info, p, sizeof(info)); - *p = '\0'; + p1 = strchr(url, '?'); + if (p1) { + av_strlcpy(info, p1, sizeof(info)); + *p1 = '\0'; } else info[0] = '\0'; av_strlcpy(filename, url + ((*url == '/') ? 1 : 0), sizeof(filename)-1); for (p = c->buffer; *p && *p != '\r' && *p != '\n'; ) { - if (strncasecmp(p, "User-Agent:", 11) == 0) { + if (av_strncasecmp(p, "User-Agent:", 11) == 0) { useragent = p + 11; if (*useragent && *useragent != '\n' && isspace(*useragent)) useragent++; @@ -1518,7 +1544,7 @@ static int http_parse_request(HTTPContext *c) redir_type = REDIR_ASX; filename[strlen(filename)-1] = 'f'; } else if (av_match_ext(filename, "asf") && - (!useragent || strncasecmp(useragent, "NSPlayer", 8) != 0)) { + (!useragent || av_strncasecmp(useragent, "NSPlayer", 8) != 0)) { /* if this isn't WMP or lookalike, return the redirector file */ redir_type = REDIR_ASF; } else if (av_match_ext(filename, "rpm,ram")) { @@ -1610,10 +1636,10 @@ static int http_parse_request(HTTPContext *c) } if (redir_type != REDIR_NONE) { - char *hostinfo = 0; + const char *hostinfo = 0; for (p = c->buffer; *p && *p != '\r' && *p != '\n'; ) { - if (strncasecmp(p, "Host:", 5) == 0) { + if (av_strncasecmp(p, "Host:", 5) == 0) { hostinfo = p + 5; break; } @@ -1688,7 +1714,8 @@ static int http_parse_request(HTTPContext *c) case REDIR_SDP: { uint8_t *sdp_data; - int sdp_data_size, len; + int sdp_data_size; + socklen_t len; struct sockaddr_in my_addr; q += snprintf(q, c->buffer_size, @@ -1738,15 +1765,15 @@ static int http_parse_request(HTTPContext *c) if (!stream->is_feed) { /* However it might be a status report from WMP! Let us log the * data as it might come in handy one day. */ - char *logline = 0; + const char *logline = 0; int client_id = 0; for (p = c->buffer; *p && *p != '\r' && *p != '\n'; ) { - if (strncasecmp(p, "Pragma: log-line=", 17) == 0) { + if (av_strncasecmp(p, "Pragma: log-line=", 17) == 0) { logline = p; break; } - if (strncasecmp(p, "Pragma: client-id=", 18) == 0) + if (av_strncasecmp(p, "Pragma: client-id=", 18) == 0) client_id = strtol(p + 18, 0, 10); p = strchr(p, '\n'); if (!p) @@ -1863,7 +1890,7 @@ static int http_parse_request(HTTPContext *c) static void fmt_bytecount(AVIOContext *pb, int64_t count) { - static const char *suffix = " kMGTP"; + static const char suffix[] = " kMGTP"; const char *s; for (s = suffix; count >= 100000 && s[1]; count /= 1000, s++); @@ -2113,22 +2140,6 @@ static void compute_status(HTTPContext *c) c->buffer_end = c->pb_buffer + len; } -/* check if the parser needs to be opened for stream i */ -static void open_parser(AVFormatContext *s, int i) -{ - AVStream *st = s->streams[i]; - AVCodec *codec; - - if (!st->codec->codec) { - codec = avcodec_find_decoder(st->codec->codec_id); - if (codec && (codec->capabilities & CODEC_CAP_PARSE_ONLY)) { - st->codec->parse_only = 1; - if (avcodec_open2(st->codec, codec, NULL) < 0) - st->codec->parse_only = 0; - } - } -} - static int open_input_stream(HTTPContext *c, const char *info) { char buf[128]; @@ -2170,14 +2181,10 @@ static int open_input_stream(HTTPContext *c, const char *info) c->fmt_in = s; if (strcmp(s->iformat->name, "ffm") && avformat_find_stream_info(c->fmt_in, NULL) < 0) { http_log("Could not find stream info '%s'\n", input_filename); - av_close_input_file(s); + avformat_close_input(&s); return -1; } - /* open each parser */ - for(i=0;inb_streams;i++) - open_parser(s, i); - /* choose stream as clock source (we favorize video stream if present) for packet sending */ c->pts_stream_index = 0; @@ -2269,7 +2276,6 @@ static int http_prepare_data(HTTPContext *c) * Default value from Libav * Try to set it use configuration option */ - c->fmt_ctx.preload = (int)(0.5*AV_TIME_BASE); c->fmt_ctx.max_delay = (int)(0.7*AV_TIME_BASE); if (avformat_write_header(&c->fmt_ctx, NULL) < 0) { @@ -2312,8 +2318,7 @@ static int http_prepare_data(HTTPContext *c) return 0; } else { if (c->stream->loop) { - av_close_input_file(c->fmt_in); - c->fmt_in = NULL; + avformat_close_input(&c->fmt_in); if (open_input_stream(c, "") < 0) goto no_loop; goto redo; @@ -2389,7 +2394,7 @@ static int http_prepare_data(HTTPContext *c) if (c->rtp_protocol == RTSP_LOWER_TRANSPORT_TCP) max_packet_size = RTSP_TCP_MAX_PACKET_SIZE; else - max_packet_size = url_get_max_packet_size(c->rtp_handles[c->packet_stream_index]); + max_packet_size = c->rtp_handles[c->packet_stream_index]->max_packet_size; ret = ffio_open_dyn_packet_buf(&ctx->pb, max_packet_size); } else { ret = avio_open_dyn_buf(&ctx->pb); @@ -2542,8 +2547,8 @@ static int http_send_data(HTTPContext *c) } else { /* send RTP packet directly in UDP */ c->buffer_ptr += 4; - url_write(c->rtp_handles[c->packet_stream_index], - c->buffer_ptr, len); + ffurl_write(c->rtp_handles[c->packet_stream_index], + c->buffer_ptr, len); c->buffer_ptr += len; /* here we continue as we can send several packets per 10 ms slot */ } @@ -2593,8 +2598,11 @@ static int http_start_receive_data(HTTPContext *c) if (c->stream->truncate) { /* truncate feed file */ ffm_write_write_index(c->feed_fd, FFM_PACKET_SIZE); - ftruncate(c->feed_fd, FFM_PACKET_SIZE); http_log("Truncating feed file '%s'\n", c->stream->feed_filename); + if (ftruncate(c->feed_fd, FFM_PACKET_SIZE) < 0) { + http_log("Error truncating feed file: %s\n", strerror(errno)); + return -1; + } } else { if ((c->stream->feed_write_index = ffm_read_write_index(fd)) < 0) { http_log("Error reading write index from feed file: %s\n", strerror(errno)); @@ -2680,8 +2688,6 @@ static int http_receive_data(HTTPContext *c) /* a packet has been received : write it in the store, except if header */ if (c->data_count > FFM_PACKET_SIZE) { - - // printf("writing pos=0x%"PRIx64" size=0x%"PRIx64"\n", feed->feed_write_index, feed->feed_size); /* XXX: use llseek or url_seek */ lseek(c->feed_fd, feed->feed_write_index, SEEK_SET); if (write(c->feed_fd, c->buffer, FFM_PACKET_SIZE) < 0) { @@ -2737,7 +2743,7 @@ static int http_receive_data(HTTPContext *c) /* Now we have the actual streams */ if (s->nb_streams != feed->nb_streams) { - av_close_input_stream(s); + avformat_close_input(&s); av_free(pb); http_log("Feed '%s' stream number does not match registered feed\n", c->stream->feed_filename); @@ -2750,7 +2756,7 @@ static int http_receive_data(HTTPContext *c) avcodec_copy_context(fst->codec, st->codec); } - av_close_input_stream(s); + avformat_close_input(&s); av_free(pb); } c->buffer_ptr = c->buffer; @@ -2842,7 +2848,7 @@ static int rtsp_parse_request(HTTPContext *c) char protocol[32]; char line[1024]; int len; - RTSPMessageHeader header1, *header = &header1; + RTSPMessageHeader header1 = { 0 }, *header = &header1; c->buffer_ptr[0] = '\0'; p = c->buffer; @@ -2868,7 +2874,6 @@ static int rtsp_parse_request(HTTPContext *c) } /* parse each header line */ - memset(header, 0, sizeof(*header)); /* skip to next line */ while (*p != '\n' && *p != '\0') p++; @@ -2984,7 +2989,8 @@ static void rtsp_cmd_describe(HTTPContext *c, const char *url) char path1[1024]; const char *path; uint8_t *content; - int content_length, len; + int content_length; + socklen_t len; struct sockaddr_in my_addr; /* find which url is asked */ @@ -3169,8 +3175,8 @@ static void rtsp_cmd_setup(HTTPContext *c, const char *url, switch(rtp_c->rtp_protocol) { case RTSP_LOWER_TRANSPORT_UDP: - rtp_port = rtp_get_local_rtp_port(rtp_c->rtp_handles[stream_index]); - rtcp_port = rtp_get_local_rtcp_port(rtp_c->rtp_handles[stream_index]); + rtp_port = ff_rtp_get_local_rtp_port(rtp_c->rtp_handles[stream_index]); + rtcp_port = ff_rtp_get_local_rtcp_port(rtp_c->rtp_handles[stream_index]); avio_printf(c->pb, "Transport: RTP/AVP/UDP;unicast;" "client_port=%d-%d;server_port=%d-%d", th->client_port_min, th->client_port_max, @@ -3426,10 +3432,10 @@ static int rtp_new_av_stream(HTTPContext *c, "rtp://%s:%d", ipaddr, ntohs(dest_addr->sin_port)); } - if (url_open(&h, ctx->filename, AVIO_FLAG_WRITE) < 0) + if (ffurl_open(&h, ctx->filename, AVIO_FLAG_WRITE, NULL, NULL) < 0) goto fail; c->rtp_handles[stream_index] = h; - max_packet_size = url_get_max_packet_size(h); + max_packet_size = h->max_packet_size; break; case RTSP_LOWER_TRANSPORT_TCP: /* RTP/TCP case */ @@ -3452,7 +3458,7 @@ static int rtp_new_av_stream(HTTPContext *c, if (avformat_write_header(ctx, NULL) < 0) { fail: if (h) - url_close(h); + ffurl_close(h); av_free(ctx); return -1; } @@ -3489,7 +3495,7 @@ static AVStream *add_av_stream1(FFStream *stream, AVCodecContext *codec, int cop } fst->priv_data = av_mallocz(sizeof(FeedData)); fst->index = stream->nb_streams; - av_set_pts_info(fst, 33, 1, 90000); + avpriv_set_pts_info(fst, 33, 1, 90000); fst->sample_aspect_ratio = codec->sample_aspect_ratio; stream->streams[stream->nb_streams++] = fst; return fst; @@ -3556,10 +3562,12 @@ static void extract_mpeg4_header(AVFormatContext *infile) AVStream *st; const uint8_t *p; + infile->flags |= AVFMT_FLAG_NOFILLIN | AVFMT_FLAG_NOPARSE; + mpeg4_count = 0; for(i=0;inb_streams;i++) { st = infile->streams[i]; - if (st->codec->codec_id == CODEC_ID_MPEG4 && + if (st->codec->codec_id == AV_CODEC_ID_MPEG4 && st->codec->extradata_size == 0) { mpeg4_count++; } @@ -3569,10 +3577,10 @@ static void extract_mpeg4_header(AVFormatContext *infile) printf("MPEG4 without extra data: trying to find header in %s\n", infile->filename); while (mpeg4_count > 0) { - if (av_read_packet(infile, &pkt) < 0) + if (av_read_frame(infile, &pkt) < 0) break; st = infile->streams[pkt.stream_index]; - if (st->codec->codec_id == CODEC_ID_MPEG4 && + if (st->codec->codec_id == AV_CODEC_ID_MPEG4 && st->codec->extradata_size == 0) { av_freep(&st->codec->extradata); /* fill extradata with the header */ @@ -3630,7 +3638,7 @@ static void build_file_streams(void) if (avformat_find_stream_info(infile, NULL) < 0) { http_log("Could not find codec parameters from '%s'\n", stream->feed_filename); - av_close_input_file(infile); + avformat_close_input(&infile); goto fail; } extract_mpeg4_header(infile); @@ -3638,7 +3646,7 @@ static void build_file_streams(void) for(i=0;inb_streams;i++) add_av_stream1(stream, infile->streams[i]->codec, 1); - av_close_input_file(infile); + avformat_close_input(&infile); } } } @@ -3728,7 +3736,7 @@ static void build_feed_streams(void) http_log("Deleting feed file '%s' as stream counts differ (%d != %d)\n", feed->feed_filename, s->nb_streams, feed->nb_streams); - av_close_input_file(s); + avformat_close_input(&s); } else http_log("Deleting feed file '%s' as it appears to be corrupt\n", feed->feed_filename); @@ -3886,22 +3894,22 @@ static void add_codec(FFStream *stream, AVCodecContext *av) memcpy(st->codec, av, sizeof(AVCodecContext)); } -static enum CodecID opt_audio_codec(const char *arg) +static enum AVCodecID opt_audio_codec(const char *arg) { AVCodec *p= avcodec_find_encoder_by_name(arg); if (p == NULL || p->type != AVMEDIA_TYPE_AUDIO) - return CODEC_ID_NONE; + return AV_CODEC_ID_NONE; return p->id; } -static enum CodecID opt_video_codec(const char *arg) +static enum AVCodecID opt_video_codec(const char *arg) { AVCodec *p= avcodec_find_encoder_by_name(arg); if (p == NULL || p->type != AVMEDIA_TYPE_VIDEO) - return CODEC_ID_NONE; + return AV_CODEC_ID_NONE; return p->id; } @@ -3938,13 +3946,13 @@ static int avserver_opt_default(const char *opt, const char *arg, int ret = 0; const AVOption *o = av_opt_find(avctx, opt, NULL, type, 0); if(o) - ret = av_set_string3(avctx, opt, arg, 1, NULL); + ret = av_opt_set(avctx, opt, arg, 0); return ret; } static int avserver_opt_preset(const char *arg, AVCodecContext *avctx, int type, - enum CodecID *audio_id, enum CodecID *video_id) + enum AVCodecID *audio_id, enum AVCodecID *video_id) { FILE *f=NULL; char filename[1000], tmp[1000], tmp2[1000], line[1000]; @@ -4026,7 +4034,7 @@ static int parse_ffconfig(const char *filename) FFStream **last_stream, *stream, *redirect; FFStream **last_feed, *feed, *s; AVCodecContext audio_enc, video_enc; - enum CodecID audio_id, video_id; + enum AVCodecID audio_id, video_id; f = fopen(filename, "r"); if (!f) { @@ -4043,8 +4051,8 @@ static int parse_ffconfig(const char *filename) stream = NULL; feed = NULL; redirect = NULL; - audio_id = CODEC_ID_NONE; - video_id = CODEC_ID_NONE; + audio_id = AV_CODEC_ID_NONE; + video_id = AV_CODEC_ID_NONE; #define ERROR(...) report_config_error(filename, line_num, &errors, __VA_ARGS__) for(;;) { @@ -4059,40 +4067,38 @@ static int parse_ffconfig(const char *filename) get_arg(cmd, sizeof(cmd), &p); - if (!strcasecmp(cmd, "Port")) { + if (!av_strcasecmp(cmd, "Port")) { get_arg(arg, sizeof(arg), &p); val = atoi(arg); if (val < 1 || val > 65536) { ERROR("Invalid_port: %s\n", arg); } my_http_addr.sin_port = htons(val); - } else if (!strcasecmp(cmd, "BindAddress")) { + } else if (!av_strcasecmp(cmd, "BindAddress")) { get_arg(arg, sizeof(arg), &p); if (resolve_host(&my_http_addr.sin_addr, arg) != 0) { ERROR("%s:%d: Invalid host/IP address: %s\n", arg); } - } else if (!strcasecmp(cmd, "NoDaemon")) { - avserver_daemon = 0; - } else if (!strcasecmp(cmd, "RTSPPort")) { + } else if (!av_strcasecmp(cmd, "RTSPPort")) { get_arg(arg, sizeof(arg), &p); val = atoi(arg); if (val < 1 || val > 65536) { ERROR("%s:%d: Invalid port: %s\n", arg); } my_rtsp_addr.sin_port = htons(atoi(arg)); - } else if (!strcasecmp(cmd, "RTSPBindAddress")) { + } else if (!av_strcasecmp(cmd, "RTSPBindAddress")) { get_arg(arg, sizeof(arg), &p); if (resolve_host(&my_rtsp_addr.sin_addr, arg) != 0) { ERROR("Invalid host/IP address: %s\n", arg); } - } else if (!strcasecmp(cmd, "MaxHTTPConnections")) { + } else if (!av_strcasecmp(cmd, "MaxHTTPConnections")) { get_arg(arg, sizeof(arg), &p); val = atoi(arg); if (val < 1 || val > 65536) { ERROR("Invalid MaxHTTPConnections: %s\n", arg); } nb_max_http_connections = val; - } else if (!strcasecmp(cmd, "MaxClients")) { + } else if (!av_strcasecmp(cmd, "MaxClients")) { get_arg(arg, sizeof(arg), &p); val = atoi(arg); if (val < 1 || val > nb_max_http_connections) { @@ -4100,7 +4106,7 @@ static int parse_ffconfig(const char *filename) } else { nb_max_connections = val; } - } else if (!strcasecmp(cmd, "MaxBandwidth")) { + } else if (!av_strcasecmp(cmd, "MaxBandwidth")) { int64_t llval; get_arg(arg, sizeof(arg), &p); llval = atoll(arg); @@ -4108,10 +4114,10 @@ static int parse_ffconfig(const char *filename) ERROR("Invalid MaxBandwidth: %s\n", arg); } else max_bandwidth = llval; - } else if (!strcasecmp(cmd, "CustomLog")) { + } else if (!av_strcasecmp(cmd, "CustomLog")) { if (!avserver_debug) get_arg(logfilename, sizeof(logfilename), &p); - } else if (!strcasecmp(cmd, "next_feed; } - } else if (!strcasecmp(cmd, "Launch")) { + } else if (!av_strcasecmp(cmd, "Launch")) { if (feed) { int i; @@ -4167,24 +4173,24 @@ static int parse_ffconfig(const char *filename) inet_ntoa(my_http_addr.sin_addr), ntohs(my_http_addr.sin_port), feed->filename); } - } else if (!strcasecmp(cmd, "ReadOnlyFile")) { + } else if (!av_strcasecmp(cmd, "ReadOnlyFile")) { if (feed) { get_arg(feed->feed_filename, sizeof(feed->feed_filename), &p); feed->readonly = 1; } else if (stream) { get_arg(stream->feed_filename, sizeof(stream->feed_filename), &p); } - } else if (!strcasecmp(cmd, "File")) { + } else if (!av_strcasecmp(cmd, "File")) { if (feed) { get_arg(feed->feed_filename, sizeof(feed->feed_filename), &p); } else if (stream) get_arg(stream->feed_filename, sizeof(stream->feed_filename), &p); - } else if (!strcasecmp(cmd, "Truncate")) { + } else if (!av_strcasecmp(cmd, "Truncate")) { if (feed) { get_arg(arg, sizeof(arg), &p); feed->truncate = strtod(arg, NULL); } - } else if (!strcasecmp(cmd, "FileMaxSize")) { + } else if (!av_strcasecmp(cmd, "FileMaxSize")) { if (feed) { char *p1; double fsize; @@ -4208,12 +4214,12 @@ static int parse_ffconfig(const char *filename) ERROR("Feed max file size is too small, must be at least %d\n", FFM_PACKET_SIZE*4); } } - } else if (!strcasecmp(cmd, "")) { + } else if (!av_strcasecmp(cmd, "")) { if (!feed) { ERROR("No corresponding for \n"); } feed = NULL; - } else if (!strcasecmp(cmd, "fmt = avserver_guess_format(NULL, stream->filename, NULL); - avcodec_get_context_defaults2(&video_enc, AVMEDIA_TYPE_VIDEO); - avcodec_get_context_defaults2(&audio_enc, AVMEDIA_TYPE_AUDIO); - audio_id = CODEC_ID_NONE; - video_id = CODEC_ID_NONE; + 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) { audio_id = stream->fmt->audio_codec; video_id = stream->fmt->video_codec; @@ -4246,7 +4252,7 @@ static int parse_ffconfig(const char *filename) *last_stream = stream; last_stream = &stream->next; } - } else if (!strcasecmp(cmd, "Feed")) { + } else if (!av_strcasecmp(cmd, "Feed")) { get_arg(arg, sizeof(arg), &p); if (stream) { FFStream *sfeed; @@ -4262,7 +4268,7 @@ static int parse_ffconfig(const char *filename) else stream->feed = sfeed; } - } else if (!strcasecmp(cmd, "Format")) { + } else if (!av_strcasecmp(cmd, "Format")) { get_arg(arg, sizeof(arg), &p); if (stream) { if (!strcmp(arg, "status")) { @@ -4283,7 +4289,7 @@ static int parse_ffconfig(const char *filename) video_id = stream->fmt->video_codec; } } - } else if (!strcasecmp(cmd, "InputFormat")) { + } else if (!av_strcasecmp(cmd, "InputFormat")) { get_arg(arg, sizeof(arg), &p); if (stream) { stream->ifmt = av_find_input_format(arg); @@ -4291,65 +4297,65 @@ static int parse_ffconfig(const char *filename) ERROR("Unknown input format: %s\n", arg); } } - } else if (!strcasecmp(cmd, "FaviconURL")) { + } else if (!av_strcasecmp(cmd, "FaviconURL")) { if (stream && stream->stream_type == STREAM_TYPE_STATUS) { get_arg(stream->feed_filename, sizeof(stream->feed_filename), &p); } else { ERROR("FaviconURL only permitted for status streams\n"); } - } else if (!strcasecmp(cmd, "Author")) { + } else if (!av_strcasecmp(cmd, "Author")) { if (stream) get_arg(stream->author, sizeof(stream->author), &p); - } else if (!strcasecmp(cmd, "Comment")) { + } else if (!av_strcasecmp(cmd, "Comment")) { if (stream) get_arg(stream->comment, sizeof(stream->comment), &p); - } else if (!strcasecmp(cmd, "Copyright")) { + } else if (!av_strcasecmp(cmd, "Copyright")) { if (stream) get_arg(stream->copyright, sizeof(stream->copyright), &p); - } else if (!strcasecmp(cmd, "Title")) { + } else if (!av_strcasecmp(cmd, "Title")) { if (stream) get_arg(stream->title, sizeof(stream->title), &p); - } else if (!strcasecmp(cmd, "Preroll")) { + } else if (!av_strcasecmp(cmd, "Preroll")) { get_arg(arg, sizeof(arg), &p); if (stream) stream->prebuffer = atof(arg) * 1000; - } else if (!strcasecmp(cmd, "StartSendOnKey")) { + } else if (!av_strcasecmp(cmd, "StartSendOnKey")) { if (stream) stream->send_on_key = 1; - } else if (!strcasecmp(cmd, "AudioCodec")) { + } else if (!av_strcasecmp(cmd, "AudioCodec")) { get_arg(arg, sizeof(arg), &p); audio_id = opt_audio_codec(arg); - if (audio_id == CODEC_ID_NONE) { + if (audio_id == AV_CODEC_ID_NONE) { ERROR("Unknown AudioCodec: %s\n", arg); } - } else if (!strcasecmp(cmd, "VideoCodec")) { + } else if (!av_strcasecmp(cmd, "VideoCodec")) { get_arg(arg, sizeof(arg), &p); video_id = opt_video_codec(arg); - if (video_id == CODEC_ID_NONE) { + if (video_id == AV_CODEC_ID_NONE) { ERROR("Unknown VideoCodec: %s\n", arg); } - } else if (!strcasecmp(cmd, "MaxTime")) { + } else if (!av_strcasecmp(cmd, "MaxTime")) { get_arg(arg, sizeof(arg), &p); if (stream) stream->max_time = atof(arg) * 1000; - } else if (!strcasecmp(cmd, "AudioBitRate")) { + } else if (!av_strcasecmp(cmd, "AudioBitRate")) { get_arg(arg, sizeof(arg), &p); if (stream) audio_enc.bit_rate = lrintf(atof(arg) * 1000); - } else if (!strcasecmp(cmd, "AudioChannels")) { + } else if (!av_strcasecmp(cmd, "AudioChannels")) { get_arg(arg, sizeof(arg), &p); if (stream) audio_enc.channels = atoi(arg); - } else if (!strcasecmp(cmd, "AudioSampleRate")) { + } else if (!av_strcasecmp(cmd, "AudioSampleRate")) { get_arg(arg, sizeof(arg), &p); if (stream) audio_enc.sample_rate = atoi(arg); - } else if (!strcasecmp(cmd, "AudioQuality")) { + } else if (!av_strcasecmp(cmd, "AudioQuality")) { get_arg(arg, sizeof(arg), &p); if (stream) { // audio_enc.quality = atof(arg) * 1000; } - } else if (!strcasecmp(cmd, "VideoBitRateRange")) { + } else if (!av_strcasecmp(cmd, "VideoBitRateRange")) { if (stream) { int minrate, maxrate; @@ -4362,32 +4368,32 @@ static int parse_ffconfig(const char *filename) ERROR("Incorrect format for VideoBitRateRange -- should be -: %s\n", arg); } } - } else if (!strcasecmp(cmd, "Debug")) { + } else if (!av_strcasecmp(cmd, "Debug")) { if (stream) { get_arg(arg, sizeof(arg), &p); video_enc.debug = strtol(arg,0,0); } - } else if (!strcasecmp(cmd, "Strict")) { + } else if (!av_strcasecmp(cmd, "Strict")) { if (stream) { get_arg(arg, sizeof(arg), &p); video_enc.strict_std_compliance = atoi(arg); } - } else if (!strcasecmp(cmd, "VideoBufferSize")) { + } else if (!av_strcasecmp(cmd, "VideoBufferSize")) { if (stream) { get_arg(arg, sizeof(arg), &p); video_enc.rc_buffer_size = atoi(arg) * 8*1024; } - } else if (!strcasecmp(cmd, "VideoBitRateTolerance")) { + } else if (!av_strcasecmp(cmd, "VideoBitRateTolerance")) { if (stream) { get_arg(arg, sizeof(arg), &p); video_enc.bit_rate_tolerance = atoi(arg) * 1000; } - } else if (!strcasecmp(cmd, "VideoBitRate")) { + } else if (!av_strcasecmp(cmd, "VideoBitRate")) { get_arg(arg, sizeof(arg), &p); if (stream) { video_enc.bit_rate = atoi(arg) * 1000; } - } else if (!strcasecmp(cmd, "VideoSize")) { + } else if (!av_strcasecmp(cmd, "VideoSize")) { get_arg(arg, sizeof(arg), &p); if (stream) { av_parse_video_size(&video_enc.width, &video_enc.height, arg); @@ -4396,7 +4402,7 @@ static int parse_ffconfig(const char *filename) ERROR("Image size must be a multiple of 16\n"); } } - } else if (!strcasecmp(cmd, "VideoFrameRate")) { + } else if (!av_strcasecmp(cmd, "VideoFrameRate")) { get_arg(arg, sizeof(arg), &p); if (stream) { AVRational frame_rate; @@ -4407,29 +4413,29 @@ static int parse_ffconfig(const char *filename) video_enc.time_base.den = frame_rate.num; } } - } else if (!strcasecmp(cmd, "VideoGopSize")) { + } else if (!av_strcasecmp(cmd, "VideoGopSize")) { get_arg(arg, sizeof(arg), &p); if (stream) video_enc.gop_size = atoi(arg); - } else if (!strcasecmp(cmd, "VideoIntraOnly")) { + } else if (!av_strcasecmp(cmd, "VideoIntraOnly")) { if (stream) video_enc.gop_size = 1; - } else if (!strcasecmp(cmd, "VideoHighQuality")) { + } else if (!av_strcasecmp(cmd, "VideoHighQuality")) { if (stream) video_enc.mb_decision = FF_MB_DECISION_BITS; - } else if (!strcasecmp(cmd, "Video4MotionVector")) { + } else if (!av_strcasecmp(cmd, "Video4MotionVector")) { if (stream) { video_enc.mb_decision = FF_MB_DECISION_BITS; //FIXME remove video_enc.flags |= CODEC_FLAG_4MV; } - } else if (!strcasecmp(cmd, "AVOptionVideo") || - !strcasecmp(cmd, "AVOptionAudio")) { + } else if (!av_strcasecmp(cmd, "AVOptionVideo") || + !av_strcasecmp(cmd, "AVOptionAudio")) { char arg2[1024]; AVCodecContext *avctx; int type; get_arg(arg, sizeof(arg), &p); get_arg(arg2, sizeof(arg2), &p); - if (!strcasecmp(cmd, "AVOptionVideo")) { + if (!av_strcasecmp(cmd, "AVOptionVideo")) { avctx = &video_enc; type = AV_OPT_FLAG_VIDEO_PARAM; } else { @@ -4439,12 +4445,12 @@ static int parse_ffconfig(const char *filename) if (avserver_opt_default(arg, arg2, avctx, type|AV_OPT_FLAG_ENCODING_PARAM)) { ERROR("AVOption error: %s %s\n", arg, arg2); } - } else if (!strcasecmp(cmd, "AVPresetVideo") || - !strcasecmp(cmd, "AVPresetAudio")) { + } else if (!av_strcasecmp(cmd, "AVPresetVideo") || + !av_strcasecmp(cmd, "AVPresetAudio")) { AVCodecContext *avctx; int type; get_arg(arg, sizeof(arg), &p); - if (!strcasecmp(cmd, "AVPresetVideo")) { + if (!av_strcasecmp(cmd, "AVPresetVideo")) { avctx = &video_enc; video_enc.codec_id = video_id; type = AV_OPT_FLAG_VIDEO_PARAM; @@ -4456,26 +4462,26 @@ static int parse_ffconfig(const char *filename) if (avserver_opt_preset(arg, avctx, type|AV_OPT_FLAG_ENCODING_PARAM, &audio_id, &video_id)) { ERROR("AVPreset error: %s\n", arg); } - } else if (!strcasecmp(cmd, "VideoTag")) { + } else if (!av_strcasecmp(cmd, "VideoTag")) { get_arg(arg, sizeof(arg), &p); if ((strlen(arg) == 4) && stream) video_enc.codec_tag = MKTAG(arg[0], arg[1], arg[2], arg[3]); - } else if (!strcasecmp(cmd, "BitExact")) { + } else if (!av_strcasecmp(cmd, "BitExact")) { if (stream) video_enc.flags |= CODEC_FLAG_BITEXACT; - } else if (!strcasecmp(cmd, "DctFastint")) { + } else if (!av_strcasecmp(cmd, "DctFastint")) { if (stream) video_enc.dct_algo = FF_DCT_FASTINT; - } else if (!strcasecmp(cmd, "IdctSimple")) { + } else if (!av_strcasecmp(cmd, "IdctSimple")) { if (stream) video_enc.idct_algo = FF_IDCT_SIMPLE; - } else if (!strcasecmp(cmd, "Qscale")) { + } else if (!av_strcasecmp(cmd, "Qscale")) { get_arg(arg, sizeof(arg), &p); if (stream) { video_enc.flags |= CODEC_FLAG_QSCALE; video_enc.global_quality = FF_QP2LAMBDA * atoi(arg); } - } else if (!strcasecmp(cmd, "VideoQDiff")) { + } else if (!av_strcasecmp(cmd, "VideoQDiff")) { get_arg(arg, sizeof(arg), &p); if (stream) { video_enc.max_qdiff = atoi(arg); @@ -4483,7 +4489,7 @@ static int parse_ffconfig(const char *filename) ERROR("VideoQDiff out of range\n"); } } - } else if (!strcasecmp(cmd, "VideoQMax")) { + } else if (!av_strcasecmp(cmd, "VideoQMax")) { get_arg(arg, sizeof(arg), &p); if (stream) { video_enc.qmax = atoi(arg); @@ -4491,7 +4497,7 @@ static int parse_ffconfig(const char *filename) ERROR("VideoQMax out of range\n"); } } - } else if (!strcasecmp(cmd, "VideoQMin")) { + } else if (!av_strcasecmp(cmd, "VideoQMin")) { get_arg(arg, sizeof(arg), &p); if (stream) { video_enc.qmin = atoi(arg); @@ -4499,39 +4505,39 @@ static int parse_ffconfig(const char *filename) ERROR("VideoQMin out of range\n"); } } - } else if (!strcasecmp(cmd, "LumaElim")) { + } else if (!av_strcasecmp(cmd, "LumaElim")) { get_arg(arg, sizeof(arg), &p); if (stream) video_enc.luma_elim_threshold = atoi(arg); - } else if (!strcasecmp(cmd, "ChromaElim")) { + } else if (!av_strcasecmp(cmd, "ChromaElim")) { get_arg(arg, sizeof(arg), &p); if (stream) video_enc.chroma_elim_threshold = atoi(arg); - } else if (!strcasecmp(cmd, "LumiMask")) { + } else if (!av_strcasecmp(cmd, "LumiMask")) { get_arg(arg, sizeof(arg), &p); if (stream) video_enc.lumi_masking = atof(arg); - } else if (!strcasecmp(cmd, "DarkMask")) { + } else if (!av_strcasecmp(cmd, "DarkMask")) { get_arg(arg, sizeof(arg), &p); if (stream) video_enc.dark_masking = atof(arg); - } else if (!strcasecmp(cmd, "NoVideo")) { - video_id = CODEC_ID_NONE; - } else if (!strcasecmp(cmd, "NoAudio")) { - audio_id = CODEC_ID_NONE; - } else if (!strcasecmp(cmd, "ACL")) { + } else if (!av_strcasecmp(cmd, "NoVideo")) { + video_id = AV_CODEC_ID_NONE; + } else if (!av_strcasecmp(cmd, "NoAudio")) { + audio_id = AV_CODEC_ID_NONE; + } else if (!av_strcasecmp(cmd, "ACL")) { parse_acl_row(stream, feed, NULL, p, filename, line_num); - } else if (!strcasecmp(cmd, "DynamicACL")) { + } else if (!av_strcasecmp(cmd, "DynamicACL")) { if (stream) { get_arg(stream->dynamic_acl, sizeof(stream->dynamic_acl), &p); } - } else if (!strcasecmp(cmd, "RTSPOption")) { + } else if (!av_strcasecmp(cmd, "RTSPOption")) { get_arg(arg, sizeof(arg), &p); if (stream) { av_freep(&stream->rtsp_option); stream->rtsp_option = av_strdup(arg); } - } else if (!strcasecmp(cmd, "MulticastAddress")) { + } else if (!av_strcasecmp(cmd, "MulticastAddress")) { get_arg(arg, sizeof(arg), &p); if (stream) { if (resolve_host(&stream->multicast_ip, arg) != 0) { @@ -4540,28 +4546,28 @@ static int parse_ffconfig(const char *filename) stream->is_multicast = 1; stream->loop = 1; /* default is looping */ } - } else if (!strcasecmp(cmd, "MulticastPort")) { + } else if (!av_strcasecmp(cmd, "MulticastPort")) { get_arg(arg, sizeof(arg), &p); if (stream) stream->multicast_port = atoi(arg); - } else if (!strcasecmp(cmd, "MulticastTTL")) { + } else if (!av_strcasecmp(cmd, "MulticastTTL")) { get_arg(arg, sizeof(arg), &p); if (stream) stream->multicast_ttl = atoi(arg); - } else if (!strcasecmp(cmd, "NoLoop")) { + } else if (!av_strcasecmp(cmd, "NoLoop")) { if (stream) stream->loop = 0; - } else if (!strcasecmp(cmd, "")) { + } else if (!av_strcasecmp(cmd, "")) { if (!stream) { ERROR("No corresponding for \n"); } else { if (stream->feed && stream->fmt && strcmp(stream->fmt->name, "ffm") != 0) { - if (audio_id != CODEC_ID_NONE) { + if (audio_id != AV_CODEC_ID_NONE) { audio_enc.codec_type = AVMEDIA_TYPE_AUDIO; audio_enc.codec_id = audio_id; add_codec(stream, &audio_enc); } - if (video_id != CODEC_ID_NONE) { + if (video_id != AV_CODEC_ID_NONE) { video_enc.codec_type = AVMEDIA_TYPE_VIDEO; video_enc.codec_id = video_id; add_codec(stream, &video_enc); @@ -4569,7 +4575,7 @@ static int parse_ffconfig(const char *filename) } stream = NULL; } - } else if (!strcasecmp(cmd, "stream_type = STREAM_TYPE_REDIRECT; } - } else if (!strcasecmp(cmd, "URL")) { + } else if (!av_strcasecmp(cmd, "URL")) { if (redirect) get_arg(redirect->feed_filename, sizeof(redirect->feed_filename), &p); - } else if (!strcasecmp(cmd, "")) { + } else if (!av_strcasecmp(cmd, "")) { if (!redirect) { ERROR("No corresponding for \n"); } else { @@ -4597,7 +4603,7 @@ static int parse_ffconfig(const char *filename) } redirect = NULL; } - } else if (!strcasecmp(cmd, "LoadModule")) { + } else if (!av_strcasecmp(cmd, "LoadModule")) { get_arg(arg, sizeof(arg), &p); #if HAVE_DLOPEN load_module(arg); @@ -4645,16 +4651,15 @@ static void handle_child_exit(int sig) static void opt_debug(void) { avserver_debug = 1; - avserver_daemon = 0; logfilename[0] = '-'; } -static void show_help(void) +void show_help_default(const char *opt, const char *arg) { printf("usage: avserver [options]\n" "Hyper fast multi format Audio/Video streaming server\n"); printf("\n"); - show_help_options(options, "Main options:\n", 0, 0); + show_help_options(options, "Main options:", 0, 0, 0); } static const OptionDef options[] = { @@ -4667,16 +4672,15 @@ static const OptionDef options[] = { int main(int argc, char **argv) { - struct sigaction sigact; + struct sigaction sigact = { { 0 } }; parse_loglevel(argc, argv, options); av_register_all(); + avformat_network_init(); show_banner(); my_program_name = argv[0]; - my_program_dir = getcwd(0, 0); - avserver_daemon = 1; parse_options(NULL, argc, argv, options, NULL); @@ -4684,7 +4688,6 @@ int main(int argc, char **argv) av_lfg_init(&random_state, av_get_random_seed()); - memset(&sigact, 0, sizeof(sigact)); sigact.sa_handler = handle_child_exit; sigact.sa_flags = SA_NOCLDSTOP | SA_RESTART; sigaction(SIGCHLD, &sigact, 0); @@ -4709,37 +4712,9 @@ int main(int argc, char **argv) compute_bandwidth(); - /* put the process in background and detach it from its TTY */ - if (avserver_daemon) { - int pid; - - pid = fork(); - if (pid < 0) { - perror("fork"); - exit(1); - } else if (pid > 0) { - /* parent : exit */ - exit(0); - } else { - /* child */ - setsid(); - close(0); - open("/dev/null", O_RDWR); - if (strcmp(logfilename, "-") != 0) { - close(1); - dup(0); - } - close(2); - dup(0); - } - } - /* signal init */ signal(SIGPIPE, SIG_IGN); - if (avserver_daemon) - chdir("/"); - if (http_server() < 0) { http_log("Could not start server\n"); exit(1);