Originally committed as revision 2034 to svn://svn.ffmpeg.org/ffmpeg/trunk
Giancarlo Formicuccia authored on 2003/07/12 07:30:12... | ... |
@@ -113,6 +113,7 @@ typedef struct HTTPContext { |
113 | 113 |
AVFormatContext *fmt_in; |
114 | 114 |
long start_time; /* In milliseconds - this wraps fairly often */ |
115 | 115 |
int64_t first_pts; /* initial pts value */ |
116 |
+ int64_t cur_pts; /* current pts value */ |
|
116 | 117 |
int pts_stream_index; /* stream we choose as clock reference */ |
117 | 118 |
/* output format handling */ |
118 | 119 |
struct FFStream *stream; |
... | ... |
@@ -786,6 +787,7 @@ static int handle_connection(HTTPContext *c) |
786 | 786 |
if (!(c->poll_entry->revents & POLLIN)) |
787 | 787 |
return 0; |
788 | 788 |
/* read the data */ |
789 |
+ read_loop: |
|
789 | 790 |
len = read(c->fd, c->buffer_ptr, 1); |
790 | 791 |
if (len < 0) { |
791 | 792 |
if (errno != EAGAIN && errno != EINTR) |
... | ... |
@@ -810,7 +812,7 @@ static int handle_connection(HTTPContext *c) |
810 | 810 |
} else if (ptr >= c->buffer_end) { |
811 | 811 |
/* request too long: cannot do anything */ |
812 | 812 |
return -1; |
813 |
- } |
|
813 |
+ } else goto read_loop; |
|
814 | 814 |
} |
815 | 815 |
break; |
816 | 816 |
|
... | ... |
@@ -2078,11 +2080,20 @@ static int av_read_frame(AVFormatContext *s, AVPacket *pkt) |
2078 | 2078 |
static int compute_send_delay(HTTPContext *c) |
2079 | 2079 |
{ |
2080 | 2080 |
int datarate = 8 * get_longterm_datarate(&c->datarate, c->data_count); |
2081 |
+ int64_t delta_pts; |
|
2082 |
+ int64_t time_pts; |
|
2083 |
+ int m_delay; |
|
2081 | 2084 |
|
2082 | 2085 |
if (datarate > c->stream->bandwidth * 2000) { |
2083 | 2086 |
return 1000; |
2084 | 2087 |
} |
2085 |
- return 0; |
|
2088 |
+ if(!c->stream->feed && c->first_pts!=AV_NOPTS_VALUE) { |
|
2089 |
+ time_pts = ((int64_t)(cur_time - c->start_time) * c->fmt_in->pts_den) / |
|
2090 |
+ ((int64_t) c->fmt_in->pts_num*1000); |
|
2091 |
+ delta_pts = c->cur_pts - time_pts; |
|
2092 |
+ m_delay = (delta_pts * 1000 * c->fmt_in->pts_num) / c->fmt_in->pts_den; |
|
2093 |
+ return m_delay>0 ? m_delay : 0; |
|
2094 |
+ } else return 0; |
|
2086 | 2095 |
} |
2087 | 2096 |
|
2088 | 2097 |
#endif |
... | ... |
@@ -2189,9 +2200,11 @@ static int http_prepare_data(HTTPContext *c) |
2189 | 2189 |
} |
2190 | 2190 |
} else { |
2191 | 2191 |
/* update first pts if needed */ |
2192 |
- if (c->first_pts == AV_NOPTS_VALUE) |
|
2192 |
+ if (c->first_pts == AV_NOPTS_VALUE) { |
|
2193 | 2193 |
c->first_pts = pkt.pts; |
2194 |
- |
|
2194 |
+ c->start_time = cur_time; |
|
2195 |
+ } |
|
2196 |
+ c->cur_pts = pkt.pts; |
|
2195 | 2197 |
/* send it to the appropriate stream */ |
2196 | 2198 |
if (c->stream->feed) { |
2197 | 2199 |
/* if coming from a feed, select the right stream */ |
... | ... |
@@ -2239,7 +2252,7 @@ static int http_prepare_data(HTTPContext *c) |
2239 | 2239 |
ctx = c->rtp_ctx[c->packet_stream_index]; |
2240 | 2240 |
if(!ctx) { |
2241 | 2241 |
av_free_packet(&pkt); |
2242 |
- return -1; |
|
2242 |
+ break; |
|
2243 | 2243 |
} |
2244 | 2244 |
codec = &ctx->streams[0]->codec; |
2245 | 2245 |
/* only one stream per RTP connection */ |
... | ... |
@@ -3044,7 +3057,7 @@ static void rtsp_cmd_pause(HTTPContext *c, const char *url, RTSPHeader *h) |
3044 | 3044 |
} |
3045 | 3045 |
|
3046 | 3046 |
rtp_c->state = HTTPSTATE_READY; |
3047 |
- |
|
3047 |
+ rtp_c->first_pts = AV_NOPTS_VALUE; |
|
3048 | 3048 |
/* now everything is OK, so we can send the connection parameters */ |
3049 | 3049 |
rtsp_reply_header(c, RTSP_STATUS_OK); |
3050 | 3050 |
/* session ID */ |