ffserver.c File Reference

#include "config.h"
#include <string.h>
#include <stdlib.h>
#include "libavutil/random.h"
#include "libavutil/avstring.h"
#include "libavformat/avformat.h"
#include "libavformat/network.h"
#include "libavformat/os_support.h"
#include "libavformat/rtp.h"
#include "libavformat/rtsp.h"
#include "libavcodec/opt.h"
#include <stdarg.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <sys/time.h>
#include <time.h>
#include <sys/wait.h>
#include <signal.h>
#include "cmdutils.h"

Go to the source code of this file.

Data Structures

struct  DataRateData
struct  HTTPContext
struct  IPAddressACL
struct  FFStream
struct  FeedData

Defines

#define closesocket   close
#define HTTP_MAX_CONNECTIONS   2000
#define IOBUFFER_INIT_SIZE   8192
#define HTTP_REQUEST_TIMEOUT   (15 * 1000)
#define RTSP_REQUEST_TIMEOUT   (3600 * 24 * 1000)
#define SYNC_TIMEOUT   (10 * 1000)
#define CHECK_CODEC(x)   (ccf->x != ccs->x)

Enumerations

enum  HTTPState {
  HTTPSTATE_WAIT_REQUEST, HTTPSTATE_SEND_HEADER, HTTPSTATE_SEND_DATA_HEADER, HTTPSTATE_SEND_DATA,
  HTTPSTATE_SEND_DATA_TRAILER, HTTPSTATE_RECEIVE_DATA, HTTPSTATE_WAIT_FEED, HTTPSTATE_READY,
  RTSPSTATE_WAIT_REQUEST, RTSPSTATE_SEND_REPLY, RTSPSTATE_SEND_PACKET
}
enum  StreamType { STREAM_TYPE_LIVE, STREAM_TYPE_STATUS, STREAM_TYPE_REDIRECT }
enum  IPAddressAction { IP_ALLOW = 1, IP_DENY }
enum  RedirType {
  REDIR_NONE, REDIR_ASX, REDIR_RAM, REDIR_ASF,
  REDIR_RTSP, REDIR_SDP
}

Functions

static void new_connection (int server_fd, int is_rtsp)
static void close_connection (HTTPContext *c)
static int handle_connection (HTTPContext *c)
static int http_parse_request (HTTPContext *c)
static int http_send_data (HTTPContext *c)
static void compute_status (HTTPContext *c)
static int open_input_stream (HTTPContext *c, const char *info)
static int http_start_receive_data (HTTPContext *c)
static int http_receive_data (HTTPContext *c)
static int rtsp_parse_request (HTTPContext *c)
static void rtsp_cmd_describe (HTTPContext *c, const char *url)
static void rtsp_cmd_options (HTTPContext *c, const char *url)
static void rtsp_cmd_setup (HTTPContext *c, const char *url, RTSPHeader *h)
static void rtsp_cmd_play (HTTPContext *c, const char *url, RTSPHeader *h)
static void rtsp_cmd_pause (HTTPContext *c, const char *url, RTSPHeader *h)
static void rtsp_cmd_teardown (HTTPContext *c, const char *url, RTSPHeader *h)
static int prepare_sdp_description (FFStream *stream, uint8_t **pbuffer, struct in_addr my_ip)
static HTTPContextrtp_new_connection (struct sockaddr_in *from_addr, FFStream *stream, const char *session_id, enum RTSPProtocol rtp_protocol)
static int rtp_new_av_stream (HTTPContext *c, int stream_index, struct sockaddr_in *dest_addr, HTTPContext *rtsp_c)
static char * ctime1 (char *buf2)
static void http_vlog (const char *fmt, va_list vargs)
void __attribute__ ((format(printf, 1, 2)))
static void http_av_log (void *ptr, int level, const char *fmt, va_list vargs)
static void log_connection (HTTPContext *c)
static void update_datarate (DataRateData *drd, int64_t count)
static int compute_datarate (DataRateData *drd, int64_t count)
static void start_children (FFStream *feed)
static int socket_open_listen (struct sockaddr_in *my_addr)
static void start_multicast (void)
static int http_server (void)
static void start_wait_request (HTTPContext *c, int is_rtsp)
static int extract_rates (char *rates, int ratelen, const char *request)
static int find_stream_in_feed (FFStream *feed, AVCodecContext *codec, int bit_rate)
static int modify_current_stream (HTTPContext *c, char *rates)
static void do_switch_stream (HTTPContext *c, int i)
static void skip_spaces (const char **pp)
static void get_word (char *buf, int buf_size, const char **pp)
static int validate_acl (FFStream *stream, HTTPContext *c)
static void compute_real_filename (char *filename, int max_size)
static void fmt_bytecount (ByteIOContext *pb, int64_t count)
static void open_parser (AVFormatContext *s, int i)
static int64_t get_server_clock (HTTPContext *c)
static int64_t get_packet_send_clock (HTTPContext *c)
static int http_prepare_data (HTTPContext *c)
static void rtsp_reply_header (HTTPContext *c, enum RTSPStatusCode error_number)
static void rtsp_reply_error (HTTPContext *c, enum RTSPStatusCode error_number)
static HTTPContextfind_rtp_session (const char *session_id)
static RTSPTransportFieldfind_transport (RTSPHeader *h, enum RTSPProtocol protocol)
static HTTPContextfind_rtp_session_with_url (const char *url, const char *session_id)
static AVStreamadd_av_stream1 (FFStream *stream, AVCodecContext *codec)
static int add_av_stream (FFStream *feed, AVStream *st)
static void remove_stream (FFStream *stream)
static void extract_mpeg4_header (AVFormatContext *infile)
static void build_file_streams (void)
static void build_feed_streams (void)
static void compute_bandwidth (void)
static void get_arg (char *buf, int buf_size, const char **pp)
static void add_codec (FFStream *stream, AVCodecContext *av)
static int opt_audio_codec (const char *arg)
static int opt_video_codec (const char *arg)
static int opt_default (const char *opt, const char *arg, AVCodecContext *avctx, int type)
static int parse_ffconfig (const char *filename)
static void handle_child_exit (int sig)
static void opt_debug ()
static void opt_show_help (void)
int main (int argc, char **argv)

