[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