diff options
author | Giancarlo Formicuccia <ilsensine@inwind.it> | 2003-07-11 22:30:12 +0000 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2003-07-11 22:30:12 +0000 |
commit | 1bc1cfdddf7ab8ef50d0fc888808d6b609eb5d8d (patch) | |
tree | 76a842f76f221a2343ba29ac6aa623d49d465d54 /ffserver.c | |
parent | 6bc114b2fb026ff0c521caf206ad08fdb5910383 (diff) | |
download | ffmpeg-1bc1cfdddf7ab8ef50d0fc888808d6b609eb5d8d.tar.gz |
- Gracefully handle the case where not all the streams are requested/wanted
from the client. Simply ignore the unwanted/unasked streams.
- Don't need to pool() for every input character! (the socket is nonblocking,
so the loop is ok).
- Partially resurrect compute_send_delay for avoiding udp flood. Without a
similar patch, udp transmission is seriously unreliable.
(note that we don't link to a specific input reference stream, it's not needed
as the pts values should be coherent anyway. Also, non-monotonic pts
progression is unimportant in the long term).
- rtsp_cmd_pause must reset the time reference
patch by (Giancarlo Formicuccia <ilsensine at inwind dot it>)
Originally committed as revision 2034 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'ffserver.c')
-rw-r--r-- | ffserver.c | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/ffserver.c b/ffserver.c index 6cebfb4942..a0ded91e6d 100644 --- a/ffserver.c +++ b/ffserver.c @@ -113,6 +113,7 @@ typedef struct HTTPContext { AVFormatContext *fmt_in; long start_time; /* In milliseconds - this wraps fairly often */ int64_t first_pts; /* initial pts value */ + int64_t cur_pts; /* current pts value */ int pts_stream_index; /* stream we choose as clock reference */ /* output format handling */ struct FFStream *stream; @@ -786,6 +787,7 @@ static int handle_connection(HTTPContext *c) if (!(c->poll_entry->revents & POLLIN)) return 0; /* read the data */ + read_loop: len = read(c->fd, c->buffer_ptr, 1); if (len < 0) { if (errno != EAGAIN && errno != EINTR) @@ -810,7 +812,7 @@ static int handle_connection(HTTPContext *c) } else if (ptr >= c->buffer_end) { /* request too long: cannot do anything */ return -1; - } + } else goto read_loop; } break; @@ -2078,11 +2080,20 @@ static int av_read_frame(AVFormatContext *s, AVPacket *pkt) static int compute_send_delay(HTTPContext *c) { int datarate = 8 * get_longterm_datarate(&c->datarate, c->data_count); + int64_t delta_pts; + int64_t time_pts; + int m_delay; if (datarate > c->stream->bandwidth * 2000) { return 1000; } - return 0; + if(!c->stream->feed && c->first_pts!=AV_NOPTS_VALUE) { + time_pts = ((int64_t)(cur_time - c->start_time) * c->fmt_in->pts_den) / + ((int64_t) c->fmt_in->pts_num*1000); + delta_pts = c->cur_pts - time_pts; + m_delay = (delta_pts * 1000 * c->fmt_in->pts_num) / c->fmt_in->pts_den; + return m_delay>0 ? m_delay : 0; + } else return 0; } #endif @@ -2189,9 +2200,11 @@ static int http_prepare_data(HTTPContext *c) } } else { /* update first pts if needed */ - if (c->first_pts == AV_NOPTS_VALUE) + if (c->first_pts == AV_NOPTS_VALUE) { c->first_pts = pkt.pts; - + c->start_time = cur_time; + } + c->cur_pts = pkt.pts; /* send it to the appropriate stream */ if (c->stream->feed) { /* if coming from a feed, select the right stream */ @@ -2239,7 +2252,7 @@ static int http_prepare_data(HTTPContext *c) ctx = c->rtp_ctx[c->packet_stream_index]; if(!ctx) { av_free_packet(&pkt); - return -1; + break; } codec = &ctx->streams[0]->codec; /* only one stream per RTP connection */ @@ -3044,7 +3057,7 @@ static void rtsp_cmd_pause(HTTPContext *c, const char *url, RTSPHeader *h) } rtp_c->state = HTTPSTATE_READY; - + rtp_c->first_pts = AV_NOPTS_VALUE; /* now everything is OK, so we can send the connection parameters */ rtsp_reply_header(c, RTSP_STATUS_OK); /* session ID */ |