summaryrefslogtreecommitdiffstats
path: root/stream/stream.c
diff options
context:
space:
mode:
Diffstat (limited to 'stream/stream.c')
-rw-r--r--stream/stream.c113
1 files changed, 86 insertions, 27 deletions
diff --git a/stream/stream.c b/stream/stream.c
index 4f12e57856..3bfa418c90 100644
--- a/stream/stream.c
+++ b/stream/stream.c
@@ -52,8 +52,6 @@
#include "core/m_option.h"
#include "core/m_struct.h"
-#include "cache2.h"
-
/// We keep these 2 for the gui atm, but they will be removed.
char *cdrom_device = NULL;
char *dvd_device = NULL;
@@ -136,7 +134,7 @@ static const stream_info_t *const auto_open_streams[] = {
NULL
};
-static stream_t *new_stream(int fd, int type);
+static stream_t *new_stream(void);
static stream_t *open_stream_plugin(const stream_info_t *sinfo,
const char *filename,
@@ -165,7 +163,7 @@ static stream_t *open_stream_plugin(const stream_info_t *sinfo,
}
}
}
- s = new_stream(-2, -2);
+ s = new_stream();
s->opts = options;
s->url = strdup(filename);
s->flags |= mode;
@@ -200,6 +198,8 @@ static stream_t *open_stream_plugin(const stream_info_t *sinfo,
s->mode = mode;
+ s->uncached_type = s->type;
+
mp_msg(MSGT_OPEN, MSGL_V, "STREAM: [%s] %s\n", sinfo->name, filename);
mp_msg(MSGT_OPEN, MSGL_V, "STREAM: Description: %s\n", sinfo->info);
mp_msg(MSGT_OPEN, MSGL_V, "STREAM: Author: %s\n", sinfo->author);
@@ -308,7 +308,7 @@ static int stream_reconnect(stream_t *s)
continue;
}
- if (stream_seek_internal(s, pos) < 0 && s->pos == pos)
+ if (stream_seek_unbuffered(s, pos) < 0 && s->pos == pos)
return 1;
}
return 0;
@@ -345,7 +345,11 @@ void stream_capture_write(stream_t *s)
}
}
-int stream_read_internal(stream_t *s, void *buf, int len)
+// Read function bypassing the local stream buffer. This will not write into
+// s->buffer, but into buf[0..len] instead.
+// Returns < 0 on error, 0 on EOF, and length of bytes read on success.
+// Partial reads are possible, even if EOF is not reached.
+int stream_read_unbuffered(stream_t *s, void *buf, int len)
{
int orig_len = len;
// we will retry even if we already reached EOF previously.
@@ -379,7 +383,7 @@ int stream_read_internal(stream_t *s, void *buf, int len)
goto eof_out;
// make sure EOF is set to ensure no endless loops
s->eof = 1;
- return stream_read_internal(s, buf, orig_len);
+ return stream_read_unbuffered(s, buf, orig_len);
eof_out:
s->eof = 1;
@@ -394,7 +398,7 @@ eof_out:
int stream_fill_buffer(stream_t *s)
{
- int len = stream_read_internal(s, s->buffer, STREAM_BUFFER_SIZE);
+ int len = stream_read_unbuffered(s, s->buffer, STREAM_BUFFER_SIZE);
if (len <= 0)
return 0;
s->buf_pos = 0;
@@ -411,7 +415,7 @@ int stream_read(stream_t *s, char *mem, int total)
int x;
x = s->buf_len - s->buf_pos;
if (x == 0) {
- if (!cache_stream_fill_buffer(s))
+ if (!stream_fill_buffer(s))
return total - len; // EOF
x = s->buf_len - s->buf_pos;
}
@@ -441,7 +445,8 @@ int stream_write_buffer(stream_t *s, unsigned char *buf, int len)
return rd;
}
-int stream_seek_internal(stream_t *s, int64_t newpos)
+// Seek function bypassing the local stream buffer.
+int stream_seek_unbuffered(stream_t *s, int64_t newpos)
{
if (newpos == 0 || newpos != s->pos) {
switch (s->type) {
@@ -492,7 +497,9 @@ int stream_seek_internal(stream_t *s, int64_t newpos)
return -1;
}
-int stream_seek_long(stream_t *s, int64_t pos)
+// Unlike stream_seek, does not try to seek within local buffer.
+// Unlike stream_seek_unbuffered(), it still fills the local buffer.
+static int stream_seek_long(stream_t *s, int64_t pos)
{
int res;
int64_t newpos = 0;
@@ -517,7 +524,7 @@ int stream_seek_long(stream_t *s, int64_t pos)
(int64_t)s->pos, (int64_t)newpos, (int64_t)pos, s->buf_len);
pos -= newpos;
- res = stream_seek_internal(s, newpos);
+ res = stream_seek_unbuffered(s, newpos);
if (res >= 0)
return res;
@@ -565,7 +572,7 @@ int stream_seek(stream_t *s, int64_t pos)
}
}
- return cache_stream_seek_long(s, pos);
+ return stream_seek_long(s, pos);
}
int stream_skip(stream_t *s, int64_t len)
@@ -578,7 +585,7 @@ int stream_skip(stream_t *s, int64_t len)
while (len > 0) {
int x = s->buf_len - s->buf_pos;
if (x == 0) {
- if (!cache_stream_fill_buffer(s))
+ if (!stream_fill_buffer(s))
return 0; // EOF
x = s->buf_len - s->buf_pos;
}
@@ -602,10 +609,6 @@ void stream_reset(stream_t *s)
int stream_control(stream_t *s, int cmd, void *arg)
{
-#ifdef CONFIG_STREAM_CACHE
- if (s->cache_pid)
- return cache_do_control(s, cmd, arg);
-#endif
if (!s->control)
return STREAM_UNSUPPORTED;
return s->control(s, cmd, arg);
@@ -620,7 +623,7 @@ void stream_update_size(stream_t *s)
}
}
-static stream_t *new_stream(int fd, int type)
+static stream_t *new_stream(void)
{
stream_t *s = talloc_zero(NULL, stream_t);
@@ -632,18 +635,13 @@ static stream_t *new_stream(int fd, int type)
}
#endif
- s->fd = fd;
- s->type = type;
- stream_reset(s);
+ s->fd = -2;
+ s->type = -2;
return s;
}
void free_stream(stream_t *s)
{
-// printf("\n*** free_stream() called ***\n");
-#ifdef CONFIG_STREAM_CACHE
- cache_uninit(s);
-#endif
stream_set_capture_file(s, NULL);
if (s->close)
@@ -662,6 +660,8 @@ void free_stream(stream_t *s)
WSACleanup(); // there might be a better place for this (-> later)
#endif
free(s->url);
+ if (s->uncached_stream)
+ free_stream(s->uncached_stream);
talloc_free(s);
}
@@ -681,6 +681,65 @@ int stream_check_interrupt(int time)
return stream_check_interrupt_cb(stream_check_interrupt_ctx, time);
}
+int stream_enable_cache_percent(stream_t **stream, int64_t stream_cache_size,
+ float stream_cache_min_percent,
+ float stream_cache_seek_min_percent)
+{
+ return stream_enable_cache(stream, stream_cache_size * 1024,
+ stream_cache_size * 1024 *
+ (stream_cache_min_percent / 100.0),
+ stream_cache_size * 1024 *
+ (stream_cache_seek_min_percent / 100.0));
+}
+
+/**
+ * \return 1 on success, 0 if the function was interrupted and -1 on error, or
+ * if the cache is disabled
+ */
+int stream_enable_cache(stream_t **stream, int64_t size, int64_t min,
+ int64_t seek_limit)
+{
+ stream_t *orig = *stream;
+
+ if (orig->mode != STREAM_READ)
+ return 1;
+
+ // Can't handle a loaded buffer.
+ orig->buf_len = orig->buf_pos = 0;
+
+ stream_t *cache = new_stream();
+ cache->type = STREAMTYPE_CACHE;
+ cache->uncached_type = orig->type;
+ cache->uncached_stream = orig;
+ cache->flags |= MP_STREAM_SEEK;
+ cache->mode = STREAM_READ;
+
+ cache->read_chunk = orig->read_chunk;
+ cache->url = strdup(orig->url);
+ cache->mime_type = talloc_strdup(cache, orig->mime_type);
+ cache->lavf_type = orig->lavf_type;
+ cache->opts = orig->opts;
+ cache->sector_size = orig->sector_size;
+ cache->read_chunk = orig->read_chunk;
+ cache->cache_size = orig->cache_size;
+ cache->start_pos = orig->start_pos;
+ cache->end_pos = orig->end_pos;
+
+ int res = -1;
+
+#ifdef CONFIG_STREAM_CACHE
+ res = stream_cache_init(cache, orig, size, min, seek_limit);
+#endif
+
+ if (res <= 0) {
+ cache->uncached_stream = NULL; // don't free original stream
+ free_stream(cache);
+ } else {
+ *stream = cache;
+ }
+ return res;
+}
+
/**
* Helper function to read 16 bits little-endian and advance pointer
*/
@@ -789,7 +848,7 @@ unsigned char *stream_read_line(stream_t *s, unsigned char *mem, int max,
len = s->buf_len - s->buf_pos;
// try to fill the buffer
if (len <= 0 &&
- (!cache_stream_fill_buffer(s) ||
+ (!stream_fill_buffer(s) ||
(len = s->buf_len - s->buf_pos) <= 0))
break;
end = find_newline(s->buffer + s->buf_pos, len, utf16);