Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FFmpeg/FFmpeg.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwm4 <nfxjfg@googlemail.com>2014-03-02 23:26:19 +0400
committerMichael Niedermayer <michaelni@gmx.at>2014-03-16 06:29:12 +0400
commitfacd3dbc6e0788f0e693a83e6ef16918b7eb960b (patch)
tree2acf4a7b8dba1edd4ac74a3db235d11fced7e8db /libavformat
parent8796c3b7d3e2904d7bc8ebfe261b53c263098935 (diff)
http: handle ICY in presence of chunked transfer encoding
Some http servers send an ICY stream in combination with chunked transfer encoding. This case was handled incorrectly by the ICY code: instead of handling chunked encoding before anything ICY related, both were mixed. Fix this by separating the ICY code from normal http reading. Move the normal http reading to a new function http_read_stream(), while http_read() handles ICY on top of http_read_stream(). The server identified itself as: cloudflare-nginx Signed-off-by: Michael Niedermayer <michaelni@gmx.at> (cherry picked from commit 636273d3d4a8c42f51832e8bf83e566e875916bf) Signed-off-by: Michael Niedermayer <michaelni@gmx.at> (cherry picked from commit 67f67a3748a038d880ed8a642184d2e3c76e29bb) Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavformat')
-rw-r--r--libavformat/http.c54
1 files changed, 39 insertions, 15 deletions
diff --git a/libavformat/http.c b/libavformat/http.c
index 26157677b1..388452ea6c 100644
--- a/libavformat/http.c
+++ b/libavformat/http.c
@@ -774,7 +774,6 @@ static int http_buf_read(URLContext *h, uint8_t *buf, int size)
}
if (len > 0) {
s->off += len;
- s->icy_data_read += len;
if (s->chunksize > 0)
s->chunksize -= len;
}
@@ -813,7 +812,7 @@ static int http_buf_read_compressed(URLContext *h, uint8_t *buf, int size)
}
#endif
-static int http_read(URLContext *h, uint8_t *buf, int size)
+static int http_read_stream(URLContext *h, uint8_t *buf, int size)
{
HTTPContext *s = h->priv_data;
int err, new_location;
@@ -848,6 +847,31 @@ static int http_read(URLContext *h, uint8_t *buf, int size)
}
size = FFMIN(size, s->chunksize);
}
+#if CONFIG_ZLIB
+ if (s->compressed)
+ return http_buf_read_compressed(h, buf, size);
+#endif
+ return http_buf_read(h, buf, size);
+}
+
+// Like http_read_stream(), but no short reads.
+// Assumes partial reads are an error.
+static int http_read_stream_all(URLContext *h, uint8_t *buf, int size)
+{
+ int pos = 0;
+ while (pos < size) {
+ int len = http_read_stream(h, buf + pos, size - pos);
+ if (len < 0)
+ return len;
+ pos += len;
+ }
+ return pos;
+}
+
+static int http_read(URLContext *h, uint8_t *buf, int size)
+{
+ HTTPContext *s = h->priv_data;
+
if (s->icy_metaint > 0) {
int remaining = s->icy_metaint - s->icy_data_read; /* until next metadata packet */
if (!remaining) {
@@ -855,17 +879,18 @@ static int http_read(URLContext *h, uint8_t *buf, int size)
// which sets the length of the packet (divided by 16). If it's 0,
// the metadata doesn't change. After the packet, icy_metaint bytes
// of normal data follow.
- int ch = http_getc(s);
- if (ch < 0)
- return ch;
+ uint8_t ch;
+ int len = http_read_stream_all(h, &ch, 1);
+ if (len < 1)
+ return len;
if (ch > 0) {
char data[255 * 16 + 1];
- int n;
int ret;
- ch *= 16;
- for (n = 0; n < ch; n++)
- data[n] = http_getc(s);
- data[ch + 1] = 0;
+ len = ch * 16;
+ ret = http_read_stream_all(h, data, len);
+ if (ret < len)
+ return ret;
+ data[len + 1] = 0;
if ((ret = av_opt_set(s, "icy_metadata_packet", data, 0)) < 0)
return ret;
}
@@ -874,11 +899,10 @@ static int http_read(URLContext *h, uint8_t *buf, int size)
}
size = FFMIN(size, remaining);
}
-#if CONFIG_ZLIB
- if (s->compressed)
- return http_buf_read_compressed(h, buf, size);
-#endif
- return http_buf_read(h, buf, size);
+ size = http_read_stream(h, buf, size);
+ if (size > 0)
+ s->icy_data_read += size;
+ return size;
}
/* used only when posting data */