[x265] [PATCH] Tcombitstream: Encoded Bit stream storage (fifo) moved from std::vector to Non STL Class
Gopu Govindaswamy
gopu at multicorewareinc.com
Mon Sep 30 12:31:53 CEST 2013
# 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
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)\
{\
More information about the x265-devel
mailing list