[x265] [PATCH] Tcombitstream: Encoded Bit stream storage (fifo) moved from std::vector to Non STL Class

Steve Borho steve at borho.org
Tue Oct 1 20:33:09 CEST 2013


On Mon, Sep 30, 2013 at 5:31 AM, Gopu Govindaswamy <
gopu at multicorewareinc.com> wrote:

> # HG changeset patch
> # User Gopu Govindaswamy <gopu at multicorewareinc.com>
> # Date 1380537103 -19800
> # Node ID 0f3aa299ee86c391135b5b1315094d5dc14341da
> # Parent  55edc34e253c14d3eccb83a7d1db43774349ff9a
> Tcombitstream: Encoded Bit stream storage (fifo) moved from std::vector to
> Non STL Class
>
> 1.Removed std::vector Class from Tcombitstream
> 2.Removed std::search_n algorithm from Tcombitstream
> 3.Implemented fifo using Pointers to an array  - Encoded Bit stream storage
> 4.insert emulation_prevention_three_byte: check the emulates and insert
> the emulation_prevention_three_byte
>   while pushing the encoded bit stream into fifo, this will avoid the
> search_n algorithm usage
>

I get decoder assertions when I have this patch applied, I can't push this.

It would perhaps be useful to split this into two patches, the first
replaces std::vector usage with malloc/memcpy and the second optimizes away
the emulation checks