Variables

const char program_name [] = "FFserver"
const int program_birth_year = 2000
static const OptionDef options []
static const char * http_state []
static struct sockaddr_in my_http_addr
static struct sockaddr_in my_rtsp_addr
static char logfilename [1024]
static HTTPContextfirst_http_ctx
static FFStreamfirst_feed
static FFStreamfirst_stream
static const char * my_program_name
static const char * my_program_dir
static const char * config_filename
static int ffserver_debug
static int ffserver_daemon
static int no_launch
static int need_to_start_children
static int nb_max_connections = 5
static int nb_connections
static uint64_t max_bandwidth = 1000
static uint64_t current_bandwidth
static int64_t cur_time
static AVRandomState random_state
static FILE * logfile = NULL
static const OptionDef options []


Define Documentation

#define CHECK_CODEC (  )     (ccf->x != ccs->x)

#define closesocket   close

Definition at line 24 of file ffserver.c.

Referenced by close_connection(), new_connection(), socket_open_listen(), tcp_close(), tcp_open(), udp_close(), and udp_open().

#define HTTP_MAX_CONNECTIONS   2000

Definition at line 63 of file ffserver.c.

Referenced by parse_ffconfig().

#define HTTP_REQUEST_TIMEOUT   (15 * 1000)

Definition at line 99 of file ffserver.c.

Referenced by start_wait_request().

#define IOBUFFER_INIT_SIZE   8192

Definition at line 96 of file ffserver.c.

Referenced by new_connection(), and rtp_new_connection().

#define RTSP_REQUEST_TIMEOUT   (3600 * 24 * 1000)

Definition at line 100 of file ffserver.c.

Referenced by start_wait_request().

#define SYNC_TIMEOUT   (10 * 1000)

Definition at line 102 of file ffserver.c.


Enumeration Type Documentation

enum HTTPState

Enumerator:
HTTPSTATE_WAIT_REQUEST 
HTTPSTATE_SEND_HEADER 
HTTPSTATE_SEND_DATA_HEADER 
HTTPSTATE_SEND_DATA 
HTTPSTATE_SEND_DATA_TRAILER 
HTTPSTATE_RECEIVE_DATA 
HTTPSTATE_WAIT_FEED 
HTTPSTATE_READY 
RTSPSTATE_WAIT_REQUEST 
RTSPSTATE_SEND_REPLY 
RTSPSTATE_SEND_PACKET 

Definition at line 65 of file ffserver.c.

