mirror of
https://github.com/xenia-project/FFmpeg.git
synced 2024-11-24 12:09:55 +00:00
avformat/http: support reading compressed data
Derived from VLC's http module. Original authors: Antoine Cellerier <dionoea@videolan.org> Sébastien Escudier <sebastien-devel@celeos.eu> Rémi Duraffort <ivoire@videolan.org> Rémi Denis-Courmont <remi@remlab.net> Francois Cartegnie <fcvlcdev@free.fr> Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
parent
274a50ab57
commit
6bab3430a7
@ -29,6 +29,10 @@
|
||||
#include "url.h"
|
||||
#include "libavutil/opt.h"
|
||||
|
||||
#if CONFIG_ZLIB
|
||||
#include <zlib.h>
|
||||
#endif
|
||||
|
||||
/* XXX: POST protocol is not completely implemented because ffmpeg uses
|
||||
only a subset of it. */
|
||||
|
||||
@ -70,6 +74,11 @@ typedef struct {
|
||||
int icy;
|
||||
char *icy_metadata_headers;
|
||||
char *icy_metadata_packet;
|
||||
#if CONFIG_ZLIB
|
||||
int compressed;
|
||||
z_stream inflate_stream;
|
||||
uint8_t *inflate_buffer;
|
||||
#endif
|
||||
} HTTPContext;
|
||||
|
||||
#define OFFSET(x) offsetof(HTTPContext, x)
|
||||
@ -396,6 +405,22 @@ static int process_line(URLContext *h, char *line, int line_count,
|
||||
return AVERROR(ENOMEM);
|
||||
av_freep(&s->icy_metadata_headers);
|
||||
s->icy_metadata_headers = buf;
|
||||
} else if (!av_strcasecmp (tag, "Content-Encoding")) {
|
||||
if (!av_strncasecmp(p, "gzip", 4) || !av_strncasecmp(p, "deflate", 7)) {
|
||||
#if CONFIG_ZLIB
|
||||
s->compressed = 1;
|
||||
inflateEnd(&s->inflate_stream);
|
||||
if (inflateInit2(&s->inflate_stream, 32 + 15) != Z_OK)
|
||||
av_log(h, AV_LOG_WARNING, "Error during zlib initialisation: %s",
|
||||
s->inflate_stream.msg);
|
||||
if (zlibCompileFlags() & (1 << 17))
|
||||
av_log(h, AV_LOG_WARNING, "Your zlib was compiled without gzip support.");
|
||||
#else
|
||||
av_log(h, AV_LOG_WARNING, "Compressed(%s) content, need zlib support", p);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
av_log(h, AV_LOG_WARNING, "Unknown content coding: %s", p);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
@ -685,6 +710,38 @@ static int http_buf_read(URLContext *h, uint8_t *buf, int size)
|
||||
return len;
|
||||
}
|
||||
|
||||
#if CONFIG_ZLIB
|
||||
#define DECOMPRESS_BUF_SIZE (256 * 1024)
|
||||
static int http_buf_read_compressed(URLContext *h, uint8_t *buf, int size)
|
||||
{
|
||||
HTTPContext *s = h->priv_data;
|
||||
int ret;
|
||||
|
||||
if (!s->inflate_buffer) {
|
||||
s->inflate_buffer = av_malloc(DECOMPRESS_BUF_SIZE);
|
||||
if (!s->inflate_buffer)
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
if (s->inflate_stream.avail_in == 0) {
|
||||
int read = http_buf_read(h, s->inflate_buffer, DECOMPRESS_BUF_SIZE);
|
||||
if (read <= 0)
|
||||
return read;
|
||||
s->inflate_stream.next_in = s->inflate_buffer;
|
||||
s->inflate_stream.avail_in = read;
|
||||
}
|
||||
|
||||
s->inflate_stream.avail_out = size;
|
||||
s->inflate_stream.next_out = buf;
|
||||
|
||||
ret = inflate(&s->inflate_stream, Z_SYNC_FLUSH);
|
||||
if (ret != Z_OK && ret != Z_STREAM_END)
|
||||
av_log(h, AV_LOG_WARNING, "inflate return value: %d, %s", ret, s->inflate_stream.msg);
|
||||
|
||||
return size - s->inflate_stream.avail_out;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int http_read(URLContext *h, uint8_t *buf, int size)
|
||||
{
|
||||
HTTPContext *s = h->priv_data;
|
||||
@ -746,6 +803,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);
|
||||
}
|
||||
|
||||
@ -797,6 +858,11 @@ static int http_close(URLContext *h)
|
||||
int ret = 0;
|
||||
HTTPContext *s = h->priv_data;
|
||||
|
||||
#if CONFIG_ZLIB
|
||||
inflateEnd(&s->inflate_stream);
|
||||
av_freep(&s->inflate_buffer);
|
||||
#endif
|
||||
|
||||
if (!s->end_chunked_post) {
|
||||
/* Close the write direction by sending the end of chunked encoding. */
|
||||
ret = http_shutdown(h, h->flags);
|
||||
|
Loading…
Reference in New Issue
Block a user