diff -r 55edc34e253c -r 0f3aa299ee86 source/Lib/TLibCommon/TComBitStream.cpp
> --- a/source/Lib/TLibCommon/TComBitStream.cpp   Sat Sep 28 22:54:44 2013
> -0500
> +++ b/source/Lib/TLibCommon/TComBitStream.cpp   Mon Sep 30 16:01:43 2013
> +0530
> @@ -41,6 +41,7 @@
>  #include <string.h>
>  #include <memory.h>
>
> +#include "common.h"
>  using namespace std;
>  using namespace x265;
>
> @@ -53,13 +54,13 @@
>
>  TComOutputBitstream::TComOutputBitstream()
>  {
> -    m_fifo = new vector<uint8_t>;
> +    m_fifo = (uint8_t *)X265_MALLOC(uint8_t, MIN_FIFO_SIZE);
>      clear();
>  }
>
>  TComOutputBitstream::~TComOutputBitstream()
>  {
> -    delete m_fifo;
> +    X265_FREE(m_fifo);
>  }
>
>  //
> ====================================================================================================================
> @@ -68,19 +69,23 @@
>
>  char* TComOutputBitstream::getByteStream() const
>  {
> -    return (char*)&m_fifo->front();
> +    return (char*)m_fifo;
>  }
>
>  UInt TComOutputBitstream::getByteStreamLength()
>  {
> -    return UInt(m_fifo->size());
> +    return m_fsize;
>  }
>
>  void TComOutputBitstream::clear()
>  {
> -    m_fifo->clear();
>      m_held_bits = 0;
>      m_num_held_bits = 0;
> +
> +    m_fsize = 0;
> +    buffsize = MIN_FIFO_SIZE;
> +    m_countStartCodeEmulations = 0;
> +    m_bitstreamsize = 0;
>  }
>
>  void TComOutputBitstream::write(UInt uiBits, UInt uiNumberOfBits)
> @@ -117,10 +122,10 @@
>
>      switch (num_total_bits >> 3)
>      {
> -    case 4: m_fifo->push_back(write_bits >> 24);
> -    case 3: m_fifo->push_back(write_bits >> 16);
> -    case 2: m_fifo->push_back(write_bits >> 8);
> -    case 1: m_fifo->push_back(write_bits);
> +    case 4: push_back(write_bits >> 24);
> +    case 3: push_back(write_bits >> 16);
> +    case 2: push_back(write_bits >> 8);
> +    case 1: push_back(write_bits);
>      }
>
>      m_held_bits = next_held_bits;
> @@ -140,11 +145,81 @@
>      {
>          return;
>      }
> -    m_fifo->push_back(m_held_bits);
> +    push_back(m_held_bits);
>      m_held_bits = 0;
>      m_num_held_bits = 0;
>  }
>
> +void TComOutputBitstream::push_back(uint8_t val)
> +{
> +    static const char emulation_prevention_three_byte[] = { 3 };
> +
> +    /* Chenck FIFO Size if not reached MIN_FIFO_SIZE and Check Allocated
> m_fifo Buffer
> +    before push the encoded bit stream to m_fifo */
> +    if (m_fsize < buffsize && m_fifo)
> +    {
> +        /* 7.4.1 ... find the next emulated 00 00 {00,01,02,03}
> +        *  if not found, continue to write remaining bytes out,
> +        *  otherwise, write all non-emulated bytes out
> +        *  insert emulation_prevention_three_byte and continue
> +        *  NOTE : if next emulated is 00 00 03 then not inserting the
> emulation_prevention_three_byte
> +        */
> +        if (m_fsize > 3 && (val == 0 || val == 1 || val == 2) &&
> m_fifo[m_fsize - 1] == 0 && m_fifo[m_fsize - 2] == 0)
> +        {
> +            m_fifo[m_fsize] = emulation_prevention_three_byte[0];
> +            m_fifo[m_fsize + 1] = val;
> +            m_countStartCodeEmulations++;
> +            m_fsize++;
> +        }
> +        else
> +        {
> +            m_fifo[m_fsize] = val;
> +        }
> +        m_fsize++;
> +    }
> +    else
> +    {
> +        buffsize += MIN_FIFO_SIZE;
> +
> +        /**  FIFO size is Reached into MIN_FIFO_SIZE then Reallocate the
> FIFO and Copy the fifo to new memory
> +        location and continue to push encoded bit streams */
> +        uint8_t *temp = (uint8_t *)X265_MALLOC(uint8_t,buffsize);
> +
> +        /* check Allocated buffer before copy the encoder bitstream and
> push into FIFO */
> +        if (temp)
> +        {
> +            ::memcpy(temp, m_fifo, m_fsize);
> +
> +            /* 7.4.1 ... find the next emulated 00 00 {00,01,02,03}
> +            *  if not found, continue to write remaining bytes out,
> +            *  otherwise, write all non-emulated bytes out
> +            *  insert emulation_prevention_three_byte and continue
> +            *  NOTE : if next emulated is 00 00 03 then not inserting the
> emulation_prevention_three_byte
> +            */
> +            if (m_fsize > 3 && (temp[m_fsize] == 0 || temp[m_fsize] == 1
> || temp[m_fsize] == 2)
> +                && m_fifo[m_fsize - 1] == 0 && m_fifo[m_fsize - 2] == 0)
> +            {
> +                temp[m_fsize] = emulation_prevention_three_byte[0];
> +                temp[m_fsize + 1] = val;
> +                m_countStartCodeEmulations++;
> +                m_fsize++;
> +            }
> +            else
> +            {
> +                temp[m_fsize] = val;
> +            }
> +            m_fsize++;
> +            X265_FREE(m_fifo);
> +
> +            /** point the reallocated buffer from temp to fifo, this can
> be free'd in Distructor */
> +            m_fifo = temp;
> +        }
> +    }
> +
> +    /* Actual Encoded bitstream size without Emulation_prevention byte */
> +    m_bitstreamsize++;
> +}
> +
>  /**
>   - add substream to the end of the current bitstream
>   .
> @@ -154,13 +229,13 @@
>  {
>      UInt uiNumBits = pcSubstream->getNumberOfWrittenBits();
>
> -    const vector<uint8_t>& rbsp = pcSubstream->getFIFO();
> -
> -    for (vector<uint8_t>::const_iterator it = rbsp.begin(); it !=
> rbsp.end(); )
> +    const uint8_t* rbsp = pcSubstream->getFIFO();
> +
> +    for (UInt count = 0; count < pcSubstream->m_fsize; count++ )
>      {
> -        write(*it++, 8);
> +        write(rbsp[count], 8);
>      }
> -
> +
>      if (uiNumBits & 0x7)
>      {
>          write(pcSubstream->getHeldBits() >> (8 - (uiNumBits & 0x7)),
> uiNumBits & 0x7);
> @@ -173,39 +248,4 @@
>      writeAlignZero();
>  }
>
> -int TComOutputBitstream::countStartCodeEmulations()
> -{
> -    UInt cnt = 0;
> -
> -    vector<uint8_t>& rbsp   = getFIFO();
> -    for (vector<uint8_t>::iterator it = rbsp.begin(); it != rbsp.end(); )
> -    {
> -        vector<uint8_t>::iterator found = it;
> -        do
> -        {
> -            // find the next emulated 00 00 {00,01,02,03}
> -            // NB, end()-1, prevents finding a trailing two byte sequence
> -            found = search_n(found, rbsp.end() - 1, 2, 0);
> -            found++;
> -            // if not found, found == end, otherwise found = second zero
> byte
> -            if (found == rbsp.end())
> -            {
> -                break;
> -            }
> -            if (*(++found) <= 3)
> -            {
> -                break;
> -            }
> -        }
> -        while (true);
> -        it = found;
> -        if (found != rbsp.end())
> -        {
> -            cnt++;
> -        }
> -    }
> -
> -    return cnt;
> -}
> -
>  //! \}
> diff -r 55edc34e253c -r 0f3aa299ee86 source/Lib/TLibCommon/TComBitStream.h
> --- a/source/Lib/TLibCommon/TComBitStream.h     Sat Sep 28 22:54:44 2013
> -0500
> +++ b/source/Lib/TLibCommon/TComBitStream.h     Mon Sep 30 16:01:43 2013
> +0530
> @@ -74,16 +74,7 @@
>   * bytestream.
>   */
>  class TComOutputBitstream : public TComBitIf
> -{
> -    /**
> -     * FIFO for storage of bytes.  Use:
> -     *  - fifo.push_back(x) to append words
> -     *  - fifo.clear() to empty the FIFO
> -     *  - &fifo.front() to get a pointer to the data array.
> -     *    NB, this pointer is only valid until the next
> push_back()/clear()
> -     */
> -    std::vector<uint8_t> *m_fifo;
> -
> +{
>      UInt m_num_held_bits; /// number of bits not flushed to bytestream.
>      UChar m_held_bits; /// the bits held and not flushed to bytestream.
>      /// this value is always msb-aligned, bigendian.
> @@ -94,6 +85,25 @@
>      TComOutputBitstream();
>      ~TComOutputBitstream();
>
> +    /**
> +    * FIFO for storage of bytes.  Use:
> +    *  - push_back(x) to append words
> +    *    NB, this pointer is only valid until the next push_back()/Free()
> +    */
> +    uint8_t *m_fifo;
> +
> +    /** hold the Number of bytes pushed into the fifo including
> emulation_prevention_three_byte */
> +    UInt    m_fsize;
> +
> +    /** hold the FIFO Size and this can be used to reallocate the fifo
> size */
> +    UInt    buffsize;
> +
> +    /** hold the number of emulation_prevention_three_byte counts are in
> Encoded bit streams */
> +    UInt    m_countStartCodeEmulations;
> +
> +    /** Actual size of the Encoded bit stream that excluded the
> emulation_prevention_three_byte */
> +    UInt    m_bitstreamsize;
> +
>      // interface for encoding
>
>      /**
> @@ -110,15 +120,18 @@
>
>      /** this function should never be called */
>      void resetBits() { assert(0); }
> +
> +    /** Push Encoded bit stream into FIFO */
> +    void push_back(uint8_t val);
>
>      // utility functions
> -
> +
>      /**
> -     * Return a pointer to the start of the byte-stream buffer.
> -     * Pointer is valid until the next write/flush/reset call.
> -     * NB, data is arranged such that subsequent bytes in the
> -     * bytestream are stored in ascending addresses.
> -     */
> +    * Return a pointer to the start of the byte-stream buffer.
> +    * Pointer is valid until the next write/flush/reset call.
> +    * NB, data is arranged such that subsequent bytes in the
> +    * bytestream are stored in ascending addresses.
> +    */
>      char* getByteStream() const;
>
>      /**
> @@ -140,23 +153,24 @@
>      /**
>       * Return the number of bits that have been written since the last
> clear()
>       */
> -    UInt getNumberOfWrittenBits() const { return UInt(m_fifo->size()) * 8
> + m_num_held_bits; }
> +    UInt getNumberOfWrittenBits() const { return m_bitstreamsize * 8 +
> m_num_held_bits; }
>
>      /**
>       * Return a reference to the internal fifo
>       */
> -    std::vector<uint8_t>& getFIFO() { return *m_fifo; }
> +    uint8_t* getFIFO() { return m_fifo; }
>
>      UChar getHeldBits()          { return m_held_bits; }
>
>      /** Return a reference to the internal fifo */
> -    std::vector<uint8_t>& getFIFO() const { return *m_fifo; }
> +    uint8_t* getFIFO() const { return m_fifo; }
>
>      void          addSubstream(TComOutputBitstream* pcSubstream);
>      void writeByteAlignment();
>
>      //! returns the number of start code emulations contained in the
> current buffer
> -    int countStartCodeEmulations();
> +    int countStartCodeEmulations( ) { return m_countStartCodeEmulations; }
> +
>  };
>  }
>  //! \}
> diff -r 55edc34e253c -r 0f3aa299ee86 source/Lib/TLibEncoder/NALwrite.cpp
> --- a/source/Lib/TLibEncoder/NALwrite.cpp       Sat Sep 28 22:54:44 2013
> -0500
> +++ b/source/Lib/TLibEncoder/NALwrite.cpp       Mon Sep 30 16:01:43 2013
> +0530
> @@ -67,67 +67,17 @@
>      out = (uint8_t *) malloc(packetSize);
>      ::memcpy(out, bsNALUHeader.getByteStream(), packetSize);
>
> -    /* write out rsbp_byte's, inserting any required
> -     * emulation_prevention_three_byte's */
> -
> -    /* 7.4.1 ...
> -     * emulation_prevention_three_byte is a byte equal to 0x03. When an
> -     * emulation_prevention_three_byte is present in the NAL unit, it
> shall be
> -     * discarded by the decoding process.
> -     * The last byte of the NAL unit shall not be equal to 0x00.
> -     * Within the NAL unit, the following three-byte sequences shall not
> occur at
> -     * any byte-aligned position:
> -     *  - 0x000000
> -     *  - 0x000001
> -     *  - 0x000002
> -     * Within the NAL unit, any four-byte sequence that starts with
> 0x000003
> -     * other than the following sequences shall not occur at any
> byte-aligned
> -     * position:
> -     *  - 0x00000300
> -     *  - 0x00000301
> -     *  - 0x00000302
> -     *  - 0x00000303
> -     */
> -    vector<uint8_t>& rbsp   = nalu.m_Bitstream.getFIFO();
> -
> -    for (vector<uint8_t>::iterator it = rbsp.begin(); it != rbsp.end(); )
> -    {
> -        /* 1) find the next emulated 00 00 {00,01,02,03}
> -         * 2a) if not found, write all remaining bytes out, stop.
> -         * 2b) otherwise, write all non-emulated bytes out
> -         * 3) insert emulation_prevention_three_byte
> -         */
> -        vector<uint8_t>::iterator found = it;
> -        do
> -        {
> -            /* NB, end()-1, prevents finding a trailing two byte sequence
> */
> -            found = search_n(found, rbsp.end() - 1, 2, 0);
> -            found++;
> -            /* if not found, found == end, otherwise found = second zero
> byte */
> -            if (found == rbsp.end())
> -                break;
> -            if (*(++found) <= 3)
> -                break;
> -        }
> -        while (true);
> -
> -        it = found;
> -        if (found != rbsp.end())
> -        {
> -            it = rbsp.insert(found, emulation_prevention_three_byte[0]);
> -        }
> -    }
>      UInt i = packetSize;
> -    out = (uint8_t *) realloc (out, (rbsp.end() - rbsp.begin()) + 4 );
> -    memcpy(out + packetSize, &(*rbsp.begin()), rbsp.end() - rbsp.begin());
> -    packetSize += rbsp.end() - rbsp.begin();
> +    out = (uint8_t *) realloc (out, nalu.m_Bitstream.m_fsize + 4 );
> +    memcpy(out + packetSize, nalu.m_Bitstream.m_fifo,
> nalu.m_Bitstream.m_fsize);
> +    packetSize += nalu.m_Bitstream.m_fsize;
>
>      /* 7.4.1.1
>       * ... when the last byte of the RBSP data is equal to 0x00 (which can
>       * only occur when the RBSP ends in a cabac_zero_word), a final byte
> equal
>       * to 0x03 is appended to the end of the data.
>       */
> -    if (rbsp.back() == 0x00)
> +    if (out[packetSize - 1] == 0x00)
>      {
>          out[i] = 3;
>          packetSize += 1;
> diff -r 55edc34e253c -r 0f3aa299ee86 source/common/common.h
> --- a/source/common/common.h    Sat Sep 28 22:54:44 2013 -0500
> +++ b/source/common/common.h    Mon Sep 30 16:01:43 2013 +0530
> @@ -96,6 +96,7 @@
>  #define X265_MAX4(a, b, c, d) X265_MAX((a), X265_MAX3((b), (c), (d)))
>  #define QP_BD_OFFSET (6*(X265_DEPTH-8))
>  #define MAX_NAL_UNITS 5
> +#define MIN_FIFO_SIZE 1000
>
>  #define CHECKED_MALLOC(var, type, count)\
>  {\
> _______________________________________________
> x265-devel mailing list
> x265-devel at videolan.org
> https://mailman.videolan.org/listinfo/x265-devel
>



-- 
Steve Borho
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20131001/4676429f/attachment-0001.html>


More information about the x265-devel mailing list