[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