00065                {
00066     HTTPSTATE_WAIT_REQUEST,
00067     HTTPSTATE_SEND_HEADER,
00068     HTTPSTATE_SEND_DATA_HEADER,
00069     HTTPSTATE_SEND_DATA,          /* sending TCP or UDP data */
00070     HTTPSTATE_SEND_DATA_TRAILER,
00071     HTTPSTATE_RECEIVE_DATA,
00072     HTTPSTATE_WAIT_FEED,          /* wait for data from the feed */
00073     HTTPSTATE_READY,
00074 
00075     RTSPSTATE_WAIT_REQUEST,
00076     RTSPSTATE_SEND_REPLY,
00077     RTSPSTATE_SEND_PACKET,
00078 };

enum IPAddressAction

Enumerator:
IP_ALLOW 
IP_DENY 

Definition at line 179 of file ffserver.c.

00179                      {
00180     IP_ALLOW = 1,
00181     IP_DENY,
00182 };

enum RedirType

Enumerator:
REDIR_NONE 
REDIR_ASX 
REDIR_RAM 
REDIR_ASF 
REDIR_RTSP 
REDIR_SDP 

Definition at line 1206 of file ffserver.c.

01206                {
01207     REDIR_NONE,
01208     REDIR_ASX,
01209     REDIR_RAM,
01210     REDIR_ASF,
01211     REDIR_RTSP,
01212     REDIR_SDP,
01213 };

enum StreamType

Enumerator:
STREAM_TYPE_LIVE 
STREAM_TYPE_STATUS 
STREAM_TYPE_REDIRECT 

Definition at line 173 of file ffserver.c.

00173                 {
00174     STREAM_TYPE_LIVE,
00175     STREAM_TYPE_STATUS,
00176     STREAM_TYPE_REDIRECT,
00177 };


Function Documentation

void __attribute__ ( (format(printf, 1, 2))   ) 

Definition at line 336 of file ffserver.c.

References http_vlog().

00337 {
00338     va_list vargs;
00339     va_start(vargs, fmt);
00340     http_vlog(fmt, vargs);
00341     va_end(vargs);
00342 }

static int add_av_stream ( FFStream feed,
AVStream st 
) [static]

Definition at line 3245 of file ffserver.c.

References AVCodecContext::bit_rate, AVCodecContext::channels, AVStream::codec, AVCodecContext::codec_id, AVCodecContext::codec_type, CODEC_TYPE_AUDIO, CODEC_TYPE_VIDEO, AVRational::den, AVCodecContext::gop_size, AVCodecContext::height, FFStream::nb_streams, AVRational::num, AVCodecContext::sample_rate, FFStream::streams, AVCodecContext::time_base, and AVCodecContext::width.

Referenced by build_feed_streams().

03246 {
03247     AVStream *fst;
03248     AVCodecContext *av, *av1;
03249     int i;
03250 
03251     av = st->codec;
03252     for(i=0;i<feed->nb_streams;i++) {
03253         st = feed->streams[i];
03254         av1 = st->codec;
03255         if (av1->codec_id == av->codec_id &&
03256             av1->codec_type == av->codec_type &&
03257             av1->bit_rate == av->bit_rate) {
03258 
03259             switch(av->codec_type) {
03260             case CODEC_TYPE_AUDIO:
03261                 if (av1->channels == av->channels &&
03262                     av1->sample_rate == av->sample_rate)
03263                     goto found;
03264                 break;
03265             case CODEC_TYPE_VIDEO:
03266                 if (av1->width == av->width &&
03267                     av1->height == av->height &&
03268                     av1->time_base.den == av->time_base.den &&
03269                     av1->time_base.num == av->time_base.num &&
03270                     av1->gop_size == av->gop_size)
03271                     goto found;
03272                 break;
03273             default:
03274                 abort();
03275             }
03276         }
03277     }
03278 
03279     fst = add_av_stream1(feed, av);
03280     if (!fst)
03281         return -1;
03282     return feed->nb_streams - 1;
03283  found:
03284     return i;
03285 }

static AVStream* add_av_stream1 ( FFStream stream,
AVCodecContext codec 
) [static]

Definition at line 3228 of file ffserver.c.

References av_mallocz(), av_set_pts_info(), avcodec_alloc_context(), AVStream::codec, AVStream::index, FFStream::nb_streams, NULL, AVStream::priv_data, and FFStream::streams.

