diff --git a/ffserver.c b/ffserver.c index 1b5d4a049f..3fc8250a51 100644 --- a/ffserver.c +++ b/ffserver.c @@ -125,6 +125,8 @@ typedef struct FFStream { /* feed specific */ int feed_opened; /* true if someone if writing to feed */ int is_feed; /* true if it is a feed */ + int conns_served; + INT64 bytes_served; INT64 feed_max_size; /* maximum storage size */ INT64 feed_write_index; /* current write position in feed (it wraps round) */ INT64 feed_size; /* current size of feed */ @@ -272,7 +274,7 @@ static int http_server(struct sockaddr_in my_addr) /* need to catch errors */ c->poll_entry = poll_entry; poll_entry->fd = fd; - poll_entry->events = 0; + poll_entry->events = POLLIN;/* Maybe this will work */ poll_entry++; break; default: @@ -398,6 +400,8 @@ static int handle_http(HTTPContext *c, long cur_time) } } else { c->buffer_ptr += len; + c->stream->bytes_served += len; + c->data_count += len; if (c->buffer_ptr >= c->buffer_end) { /* if error, exit */ if (c->http_error) @@ -432,7 +436,7 @@ static int handle_http(HTTPContext *c, long cur_time) break; case HTTPSTATE_WAIT_FEED: /* no need to read if no events */ - if (c->poll_entry->revents & (POLLERR | POLLHUP)) + if (c->poll_entry->revents & (POLLIN | POLLERR | POLLHUP)) return -1; /* nothing to do, we'll be waken up by incoming feed packets */ @@ -647,6 +651,7 @@ static int http_parse_request(HTTPContext *c) } c->stream = stream; + stream->conns_served++; /* XXX: add there authenticate and IP match */ @@ -770,79 +775,113 @@ static void compute_stats(HTTPContext *c) q += sprintf(q, "

FFServer Status

\n"); /* format status */ q += sprintf(q, "

Available Streams

\n"); - q += sprintf(q, "\n"); - q += sprintf(q, "
PathFormatBit rate (kbits/s)VideoAudioFeed\n"); + q += sprintf(q, "\n"); + q += sprintf(q, "
PathServed
Conns

kbytes
FormatBit rate
kbits/s
Video
kbits/s

Codec
Audio
kbits/s

Codec
Feed\n"); stream = first_stream; while (stream != NULL) { char sfilename[1024]; char *eosf; - strlcpy(sfilename, stream->filename, sizeof(sfilename) - 1); - eosf = sfilename + strlen(sfilename); - if (eosf - sfilename >= 4) { - if (strcmp(eosf - 4, ".asf") == 0) { - strcpy(eosf - 4, ".asx"); - } else if (strcmp(eosf - 3, ".rm") == 0) { - strcpy(eosf - 3, ".ram"); + if (stream->feed != stream) { + strlcpy(sfilename, stream->filename, sizeof(sfilename) - 1); + eosf = sfilename + strlen(sfilename); + if (eosf - sfilename >= 4) { + if (strcmp(eosf - 4, ".asf") == 0) { + strcpy(eosf - 4, ".asx"); + } else if (strcmp(eosf - 3, ".rm") == 0) { + strcpy(eosf - 3, ".ram"); + } } - } - - q += sprintf(q, "
%s ", - sfilename, stream->filename); - switch(stream->stream_type) { - case STREAM_TYPE_LIVE: - { - int audio_bit_rate = 0; - int video_bit_rate = 0; - char *audio_codec_name = ""; - char *video_codec_name = ""; - char *audio_codec_name_extra = ""; - char *video_codec_name_extra = ""; + + q += sprintf(q, "
%s ", + sfilename, stream->filename); + q += sprintf(q, " %d %lld", + stream->conns_served, stream->bytes_served / 1000); + switch(stream->stream_type) { + case STREAM_TYPE_LIVE: + { + int audio_bit_rate = 0; + int video_bit_rate = 0; + char *audio_codec_name = ""; + char *video_codec_name = ""; + char *audio_codec_name_extra = ""; + char *video_codec_name_extra = ""; - for(i=0;inb_streams;i++) { - AVStream *st = stream->streams[i]; - AVCodec *codec = avcodec_find_encoder(st->codec.codec_id); - switch(st->codec.codec_type) { - case CODEC_TYPE_AUDIO: - audio_bit_rate += st->codec.bit_rate; - if (codec) { - if (*audio_codec_name) - audio_codec_name_extra = "..."; - audio_codec_name = codec->name; + for(i=0;inb_streams;i++) { + AVStream *st = stream->streams[i]; + AVCodec *codec = avcodec_find_encoder(st->codec.codec_id); + switch(st->codec.codec_type) { + case CODEC_TYPE_AUDIO: + audio_bit_rate += st->codec.bit_rate; + if (codec) { + if (*audio_codec_name) + audio_codec_name_extra = "..."; + audio_codec_name = codec->name; + } + break; + case CODEC_TYPE_VIDEO: + video_bit_rate += st->codec.bit_rate; + if (codec) { + if (*video_codec_name) + video_codec_name_extra = "..."; + video_codec_name = codec->name; + } + break; + default: + abort(); } - break; - case CODEC_TYPE_VIDEO: - video_bit_rate += st->codec.bit_rate; - if (codec) { - if (*video_codec_name) - video_codec_name_extra = "..."; - video_codec_name = codec->name; - } - break; - default: - abort(); } + q += sprintf(q, " %s %d %d %s %s %d %s %s", + stream->fmt->name, + (audio_bit_rate + video_bit_rate) / 1000, + video_bit_rate / 1000, video_codec_name, video_codec_name_extra, + audio_bit_rate / 1000, audio_codec_name, audio_codec_name_extra); + if (stream->feed) { + q += sprintf(q, "%s", stream->feed->filename); + } else { + q += sprintf(q, "%s", stream->feed_filename); + } + q += sprintf(q, "\n"); } - q += sprintf(q, " %s %d %d %s %s %d %s %s", - stream->fmt->name, - (audio_bit_rate + video_bit_rate) / 1000, - video_bit_rate / 1000, video_codec_name, video_codec_name_extra, - audio_bit_rate / 1000, audio_codec_name, audio_codec_name_extra); - if (stream->feed) { - q += sprintf(q, "%s", stream->feed->filename); - } else { - q += sprintf(q, "%s", stream->feed_filename); - } - q += sprintf(q, "\n"); + break; + default: + q += sprintf(q, " - - - - \n"); + break; } - break; - default: - q += sprintf(q, " - - - -\n"); - break; } stream = stream->next; } q += sprintf(q, "
\n"); + + stream = first_stream; + while (stream != NULL) { + if (stream->feed == stream) { + q += sprintf(q, "

Feed %s

", stream->filename); + q += sprintf(q, "
Streamtypekbits/scodec\n"); + + for (i = 0; i < stream->nb_streams; i++) { + AVStream *st = stream->streams[i]; + AVCodec *codec = avcodec_find_encoder(st->codec.codec_id); + char *type = "unknown"; + + switch(st->codec.codec_type) { + case CODEC_TYPE_AUDIO: + type = "audio"; + break; + case CODEC_TYPE_VIDEO: + type = "video"; + break; + default: + abort(); + } + q += sprintf(q, "
%d%s%d%s\n", + i, type, st->codec.bit_rate/1000, codec ? codec->name : ""); + } + q += sprintf(q, "
\n"); + + } + stream = stream->next; + } #if 0 { @@ -887,7 +926,7 @@ static void compute_stats(HTTPContext *c) q += sprintf(q, "
#FileIPStateSize\n"); c1 = first_http_ctx; i = 0; - while (c1 != NULL) { + while (c1 != NULL && q < (char *) c->buffer + sizeof(c->buffer) - 2048) { i++; p = inet_ntoa(c1->from_addr.sin_addr); q += sprintf(q, "
%d%s%s %s %s %Ld\n", @@ -903,7 +942,7 @@ static void compute_stats(HTTPContext *c) /* date */ ti = time(NULL); p = ctime(&ti); - q += sprintf(q, "
Generated at %s", p); + q += sprintf(q, "
Generated at %s", p); q += sprintf(q, "\n\n"); c->buffer_ptr = c->buffer; @@ -1088,6 +1127,7 @@ static int http_prepare_data(HTTPContext *c) c->stream->feed->feed_write_index, c->stream->feed->feed_size); } + if (av_read_packet(c->fmt_in, &pkt) < 0) { if (c->stream->feed && c->stream->feed->feed_opened) { /* if coming from feed, it means we reached the end of the @@ -1168,7 +1208,7 @@ static int http_send_data(HTTPContext *c) if (ret < 0) return -1; else if (ret == 0) { - break; + continue; } else { /* state change requested */ return 0; @@ -1185,6 +1225,7 @@ static int http_send_data(HTTPContext *c) } else { c->buffer_ptr += len; c->data_count += len; + c->stream->bytes_served += len; } } return 0; @@ -1216,9 +1257,26 @@ static int http_start_receive_data(HTTPContext *c) static int http_receive_data(HTTPContext *c) { - int len; HTTPContext *c1; + if (c->buffer_end > c->buffer_ptr) { + int len; + + len = read(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr); + if (len < 0) { + if (errno != EAGAIN && errno != EINTR) { + /* error : close connection */ + goto fail; + } + } else if (len == 0) { + /* end of connection : close it */ + goto fail; + } else { + c->buffer_ptr += len; + c->data_count += len; + } + } + if (c->buffer_ptr >= c->buffer_end) { FFStream *feed = c->stream; /* a packet has been received : write it in the store, except @@ -1276,19 +1334,6 @@ static int http_receive_data(HTTPContext *c) c->buffer_ptr = c->buffer; } - len = read(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr); - if (len < 0) { - if (errno != EAGAIN && errno != EINTR) { - /* error : close connection */ - goto fail; - } - } else if (len == 0) { - /* end of connection : close it */ - goto fail; - } else { - c->buffer_ptr += len; - c->data_count += len; - } return 0; fail: c->stream->feed_opened = 0;