On Mon, Sep 30, 2013 at 5:31 AM, Gopu Govindaswamy < [email protected]> wrote:
> # HG changeset patch > # User Gopu Govindaswamy <[email protected]> > # 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 > [email protected] > https://mailman.videolan.org/listinfo/x265-devel > -- Steve Borho
_______________________________________________ x265-devel mailing list [email protected] https://mailman.videolan.org/listinfo/x265-devel