03229 {
03230     AVStream *fst;
03231 
03232     fst = av_mallocz(sizeof(AVStream));
03233     if (!fst)
03234         return NULL;
03235     fst->codec= avcodec_alloc_context();
03236     fst->priv_data = av_mallocz(sizeof(FeedData));
03237     memcpy(fst->codec, codec, sizeof(AVCodecContext));
03238     fst->index = stream->nb_streams;
03239     av_set_pts_info(fst, 33, 1, 90000);
03240     stream->streams[stream->nb_streams++] = fst;
03241     return fst;
03242 }

static void add_codec ( FFStream stream,
AVCodecContext av 
) [static]

Definition at line 3609 of file ffserver.c.

References av_mallocz(), avcodec_alloc_context(), AVCodecContext::b_quant_factor, AVCodecContext::b_quant_offset, AVCodecContext::bit_rate, AVCodecContext::bit_rate_tolerance, AVCodecContext::channels, AVStream::codec, AVCodecContext::codec_type, CODEC_TYPE_AUDIO, CODEC_TYPE_VIDEO, AVRational::den, FF_CMP_DCTMAX, FFMAX, AVCodecContext::frame_skip_cmp, AVCodecContext::height, AVCodecContext::i_quant_factor, AVCodecContext::max_qdiff, ME_EPZS, AVCodecContext::me_method, FFStream::nb_streams, AVCodecContext::nsse_weight, AVRational::num, AVCodecContext::qblur, AVCodecContext::qcompress, AVCodecContext::qmax, AVCodecContext::qmin, AVCodecContext::rc_buffer_aggressivity, AVCodecContext::rc_buffer_size, AVCodecContext::rc_eq, AVCodecContext::rc_max_rate, AVCodecContext::sample_rate, FFStream::streams, AVCodecContext::time_base, and AVCodecContext::width.

Referenced by parse_ffconfig().

03610 {
03611     AVStream *st;
03612 
03613     /* compute default parameters */
03614     switch(av->codec_type) {
03615     case CODEC_TYPE_AUDIO:
03616         if (av->bit_rate == 0)
03617             av->bit_rate = 64000;
03618         if (av->sample_rate == 0)
03619             av->sample_rate = 22050;
03620         if (av->channels == 0)
03621             av->channels = 1;
03622         break;
03623     case CODEC_TYPE_VIDEO:
03624         if (av->bit_rate == 0)
03625             av->bit_rate = 64000;
03626         if (av->time_base.num == 0){
03627             av->time_base.den = 5;
03628             av->time_base.num = 1;
03629         }
03630         if (av->width == 0 || av->height == 0) {
03631             av->width = 160;
03632             av->height = 128;
03633         }
03634         /* Bitrate tolerance is less for streaming */
03635         if (av->bit_rate_tolerance == 0)
03636             av->bit_rate_tolerance = FFMAX(av->bit_rate / 4,
03637                       (int64_t)av->bit_rate*av->time_base.num/av->time_base.den);
03638         if (av->qmin == 0)
03639             av->qmin = 3;
03640         if (av->qmax == 0)
03641             av->qmax = 31;
03642         if (av->max_qdiff == 0)
03643             av->max_qdiff = 3;
03644         av->qcompress = 0.5;
03645         av->qblur = 0.5;
03646 
03647         if (!av->nsse_weight)
03648             av->nsse_weight = 8;
03649 
03650         av->frame_skip_cmp = FF_CMP_DCTMAX;
03651         av->me_method = ME_EPZS;
03652         av->rc_buffer_aggressivity = 1.0;
03653 
03654         if (!av->rc_eq)
03655             av->rc_eq = "tex^qComp";
03656         if (!av->i_quant_factor)
03657             av->i_quant_factor = -0.8;
03658         if (!av->b_quant_factor)
03659             av->b_quant_factor = 1.25;
03660         if (!av->b_quant_offset)
03661             av->b_quant_offset = 1.25;
03662         if (!av->rc_max_rate)
03663             av->rc_max_rate = av->bit_rate * 2;
03664 
03665         if (av->rc_max_rate && !av->rc_buffer_size) {
03666             av->rc_buffer_size = av->rc_max_rate;
03667         }
03668 
03669 
03670         break;
03671     default:
03672         abort();
03673     }
03674 
03675     st = av_mallocz(sizeof(AVStream));
03676     if (!st)
03677         return;
03678     st->codec = avcodec_alloc_context();
03679     stream->streams[stream->nb_streams++] = st;
03680     memcpy(st->codec, av, sizeof(AVCodecContext));
03681 }

