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