[vlc-devel] [PATCH] stream: add stream_ForcedPeekNew
Francois Cartegnie
fcvlcdev at free.fr
Thu Sep 10 17:18:16 CEST 2015
Creates a stream_Memory like backend
pointing to an existing stream to convert
reads into peek only requests.
Helps dealing with seekable only designed code
(using stream_Readline for exemple)
---
include/vlc_stream.h | 7 +++++++
src/input/stream_memory.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++-
src/libvlccore.sym | 1 +
3 files changed, 57 insertions(+), 1 deletion(-)
diff --git a/include/vlc_stream.h b/include/vlc_stream.h
index cbdd2fa..fa418f4 100644
--- a/include/vlc_stream.h
+++ b/include/vlc_stream.h
@@ -226,6 +226,13 @@ VLC_API stream_t * stream_MemoryNew(vlc_object_t *p_obj, uint8_t *p_buffer, uint
#define stream_MemoryNew( a, b, c, d ) stream_MemoryNew( VLC_OBJECT(a), b, c, d )
/**
+ * Create a stream_t reading from another stream, without modifying
+ * its read pointer.
+ * You must delete it using stream_Delete.
+ */
+VLC_API stream_t * stream_ForcedPeekNew( stream_t *p_backend );
+
+/**
* Create a stream_t reading from a URL.
* You must delete it using stream_Delete.
*/
diff --git a/src/input/stream_memory.c b/src/input/stream_memory.c
index 3fc23a9..7a97893 100644
--- a/src/input/stream_memory.c
+++ b/src/input/stream_memory.c
@@ -33,7 +33,7 @@ struct stream_sys_t
size_t i_pos; /* Current reading offset */
size_t i_size;
uint8_t *p_buffer;
-
+ stream_t *p_backend_stream; /* Only used by forced peek */
};
static ssize_t Read( stream_t *, void *p_read, size_t i_read );
@@ -41,6 +41,9 @@ static int Seek( stream_t *, uint64_t );
static int Control( stream_t *, int i_query, va_list );
static void Delete ( stream_t * );
+
+static ssize_t PeekBackend( stream_t *, void *p_read, size_t i_read );
+
#undef stream_MemoryNew
/**
* Create a stream from a memory buffer
@@ -70,6 +73,7 @@ stream_t *stream_MemoryNew( vlc_object_t *p_this, uint8_t *p_buffer,
p_sys->i_size = i_size;
p_sys->p_buffer = p_buffer;
p_sys->i_preserve_memory = i_preserve_memory;
+ p_sys->p_backend_stream = NULL;
s->pf_read = Read;
s->pf_seek = Seek;
@@ -79,6 +83,27 @@ stream_t *stream_MemoryNew( vlc_object_t *p_this, uint8_t *p_buffer,
return s;
}
+/**
+ * Create a virtual stream to issue peek only requests to
+ * an existing stream
+ *
+ * \param p_backend_stream the stream to be used as backend
+ */
+stream_t *stream_ForcedPeekNew( stream_t *p_backend_stream )
+{
+ if( (uint64_t) stream_Size( p_backend_stream ) <= stream_Tell( p_backend_stream ) )
+ return NULL;
+
+ /* Init an empty stream Mem */
+ stream_t *s = stream_MemoryNew( VLC_OBJECT(p_backend_stream), NULL, 0, true );
+ if( !s )
+ return NULL;
+ s->p_sys->i_size = stream_Size( p_backend_stream ) - stream_Tell( p_backend_stream );
+ s->p_sys->p_backend_stream = p_backend_stream;
+ s->pf_read = PeekBackend;
+ return s;
+}
+
static void Delete( stream_t *s )
{
if( !s->p_sys->i_preserve_memory ) free( s->p_sys->p_buffer );
@@ -161,3 +186,26 @@ static int Seek( stream_t *s, uint64_t offset )
p_sys->i_pos = offset;
return VLC_SUCCESS;
}
+
+/* Peek Only Stream */
+static ssize_t PeekBackend( stream_t *s, void *p_read, size_t i_read )
+{
+ stream_sys_t *p_sys = s->p_sys;
+
+ const uint8_t *p_peek;
+ const ssize_t i_peek = stream_Peek( p_sys->p_backend_stream, &p_peek, p_sys->i_pos + i_read );
+ if( i_peek < 0 )
+ {
+ /* error code */
+ return i_peek;
+ }
+ else if( (size_t) i_peek > p_sys->i_pos )
+ {
+ i_read = i_peek - p_sys->i_pos;
+ memcpy( p_read, &p_peek[p_sys->i_pos], i_read );
+ p_sys->i_pos += i_read;
+ return i_read;
+ }
+ else /* returned less than current pos/last read */
+ return VLC_EGENERIC;
+}
diff --git a/src/libvlccore.sym b/src/libvlccore.sym
index 372b312..d0f5111 100644
--- a/src/libvlccore.sym
+++ b/src/libvlccore.sym
@@ -399,6 +399,7 @@ stream_DemuxNew
stream_DemuxSend
stream_DemuxControlVa
stream_FilterNew
+stream_ForcedPeekNew
stream_MemoryNew
stream_Peek
stream_Read
--
2.4.3
More information about the vlc-devel
mailing list