static void build_feed_streams ( void   )  [static]

Definition at line 3398 of file ffserver.c.

References add_av_stream(), FFStream::feed, FFStream::feed_streams, first_stream, FFStream::is_feed, FFStream::next, NULL, and FFStream::streams.

Referenced by main().

03399 {
03400     FFStream *stream, *feed;
03401     int i;
03402 
03403     /* gather all streams */
03404     for(stream = first_stream; stream != NULL; stream = stream->next) {
03405         feed = stream->feed;
03406         if (feed) {
03407             if (!stream->is_feed) {
03408                 /* we handle a stream coming from a feed */
03409                 for(i=0;i<stream->nb_streams;i++)
03410                     stream->feed_streams[i] = add_av_stream(feed, stream->streams[i]);
03411             }
03412         }
03413     }
03414 
03415     /* gather all streams */
03416     for(stream = first_stream; stream != NULL; stream = stream->next) {
03417         feed = stream->feed;
03418         if (feed) {
03419             if (stream->is_feed) {
03420                 for(i=0;i<stream->nb_streams;i++)
03421                     stream->feed_streams[i] = i;
03422             }
03423         }
03424     }
03425 
03426     /* create feed files if needed */
03427     for(feed = first_feed; feed != NULL; feed = feed->next_feed) {
03428         int fd;
03429 
03430         if (url_exist(feed->feed_filename)) {
03431             /* See if it matches */
03432             AVFormatContext *s;
03433             int matches = 0;
03434 
03435             if (av_open_input_file(&s, feed->feed_filename, NULL, FFM_PACKET_SIZE, NULL) >= 0) {
03436                 /* Now see if it matches */
03437                 if (s->nb_streams == feed->nb_streams) {
03438                     matches = 1;
03439                     for(i=0;i<s->nb_streams;i++) {
03440                         AVStream *sf, *ss;
03441                         sf = feed->streams[i];
03442                         ss = s->streams[i];
03443 
03444                         if (sf->index != ss->index ||
03445                             sf->id != ss->id) {
03446                             http_log("Index & Id do not match for stream %d (%s)\n",
03447                                    i, feed->feed_filename);
03448                             matches = 0;
03449                         } else {
03450                             AVCodecContext *ccf, *ccs;
03451 
03452                             ccf = sf->codec;
03453                             ccs = ss->codec;
03454 #define CHECK_CODEC(x)  (ccf->x != ccs->x)
03455 
03456                             if (CHECK_CODEC(codec) || CHECK_CODEC(codec_type)) {
03457                                 http_log("Codecs do not match for stream %d\n", i);
03458                                 matches = 0;
03459                             } else if (CHECK_CODEC(bit_rate) || CHECK_CODEC(flags)) {
03460                                 http_log("Codec bitrates do not match for stream %d\n", i);
03461                                 matches = 0;
03462                             } else if (ccf->codec_type == CODEC_TYPE_VIDEO) {
03463                                 if (CHECK_CODEC(time_base.den) ||
03464                                     CHECK_CODEC(time_base.num) ||
03465                                     CHECK_CODEC(width) ||
03466                                     CHECK_CODEC(height)) {
03467                                     http_log("Codec width, height and framerate do not match for stream %d\n", i);
03468                                     matches = 0;
03469                                 }
03470                             } else if (ccf->codec_type == CODEC_TYPE_AUDIO) {
03471                                 if (CHECK_CODEC(sample_rate) ||
03472                                     CHECK_CODEC(channels) ||
03473                                     CHECK_CODEC(frame_size)) {
03474                                     http_log("Codec sample_rate, channels, frame_size do not match for stream %d\n", i);
03475                                     matches = 0;
03476                                 }
03477                             } else {
03478                                 http_log("Unknown codec type\n");
03479                                 matches = 0;
03480                             }
03481                         }
03482                         if (!matches)
03483                             break;
03484                     }
03485                 } else
03486                     http_log("Deleting feed file '%s' as stream counts differ (%d != %d)\n",
03487                         feed->feed_filename, s->nb_streams, feed->nb_streams);
03488 
03489                 av_close_input_file(s);
03490             } else
03491                 http_log("Deleting feed file '%s' as it appears to be corrupt\n",
03492                         feed->feed_filename);
03493 
03494             if (!matches) {
03495                 if (feed->readonly) {
03496                     http_log("Unable to delete feed file '%s' as it is marked readonly\n",
03497                         feed->feed_filename);
03498                     exit(1);
03499                 }
03500                 unlink(feed->feed_filename);
03501             }
03502         }
03503         if (!url_exist(feed->feed_filename)) {
03504             AVFormatContext s1, *s = &s1;
03505 
03506             if (feed->readonly) {
03507                 http_log("Unable to create feed file '%s' as it is marked readonly\n",
03508                     feed->feed_filename);
03509                 exit(1);
03510             }
03511 
03512             /* only write the header of the ffm file */
03513             if (url_fopen(&s->pb, feed->feed_filename, URL_WRONLY) < 0) {
03514                 http_log("Could not open output feed file '%s'\n",
03515                          feed->feed_filename);
03516                 exit(1);
03517             }
03518             s->oformat = feed->fmt;
03519             s->nb_streams = feed->nb_streams;
03520             for(i=0;i<s->nb_streams;i++) {
03521                 AVStream *st;
03522                 st = feed->streams[i];
03523                 s->streams[i] = st;
03524             }
03525             av_set_parameters(s, NULL);
03526             if (av_write_header(s) < 0) {
03527                 http_log("Container doesn't supports the required parameters\n");
03528                 exit(1);
03529             }
03530             /* XXX: need better api */
03531             av_freep(&s->priv_data);
03532             url_fclose(s->pb);
03533         }
03534         /* get feed size and write index */
03535         fd = open(feed->feed_filename, O_RDONLY);
03536         if (fd < 0) {
03537             http_log("Could not open output feed file '%s'\n",
03538                     feed->feed_filename);
03539             exit(1);
03540         }
03541 
03542         feed->feed_write_index = ffm_read_write_index(fd);
03543         feed->feed_size = lseek(fd, 0, SEEK_END);
03544         /* ensure that we do not wrap before the end of file */
03545         if (feed->feed_max_size && feed->feed_max_size < feed->feed_size)
03546             feed->feed_max_size = feed->feed_size;
03547 
03548         close(fd);
03549     }
03550 }

