#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 HTTPContext * | rtp_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 HTTPContext * | find_rtp_session (const char *session_id) |
| static RTSPTransportField * | find_transport (RTSPHeader *h, enum RTSPProtocol protocol) |
| static HTTPContext * | find_rtp_session_with_url (const char *url, const char *session_id) |
| static AVStream * | add_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 HTTPContext * | first_http_ctx |
| static FFStream * | first_feed |
| static FFStream * | first_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 CHECK_CODEC | ( | x | ) | (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 |
| #define HTTP_REQUEST_TIMEOUT (15 * 1000) |
| #define IOBUFFER_INIT_SIZE 8192 |
| #define RTSP_REQUEST_TIMEOUT (3600 * 24 * 1000) |
| #define SYNC_TIMEOUT (10 * 1000) |
Definition at line 102 of file ffserver.c.
| enum HTTPState |
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 |
| enum RedirType |
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 |
Definition at line 173 of file ffserver.c.
00173 { 00174 STREAM_TYPE_LIVE, 00175 STREAM_TYPE_STATUS, 00176 STREAM_TYPE_REDIRECT, 00177 };
| 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 }
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;