[vlc-devel] [PATCH 4/8] dash: added blockbuffer

Hugo Beauzée-Luyssen beauze.h at gmail.com
Sun Feb 5 22:22:07 CET 2012


On Sun, Feb 5, 2012 at 10:34 AM, Christopher Mueller
<christopher.mueller at itec.aau.at> wrote:
> ---
>  modules/stream_filter/dash/Modules.am              |    3 +
>  modules/stream_filter/dash/buffer/BlockBuffer.cpp  |  196 ++++++++++++++++++++
>  modules/stream_filter/dash/buffer/BlockBuffer.h    |   73 ++++++++
>  .../stream_filter/dash/buffer/IBufferObserver.h    |   42 ++++
>  4 files changed, 314 insertions(+), 0 deletions(-)
>  create mode 100644 modules/stream_filter/dash/buffer/BlockBuffer.cpp
>  create mode 100644 modules/stream_filter/dash/buffer/BlockBuffer.h
>  create mode 100644 modules/stream_filter/dash/buffer/IBufferObserver.h
>
> diff --git a/modules/stream_filter/dash/Modules.am b/modules/stream_filter/dash/Modules.am
> index fdc1076..00fb071 100644
> --- a/modules/stream_filter/dash/Modules.am
> +++ b/modules/stream_filter/dash/Modules.am
> @@ -9,6 +9,9 @@ SOURCES_stream_filter_dash = \
>     adaptationlogic/IDownloadRateObserver.h \
>     adaptationlogic/RateBasedAdaptationLogic.h \
>     adaptationlogic/RateBasedAdaptationLogic.cpp \
> +    buffer/BlockBuffer.cpp \
> +    buffer/BlockBuffer.h \
> +    buffer/IBufferObserver.h \
>     exceptions/EOFException.h \
>     http/Chunk.cpp \
>     http/Chunk.h \
> diff --git a/modules/stream_filter/dash/buffer/BlockBuffer.cpp b/modules/stream_filter/dash/buffer/BlockBuffer.cpp
> new file mode 100644
> index 0000000..a3b28b4
> --- /dev/null
> +++ b/modules/stream_filter/dash/buffer/BlockBuffer.cpp
> @@ -0,0 +1,196 @@
> +/*
> + * BlockBuffer.cpp
> + *****************************************************************************
> + * Copyright (C) 2010 - 2011 Klagenfurt University
> + *
> + * Created on: Aug 10, 2010
> + * Authors: Christopher Mueller <christopher.mueller at itec.uni-klu.ac.at>
> + *          Christian Timmerer  <christian.timmerer at itec.uni-klu.ac.at>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU Lesser General Public License as published
> + * by the Free Software Foundation; either version 2.1 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
> + *****************************************************************************/
> +
> +#include "buffer/BlockBuffer.h"
> +
> +using namespace dash::buffer;
> +
> +BlockBuffer::BlockBuffer    (stream_t *stream) :
> +             sizeMilliSec   (0),
> +             sizeBytes      (0),
> +             stream         (stream),
> +             isEOF          (false)
> +
> +{
> +    this->capacityMilliSec  = var_InheritInteger(stream, "dash-bufferSize") * 1000;
> +

If this value is 0, BlockBuffer::notify will try to divide by zero.
Also, you should probably check for inconsistant value, such as
negative ones.

> +    block_BytestreamInit(&this->buffer);
> +    vlc_mutex_init(&this->monitorMutex);
> +    vlc_cond_init(&this->empty);
> +    vlc_cond_init(&this->full);
> +}
> +BlockBuffer::~BlockBuffer   ()
> +{
> +    std::cout << "Delete buffer" << std::endl;
> +    block_BytestreamRelease(&this->buffer);
> +    vlc_mutex_destroy(&this->monitorMutex);
> +    vlc_cond_destroy(&this->empty);
> +    vlc_cond_destroy(&this->full);
> +}
> +
> +int     BlockBuffer::peek                 (const uint8_t **pp_peek, unsigned int len)
> +{
> +    vlc_mutex_lock(&this->monitorMutex);
> +
> +    while(this->sizeBytes == 0 && !this->isEOF)
> +        vlc_cond_wait(&this->full, &this->monitorMutex);
> +
> +    if(this->sizeBytes == 0)
> +    {
> +        vlc_cond_signal(&this->empty);
> +        vlc_mutex_unlock(&this->monitorMutex);
> +        return 0;
> +    }
> +
> +    int     ret     = len > this->sizeBytes ? this->sizeBytes : len;
> +    uint8_t *peek   = new uint8_t[ret];

This will leak. Also if you are allocating a value that is supposed to
be freed by VLC, you must use malloc(), as vlc will use free()

> +
> +    std::cout << "Peek Bytes: " << ret << " from buffer length: " << this->sizeBytes << std::endl;
> +
> +    block_PeekBytes(&this->buffer, peek, ret);
> +    *pp_peek = peek;
> +
> +    std::cout << "Buffer length Sec: " << this->sizeMilliSec << " Bytes: " << this->sizeBytes<< std::endl;
> +    vlc_mutex_unlock(&this->monitorMutex);
> +    return ret;
> +}
> +int     BlockBuffer::get                  (void *p_data, unsigned int len)
> +{
> +    vlc_mutex_lock(&this->monitorMutex);
> +
> +    while(this->sizeBytes == 0 && !this->isEOF)
> +        vlc_cond_wait(&this->full, &this->monitorMutex);
> +
> +    if(this->sizeBytes == 0)
> +    {
> +        vlc_cond_signal(&this->empty);
> +        vlc_mutex_unlock(&this->monitorMutex);
> +        return 0;
> +    }
> +
> +    int ret = len > this->sizeBytes ? this->sizeBytes : len;
> +
> +    this->reduceBufferMilliSec(ret);
> +
> +    std::cout << "Get Bytes: " << ret << " from buffer length: " << this->sizeBytes << std::endl;
> +
> +    block_GetBytes(&this->buffer, (uint8_t *)p_data, ret);
> +
> +    this->sizeBytes -= ret;
> +
> +    if(this->sizeBytes == 0)
> +        this->sizeMilliSec = 0;
> +
> +    std::cout << "Buffer length: " << this->sizeMilliSec << " Bytes: " << this->sizeBytes << std::endl;
> +
> +    vlc_cond_signal(&this->empty);
> +    vlc_mutex_unlock(&this->monitorMutex);
> +    return ret;
> +}
> +void    BlockBuffer::put                  (block_t *block)
> +{
> +    vlc_mutex_lock(&this->monitorMutex);
> +
> +    while(this->sizeMilliSec >= this->capacityMilliSec && !this->isEOF)
> +        vlc_cond_wait(&this->empty, &this->monitorMutex);
> +
> +    if(this->isEOF)
> +    {
> +        vlc_cond_signal(&this->full);
> +        vlc_mutex_unlock(&this->monitorMutex);
> +        return;
> +    }
> +
> +    std::cout << "Put MilliSec: " << block->i_length << " Bytes: " << block->i_buffer << " into buffer" << std::endl;
> +    this->sizeMilliSec   += block->i_length;
> +    this->sizeBytes += block->i_buffer;
> +
> +    block_BytestreamPush(&this->buffer, block);
> +
> +    std::cout << "Buffer length: " << this->sizeMilliSec << " Bytes: " << this->sizeBytes << std::endl;
> +    vlc_cond_signal(&this->full);
> +    vlc_mutex_unlock(&this->monitorMutex);
> +}
> +void    BlockBuffer::setEOF               (bool value)
> +{
> +    vlc_mutex_lock(&this->monitorMutex);
> +    this->isEOF = value;
> +    vlc_cond_signal(&this->empty);
> +    vlc_cond_signal(&this->full);
> +    vlc_mutex_unlock(&this->monitorMutex);
> +}
> +bool    BlockBuffer::getEOF               ()
> +{
> +    vlc_mutex_lock(&this->monitorMutex);
> +    bool ret = this->isEOF;
> +    vlc_mutex_unlock(&this->monitorMutex);
> +    return ret;
> +}
> +void    BlockBuffer::attach               (IBufferObserver *observer)
> +{
> +    this->bufferObservers.push_back(observer);
> +}
> +void    BlockBuffer::notify               ()
> +{
> +    for(size_t i = 0; i < this->bufferObservers.size(); i++)
> +        this->bufferObservers.at(i)->bufferLevelChanged(this->sizeMilliSec, this->sizeMilliSec / this->capacityMilliSec);
> +}
> +void    BlockBuffer::reduceBufferMilliSec (size_t bytes)
> +{
> +    size_t  pos = 0;
> +    mtime_t sec = 0;
> +
> +    block_t *block = this->buffer.p_block;
> +
> +    if(bytes <= (block->i_buffer - this->buffer.i_offset))
> +    {
> +        pos = bytes;
> +        sec = (block->i_length / block->i_buffer) * bytes;
> +    }
> +    else
> +    {
> +        pos = block->i_buffer;
> +        sec = (block->i_length / block->i_buffer) * (block->i_buffer - this->buffer.i_offset);
> +    }
> +
> +    while(pos < bytes)
> +    {
> +        block = this->buffer.p_block->p_next;
> +        if((bytes - pos) <= (block->i_buffer - this->buffer.i_offset))
> +        {
> +            pos = bytes;
> +            sec += (block->i_length/ block->i_buffer) * (bytes - pos);
> +        }
> +        else
> +        {
> +            pos += block->i_buffer;
> +            sec += block->i_length;
> +        }
> +    }
> +
> +    this->sizeMilliSec -= sec;
> +
> +    if(this->sizeMilliSec < 0)
> +        this->sizeMilliSec = 0;
> +}
> diff --git a/modules/stream_filter/dash/buffer/BlockBuffer.h b/modules/stream_filter/dash/buffer/BlockBuffer.h
> new file mode 100644
> index 0000000..d1035e3
> --- /dev/null
> +++ b/modules/stream_filter/dash/buffer/BlockBuffer.h
> @@ -0,0 +1,73 @@
> +/*
> + * BlockBuffer.h
> + *****************************************************************************
> + * Copyright (C) 2010 - 2011 Klagenfurt University
> + *
> + * Created on: Aug 10, 2010
> + * Authors: Christopher Mueller <christopher.mueller at itec.uni-klu.ac.at>
> + *          Christian Timmerer  <christian.timmerer at itec.uni-klu.ac.at>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU Lesser General Public License as published
> + * by the Free Software Foundation; either version 2.1 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
> + *****************************************************************************/
> +
> +#ifndef BLOCKBUFFER_H_
> +#define BLOCKBUFFER_H_
> +
> +#include "buffer/IBufferObserver.h"
> +
> +#include <vlc_stream.h>
> +#include <vlc_block_helper.h>
> +#include <vector>
> +
> +#include <iostream>
> +
> +namespace dash
> +{
> +    namespace buffer
> +    {
> +        class BlockBuffer
> +        {
> +            public:
> +                BlockBuffer           (stream_t *stream);
> +                virtual ~BlockBuffer  ();
> +
> +                void    put         (block_t *block);
> +                int     get         (void *p_data, unsigned int len);
> +                int     peek        (const uint8_t **pp_peek, unsigned int i_peek);
> +                void    setEOF      (bool value);
> +                bool    getEOF      ();
> +                mtime_t sizeLeft    ();
> +                void    attach      (IBufferObserver *observer);
> +                void    notify      ();
> +
> +            private:
> +                mtime_t             capacityMilliSec;
> +                mtime_t             sizeMilliSec;
> +                size_t              sizeBytes;
> +                vlc_mutex_t         monitorMutex;
> +                vlc_cond_t          empty;
> +                vlc_cond_t          full;
> +                stream_t            *stream;
> +                bool                isEOF;
> +                block_bytestream_t  buffer;
> +
> +                std::vector<IBufferObserver *> bufferObservers;
> +
> +                void reduceBufferMilliSec(size_t bytes);
> +        };
> +    }
> +}
> +
> +#endif /* BLOCKBUFFER_H_ */
> diff --git a/modules/stream_filter/dash/buffer/IBufferObserver.h b/modules/stream_filter/dash/buffer/IBufferObserver.h
> new file mode 100644
> index 0000000..b2a6315
> --- /dev/null
> +++ b/modules/stream_filter/dash/buffer/IBufferObserver.h
> @@ -0,0 +1,42 @@
> +/*
> + * IBufferObserver.h
> + *****************************************************************************
> + * Copyright (C) 2010 - 2011 Klagenfurt University
> + *
> + * Created on: Aug 10, 2010
> + * Authors: Christopher Mueller <christopher.mueller at itec.uni-klu.ac.at>
> + *          Christian Timmerer  <christian.timmerer at itec.uni-klu.ac.at>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU Lesser General Public License as published
> + * by the Free Software Foundation; either version 2.1 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
> + *****************************************************************************/
> +
> +#ifndef IBUFFEROBSERVER_H_
> +#define IBUFFEROBSERVER_H_
> +
> +#include <vlc_common.h>
> +
> +namespace dash
> +{
> +    namespace buffer
> +    {
> +        class IBufferObserver
> +        {
> +            public:

This interface is missing a virtual destructor.

> +                virtual void bufferLevelChanged(mtime_t bufferedSeconds, int bufferedPercent) = 0;
> +        };
> +    }
> +}
> +
> +#endif /* IBUFFEROBSERVER_H_ */
> --
> 1.7.0.4
>
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> http://mailman.videolan.org/listinfo/vlc-devel



-- 
Hugo Beauzée-Luyssen



More information about the vlc-devel mailing list