static void build_file_streams ( void   )  [static]

Definition at line 3349 of file ffserver.c.

References FFStream::ap_in, av_mallocz(), av_open_input_file(), FFStream::feed, FFStream::feed_filename, first_stream, FFStream::fmt, FFStream::ifmt, AVFormatParameters::mpeg2ts_compute_pcr, AVFormatParameters::mpeg2ts_raw, AVOutputFormat::name, FFStream::next, NULL, remove_stream(), FFStream::stream_type, and STREAM_TYPE_LIVE.

Referenced by main().

03350 {
03351     FFStream *stream, *stream_next;
03352     AVFormatContext *infile;
03353     int i, ret;
03354 
03355     /* gather all streams */
03356     for(stream = first_stream; stream != NULL; stream = stream_next) {
03357         stream_next = stream->next;
03358         if (stream->stream_type == STREAM_TYPE_LIVE &&
03359             !stream->feed) {
03360             /* the stream comes from a file */
03361             /* try to open the file */
03362             /* open stream */
03363             stream->ap_in = av_mallocz(sizeof(AVFormatParameters));
03364             if (stream->fmt && !strcmp(stream->fmt->name, "rtp")) {
03365                 /* specific case : if transport stream output to RTP,
03366                    we use a raw transport stream reader */
03367                 stream->ap_in->mpeg2ts_raw = 1;
03368                 stream->ap_in->mpeg2ts_compute_pcr = 1;
03369             }
03370 
03371             if ((ret = av_open_input_file(&infile, stream->feed_filename,
03372                                           stream->ifmt, 0, stream->ap_in)) < 0) {
03373                 http_log("could not open %s: %d\n", stream->feed_filename, ret);
03374                 /* remove stream (no need to spend more time on it) */
03375             fail:
03376                 remove_stream(stream);
03377             } else {
03378                 /* find all the AVStreams inside and reference them in
03379                    'stream' */
03380                 if (av_find_stream_info(infile) < 0) {
03381                     http_log("Could not find codec parameters from '%s'\n",
03382                              stream->feed_filename);
03383                     av_close_input_file(infile);
03384                     goto fail;
03385                 }
03386                 extract_mpeg4_header(infile);
03387 
03388                 for(i=0;i<infile->nb_streams;i++)
03389                     add_av_stream1(stream, infile->streams[i]->codec);
03390 
03391                 av_close_input_file(infile);
03392             }
03393         }
03394     }
03395 }

