Browse code

- 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

Giancarlo Formicuccia authored on 2003/07/12 07:30:12
Showing 1 changed files
... ...
@@ -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 */