Originally committed as revision 514 to svn://svn.ffmpeg.org/ffmpeg/trunk
Philip Gladstone authored on 2002/05/19 06:33:05... | ... |
@@ -125,6 +125,8 @@ typedef struct FFStream { |
125 | 125 |
/* feed specific */ |
126 | 126 |
int feed_opened; /* true if someone if writing to feed */ |
127 | 127 |
int is_feed; /* true if it is a feed */ |
128 |
+ int conns_served; |
|
129 |
+ INT64 bytes_served; |
|
128 | 130 |
INT64 feed_max_size; /* maximum storage size */ |
129 | 131 |
INT64 feed_write_index; /* current write position in feed (it wraps round) */ |
130 | 132 |
INT64 feed_size; /* current size of feed */ |
... | ... |
@@ -272,7 +274,7 @@ static int http_server(struct sockaddr_in my_addr) |
272 | 272 |
/* need to catch errors */ |
273 | 273 |
c->poll_entry = poll_entry; |
274 | 274 |
poll_entry->fd = fd; |
275 |
- poll_entry->events = 0; |
|
275 |
+ poll_entry->events = POLLIN;/* Maybe this will work */ |
|
276 | 276 |
poll_entry++; |
277 | 277 |
break; |
278 | 278 |
default: |
... | ... |
@@ -398,6 +400,8 @@ static int handle_http(HTTPContext *c, long cur_time) |
398 | 398 |
} |
399 | 399 |
} else { |
400 | 400 |
c->buffer_ptr += len; |
401 |
+ c->stream->bytes_served += len; |
|
402 |
+ c->data_count += len; |
|
401 | 403 |
if (c->buffer_ptr >= c->buffer_end) { |
402 | 404 |
/* if error, exit */ |
403 | 405 |
if (c->http_error) |
... | ... |
@@ -432,7 +436,7 @@ static int handle_http(HTTPContext *c, long cur_time) |
432 | 432 |
break; |
433 | 433 |
case HTTPSTATE_WAIT_FEED: |
434 | 434 |
/* no need to read if no events */ |
435 |
- if (c->poll_entry->revents & (POLLERR | POLLHUP)) |
|
435 |
+ if (c->poll_entry->revents & (POLLIN | POLLERR | POLLHUP)) |
|
436 | 436 |
return -1; |
437 | 437 |
|
438 | 438 |
/* nothing to do, we'll be waken up by incoming feed packets */ |
... | ... |
@@ -647,6 +651,7 @@ static int http_parse_request(HTTPContext *c) |
647 | 647 |
} |
648 | 648 |
|
649 | 649 |
c->stream = stream; |
650 |
+ stream->conns_served++; |
|
650 | 651 |
|
651 | 652 |
/* XXX: add there authenticate and IP match */ |
652 | 653 |
|
... | ... |
@@ -770,79 +775,113 @@ static void compute_stats(HTTPContext *c) |
770 | 770 |
q += sprintf(q, "<H1>FFServer Status</H1>\n"); |
771 | 771 |
/* format status */ |
772 | 772 |
q += sprintf(q, "<H2>Available Streams</H2>\n"); |
773 |
- q += sprintf(q, "<TABLE>\n"); |
|
774 |
- q += sprintf(q, "<TR><Th>Path<Th>Format<Th>Bit rate (kbits/s)<Th COLSPAN=2>Video<Th COLSPAN=2>Audio<Th align=left>Feed\n"); |
|
773 |
+ q += sprintf(q, "<TABLE cellspacing=0 cellpadding=4>\n"); |
|
774 |
+ q += sprintf(q, "<TR><Th valign=top>Path<th align=left>Served<br>Conns<Th><br>kbytes<Th valign=top>Format<Th>Bit rate<br>kbits/s<Th align=left>Video<br>kbits/s<th><br>Codec<Th align=left>Audio<br>kbits/s<th><br>Codec<Th align=left valign=top>Feed\n"); |
|
775 | 775 |
stream = first_stream; |
776 | 776 |
while (stream != NULL) { |
777 | 777 |
char sfilename[1024]; |
778 | 778 |
char *eosf; |
779 | 779 |
|
780 |
- strlcpy(sfilename, stream->filename, sizeof(sfilename) - 1); |
|
781 |
- eosf = sfilename + strlen(sfilename); |
|
782 |
- if (eosf - sfilename >= 4) { |
|
783 |
- if (strcmp(eosf - 4, ".asf") == 0) { |
|
784 |
- strcpy(eosf - 4, ".asx"); |
|
785 |
- } else if (strcmp(eosf - 3, ".rm") == 0) { |
|
786 |
- strcpy(eosf - 3, ".ram"); |
|
780 |
+ if (stream->feed != stream) { |
|
781 |
+ strlcpy(sfilename, stream->filename, sizeof(sfilename) - 1); |
|
782 |
+ eosf = sfilename + strlen(sfilename); |
|
783 |
+ if (eosf - sfilename >= 4) { |
|
784 |
+ if (strcmp(eosf - 4, ".asf") == 0) { |
|
785 |
+ strcpy(eosf - 4, ".asx"); |
|
786 |
+ } else if (strcmp(eosf - 3, ".rm") == 0) { |
|
787 |
+ strcpy(eosf - 3, ".ram"); |
|
788 |
+ } |
|
787 | 789 |
} |
788 |
- } |
|
789 |
- |
|
790 |
- q += sprintf(q, "<TR><TD><A HREF=\"/%s\">%s</A> ", |
|
791 |
- sfilename, stream->filename); |
|
792 |
- switch(stream->stream_type) { |
|
793 |
- case STREAM_TYPE_LIVE: |
|
794 |
- { |
|
795 |
- int audio_bit_rate = 0; |
|
796 |
- int video_bit_rate = 0; |
|
797 |
- char *audio_codec_name = ""; |
|
798 |
- char *video_codec_name = ""; |
|
799 |
- char *audio_codec_name_extra = ""; |
|
800 |
- char *video_codec_name_extra = ""; |
|
801 |
- |
|
802 |
- for(i=0;i<stream->nb_streams;i++) { |
|
803 |
- AVStream *st = stream->streams[i]; |
|
804 |
- AVCodec *codec = avcodec_find_encoder(st->codec.codec_id); |
|
805 |
- switch(st->codec.codec_type) { |
|
806 |
- case CODEC_TYPE_AUDIO: |
|
807 |
- audio_bit_rate += st->codec.bit_rate; |
|
808 |
- if (codec) { |
|
809 |
- if (*audio_codec_name) |
|
810 |
- audio_codec_name_extra = "..."; |
|
811 |
- audio_codec_name = codec->name; |
|
812 |
- } |
|
813 |
- break; |
|
814 |
- case CODEC_TYPE_VIDEO: |
|
815 |
- video_bit_rate += st->codec.bit_rate; |
|
816 |
- if (codec) { |
|
817 |
- if (*video_codec_name) |
|
818 |
- video_codec_name_extra = "..."; |
|
819 |
- video_codec_name = codec->name; |
|
790 |
+ |
|
791 |
+ q += sprintf(q, "<TR><TD><A HREF=\"/%s\">%s</A> ", |
|
792 |
+ sfilename, stream->filename); |
|
793 |
+ q += sprintf(q, "<td align=right> %d <td align=right> %lld", |
|
794 |
+ stream->conns_served, stream->bytes_served / 1000); |
|
795 |
+ switch(stream->stream_type) { |
|
796 |
+ case STREAM_TYPE_LIVE: |
|
797 |
+ { |
|
798 |
+ int audio_bit_rate = 0; |
|
799 |
+ int video_bit_rate = 0; |
|
800 |
+ char *audio_codec_name = ""; |
|
801 |
+ char *video_codec_name = ""; |
|
802 |
+ char *audio_codec_name_extra = ""; |
|
803 |
+ char *video_codec_name_extra = ""; |
|
804 |
+ |
|
805 |
+ for(i=0;i<stream->nb_streams;i++) { |
|
806 |
+ AVStream *st = stream->streams[i]; |
|
807 |
+ AVCodec *codec = avcodec_find_encoder(st->codec.codec_id); |
|
808 |
+ switch(st->codec.codec_type) { |
|
809 |
+ case CODEC_TYPE_AUDIO: |
|
810 |
+ audio_bit_rate += st->codec.bit_rate; |
|
811 |
+ if (codec) { |
|
812 |
+ if (*audio_codec_name) |
|
813 |
+ audio_codec_name_extra = "..."; |
|
814 |
+ audio_codec_name = codec->name; |
|
815 |
+ } |
|
816 |
+ break; |
|
817 |
+ case CODEC_TYPE_VIDEO: |
|
818 |
+ video_bit_rate += st->codec.bit_rate; |
|
819 |
+ if (codec) { |
|
820 |
+ if (*video_codec_name) |
|
821 |
+ video_codec_name_extra = "..."; |
|
822 |
+ video_codec_name = codec->name; |
|
823 |
+ } |
|
824 |
+ break; |
|
825 |
+ default: |
|
826 |
+ abort(); |
|
820 | 827 |
} |
821 |
- break; |
|
822 |
- default: |
|
823 |
- abort(); |
|
824 | 828 |
} |
829 |
+ q += sprintf(q, "<TD align=center> %s <TD align=right> %d <TD align=right> %d <TD> %s %s <TD align=right> %d <TD> %s %s", |
|
830 |
+ stream->fmt->name, |
|
831 |
+ (audio_bit_rate + video_bit_rate) / 1000, |
|
832 |
+ video_bit_rate / 1000, video_codec_name, video_codec_name_extra, |
|
833 |
+ audio_bit_rate / 1000, audio_codec_name, audio_codec_name_extra); |
|
834 |
+ if (stream->feed) { |
|
835 |
+ q += sprintf(q, "<TD>%s", stream->feed->filename); |
|
836 |
+ } else { |
|
837 |
+ q += sprintf(q, "<TD>%s", stream->feed_filename); |
|
838 |
+ } |
|
839 |
+ q += sprintf(q, "\n"); |
|
825 | 840 |
} |
826 |
- q += sprintf(q, "<TD> %s <TD> %d <TD> %d <TD> %s %s <TD> %d <TD> %s %s", |
|
827 |
- stream->fmt->name, |
|
828 |
- (audio_bit_rate + video_bit_rate) / 1000, |
|
829 |
- video_bit_rate / 1000, video_codec_name, video_codec_name_extra, |
|
830 |
- audio_bit_rate / 1000, audio_codec_name, audio_codec_name_extra); |
|
831 |
- if (stream->feed) { |
|
832 |
- q += sprintf(q, "<TD>%s", stream->feed->filename); |
|
833 |
- } else { |
|
834 |
- q += sprintf(q, "<TD>%s", stream->feed_filename); |
|
835 |
- } |
|
836 |
- q += sprintf(q, "\n"); |
|
841 |
+ break; |
|
842 |
+ default: |
|
843 |
+ q += sprintf(q, "<TD align=center> - <TD align=right> - <TD align=right> - <td><td align=right> - <TD>\n"); |
|
844 |
+ break; |
|
837 | 845 |
} |
838 |
- break; |
|
839 |
- default: |
|
840 |
- q += sprintf(q, "<TD> - <TD> - <TD COLSPAN=2> - <TD COLSPAN=2> -\n"); |
|
841 |
- break; |
|
842 | 846 |
} |
843 | 847 |
stream = stream->next; |
844 | 848 |
} |
845 | 849 |
q += sprintf(q, "</TABLE>\n"); |
850 |
+ |
|
851 |
+ stream = first_stream; |
|
852 |
+ while (stream != NULL) { |
|
853 |
+ if (stream->feed == stream) { |
|
854 |
+ q += sprintf(q, "<h2>Feed %s</h2>", stream->filename); |
|
855 |
+ q += sprintf(q, "<table cellspacing=0 cellpadding=4><tr><th>Stream<th>type<th>kbits/s<th align=left>codec\n"); |
|
856 |
+ |
|
857 |
+ for (i = 0; i < stream->nb_streams; i++) { |
|
858 |
+ AVStream *st = stream->streams[i]; |
|
859 |
+ AVCodec *codec = avcodec_find_encoder(st->codec.codec_id); |
|
860 |
+ char *type = "unknown"; |
|
861 |
+ |
|
862 |
+ switch(st->codec.codec_type) { |
|
863 |
+ case CODEC_TYPE_AUDIO: |
|
864 |
+ type = "audio"; |
|
865 |
+ break; |
|
866 |
+ case CODEC_TYPE_VIDEO: |
|
867 |
+ type = "video"; |
|
868 |
+ break; |
|
869 |
+ default: |
|
870 |
+ abort(); |
|
871 |
+ } |
|
872 |
+ q += sprintf(q, "<tr><td align=right>%d<td>%s<td align=right>%d<td>%s\n", |
|
873 |
+ i, type, st->codec.bit_rate/1000, codec ? codec->name : ""); |
|
874 |
+ } |
|
875 |
+ q += sprintf(q, "</table>\n"); |
|
876 |
+ |
|
877 |
+ } |
|
878 |
+ stream = stream->next; |
|
879 |
+ } |
|
846 | 880 |
|
847 | 881 |
#if 0 |
848 | 882 |
{ |
... | ... |
@@ -887,7 +926,7 @@ static void compute_stats(HTTPContext *c) |
887 | 887 |
q += sprintf(q, "<TR><TD>#<TD>File<TD>IP<TD>State<TD>Size\n"); |
888 | 888 |
c1 = first_http_ctx; |
889 | 889 |
i = 0; |
890 |
- while (c1 != NULL) { |
|
890 |
+ while (c1 != NULL && q < (char *) c->buffer + sizeof(c->buffer) - 2048) { |
|
891 | 891 |
i++; |
892 | 892 |
p = inet_ntoa(c1->from_addr.sin_addr); |
893 | 893 |
q += sprintf(q, "<TR><TD><B>%d</B><TD>%s%s <TD> %s <TD> %s <TD> %Ld\n", |
... | ... |
@@ -903,7 +942,7 @@ static void compute_stats(HTTPContext *c) |
903 | 903 |
/* date */ |
904 | 904 |
ti = time(NULL); |
905 | 905 |
p = ctime(&ti); |
906 |
- q += sprintf(q, "<HR>Generated at %s", p); |
|
906 |
+ q += sprintf(q, "<HR size=1 noshade>Generated at %s", p); |
|
907 | 907 |
q += sprintf(q, "</BODY>\n</HTML>\n"); |
908 | 908 |
|
909 | 909 |
c->buffer_ptr = c->buffer; |
... | ... |
@@ -1088,6 +1127,7 @@ static int http_prepare_data(HTTPContext *c) |
1088 | 1088 |
c->stream->feed->feed_write_index, |
1089 | 1089 |
c->stream->feed->feed_size); |
1090 | 1090 |
} |
1091 |
+ |
|
1091 | 1092 |
if (av_read_packet(c->fmt_in, &pkt) < 0) { |
1092 | 1093 |
if (c->stream->feed && c->stream->feed->feed_opened) { |
1093 | 1094 |
/* if coming from feed, it means we reached the end of the |
... | ... |
@@ -1168,7 +1208,7 @@ static int http_send_data(HTTPContext *c) |
1168 | 1168 |
if (ret < 0) |
1169 | 1169 |
return -1; |
1170 | 1170 |
else if (ret == 0) { |
1171 |
- break; |
|
1171 |
+ continue; |
|
1172 | 1172 |
} else { |
1173 | 1173 |
/* state change requested */ |
1174 | 1174 |
return 0; |
... | ... |
@@ -1185,6 +1225,7 @@ static int http_send_data(HTTPContext *c) |
1185 | 1185 |
} else { |
1186 | 1186 |
c->buffer_ptr += len; |
1187 | 1187 |
c->data_count += len; |
1188 |
+ c->stream->bytes_served += len; |
|
1188 | 1189 |
} |
1189 | 1190 |
} |
1190 | 1191 |
return 0; |
... | ... |
@@ -1216,9 +1257,26 @@ static int http_start_receive_data(HTTPContext *c) |
1216 | 1216 |
|
1217 | 1217 |
static int http_receive_data(HTTPContext *c) |
1218 | 1218 |
{ |
1219 |
- int len; |
|
1220 | 1219 |
HTTPContext *c1; |
1221 | 1220 |
|
1221 |
+ if (c->buffer_end > c->buffer_ptr) { |
|
1222 |
+ int len; |
|
1223 |
+ |
|
1224 |
+ len = read(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr); |
|
1225 |
+ if (len < 0) { |
|
1226 |
+ if (errno != EAGAIN && errno != EINTR) { |
|
1227 |
+ /* error : close connection */ |
|
1228 |
+ goto fail; |
|
1229 |
+ } |
|
1230 |
+ } else if (len == 0) { |
|
1231 |
+ /* end of connection : close it */ |
|
1232 |
+ goto fail; |
|
1233 |
+ } else { |
|
1234 |
+ c->buffer_ptr += len; |
|
1235 |
+ c->data_count += len; |
|
1236 |
+ } |
|
1237 |
+ } |
|
1238 |
+ |
|
1222 | 1239 |
if (c->buffer_ptr >= c->buffer_end) { |
1223 | 1240 |
FFStream *feed = c->stream; |
1224 | 1241 |
/* a packet has been received : write it in the store, except |
... | ... |
@@ -1276,19 +1334,6 @@ static int http_receive_data(HTTPContext *c) |
1276 | 1276 |
c->buffer_ptr = c->buffer; |
1277 | 1277 |
} |
1278 | 1278 |
|
1279 |
- len = read(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr); |
|
1280 |
- if (len < 0) { |
|
1281 |
- if (errno != EAGAIN && errno != EINTR) { |
|
1282 |
- /* error : close connection */ |
|
1283 |
- goto fail; |
|
1284 |
- } |
|
1285 |
- } else if (len == 0) { |
|
1286 |
- /* end of connection : close it */ |
|
1287 |
- goto fail; |
|
1288 |
- } else { |
|
1289 |
- c->buffer_ptr += len; |
|
1290 |
- c->data_count += len; |
|
1291 |
- } |
|
1292 | 1279 |
return 0; |
1293 | 1280 |
fail: |
1294 | 1281 |
c->stream->feed_opened = 0; |