static void close_connection ( HTTPContext c  )  [static]

Definition at line 737 of file ffserver.c.

References avcodec_close(), c, c1, closesocket, AVCodecContext::codec, AVStream::codec, first_http_ctx, and NULL.

Referenced by rtsp_cmd_teardown().

00738 {
00739     HTTPContext **cp, *c1;
00740     int i, nb_streams;
00741     AVFormatContext *ctx;
00742     URLContext *h;
00743     AVStream *st;
00744 
00745     /* remove connection from list */
00746     cp = &first_http_ctx;
00747     while ((*cp) != NULL) {
00748         c1 = *cp;
00749         if (c1 == c)
00750             *cp = c->next;
00751         else
00752             cp = &c1->next;
00753     }
00754 
00755     /* remove references, if any (XXX: do it faster) */
00756     for(c1 = first_http_ctx; c1 != NULL; c1 = c1->next) {
00757         if (c1->rtsp_c == c)
00758             c1->rtsp_c = NULL;
00759     }
00760 
00761     /* remove connection associated resources */
00762     if (c->fd >= 0)
00763         closesocket(c->fd);
00764     if (c->fmt_in) {
00765         /* close each frame parser */
00766         for(i=0;i<c->fmt_in->nb_streams;i++) {
00767             st = c->fmt_in->streams[i];
00768             if (st->codec->codec)
00769                 avcodec_close(st->codec);
00770         }
00771         av_close_input_file(c->fmt_in);
00772     }
00773 
00774     /* free RTP output streams if any */
00775     nb_streams = 0;
00776     if (c->stream)
00777         nb_streams = c->stream->nb_streams;
00778 
00779     for(i=0;i<nb_streams;i++) {
00780         ctx = c->rtp_ctx[i];
00781         if (ctx) {
00782             av_write_trailer(ctx);
00783             av_free(ctx);
00784         }
00785         h = c->rtp_handles[i];
00786         if (h)
00787             url_close(h);
00788     }
00789 
00790     ctx = &c->fmt_ctx;
00791 
00792     if (!c->last_packet_sent) {
00793         if (ctx->oformat) {
00794             /* prepare header */
00795             if (url_open_dyn_buf(&ctx->pb) >= 0) {
00796                 av_write_trailer(ctx);
00797                 av_freep(&c->pb_buffer);
00798                 url_close_dyn_buf(ctx->pb, &c->pb_buffer);
00799             }
00800         }
00801     }
00802 
00803     for(i=0; i<ctx->nb_streams; i++)
00804         av_free(ctx->streams[i]);
00805 
00806     if (c->stream && !c->post && c->stream->stream_type == STREAM_TYPE_LIVE)
00807         current_bandwidth -= c->stream->bandwidth;
00808 
00809     /* signal that there is no feed if we are the feeder socket */
00810     if (c->state == HTTPSTATE_RECEIVE_DATA && c->stream) {
00811         c->stream->feed_opened = 0;
00812         close(c->feed_fd);
00813     }
00814 
00815     av_freep(&c->pb_buffer);
00816     av_freep(&c->packet_buffer);
00817     av_free(c->buffer);
00818     av_free(c);
00819     nb_connections--;
00820 }

static void compute_bandwidth ( void   )  [static]

Definition at line 3553 of file ffserver.c.

References FFStream::bandwidth, CODEC_TYPE_AUDIO, CODEC_TYPE_VIDEO, first_stream, FFStream::nb_streams, FFStream::next, NULL, and FFStream::streams.

Referenced by main().

03554 {
03555     unsigned bandwidth;
03556     int i;
03557     FFStream *stream;
03558 
03559     for(stream = first_stream; stream != NULL; stream = stream->next) {
03560         bandwidth = 0;
03561         for(i=0;i<stream->nb_streams;i++) {
03562             AVStream *st = stream->streams[i];
03563             switch(st->codec->codec_type) {
03564             case CODEC_TYPE_AUDIO:
03565             case CODEC_TYPE_VIDEO:
03566                 bandwidth += st->codec->bit_rate;
03567                 break;