[SCM] libav/experimental: Update to work with chunked encoding HTTP streams (as served by FFmpeg since a few months now). Fixes issue 1738.

siretart at users.alioth.debian.org siretart at users.alioth.debian.org
Sun Jun 30 17:02:39 UTC 2013


The following commit has been merged in the experimental branch:
commit 19c8c4ecf4e26762327a472dcf34132ceb196e30
Author: Ronald S. Bultje <rsbultje at gmail.com>
Date:   Wed Mar 3 18:41:50 2010 +0000

    Update to work with chunked encoding HTTP streams (as served by FFmpeg since
    a few months now). Fixes issue 1738.
    
    Originally committed as revision 22175 to svn://svn.ffmpeg.org/ffmpeg/trunk

diff --git a/ffserver.c b/ffserver.c
index 87f162f..9a53e49 100644
--- a/ffserver.c
+++ b/ffserver.c
@@ -124,6 +124,8 @@ typedef struct HTTPContext {
     uint8_t *buffer_ptr, *buffer_end;
     int http_error;
     int post;
+    int chunked_encoding;
+    int chunk_size;               /* 0 if it needs to be read */
     struct HTTPContext *next;
     int got_key_frame; /* stream 0 => 1, stream 1 => 2, stream 2=> 4 */
     int64_t data_count;
@@ -2440,17 +2442,46 @@ static int http_start_receive_data(HTTPContext *c)
     c->buffer_ptr = c->buffer;
     c->buffer_end = c->buffer + FFM_PACKET_SIZE;
     c->stream->feed_opened = 1;
+    c->chunked_encoding = !!strcasestr(c->buffer, "Transfer-Encoding: chunked");
     return 0;
 }
 
 static int http_receive_data(HTTPContext *c)
 {
     HTTPContext *c1;
+    int len, loop_run = 0;
 
-    if (c->buffer_end > c->buffer_ptr) {
-        int len;
+    while (c->chunked_encoding && !c->chunk_size &&
+           c->buffer_end > c->buffer_ptr) {
+        /* read chunk header, if present */
+        len = recv(c->fd, c->buffer_ptr, 1, 0);
+
+        if (len < 0) {
+            if (ff_neterrno() != FF_NETERROR(EAGAIN) &&
+                ff_neterrno() != FF_NETERROR(EINTR))
+                /* error : close connection */
+                goto fail;
+        } else if (len == 0) {
+            /* end of connection : close it */
+            goto fail;
+        } else if (c->buffer_ptr - c->buffer >= 2 &&
+                   !memcmp(c->buffer_ptr - 1, "\r\n", 2)) {
+            c->chunk_size = strtol(c->buffer, 0, 16);
+            if (c->chunk_size == 0) // end of stream
+                goto fail;
+            c->buffer_ptr = c->buffer;
+            break;
+        } else if (++loop_run > 10) {
+            /* no chunk header, abort */
+            goto fail;
+        } else {
+            c->buffer_ptr++;
+        }
+    }
 
-        len = recv(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr, 0);
+    if (c->buffer_end > c->buffer_ptr) {
+        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))
@@ -2460,6 +2491,7 @@ static int http_receive_data(HTTPContext *c)
             /* end of connection : close it */
             goto fail;
         else {
+            c->chunk_size -= len;
             c->buffer_ptr += len;
             c->data_count += len;
             update_datarate(&c->datarate, c->data_count);

-- 
Libav/FFmpeg packaging



More information about the pkg-multimedia-commits mailing list