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

Hugo Beauzée-Luyssen beauze.h at gmail.com
Tue Feb 7 13:13:24 CET 2012


2012/2/7 Christopher Müller <christopher.mueller at itec.uni-klu.ac.at>:
>> Von: vlc-devel-bounces at videolan.org [mailto:vlc-devel-
>> bounces at videolan.org] Im Auftrag von Hugo Beauzée-Luyssen
>> Gesendet: Dienstag, 07. Februar 2012 12:28
>> An: Mailing list for VLC media player developers
>> Betreff: Re: [vlc-devel] [PATCH 4/8] dash: added blockbuffer
>>
>> 2012/2/6 Christopher Müller <christopher.mueller at itec.uni-klu.ac.at>:
>> > Fixed the leakage and added the include config.h.
>> >
>> >> -----Ursprüngliche Nachricht-----
>> >> Von: vlc-devel-bounces at videolan.org [mailto:vlc-devel-
>> >> bounces at videolan.org] Im Auftrag von Hugo Beauzée-Luyssen
>> >> Gesendet: Sonntag, 05. Februar 2012 22:22
>> >> An: Mailing list for VLC media player developers
>> >> Betreff: Re: [vlc-devel] [PATCH 4/8] dash: added blockbuffer
>> >>
>> >> 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
>>
>> I must have expressed myself badly, there were two problems :
>> - You are allocating a buffer that will no be freed by VLC, therefore,
>> each time peek() will be called, you will leak.
>
> So what is the correct way. Is the memory allocated? If not when do I know that I can delete the memory?
>

You have to allocate the memory once, or reallocating if a larger
buffer is needed.
Take a look at HLS sources as an example.

>> - My guess was that you assumed the buffer would be freed by VLC, in
>> which case, you would have to use malloc, not new.
>
> That is what I have assumed ;)
>

Best regards,

-- 
Hugo Beauzée-Luyssen



More information about the vlc-devel mailing list