#include "libavutil/avstring.h"
#include "libavutil/lfg.h"
#include "libavutil/random_seed.h"
+#include "libavutil/parseutils.h"
#include "libavcodec/opt.h"
#include <stdarg.h>
#include <unistd.h>
"RTSP_SEND_PACKET",
};
+#if !FF_API_MAX_STREAMS
+#define MAX_STREAMS 20
+#endif
+
#define IOBUFFER_INIT_SIZE 8192
/* timeouts are in ms */
/* RTSP state specific */
uint8_t *pb_buffer; /* XXX: use that in all the code */
- ByteIOContext *pb;
+ AVIOContext *pb;
int seq; /* RTSP sequence number */
/* RTP state specific */
}
}
-static void __attribute__ ((format (printf, 1, 2))) http_log(const char *fmt, ...)
+#ifdef __GNUC__
+__attribute__ ((format (printf, 1, 2)))
+#endif
+static void http_log(const char *fmt, ...)
{
va_list vargs;
va_start(vargs, fmt);
second to handle timeouts */
do {
ret = poll(poll_table, poll_entry - poll_table, delay);
- if (ret < 0 && ff_neterrno() != FF_NETERROR(EAGAIN) &&
- ff_neterrno() != FF_NETERROR(EINTR))
+ if (ret < 0 && ff_neterrno() != AVERROR(EAGAIN) &&
+ ff_neterrno() != AVERROR(EINTR))
return -1;
} while (ret < 0);
{
char buffer[300];
int len = snprintf(buffer, sizeof(buffer),
- "HTTP/1.0 200 Server too busy\r\n"
+ "HTTP/1.0 503 Server too busy\r\n"
"Content-type: text/html\r\n"
"\r\n"
"<html><head><title>Too busy</title></head><body>\r\n"
read_loop:
len = recv(c->fd, c->buffer_ptr, 1, 0);
if (len < 0) {
- if (ff_neterrno() != FF_NETERROR(EAGAIN) &&
- ff_neterrno() != FF_NETERROR(EINTR))
+ if (ff_neterrno() != AVERROR(EAGAIN) &&
+ ff_neterrno() != AVERROR(EINTR))
return -1;
} else if (len == 0) {
return -1;
return 0;
len = send(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr, 0);
if (len < 0) {
- if (ff_neterrno() != FF_NETERROR(EAGAIN) &&
- ff_neterrno() != FF_NETERROR(EINTR)) {
+ if (ff_neterrno() != AVERROR(EAGAIN) &&
+ ff_neterrno() != AVERROR(EINTR)) {
/* error : close connection */
av_freep(&c->pb_buffer);
return -1;
return 0;
len = send(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr, 0);
if (len < 0) {
- if (ff_neterrno() != FF_NETERROR(EAGAIN) &&
- ff_neterrno() != FF_NETERROR(EINTR)) {
+ if (ff_neterrno() != AVERROR(EAGAIN) &&
+ ff_neterrno() != AVERROR(EINTR)) {
/* error : close connection */
av_freep(&c->pb_buffer);
return -1;
len = send(c->fd, c->packet_buffer_ptr,
c->packet_buffer_end - c->packet_buffer_ptr, 0);
if (len < 0) {
- if (ff_neterrno() != FF_NETERROR(EAGAIN) &&
- ff_neterrno() != FF_NETERROR(EINTR)) {
+ if (ff_neterrno() != AVERROR(EAGAIN) &&
+ ff_neterrno() != AVERROR(EINTR)) {
/* error : close connection */
av_freep(&c->packet_buffer);
return -1;
return action_required;
}
-
-static void do_switch_stream(HTTPContext *c, int i)
-{
- if (c->switch_feed_streams[i] >= 0) {
-#ifdef PHILIP
- c->feed_streams[i] = c->switch_feed_streams[i];
-#endif
-
- /* Now update the stream */
- }
- c->switch_feed_streams[i] = -1;
-}
-
/* XXX: factorize in utils.c ? */
/* XXX: take care with different space meaning */
static void skip_spaces(const char **pp)
if (modify_current_stream(c, ratebuf)) {
for (i = 0; i < FF_ARRAY_ELEMS(c->feed_streams); i++) {
if (c->switch_feed_streams[i] >= 0)
- do_switch_stream(c, i);
+ c->switch_feed_streams[i] = -1;
}
}
}
}
if (c->post == 0 && max_bandwidth < current_bandwidth) {
- c->http_error = 200;
+ c->http_error = 503;
q = c->buffer;
q += snprintf(q, c->buffer_size,
- "HTTP/1.0 200 Server too busy\r\n"
+ "HTTP/1.0 503 Server too busy\r\n"
"Content-type: text/html\r\n"
"\r\n"
"<html><head><title>Too busy</title></head><body>\r\n"
return 0;
}
-static void fmt_bytecount(ByteIOContext *pb, int64_t count)
+static void fmt_bytecount(AVIOContext *pb, int64_t count)
{
static const char *suffix = " kMGTP";
const char *s;
for (s = suffix; count >= 100000 && s[1]; count /= 1000, s++);
- url_fprintf(pb, "%"PRId64"%c", count, *s);
+ avio_printf(pb, "%"PRId64"%c", count, *s);
}
static void compute_status(HTTPContext *c)
char *p;
time_t ti;
int i, len;
- ByteIOContext *pb;
+ AVIOContext *pb;
if (url_open_dyn_buf(&pb) < 0) {
/* XXX: return an error ? */
return;
}
- url_fprintf(pb, "HTTP/1.0 200 OK\r\n");
- url_fprintf(pb, "Content-type: %s\r\n", "text/html");
- url_fprintf(pb, "Pragma: no-cache\r\n");
- url_fprintf(pb, "\r\n");
+ avio_printf(pb, "HTTP/1.0 200 OK\r\n");
+ avio_printf(pb, "Content-type: %s\r\n", "text/html");
+ avio_printf(pb, "Pragma: no-cache\r\n");
+ avio_printf(pb, "\r\n");
- url_fprintf(pb, "<html><head><title>%s Status</title>\n", program_name);
+ avio_printf(pb, "<html><head><title>%s Status</title>\n", program_name);
if (c->stream->feed_filename[0])
- url_fprintf(pb, "<link rel=\"shortcut icon\" href=\"%s\">\n", c->stream->feed_filename);
- url_fprintf(pb, "</head>\n<body>");
- url_fprintf(pb, "<h1>%s Status</h1>\n", program_name);
+ avio_printf(pb, "<link rel=\"shortcut icon\" href=\"%s\">\n", c->stream->feed_filename);
+ avio_printf(pb, "</head>\n<body>");
+ avio_printf(pb, "<h1>%s Status</h1>\n", program_name);
/* format status */
- url_fprintf(pb, "<h2>Available Streams</h2>\n");
- url_fprintf(pb, "<table cellspacing=0 cellpadding=4>\n");
- url_fprintf(pb, "<tr><th valign=top>Path<th align=left>Served<br>Conns<th><br>bytes<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");
+ avio_printf(pb, "<h2>Available Streams</h2>\n");
+ avio_printf(pb, "<table cellspacing=0 cellpadding=4>\n");
+ avio_printf(pb, "<tr><th valign=top>Path<th align=left>Served<br>Conns<th><br>bytes<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");
stream = first_stream;
while (stream != NULL) {
char sfilename[1024];
}
}
- url_fprintf(pb, "<tr><td><a href=\"/%s\">%s</a> ",
+ avio_printf(pb, "<tr><td><a href=\"/%s\">%s</a> ",
sfilename, stream->filename);
- url_fprintf(pb, "<td align=right> %d <td align=right> ",
+ avio_printf(pb, "<td align=right> %d <td align=right> ",
stream->conns_served);
fmt_bytecount(pb, stream->bytes_served);
switch(stream->stream_type) {
abort();
}
}
- url_fprintf(pb, "<td align=center> %s <td align=right> %d <td align=right> %d <td> %s %s <td align=right> %d <td> %s %s",
+ 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)
- url_fprintf(pb, "<td>%s", stream->feed->filename);
+ avio_printf(pb, "<td>%s", stream->feed->filename);
else
- url_fprintf(pb, "<td>%s", stream->feed_filename);
- url_fprintf(pb, "\n");
+ avio_printf(pb, "<td>%s", stream->feed_filename);
+ avio_printf(pb, "\n");
}
break;
default:
- url_fprintf(pb, "<td align=center> - <td align=right> - <td align=right> - <td><td align=right> - <td>\n");
+ avio_printf(pb, "<td align=center> - <td align=right> - <td align=right> - <td><td align=right> - <td>\n");
break;
}
}
stream = stream->next;
}
- url_fprintf(pb, "</table>\n");
+ avio_printf(pb, "</table>\n");
stream = first_stream;
while (stream != NULL) {
if (stream->feed == stream) {
- url_fprintf(pb, "<h2>Feed %s</h2>", stream->filename);
+ avio_printf(pb, "<h2>Feed %s</h2>", stream->filename);
if (stream->pid) {
- url_fprintf(pb, "Running as pid %d.\n", stream->pid);
+ avio_printf(pb, "Running as pid %d.\n", stream->pid);
#if defined(linux) && !defined(CONFIG_NOCUTILS)
{
if (fscanf(pid_stat, "%10s %64s", cpuperc,
cpuused) == 2) {
- url_fprintf(pb, "Currently using %s%% of the cpu. Total time used %s.\n",
+ avio_printf(pb, "Currently using %s%% of the cpu. Total time used %s.\n",
cpuperc, cpuused);
}
fclose(pid_stat);
}
#endif
- url_fprintf(pb, "<p>");
+ avio_printf(pb, "<p>");
}
- url_fprintf(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, "<table cellspacing=0 cellpadding=4><tr><th>Stream<th>type<th>kbits/s<th align=left>codec<th align=left>Parameters\n");
for (i = 0; i < stream->nb_streams; i++) {
AVStream *st = stream->streams[i];
default:
abort();
}
- url_fprintf(pb, "<tr><td align=right>%d<td>%s<td align=right>%d<td>%s<td>%s\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);
}
- url_fprintf(pb, "</table>\n");
+ avio_printf(pb, "</table>\n");
}
stream = stream->next;
}
/* connection status */
- url_fprintf(pb, "<h2>Connection Status</h2>\n");
+ avio_printf(pb, "<h2>Connection Status</h2>\n");
- url_fprintf(pb, "Number of connections: %d / %d<br>\n",
+ avio_printf(pb, "Number of connections: %d / %d<br>\n",
nb_connections, nb_max_connections);
- url_fprintf(pb, "Bandwidth in use: %"PRIu64"k / %"PRIu64"k<br>\n",
+ avio_printf(pb, "Bandwidth in use: %"PRIu64"k / %"PRIu64"k<br>\n",
current_bandwidth, max_bandwidth);
- url_fprintf(pb, "<table>\n");
- url_fprintf(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, "<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");
c1 = first_http_ctx;
i = 0;
while (c1 != NULL) {
i++;
p = inet_ntoa(c1->from_addr.sin_addr);
- url_fprintf(pb, "<tr><td><b>%d</b><td>%s%s<td>%s<td>%s<td>%s<td align=right>",
+ 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)" : "",
c1->protocol,
http_state[c1->state]);
fmt_bytecount(pb, bitrate);
- url_fprintf(pb, "<td align=right>");
+ avio_printf(pb, "<td align=right>");
fmt_bytecount(pb, compute_datarate(&c1->datarate, c1->data_count) * 8);
- url_fprintf(pb, "<td align=right>");
+ avio_printf(pb, "<td align=right>");
fmt_bytecount(pb, c1->data_count);
- url_fprintf(pb, "\n");
+ avio_printf(pb, "\n");
c1 = c1->next;
}
- url_fprintf(pb, "</table>\n");
+ avio_printf(pb, "</table>\n");
/* date */
ti = time(NULL);
p = ctime(&ti);
- url_fprintf(pb, "<hr size=1 noshade>Generated at %s", p);
- url_fprintf(pb, "</body>\n</html>\n");
+ avio_printf(pb, "<hr size=1 noshade>Generated at %s", p);
+ avio_printf(pb, "</body>\n</html>\n");
len = url_close_dyn_buf(pb, &c->pb_buffer);
c->buffer_ptr = c->pb_buffer;
strcpy(input_filename, c->stream->feed->feed_filename);
buf_size = FFM_PACKET_SIZE;
/* compute position (absolute time) */
- if (find_info_tag(buf, sizeof(buf), "date", info)) {
- stream_pos = parse_date(buf, 0);
- if (stream_pos == INT64_MIN)
- return -1;
- } else if (find_info_tag(buf, sizeof(buf), "buffer", info)) {
+ if (av_find_info_tag(buf, sizeof(buf), "date", info)) {
+ if ((ret = av_parse_time(&stream_pos, buf, 0)) < 0)
+ return ret;
+ } else if (av_find_info_tag(buf, sizeof(buf), "buffer", info)) {
int prebuffer = strtol(buf, 0, 10);
stream_pos = av_gettime() - prebuffer * (int64_t)1000000;
} else
strcpy(input_filename, c->stream->feed_filename);
buf_size = 0;
/* compute position (relative time) */
- if (find_info_tag(buf, sizeof(buf), "date", info)) {
- stream_pos = parse_date(buf, 1);
- if (stream_pos == INT64_MIN)
- return -1;
+ if (av_find_info_tag(buf, sizeof(buf), "date", info)) {
+ if ((ret = av_parse_time(&stream_pos, buf, 1)) < 0)
+ return ret;
} else
stream_pos = 0;
}
else {
AVPacket pkt;
redo:
- if (av_read_frame(c->fmt_in, &pkt) < 0) {
- if (c->stream->feed && c->stream->feed->feed_opened) {
+ ret = av_read_frame(c->fmt_in, &pkt);
+ 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 */
c->state = HTTPSTATE_WAIT_FEED;
return 1; /* state changed */
+ } else if (ret == AVERROR(EAGAIN)) {
+ /* input not ready, come back later */
+ return 0;
} else {
if (c->stream->loop) {
av_close_input_file(c->fmt_in);
for(i=0;i<c->stream->nb_streams;i++) {
if (c->switch_feed_streams[i] == pkt.stream_index)
if (pkt.flags & AV_PKT_FLAG_KEY)
- do_switch_stream(c, i);
+ c->switch_feed_streams[i] = -1;
if (c->switch_feed_streams[i] >= 0)
c->switch_pending = 1;
}
if (c->is_packetized) {
/* compute send time and duration */
c->cur_pts = av_rescale_q(pkt.dts, ist->time_base, AV_TIME_BASE_Q);
- if (ist->start_time != AV_NOPTS_VALUE)
- c->cur_pts -= av_rescale_q(ist->start_time, ist->time_base, AV_TIME_BASE_Q);
+ c->cur_pts -= c->first_pts;
c->cur_frame_duration = av_rescale_q(pkt.duration, ist->time_base, AV_TIME_BASE_Q);
/* find RTP context */
c->packet_stream_index = pkt.stream_index;
if (c->rtp_protocol == RTSP_LOWER_TRANSPORT_TCP) {
/* RTP packets are sent inside the RTSP TCP connection */
- ByteIOContext *pb;
+ AVIOContext *pb;
int interleaved_index, size;
uint8_t header[4];
HTTPContext *rtsp_c;
header[1] = interleaved_index;
header[2] = len >> 8;
header[3] = len;
- put_buffer(pb, header, 4);
+ avio_write(pb, header, 4);
/* write RTP packet data */
c->buffer_ptr += 4;
- put_buffer(pb, c->buffer_ptr, len);
+ avio_write(pb, c->buffer_ptr, len);
size = url_close_dyn_buf(pb, &c->packet_buffer);
/* prepare asynchronous TCP sending */
rtsp_c->packet_buffer_ptr = c->packet_buffer;
/* TCP data output */
len = send(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr, 0);
if (len < 0) {
- if (ff_neterrno() != FF_NETERROR(EAGAIN) &&
- ff_neterrno() != FF_NETERROR(EINTR))
+ if (ff_neterrno() != AVERROR(EAGAIN) &&
+ ff_neterrno() != AVERROR(EINTR))
/* error : close connection */
return -1;
else
len = recv(c->fd, c->buffer_ptr, 1, 0);
if (len < 0) {
- if (ff_neterrno() != FF_NETERROR(EAGAIN) &&
- ff_neterrno() != FF_NETERROR(EINTR))
+ if (ff_neterrno() != AVERROR(EAGAIN) &&
+ ff_neterrno() != AVERROR(EINTR))
/* error : close connection */
goto fail;
return 0;
len = recv(c->fd, c->buffer_ptr,
FFMIN(c->chunk_size, c->buffer_end - c->buffer_ptr), 0);
if (len < 0) {
- if (ff_neterrno() != FF_NETERROR(EAGAIN) &&
- ff_neterrno() != FF_NETERROR(EINTR))
+ if (ff_neterrno() != AVERROR(EAGAIN) &&
+ ff_neterrno() != AVERROR(EINTR))
/* error : close connection */
goto fail;
} else if (len == 0)
} else {
/* We have a header in our hands that contains useful data */
AVFormatContext *s = NULL;
- ByteIOContext *pb;
+ AVIOContext *pb;
AVInputFormat *fmt_in;
int i;
if (!fmt_in)
goto fail;
- url_open_buf(&pb, c->buffer, c->buffer_end - c->buffer, URL_RDONLY);
+ pb = avio_alloc_context(c->buffer, c->buffer_end - c->buffer,
+ 0, NULL, NULL, NULL, NULL);
pb->is_streamed = 1;
if (av_open_input_stream(&s, pb, c->stream->feed_filename, fmt_in, NULL) < 0) {
for (i = 0; i < s->nb_streams; i++) {
AVStream *fst = feed->streams[i];
AVStream *st = s->streams[i];
- memcpy(fst->codec, st->codec, sizeof(AVCodecContext));
- if (fst->codec->extradata_size) {
- fst->codec->extradata = av_malloc(fst->codec->extradata_size);
- if (!fst->codec->extradata)
- goto fail;
- memcpy(fst->codec->extradata, st->codec->extradata,
- fst->codec->extradata_size);
- }
+ avcodec_copy_context(fst->codec, st->codec);
}
av_close_input_stream(s);
break;
}
- url_fprintf(c->pb, "RTSP/1.0 %d %s\r\n", error_number, str);
- url_fprintf(c->pb, "CSeq: %d\r\n", c->seq);
+ avio_printf(c->pb, "RTSP/1.0 %d %s\r\n", error_number, str);
+ avio_printf(c->pb, "CSeq: %d\r\n", c->seq);
/* output GMT time */
ti = time(NULL);
tm = gmtime(&ti);
strftime(buf2, sizeof(buf2), "%a, %d %b %Y %H:%M:%S", tm);
- url_fprintf(c->pb, "Date: %s GMT\r\n", buf2);
+ avio_printf(c->pb, "Date: %s GMT\r\n", buf2);
}
static void rtsp_reply_error(HTTPContext *c, enum RTSPStatusCode error_number)
{
rtsp_reply_header(c, error_number);
- url_fprintf(c->pb, "\r\n");
+ avio_printf(c->pb, "\r\n");
}
static int rtsp_parse_request(HTTPContext *c)
len = sizeof(line) - 1;
memcpy(line, p, len);
line[len] = '\0';
- ff_rtsp_parse_line(header, line, NULL);
+ ff_rtsp_parse_line(header, line, NULL, NULL);
p = p1 + 1;
}
struct in_addr my_ip)
{
AVFormatContext *avc;
- AVStream avs[MAX_STREAMS];
+ AVStream *avs = NULL;
int i;
avc = avformat_alloc_context();
snprintf(avc->filename, 1024, "rtp://0.0.0.0");
}
+#if !FF_API_MAX_STREAMS
+ if (avc->nb_streams >= INT_MAX/sizeof(*avc->streams) ||
+ !(avc->streams = av_malloc(avc->nb_streams * sizeof(*avc->streams))))
+ goto sdp_done;
+#endif
+ if (avc->nb_streams >= INT_MAX/sizeof(*avs) ||
+ !(avs = av_malloc(avc->nb_streams * sizeof(*avs))))
+ goto sdp_done;
+
for(i = 0; i < stream->nb_streams; i++) {
avc->streams[i] = &avs[i];
avc->streams[i]->codec = stream->streams[i]->codec;
}
*pbuffer = av_mallocz(2048);
avf_sdp_create(&avc, 1, *pbuffer, 2048);
+
+ sdp_done:
+#if !FF_API_MAX_STREAMS
+ av_free(avc->streams);
+#endif
av_metadata_free(&avc->metadata);
av_free(avc);
+ av_free(avs);
return strlen(*pbuffer);
}
static void rtsp_cmd_options(HTTPContext *c, const char *url)
{
// rtsp_reply_header(c, RTSP_STATUS_OK);
- url_fprintf(c->pb, "RTSP/1.0 %d %s\r\n", RTSP_STATUS_OK, "OK");
- url_fprintf(c->pb, "CSeq: %d\r\n", c->seq);
- url_fprintf(c->pb, "Public: %s\r\n", "OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE");
- url_fprintf(c->pb, "\r\n");
+ 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", "OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE");
+ avio_printf(c->pb, "\r\n");
}
static void rtsp_cmd_describe(HTTPContext *c, const char *url)
struct sockaddr_in my_addr;
/* find which url is asked */
- ff_url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);
+ av_url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);
path = path1;
if (*path == '/')
path++;
return;
}
rtsp_reply_header(c, RTSP_STATUS_OK);
- url_fprintf(c->pb, "Content-Type: application/sdp\r\n");
- url_fprintf(c->pb, "Content-Length: %d\r\n", content_length);
- url_fprintf(c->pb, "\r\n");
- put_buffer(c->pb, content, content_length);
+ avio_printf(c->pb, "Content-Base: %s/\r\n", url);
+ avio_printf(c->pb, "Content-Type: application/sdp\r\n");
+ avio_printf(c->pb, "Content-Length: %d\r\n", content_length);
+ avio_printf(c->pb, "\r\n");
+ avio_write(c->pb, content, content_length);
av_free(content);
}
RTSPActionServerSetup setup;
/* find which url is asked */
- ff_url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);
+ av_url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);
path = path1;
if (*path == '/')
path++;
/* now everything is OK, so we can send the connection parameters */
rtsp_reply_header(c, RTSP_STATUS_OK);
/* session ID */
- url_fprintf(c->pb, "Session: %s\r\n", rtp_c->session_id);
+ avio_printf(c->pb, "Session: %s\r\n", rtp_c->session_id);
switch(rtp_c->rtp_protocol) {
case RTSP_LOWER_TRANSPORT_UDP:
rtp_port = rtp_get_local_rtp_port(rtp_c->rtp_handles[stream_index]);
rtcp_port = rtp_get_local_rtcp_port(rtp_c->rtp_handles[stream_index]);
- url_fprintf(c->pb, "Transport: RTP/AVP/UDP;unicast;"
+ avio_printf(c->pb, "Transport: RTP/AVP/UDP;unicast;"
"client_port=%d-%d;server_port=%d-%d",
th->client_port_min, th->client_port_max,
rtp_port, rtcp_port);
break;
case RTSP_LOWER_TRANSPORT_TCP:
- url_fprintf(c->pb, "Transport: RTP/AVP/TCP;interleaved=%d-%d",
+ avio_printf(c->pb, "Transport: RTP/AVP/TCP;interleaved=%d-%d",
stream_index * 2, stream_index * 2 + 1);
break;
default:
break;
}
if (setup.transport_option[0] != '\0')
- url_fprintf(c->pb, ";%s", setup.transport_option);
- url_fprintf(c->pb, "\r\n");
+ avio_printf(c->pb, ";%s", setup.transport_option);
+ avio_printf(c->pb, "\r\n");
- url_fprintf(c->pb, "\r\n");
+ avio_printf(c->pb, "\r\n");
}
char path1[1024];
const char *path;
char buf[1024];
- int s;
+ int s, len;
rtp_c = find_rtp_session(session_id);
if (!rtp_c)
return NULL;
/* find which url is asked */
- ff_url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);
+ av_url_split(NULL, 0, NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);
path = path1;
if (*path == '/')
path++;
return rtp_c;
}
}
+ len = strlen(path);
+ if (len > 0 && path[len - 1] == '/' &&
+ !strncmp(path, rtp_c->stream->filename, len - 1))
+ return rtp_c;
return NULL;
}
/* now everything is OK, so we can send the connection parameters */
rtsp_reply_header(c, RTSP_STATUS_OK);
/* session ID */
- url_fprintf(c->pb, "Session: %s\r\n", rtp_c->session_id);
- url_fprintf(c->pb, "\r\n");
+ avio_printf(c->pb, "Session: %s\r\n", rtp_c->session_id);
+ avio_printf(c->pb, "\r\n");
}
static void rtsp_cmd_pause(HTTPContext *c, const char *url, RTSPMessageHeader *h)
/* now everything is OK, so we can send the connection parameters */
rtsp_reply_header(c, RTSP_STATUS_OK);
/* session ID */
- url_fprintf(c->pb, "Session: %s\r\n", rtp_c->session_id);
- url_fprintf(c->pb, "\r\n");
+ avio_printf(c->pb, "Session: %s\r\n", rtp_c->session_id);
+ avio_printf(c->pb, "\r\n");
}
static void rtsp_cmd_teardown(HTTPContext *c, const char *url, RTSPMessageHeader *h)
/* now everything is OK, so we can send the connection parameters */
rtsp_reply_header(c, RTSP_STATUS_OK);
/* session ID */
- url_fprintf(c->pb, "Session: %s\r\n", session_id);
- url_fprintf(c->pb, "\r\n");
+ avio_printf(c->pb, "Session: %s\r\n", session_id);
+ avio_printf(c->pb, "\r\n");
}
fst->priv_data = av_mallocz(sizeof(FeedData));
fst->index = stream->nb_streams;
av_set_pts_info(fst, 33, 1, 90000);
+ fst->sample_aspect_ratio = codec->sample_aspect_ratio;
stream->streams[stream->nb_streams++] = fst;
return fst;
}
ccs = ss->codec;
#define CHECK_CODEC(x) (ccf->x != ccs->x)
- if (CHECK_CODEC(codec) || CHECK_CODEC(codec_type)) {
+ if (CHECK_CODEC(codec_id) || CHECK_CODEC(codec_type)) {
http_log("Codecs do not match for stream %d\n", i);
matches = 0;
} else if (CHECK_CODEC(bit_rate) || CHECK_CODEC(flags)) {
}
/* only write the header of the ffm file */
- if (url_fopen(&s->pb, feed->feed_filename, URL_WRONLY) < 0) {
+ if (avio_open(&s->pb, feed->feed_filename, URL_WRONLY) < 0) {
http_log("Could not open output feed file '%s'\n",
feed->feed_filename);
exit(1);
}
/* XXX: need better api */
av_freep(&s->priv_data);
- url_fclose(s->pb);
+ avio_close(s->pb);
}
/* get feed size and write index */
fd = open(feed->feed_filename, O_RDONLY);
return ret;
}
+static int ffserver_opt_preset(const char *arg,
+ AVCodecContext *avctx, int type,
+ enum CodecID *audio_id, enum CodecID *video_id)
+{
+ FILE *f=NULL;
+ char filename[1000], tmp[1000], tmp2[1000], line[1000];
+ int ret = 0;
+ AVCodec *codec = avcodec_find_encoder(avctx->codec_id);
+
+ if (!(f = get_preset_file(filename, sizeof(filename), arg, 0,
+ codec ? codec->name : NULL))) {
+ fprintf(stderr, "File for preset '%s' not found\n", arg);
+ return 1;
+ }
+
+ while(!feof(f)){
+ int e= fscanf(f, "%999[^\n]\n", line) - 1;
+ if(line[0] == '#' && !e)
+ continue;
+ e|= sscanf(line, "%999[^=]=%999[^\n]\n", tmp, tmp2) - 2;
+ if(e){
+ fprintf(stderr, "%s: Invalid syntax: '%s'\n", filename, line);
+ ret = 1;
+ break;
+ }
+ if(!strcmp(tmp, "acodec")){
+ *audio_id = opt_audio_codec(tmp2);
+ }else if(!strcmp(tmp, "vcodec")){
+ *video_id = opt_video_codec(tmp2);
+ }else if(!strcmp(tmp, "scodec")){
+ /* opt_subtitle_codec(tmp2); */
+ }else if(ffserver_opt_default(tmp, tmp2, avctx, type) < 0){
+ fprintf(stderr, "%s: Invalid option or argument: '%s', parsed as '%s' = '%s'\n", filename, line, tmp, tmp2);
+ ret = 1;
+ break;
+ }
+ }
+
+ fclose(f);
+
+ return ret;
+}
+
static AVOutputFormat *ffserver_guess_format(const char *short_name, const char *filename,
const char *mime_type)
{
} else if (!strcasecmp(cmd, "AudioBitRate")) {
get_arg(arg, sizeof(arg), &p);
if (stream)
- audio_enc.bit_rate = atoi(arg) * 1000;
+ audio_enc.bit_rate = lrintf(atof(arg) * 1000);
} else if (!strcasecmp(cmd, "AudioChannels")) {
get_arg(arg, sizeof(arg), &p);
if (stream)
} else if (!strcasecmp(cmd, "VideoSize")) {
get_arg(arg, sizeof(arg), &p);
if (stream) {
- av_parse_video_frame_size(&video_enc.width, &video_enc.height, arg);
+ av_parse_video_size(&video_enc.width, &video_enc.height, arg);
if ((video_enc.width % 16) != 0 ||
(video_enc.height % 16) != 0) {
ERROR("Image size must be a multiple of 16\n");
get_arg(arg, sizeof(arg), &p);
if (stream) {
AVRational frame_rate;
- if (av_parse_video_frame_rate(&frame_rate, arg) < 0) {
+ if (av_parse_video_rate(&frame_rate, arg) < 0) {
ERROR("Incorrect frame rate: %s\n", arg);
} else {
video_enc.time_base.num = frame_rate.den;
if (ffserver_opt_default(arg, arg2, avctx, type|AV_OPT_FLAG_ENCODING_PARAM)) {
ERROR("AVOption error: %s %s\n", arg, arg2);
}
+ } else if (!strcasecmp(cmd, "AVPresetVideo") ||
+ !strcasecmp(cmd, "AVPresetAudio")) {
+ AVCodecContext *avctx;
+ int type;
+ get_arg(arg, sizeof(arg), &p);
+ if (!strcasecmp(cmd, "AVPresetVideo")) {
+ avctx = &video_enc;
+ video_enc.codec_id = video_id;
+ type = AV_OPT_FLAG_VIDEO_PARAM;
+ } else {
+ avctx = &audio_enc;
+ audio_enc.codec_id = audio_id;
+ type = AV_OPT_FLAG_AUDIO_PARAM;
+ }
+ if (ffserver_opt_preset(arg, avctx, type|AV_OPT_FLAG_ENCODING_PARAM, &audio_id, &video_id)) {
+ ERROR("AVPreset error: %s\n", arg);
+ }
} else if (!strcasecmp(cmd, "VideoTag")) {
get_arg(arg, sizeof(arg), &p);
if ((strlen(arg) == 4) && stream)