[vlc-commits] stream: add pf_block callback
Rémi Denis-Courmont
git at videolan.org
Thu Jul 21 21:30:16 CEST 2016
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Tue Jul 19 23:34:37 2016 +0300| [f1ed338b120f790b31c74bf34c372ffbfe57ebb1] | committer: Rémi Denis-Courmont
stream: add pf_block callback
This adds support for block-based stream filters.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=f1ed338b120f790b31c74bf34c372ffbfe57ebb1
---
include/vlc_stream.h | 1 +
src/input/stream.c | 88 +++++++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 81 insertions(+), 8 deletions(-)
diff --git a/include/vlc_stream.h b/include/vlc_stream.h
index 376dee6..cb0afbc 100644
--- a/include/vlc_stream.h
+++ b/include/vlc_stream.h
@@ -57,6 +57,7 @@ struct stream_t
/* */
ssize_t (*pf_read)(stream_t *, void *, size_t);
+ block_t * (*pf_block)(stream_t *, bool *eof);
int (*pf_readdir)( stream_t *, input_item_node_t * );
int (*pf_seek)(stream_t *, uint64_t);
int (*pf_control)( stream_t *, int i_query, va_list );
diff --git a/src/input/stream.c b/src/input/stream.c
index 058c063..dc109a0 100644
--- a/src/input/stream.c
+++ b/src/input/stream.c
@@ -45,6 +45,7 @@ typedef struct stream_priv_t
{
stream_t stream;
void (*destroy)(stream_t *);
+ block_t *block;
block_t *peek;
uint64_t offset;
bool eof;
@@ -80,12 +81,14 @@ stream_t *stream_CommonNew(vlc_object_t *parent, void (*destroy)(stream_t *))
s->psz_url = NULL;
s->p_source = NULL;
s->pf_read = NULL;
+ s->pf_block = NULL;
s->pf_readdir = NULL;
s->pf_control = NULL;
s->p_sys = NULL;
s->p_input = NULL;
assert(destroy != NULL);
priv->destroy = destroy;
+ priv->block = NULL;
priv->peek = NULL;
priv->offset = 0;
priv->eof = false;
@@ -107,6 +110,8 @@ void stream_CommonDelete(stream_t *s)
if (priv->peek != NULL)
block_Release(priv->peek);
+ if (priv->block != NULL)
+ block_Release(priv->block);
free(s->psz_url);
vlc_object_release(s);
@@ -332,6 +337,7 @@ error:
static ssize_t stream_ReadRaw(stream_t *s, void *buf, size_t len)
{
+ stream_priv_t *priv = (stream_priv_t *)s;
size_t copy = 0;
ssize_t ret = 0;
@@ -343,7 +349,45 @@ static ssize_t stream_ReadRaw(stream_t *s, void *buf, size_t len)
break;
}
- ret = s->pf_read(s, buf, len);
+ if (s->pf_read != NULL)
+ {
+ assert(priv->block == NULL);
+ ret = s->pf_read(s, buf, len);
+ }
+ else if (s->pf_block != NULL)
+ {
+ block_t *block = priv->block;
+ bool eof = false;
+
+ if (block == NULL)
+ block = s->pf_block(s, &eof);
+
+ if (block == NULL)
+ {
+ assert(priv->block == NULL);
+ ret = eof ? 0 : -1;
+ }
+ else if (block->i_buffer <= len)
+ {
+ if (buf != NULL)
+ memcpy(buf, block->p_buffer, block->i_buffer);
+ ret = block->i_buffer;
+ block_Release(block);
+ priv->block = NULL;
+ }
+ else
+ {
+ if (buf != NULL)
+ memcpy(buf, block->p_buffer, len);
+ ret = len;
+ block->p_buffer += len;
+ block->i_buffer -= len;
+ priv->block = block;
+ }
+ }
+ else
+ ret = -1;
+
if (ret <= 0)
break;
@@ -402,11 +446,16 @@ ssize_t stream_Read(stream_t *s, void *buf, size_t len)
ssize_t stream_Peek(stream_t *s, const uint8_t **restrict bufp, size_t len)
{
stream_priv_t *priv = (stream_priv_t *)s;
- block_t *peek = priv->peek;
- if (peek == NULL)
+ if (priv->peek == NULL)
+ {
+ priv->peek = priv->block;
+ priv->block = NULL;
+ }
+
+ if (priv->peek == NULL)
{
- peek = block_Alloc(len);
+ block_t *peek = block_Alloc(len);
if (unlikely(peek == NULL))
return VLC_ENOMEM;
@@ -430,11 +479,11 @@ ssize_t stream_Peek(stream_t *s, const uint8_t **restrict bufp, size_t len)
return ret;
}
- if (peek->i_buffer < len)
+ if (priv->peek->i_buffer < len)
{
- size_t avail = peek->i_buffer;
+ size_t avail = priv->peek->i_buffer;
- peek = block_TryRealloc(peek, 0, len);
+ block_t *peek = block_TryRealloc(priv->peek, 0, len);
if (unlikely(peek == NULL))
return VLC_ENOMEM;
@@ -449,7 +498,7 @@ ssize_t stream_Peek(stream_t *s, const uint8_t **restrict bufp, size_t len)
}
/* Nothing to do */
- *bufp = peek->p_buffer;
+ *bufp = priv->peek->p_buffer;
return len;
}
@@ -463,6 +512,16 @@ block_t *stream_ReadBlock(stream_t *s)
block = priv->peek;
priv->peek = NULL;
}
+ else if (priv->block != NULL)
+ {
+ block = priv->block;
+ priv->block = NULL;
+ }
+ else if (s->pf_block != NULL)
+ {
+ priv->eof = false;
+ block = s->pf_block(s, &priv->eof);
+ }
else
{
if (vlc_killed())
@@ -553,6 +612,12 @@ int stream_Seek(stream_t *s, uint64_t offset)
block_Release(peek);
}
+ if (priv->block != NULL)
+ {
+ block_Release(priv->block);
+ priv->block = NULL;
+ }
+
return VLC_SUCCESS;
}
@@ -592,6 +657,13 @@ int stream_vaControl(stream_t *s, int cmd, va_list args)
block_Release(priv->peek);
priv->peek = NULL;
}
+
+ if (priv->block != NULL)
+ {
+ block_Release(priv->block);
+ priv->block = NULL;
+ }
+
return VLC_SUCCESS;
}
More information about the vlc-commits
mailing list