|
@@ -31,7 +31,7 @@
|
|
|
#include <stdlib.h>
|
|
|
#include <stdio.h>
|
|
|
#include "libavformat/avformat.h"
|
|
|
-// FIXME those are internal headers, ffserver _really_ shouldn't use them
|
|
|
+/* FIXME: those are internal headers, ffserver _really_ shouldn't use them */
|
|
|
#include "libavformat/ffm.h"
|
|
|
#include "libavformat/network.h"
|
|
|
#include "libavformat/os_support.h"
|
|
@@ -251,7 +251,8 @@ static unsigned int nb_connections;
|
|
|
|
|
|
static uint64_t current_bandwidth;
|
|
|
|
|
|
-static int64_t cur_time; // Making this global saves on passing it around everywhere
|
|
|
+/* Making this global saves on passing it around everywhere */
|
|
|
+static int64_t cur_time;
|
|
|
|
|
|
static AVLFG random_state;
|
|
|
|
|
@@ -630,9 +631,8 @@ static int http_server(void)
|
|
|
poll_entry++;
|
|
|
} else {
|
|
|
/* when ffserver is doing the timing, we work by
|
|
|
- looking at which packet needs to be sent every
|
|
|
- 10 ms */
|
|
|
- /* one tick wait XXX: 10 ms assumed */
|
|
|
+ * looking at which packet needs to be sent every
|
|
|
+ * 10 ms (one tick wait XXX: 10 ms assumed) */
|
|
|
if (delay > 10)
|
|
|
delay = 10;
|
|
|
}
|
|
@@ -655,7 +655,7 @@ static int http_server(void)
|
|
|
}
|
|
|
|
|
|
/* wait for an event on one connection. We poll at least every
|
|
|
- second to handle timeouts */
|
|
|
+ * second to handle timeouts */
|
|
|
do {
|
|
|
ret = poll(poll_table, poll_entry - poll_table, delay);
|
|
|
if (ret < 0 && ff_neterrno() != AVERROR(EAGAIN) &&
|
|
@@ -900,11 +900,11 @@ static int handle_connection(HTTPContext *c)
|
|
|
if ((ptr >= c->buffer + 2 && !memcmp(ptr-2, "\n\n", 2)) ||
|
|
|
(ptr >= c->buffer + 4 && !memcmp(ptr-4, "\r\n\r\n", 4))) {
|
|
|
/* request found : parse it and reply */
|
|
|
- if (c->state == HTTPSTATE_WAIT_REQUEST) {
|
|
|
+ if (c->state == HTTPSTATE_WAIT_REQUEST)
|
|
|
ret = http_parse_request(c);
|
|
|
- } else {
|
|
|
+ else
|
|
|
ret = rtsp_parse_request(c);
|
|
|
- }
|
|
|
+
|
|
|
if (ret < 0)
|
|
|
return -1;
|
|
|
} else if (ptr >= c->buffer_end) {
|
|
@@ -949,8 +949,8 @@ static int handle_connection(HTTPContext *c)
|
|
|
case HTTPSTATE_SEND_DATA_HEADER:
|
|
|
case HTTPSTATE_SEND_DATA_TRAILER:
|
|
|
/* for packetized output, we consider we can always write (the
|
|
|
- input streams set the speed). It may be better to verify
|
|
|
- that we do not rely too much on the kernel queues */
|
|
|
+ * input streams set the speed). It may be better to verify
|
|
|
+ * that we do not rely too much on the kernel queues */
|
|
|
if (!c->is_packetized) {
|
|
|
if (c->poll_entry->revents & (POLLERR | POLLHUP))
|
|
|
return -1;
|
|
@@ -1277,8 +1277,10 @@ static int validate_acl(FFServerStream *stream, HTTPContext *c)
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-/* compute the real filename of a file by matching it without its
|
|
|
- extensions to all the stream's filenames */
|
|
|
+/**
|
|
|
+ * compute the real filename of a file by matching it without its
|
|
|
+ * extensions to all the stream's filenames
|
|
|
+ */
|
|
|
static void compute_real_filename(char *filename, int max_size)
|
|
|
{
|
|
|
char file1[1024];
|
|
@@ -1396,7 +1398,7 @@ static int http_parse_request(HTTPContext *c)
|
|
|
compute_real_filename(filename, sizeof(filename) - 1);
|
|
|
}
|
|
|
|
|
|
- // "redirect" / request to index.html
|
|
|
+ /* "redirect" request to index.html */
|
|
|
if (!strlen(filename))
|
|
|
av_strlcpy(filename, "index.html", sizeof(filename) - 1);
|
|
|
|
|
@@ -1735,8 +1737,9 @@ static int http_parse_request(HTTPContext *c)
|
|
|
return 0;
|
|
|
send_status:
|
|
|
compute_status(c);
|
|
|
- c->http_error = 200; /* horrible : we use this value to avoid
|
|
|
- going to the send data state */
|
|
|
+ /* horrible: we use this value to avoid
|
|
|
+ * going to the send data state */
|
|
|
+ c->http_error = 200;
|
|
|
c->state = HTTPSTATE_SEND_HEADER;
|
|
|
return 0;
|
|
|
}
|
|
@@ -1847,8 +1850,8 @@ static void compute_status(HTTPContext *c)
|
|
|
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 */
|
|
|
+ * unicast. Generate an SDP redirector if
|
|
|
+ * multicast */
|
|
|
eosf = strrchr(sfilename, '.');
|
|
|
if (!eosf)
|
|
|
eosf = sfilename + strlen(sfilename);
|
|
@@ -2119,8 +2122,7 @@ static int64_t get_server_clock(HTTPContext *c)
|
|
|
return (cur_time - c->start_time) * 1000;
|
|
|
}
|
|
|
|
|
|
-/* return the estimated time at which the current packet must be sent
|
|
|
- (in us) */
|
|
|
+/* return the estimated time (in us) at which the current packet must be sent */
|
|
|
static int64_t get_packet_send_clock(HTTPContext *c)
|
|
|
{
|
|
|
int bytes_left, bytes_sent, frame_bytes;
|
|
@@ -2158,7 +2160,8 @@ static int http_prepare_data(HTTPContext *c)
|
|
|
AVStream *src;
|
|
|
c->fmt_ctx.streams[i] = av_mallocz(sizeof(AVStream));
|
|
|
|
|
|
- /* if file or feed, then just take streams from FFServerStream struct */
|
|
|
+ /* if file or feed, then just take streams from FFServerStream
|
|
|
+ * struct */
|
|
|
if (!c->stream->feed ||
|
|
|
c->stream->feed == c->stream)
|
|
|
src = c->stream->streams[i];
|
|
@@ -2223,7 +2226,7 @@ static int http_prepare_data(HTTPContext *c)
|
|
|
if (ret < 0) {
|
|
|
if (c->stream->feed) {
|
|
|
/* if coming from feed, it means we reached the end of the
|
|
|
- ffm file, so must wait for more data */
|
|
|
+ * ffm file, so must wait for more data */
|
|
|
c->state = HTTPSTATE_WAIT_FEED;
|
|
|
return 1; /* state changed */
|
|
|
}
|
|
@@ -2310,9 +2313,9 @@ static int http_prepare_data(HTTPContext *c)
|
|
|
max_packet_size = c->rtp_handles[c->packet_stream_index]->max_packet_size;
|
|
|
ret = ffio_open_dyn_packet_buf(&ctx->pb,
|
|
|
max_packet_size);
|
|
|
- } else {
|
|
|
+ } else
|
|
|
ret = avio_open_dyn_buf(&ctx->pb);
|
|
|
- }
|
|
|
+
|
|
|
if (ret < 0) {
|
|
|
/* XXX: potential leak */
|
|
|
return -1;
|
|
@@ -2375,7 +2378,8 @@ static int http_prepare_data(HTTPContext *c)
|
|
|
|
|
|
/* should convert the format at the same time */
|
|
|
/* send data starting at c->buffer_ptr to the output connection
|
|
|
- * (either UDP or TCP) */
|
|
|
+ * (either UDP or TCP)
|
|
|
+ */
|
|
|
static int http_send_data(HTTPContext *c)
|
|
|
{
|
|
|
int len, ret;
|
|
@@ -2456,8 +2460,8 @@ static int http_send_data(HTTPContext *c)
|
|
|
rtsp_c->packet_buffer_ptr += len;
|
|
|
if (rtsp_c->packet_buffer_ptr < rtsp_c->packet_buffer_end) {
|
|
|
/* if we could not send all the data, we will
|
|
|
- send it later, so a new state is needed to
|
|
|
- "lock" the RTSP TCP connection */
|
|
|
+ * send it later, so a new state is needed to
|
|
|
+ * "lock" the RTSP TCP connection */
|
|
|
rtsp_c->state = RTSPSTATE_SEND_PACKET;
|
|
|
break;
|
|
|
} else
|
|
@@ -2585,12 +2589,11 @@ static int http_receive_data(HTTPContext *c)
|
|
|
goto fail;
|
|
|
c->buffer_ptr = c->buffer;
|
|
|
break;
|
|
|
- } else if (++loop_run > 10) {
|
|
|
+ } else if (++loop_run > 10)
|
|
|
/* no chunk header, abort */
|
|
|
goto fail;
|
|
|
- } else {
|
|
|
+ else
|
|
|
c->buffer_ptr++;
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
if (c->buffer_end > c->buffer_ptr) {
|
|
@@ -2623,7 +2626,7 @@ static int http_receive_data(HTTPContext *c)
|
|
|
if (c->buffer_ptr >= c->buffer_end) {
|
|
|
FFServerStream *feed = c->stream;
|
|
|
/* a packet has been received : write it in the store, except
|
|
|
- if header */
|
|
|
+ * if header */
|
|
|
if (c->data_count > FFM_PACKET_SIZE) {
|
|
|
/* XXX: use llseek or url_seek
|
|
|
* XXX: Should probably fail? */
|
|
@@ -2829,10 +2832,10 @@ static int rtsp_parse_request(HTTPContext *c)
|
|
|
the_end:
|
|
|
len = avio_close_dyn_buf(c->pb, &c->pb_buffer);
|
|
|
c->pb = NULL; /* safety */
|
|
|
- if (len < 0) {
|
|
|
+ if (len < 0)
|
|
|
/* XXX: cannot do more */
|
|
|
return -1;
|
|
|
- }
|
|
|
+
|
|
|
c->buffer_ptr = c->pb_buffer;
|
|
|
c->buffer_end = c->pb_buffer + len;
|
|
|
c->state = RTSPSTATE_SEND_REPLY;
|
|
@@ -2851,9 +2854,9 @@ static int prepare_sdp_description(FFServerStream *stream, uint8_t **pbuffer,
|
|
|
*pbuffer = NULL;
|
|
|
|
|
|
avc = avformat_alloc_context();
|
|
|
- if (!avc || !rtp_format) {
|
|
|
+ if (!avc || !rtp_format)
|
|
|
return -1;
|
|
|
- }
|
|
|
+
|
|
|
avc->oformat = rtp_format;
|
|
|
av_dict_set(&avc->metadata, "title",
|
|
|
entry ? entry->value : "No Title", 0);
|
|
@@ -2862,9 +2865,8 @@ static int prepare_sdp_description(FFServerStream *stream, uint8_t **pbuffer,
|
|
|
snprintf(avc->filename, 1024, "rtp://%s:%d?multicast=1?ttl=%d",
|
|
|
inet_ntoa(stream->multicast_ip),
|
|
|
stream->multicast_port, stream->multicast_ttl);
|
|
|
- } else {
|
|
|
+ } else
|
|
|
snprintf(avc->filename, 1024, "rtp://0.0.0.0");
|
|
|
- }
|
|
|
|
|
|
avc->streams = av_malloc_array(avc->nb_streams, sizeof(*avc->streams));
|
|
|
if (!avc->streams)
|
|
@@ -2894,7 +2896,7 @@ static int prepare_sdp_description(FFServerStream *stream, uint8_t **pbuffer,
|
|
|
|
|
|
static void rtsp_cmd_options(HTTPContext *c, const char *url)
|
|
|
{
|
|
|
-// rtsp_reply_header(c, RTSP_STATUS_OK);
|
|
|
+ /* rtsp_reply_header(c, RTSP_STATUS_OK); */
|
|
|
avio_printf(c->pb, "RTSP/1.0 %d %s\r\n", RTSP_STATUS_OK, "OK");
|
|
|
avio_printf(c->pb, "CSeq: %d\r\n", c->seq);
|
|
|
avio_printf(c->pb, "Public: %s\r\n",
|
|
@@ -3061,7 +3063,7 @@ static void rtsp_cmd_setup(HTTPContext *c, const char *url,
|
|
|
}
|
|
|
|
|
|
/* test if stream is OK (test needed because several SETUP needs
|
|
|
- to be done for a given file) */
|
|
|
+ * to be done for a given file) */
|
|
|
if (rtp_c->stream != stream) {
|
|
|
rtsp_reply_error(c, RTSP_STATUS_SERVICE);
|
|
|
return;
|
|
@@ -3122,8 +3124,10 @@ static void rtsp_cmd_setup(HTTPContext *c, const char *url,
|
|
|
}
|
|
|
|
|
|
|
|
|
-/* find an RTP connection by using the session ID. Check consistency
|
|
|
- with filename */
|
|
|
+/**
|
|
|
+ * find an RTP connection by using the session ID. Check consistency
|
|
|
+ * with filename
|
|
|
+ */
|
|
|
static HTTPContext *find_rtp_session_with_url(const char *url,
|
|
|
const char *session_id)
|
|
|
{
|
|
@@ -3146,10 +3150,10 @@ static HTTPContext *find_rtp_session_with_url(const char *url,
|
|
|
for(s=0; s<rtp_c->stream->nb_streams; ++s) {
|
|
|
snprintf(buf, sizeof(buf), "%s/streamid=%d",
|
|
|
rtp_c->stream->filename, s);
|
|
|
- if(!strncmp(path, buf, sizeof(buf))) {
|
|
|
- // XXX: Should we reply with RTSP_STATUS_ONLY_AGGREGATE if nb_streams>1?
|
|
|
+ if(!strncmp(path, buf, sizeof(buf)))
|
|
|
+ /* XXX: Should we reply with RTSP_STATUS_ONLY_AGGREGATE
|
|
|
+ * if nb_streams>1? */
|
|
|
return rtp_c;
|
|
|
- }
|
|
|
}
|
|
|
len = strlen(path);
|
|
|
if (len > 0 && path[len - 1] == '/' &&
|
|
@@ -3227,7 +3231,7 @@ static HTTPContext *rtp_new_connection(struct sockaddr_in *from_addr,
|
|
|
const char *proto_str;
|
|
|
|
|
|
/* XXX: should output a warning page when coming
|
|
|
- close to the connection limit */
|
|
|
+ * close to the connection limit */
|
|
|
if (nb_connections >= config.nb_max_connections)
|
|
|
goto fail;
|
|
|
|
|
@@ -3282,9 +3286,11 @@ static HTTPContext *rtp_new_connection(struct sockaddr_in *from_addr,
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
-/* add a new RTP stream in an RTP connection (used in RTSP SETUP
|
|
|
- command). If RTP/TCP protocol is used, TCP connection 'rtsp_c' is
|
|
|
- used. */
|
|
|
+/**
|
|
|
+ * add a new RTP stream in an RTP connection (used in RTSP SETUP
|
|
|
+ * command). If RTP/TCP protocol is used, TCP connection 'rtsp_c' is
|
|
|
+ * used.
|
|
|
+ */
|
|
|
static int rtp_new_av_stream(HTTPContext *c,
|
|
|
int stream_index, struct sockaddr_in *dest_addr,
|
|
|
HTTPContext *rtsp_c)
|
|
@@ -3362,10 +3368,10 @@ static int rtp_new_av_stream(HTTPContext *c,
|
|
|
|
|
|
/* normally, no packets should be output here, but the packet size may
|
|
|
* be checked */
|
|
|
- if (ffio_open_dyn_packet_buf(&ctx->pb, max_packet_size) < 0) {
|
|
|
+ if (ffio_open_dyn_packet_buf(&ctx->pb, max_packet_size) < 0)
|
|
|
/* XXX: close stream */
|
|
|
goto fail;
|
|
|
- }
|
|
|
+
|
|
|
if (avformat_write_header(ctx, NULL) < 0) {
|
|
|
fail:
|
|
|
if (h)
|
|
@@ -3402,12 +3408,12 @@ static AVStream *add_av_stream1(FFServerStream *stream,
|
|
|
return NULL;
|
|
|
}
|
|
|
avcodec_copy_context(fst->codec, codec);
|
|
|
- } else {
|
|
|
+ } else
|
|
|
/* live streams must use the actual feed's codec since it may be
|
|
|
* updated later to carry extradata needed by them.
|
|
|
*/
|
|
|
fst->codec = codec;
|
|
|
- }
|
|
|
+
|
|
|
fst->priv_data = av_mallocz(sizeof(FeedData));
|
|
|
fst->index = stream->nb_streams;
|
|
|
avpriv_set_pts_info(fst, 33, 1, 90000);
|
|
@@ -3539,7 +3545,7 @@ static void build_file_streams(void)
|
|
|
/* open stream */
|
|
|
if (stream->fmt && !strcmp(stream->fmt->name, "rtp")) {
|
|
|
/* specific case : if transport stream output to RTP,
|
|
|
- we use a raw transport stream reader */
|
|
|
+ * we use a raw transport stream reader */
|
|
|
av_dict_set(&stream->in_opts, "mpeg2ts_compute_pcr", "1", 0);
|
|
|
}
|
|
|
|
|
@@ -3561,7 +3567,7 @@ static void build_file_streams(void)
|
|
|
remove_stream(stream);
|
|
|
} else {
|
|
|
/* find all the AVStreams inside and reference them in
|
|
|
- 'stream' */
|
|
|
+ * 'stream' */
|
|
|
if (avformat_find_stream_info(infile, NULL) < 0) {
|
|
|
http_log("Could not find codec parameters from '%s'\n",
|
|
|
stream->feed_filename);
|