|
|
|
@ -1774,153 +1774,172 @@ static void compute_status(HTTPContext *c) |
|
|
|
|
stream = stream->next; |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
av_strlcpy(sfilename, stream->filename, sizeof(sfilename) - 10); |
|
|
|
|
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"); |
|
|
|
|
else if (stream->fmt && !strcmp(stream->fmt->name, "rtp")) { |
|
|
|
|
/* generate a sample RTSP director if
|
|
|
|
|
unicast. Generate an SDP redirector if |
|
|
|
|
multicast */ |
|
|
|
|
eosf = strrchr(sfilename, '.'); |
|
|
|
|
if (!eosf) |
|
|
|
|
eosf = sfilename + strlen(sfilename); |
|
|
|
|
if (stream->is_multicast) |
|
|
|
|
strcpy(eosf, ".sdp"); |
|
|
|
|
else |
|
|
|
|
strcpy(eosf, ".rtsp"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
av_strlcpy(sfilename, stream->filename, sizeof(sfilename) - 10); |
|
|
|
|
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"); |
|
|
|
|
else if (stream->fmt && !strcmp(stream->fmt->name, "rtp")) { |
|
|
|
|
/* generate a sample RTSP director if
|
|
|
|
|
unicast. Generate an SDP redirector if |
|
|
|
|
multicast */ |
|
|
|
|
eosf = strrchr(sfilename, '.'); |
|
|
|
|
if (!eosf) |
|
|
|
|
eosf = sfilename + strlen(sfilename); |
|
|
|
|
if (stream->is_multicast) |
|
|
|
|
strcpy(eosf, ".sdp"); |
|
|
|
|
else |
|
|
|
|
strcpy(eosf, ".rtsp"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
avio_printf(pb, "<tr><td><a href=\"/%s\">%s</a> ", |
|
|
|
|
sfilename, stream->filename); |
|
|
|
|
avio_printf(pb, "<td align=right> %d <td align=right> ", |
|
|
|
|
stream->conns_served); |
|
|
|
|
fmt_bytecount(pb, stream->bytes_served); |
|
|
|
|
switch(stream->stream_type) { |
|
|
|
|
case STREAM_TYPE_LIVE: { |
|
|
|
|
int audio_bit_rate = 0; |
|
|
|
|
int video_bit_rate = 0; |
|
|
|
|
const char *audio_codec_name = ""; |
|
|
|
|
const char *video_codec_name = ""; |
|
|
|
|
const char *audio_codec_name_extra = ""; |
|
|
|
|
const char *video_codec_name_extra = ""; |
|
|
|
|
|
|
|
|
|
for(i=0;i<stream->nb_streams;i++) { |
|
|
|
|
AVStream *st = stream->streams[i]; |
|
|
|
|
AVCodec *codec = avcodec_find_encoder(st->codec->codec_id); |
|
|
|
|
switch(st->codec->codec_type) { |
|
|
|
|
case AVMEDIA_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 AVMEDIA_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; |
|
|
|
|
case AVMEDIA_TYPE_DATA: |
|
|
|
|
video_bit_rate += st->codec->bit_rate; |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
abort(); |
|
|
|
|
} |
|
|
|
|
avio_printf(pb, "<tr><td><a href=\"/%s\">%s</a> ", |
|
|
|
|
sfilename, stream->filename); |
|
|
|
|
avio_printf(pb, "<td align=right> %d <td align=right> ", |
|
|
|
|
stream->conns_served); |
|
|
|
|
fmt_bytecount(pb, stream->bytes_served); |
|
|
|
|
|
|
|
|
|
switch(stream->stream_type) { |
|
|
|
|
case STREAM_TYPE_LIVE: { |
|
|
|
|
int audio_bit_rate = 0; |
|
|
|
|
int video_bit_rate = 0; |
|
|
|
|
const char *audio_codec_name = ""; |
|
|
|
|
const char *video_codec_name = ""; |
|
|
|
|
const char *audio_codec_name_extra = ""; |
|
|
|
|
const char *video_codec_name_extra = ""; |
|
|
|
|
|
|
|
|
|
for(i=0;i<stream->nb_streams;i++) { |
|
|
|
|
AVStream *st = stream->streams[i]; |
|
|
|
|
AVCodec *codec = avcodec_find_encoder(st->codec->codec_id); |
|
|
|
|
|
|
|
|
|
switch(st->codec->codec_type) { |
|
|
|
|
case AVMEDIA_TYPE_AUDIO: |
|
|
|
|
audio_bit_rate += st->codec->bit_rate; |
|
|
|
|
if (codec) { |
|
|
|
|
if (*audio_codec_name) |
|
|
|
|
audio_codec_name_extra = "..."; |
|
|
|
|
audio_codec_name = codec->name; |
|
|
|
|
} |
|
|
|
|
avio_printf(pb, "<td align=center> %s <td align=right> %d <td align=right> %d <td> %s %s <td align=right> %d <td> %s %s", |
|
|
|
|
stream->fmt->name, |
|
|
|
|
stream->bandwidth, |
|
|
|
|
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) |
|
|
|
|
avio_printf(pb, "<td>%s", stream->feed->filename); |
|
|
|
|
else |
|
|
|
|
avio_printf(pb, "<td>%s", stream->feed_filename); |
|
|
|
|
avio_printf(pb, "\n"); |
|
|
|
|
break; |
|
|
|
|
case AVMEDIA_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; |
|
|
|
|
case AVMEDIA_TYPE_DATA: |
|
|
|
|
video_bit_rate += st->codec->bit_rate; |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
abort(); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
avio_printf(pb, "<td align=center> - <td align=right> - <td align=right> - <td><td align=right> - <td>\n"); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
avio_printf(pb, "<td align=center> %s <td align=right> %d " |
|
|
|
|
"<td align=right> %d <td> %s %s <td align=right> " |
|
|
|
|
"%d <td> %s %s", |
|
|
|
|
stream->fmt->name, stream->bandwidth, |
|
|
|
|
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) |
|
|
|
|
avio_printf(pb, "<td>%s", stream->feed->filename); |
|
|
|
|
else |
|
|
|
|
avio_printf(pb, "<td>%s", stream->feed_filename); |
|
|
|
|
avio_printf(pb, "\n"); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
avio_printf(pb, "<td align=center> - <td align=right> - " |
|
|
|
|
"<td align=right> - <td><td align=right> - <td>\n"); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
stream = stream->next; |
|
|
|
|
} |
|
|
|
|
avio_printf(pb, "</table>\n"); |
|
|
|
|
|
|
|
|
|
stream = config.first_stream; |
|
|
|
|
while (stream) { |
|
|
|
|
|
|
|
|
|
if (stream->feed != stream) { |
|
|
|
|
stream = stream->next; |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
avio_printf(pb, "<h2>Feed %s</h2>", stream->filename); |
|
|
|
|
if (stream->pid) { |
|
|
|
|
avio_printf(pb, "Running as pid %d.\n", stream->pid); |
|
|
|
|
|
|
|
|
|
avio_printf(pb, "<h2>Feed %s</h2>", stream->filename); |
|
|
|
|
if (stream->pid) { |
|
|
|
|
avio_printf(pb, "Running as pid %d.\n", stream->pid); |
|
|
|
|
|
|
|
|
|
#if defined(linux) |
|
|
|
|
{ |
|
|
|
|
FILE *pid_stat; |
|
|
|
|
char ps_cmd[64]; |
|
|
|
|
|
|
|
|
|
/* This is somewhat linux specific I guess */ |
|
|
|
|
snprintf(ps_cmd, sizeof(ps_cmd), |
|
|
|
|
"ps -o \"%%cpu,cputime\" --no-headers %d", |
|
|
|
|
stream->pid); |
|
|
|
|
|
|
|
|
|
pid_stat = popen(ps_cmd, "r"); |
|
|
|
|
if (pid_stat) { |
|
|
|
|
char cpuperc[10]; |
|
|
|
|
char cpuused[64]; |
|
|
|
|
|
|
|
|
|
if (fscanf(pid_stat, "%9s %63s", cpuperc, |
|
|
|
|
cpuused) == 2) { |
|
|
|
|
avio_printf(pb, "Currently using %s%% of the cpu. Total time used %s.\n", |
|
|
|
|
cpuperc, cpuused); |
|
|
|
|
} |
|
|
|
|
fclose(pid_stat); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
{ |
|
|
|
|
FILE *pid_stat; |
|
|
|
|
char ps_cmd[64]; |
|
|
|
|
|
|
|
|
|
/* This is somewhat linux specific I guess */ |
|
|
|
|
snprintf(ps_cmd, sizeof(ps_cmd), |
|
|
|
|
"ps -o \"%%cpu,cputime\" --no-headers %d", |
|
|
|
|
stream->pid); |
|
|
|
|
|
|
|
|
|
pid_stat = popen(ps_cmd, "r"); |
|
|
|
|
if (pid_stat) { |
|
|
|
|
char cpuperc[10]; |
|
|
|
|
char cpuused[64]; |
|
|
|
|
|
|
|
|
|
if (fscanf(pid_stat, "%9s %63s", cpuperc, cpuused) == 2) { |
|
|
|
|
avio_printf(pb, "Currently using %s%% of the cpu. " |
|
|
|
|
"Total time used %s.\n", |
|
|
|
|
cpuperc, cpuused); |
|
|
|
|
} |
|
|
|
|
fclose(pid_stat); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
avio_printf(pb, "<p>"); |
|
|
|
|
} |
|
|
|
|
avio_printf(pb, "<table cellspacing=0 cellpadding=4><tr><th>Stream<th>type<th>kbits/s<th align=left>codec<th align=left>Parameters\n"); |
|
|
|
|
avio_printf(pb, "<p>"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for (i = 0; i < stream->nb_streams; i++) { |
|
|
|
|
AVStream *st = stream->streams[i]; |
|
|
|
|
AVCodec *codec = avcodec_find_encoder(st->codec->codec_id); |
|
|
|
|
const char *type = "unknown"; |
|
|
|
|
char parameters[64]; |
|
|
|
|
avio_printf(pb, "<table cellspacing=0 cellpadding=4><tr><th>Stream<th>" |
|
|
|
|
"type<th>kbits/s<th align=left>codec<th align=left>" |
|
|
|
|
"Parameters\n"); |
|
|
|
|
|
|
|
|
|
parameters[0] = 0; |
|
|
|
|
for (i = 0; i < stream->nb_streams; i++) { |
|
|
|
|
AVStream *st = stream->streams[i]; |
|
|
|
|
AVCodec *codec = avcodec_find_encoder(st->codec->codec_id); |
|
|
|
|
const char *type = "unknown"; |
|
|
|
|
char parameters[64]; |
|
|
|
|
|
|
|
|
|
switch(st->codec->codec_type) { |
|
|
|
|
case AVMEDIA_TYPE_AUDIO: |
|
|
|
|
type = "audio"; |
|
|
|
|
snprintf(parameters, sizeof(parameters), "%d channel(s), %d Hz", st->codec->channels, st->codec->sample_rate); |
|
|
|
|
break; |
|
|
|
|
case AVMEDIA_TYPE_VIDEO: |
|
|
|
|
type = "video"; |
|
|
|
|
snprintf(parameters, sizeof(parameters), "%dx%d, q=%d-%d, fps=%d", st->codec->width, st->codec->height, |
|
|
|
|
st->codec->qmin, st->codec->qmax, st->codec->time_base.den / st->codec->time_base.num); |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
abort(); |
|
|
|
|
} |
|
|
|
|
avio_printf(pb, "<tr><td align=right>%d<td>%s<td align=right>%d<td>%s<td>%s\n", |
|
|
|
|
i, type, st->codec->bit_rate/1000, codec ? codec->name : "", parameters); |
|
|
|
|
parameters[0] = 0; |
|
|
|
|
|
|
|
|
|
switch(st->codec->codec_type) { |
|
|
|
|
case AVMEDIA_TYPE_AUDIO: |
|
|
|
|
type = "audio"; |
|
|
|
|
snprintf(parameters, sizeof(parameters), "%d channel(s), %d Hz", |
|
|
|
|
st->codec->channels, st->codec->sample_rate); |
|
|
|
|
break; |
|
|
|
|
case AVMEDIA_TYPE_VIDEO: |
|
|
|
|
type = "video"; |
|
|
|
|
snprintf(parameters, sizeof(parameters), |
|
|
|
|
"%dx%d, q=%d-%d, fps=%d", st->codec->width, |
|
|
|
|
st->codec->height, st->codec->qmin, st->codec->qmax, |
|
|
|
|
st->codec->time_base.den / st->codec->time_base.num); |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
abort(); |
|
|
|
|
} |
|
|
|
|
avio_printf(pb, "</table>\n"); |
|
|
|
|
|
|
|
|
|
avio_printf(pb, "<tr><td align=right>%d<td>%s<td align=right>%d" |
|
|
|
|
"<td>%s<td>%s\n", |
|
|
|
|
i, type, st->codec->bit_rate/1000, |
|
|
|
|
codec ? codec->name : "", parameters); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
avio_printf(pb, "</table>\n"); |
|
|
|
|
stream = stream->next; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -1928,13 +1947,14 @@ static void compute_status(HTTPContext *c) |
|
|
|
|
avio_printf(pb, "<h2>Connection Status</h2>\n"); |
|
|
|
|
|
|
|
|
|
avio_printf(pb, "Number of connections: %d / %d<br>\n", |
|
|
|
|
nb_connections, config.nb_max_connections); |
|
|
|
|
nb_connections, config.nb_max_connections); |
|
|
|
|
|
|
|
|
|
avio_printf(pb, "Bandwidth in use: %"PRIu64"k / %"PRIu64"k<br>\n", |
|
|
|
|
current_bandwidth, config.max_bandwidth); |
|
|
|
|
current_bandwidth, config.max_bandwidth); |
|
|
|
|
|
|
|
|
|
avio_printf(pb, "<table>\n"); |
|
|
|
|
avio_printf(pb, "<tr><th>#<th>File<th>IP<th>Proto<th>State<th>Target bits/sec<th>Actual bits/sec<th>Bytes transferred\n"); |
|
|
|
|
avio_printf(pb, "<tr><th>#<th>File<th>IP<th>Proto<th>State<th>Target " |
|
|
|
|
"bits/sec<th>Actual bits/sec<th>Bytes transferred\n"); |
|
|
|
|
c1 = first_http_ctx; |
|
|
|
|
i = 0; |
|
|
|
|
while (c1) { |
|
|
|
@ -1953,13 +1973,11 @@ static void compute_status(HTTPContext *c) |
|
|
|
|
|
|
|
|
|
i++; |
|
|
|
|
p = inet_ntoa(c1->from_addr.sin_addr); |
|
|
|
|
avio_printf(pb, "<tr><td><b>%d</b><td>%s%s<td>%s<td>%s<td>%s<td align=right>", |
|
|
|
|
i, |
|
|
|
|
c1->stream ? c1->stream->filename : "", |
|
|
|
|
c1->state == HTTPSTATE_RECEIVE_DATA ? "(input)" : "", |
|
|
|
|
p, |
|
|
|
|
c1->protocol, |
|
|
|
|
http_state[c1->state]); |
|
|
|
|
avio_printf(pb, "<tr><td><b>%d</b><td>%s%s<td>%s<td>%s<td>%s" |
|
|
|
|
"<td align=right>", |
|
|
|
|
i, c1->stream ? c1->stream->filename : "", |
|
|
|
|
c1->state == HTTPSTATE_RECEIVE_DATA ? "(input)" : "", p, |
|
|
|
|
c1->protocol, http_state[c1->state]); |
|
|
|
|
fmt_bytecount(pb, bitrate); |
|
|
|
|
avio_printf(pb, "<td align=right>"); |
|
|
|
|
fmt_bytecount(pb, compute_datarate(&c1->datarate, c1->data_count) * 8); |
|
|
|
|