0
|
1 /* The copyright in this software is being made available under the BSD
|
|
2 * License, included below. This software may be subject to other third party
|
|
3 * and contributor rights, including patent rights, and no such rights are
|
|
4 * granted under this license.
|
|
5 *
|
|
6 * Copyright (c) 2010-2014, ITU/ISO/IEC
|
|
7 * All rights reserved.
|
|
8 *
|
|
9 * Redistribution and use in source and binary forms, with or without
|
|
10 * modification, are permitted provided that the following conditions are met:
|
|
11 *
|
|
12 * * Redistributions of source code must retain the above copyright notice,
|
|
13 * this list of conditions and the following disclaimer.
|
|
14 * * Redistributions in binary form must reproduce the above copyright notice,
|
|
15 * this list of conditions and the following disclaimer in the documentation
|
|
16 * and/or other materials provided with the distribution.
|
|
17 * * Neither the name of the ITU/ISO/IEC nor the names of its contributors may
|
|
18 * be used to endorse or promote products derived from this software without
|
|
19 * specific prior written permission.
|
|
20 *
|
|
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
|
|
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
|
31 * THE POSSIBILITY OF SUCH DAMAGE.
|
|
32 */
|
|
33
|
|
34 /** \file TComBitStream.h
|
|
35 \brief class for handling bitstream (header)
|
|
36 */
|
|
37
|
|
38 #ifndef __TCOMBITSTREAM__
|
|
39 #define __TCOMBITSTREAM__
|
|
40
|
|
41 #if _MSC_VER > 1000
|
|
42 #pragma once
|
|
43 #endif // _MSC_VER > 1000
|
|
44
|
|
45 #include <stdint.h>
|
|
46 #include <vector>
|
|
47 #include <stdio.h>
|
|
48 #include <assert.h>
|
|
49 #include "CommonDef.h"
|
|
50
|
|
51 //! \ingroup TLibCommon
|
|
52 //! \{
|
|
53
|
|
54 // ====================================================================================================================
|
|
55 // Class definition
|
|
56 // ====================================================================================================================
|
|
57
|
|
58 /// pure virtual class for basic bit handling
|
|
59 class TComBitIf
|
|
60 {
|
|
61 public:
|
|
62 virtual Void writeAlignOne () {};
|
|
63 virtual Void writeAlignZero () {};
|
|
64 virtual Void write ( UInt uiBits, UInt uiNumberOfBits ) = 0;
|
|
65 virtual Void resetBits () = 0;
|
|
66 virtual UInt getNumberOfWrittenBits() const = 0;
|
|
67 virtual ~TComBitIf() {}
|
|
68 };
|
|
69
|
|
70 /**
|
|
71 * Model of a writable bitstream that accumulates bits to produce a
|
|
72 * bytestream.
|
|
73 */
|
|
74 class TComOutputBitstream : public TComBitIf
|
|
75 {
|
|
76 /**
|
|
77 * FIFO for storage of bytes. Use:
|
|
78 * - fifo.push_back(x) to append words
|
|
79 * - fifo.clear() to empty the FIFO
|
|
80 * - &fifo.front() to get a pointer to the data array.
|
|
81 * NB, this pointer is only valid until the next push_back()/clear()
|
|
82 */
|
|
83 std::vector<uint8_t> m_fifo;
|
|
84
|
|
85 UInt m_num_held_bits; /// number of bits not flushed to bytestream.
|
|
86 UChar m_held_bits; /// the bits held and not flushed to bytestream.
|
|
87 /// this value is always msb-aligned, bigendian.
|
|
88 public:
|
|
89 // create / destroy
|
|
90 TComOutputBitstream();
|
|
91 ~TComOutputBitstream();
|
|
92
|
|
93 // interface for encoding
|
|
94 /**
|
|
95 * append uiNumberOfBits least significant bits of uiBits to
|
|
96 * the current bitstream
|
|
97 */
|
|
98 Void write ( UInt uiBits, UInt uiNumberOfBits );
|
|
99
|
|
100 /** insert one bits until the bitstream is byte-aligned */
|
|
101 Void writeAlignOne ();
|
|
102
|
|
103 /** insert zero bits until the bitstream is byte-aligned */
|
|
104 Void writeAlignZero ();
|
|
105
|
|
106 /** this function should never be called */
|
|
107 Void resetBits() { assert(0); }
|
|
108
|
|
109 // utility functions
|
|
110
|
|
111 /**
|
|
112 * Return a pointer to the start of the byte-stream buffer.
|
|
113 * Pointer is valid until the next write/flush/reset call.
|
|
114 * NB, data is arranged such that subsequent bytes in the
|
|
115 * bytestream are stored in ascending addresses.
|
|
116 */
|
|
117 Char* getByteStream() const;
|
|
118
|
|
119 /**
|
|
120 * Return the number of valid bytes available from getByteStream()
|
|
121 */
|
|
122 UInt getByteStreamLength();
|
|
123
|
|
124 /**
|
|
125 * Reset all internal state.
|
|
126 */
|
|
127 Void clear();
|
|
128
|
|
129 /**
|
|
130 * returns the number of bits that need to be written to
|
|
131 * achieve byte alignment.
|
|
132 */
|
|
133 Int getNumBitsUntilByteAligned() { return (8 - m_num_held_bits) & 0x7; }
|
|
134
|
|
135 /**
|
|
136 * Return the number of bits that have been written since the last clear()
|
|
137 */
|
|
138 UInt getNumberOfWrittenBits() const { return UInt(m_fifo.size()) * 8 + m_num_held_bits; }
|
|
139
|
|
140 Void insertAt(const TComOutputBitstream& src, UInt pos);
|
|
141
|
|
142 /**
|
|
143 * Return a reference to the internal fifo
|
|
144 */
|
|
145 std::vector<uint8_t>& getFIFO() { return m_fifo; }
|
|
146
|
|
147 UChar getHeldBits () { return m_held_bits; }
|
|
148
|
|
149 //TComOutputBitstream& operator= (const TComOutputBitstream& src);
|
|
150 /** Return a reference to the internal fifo */
|
|
151 const std::vector<uint8_t>& getFIFO() const { return m_fifo; }
|
|
152
|
|
153 Void addSubstream ( TComOutputBitstream* pcSubstream );
|
|
154 Void writeByteAlignment();
|
|
155
|
|
156 //! returns the number of start code emulations contained in the current buffer
|
|
157 Int countStartCodeEmulations();
|
|
158 };
|
|
159
|
|
160 /**
|
|
161 * Model of an input bitstream that extracts bits from a predefined
|
|
162 * bytestream.
|
|
163 */
|
|
164 class TComInputBitstream
|
|
165 {
|
|
166 std::vector<uint8_t> *m_fifo; /// FIFO for storage of complete bytes
|
|
167 std::vector<UInt> m_emulationPreventionByteLocation;
|
|
168
|
|
169 protected:
|
|
170 UInt m_fifo_idx; /// Read index into m_fifo
|
|
171
|
|
172 UInt m_num_held_bits;
|
|
173 UChar m_held_bits;
|
|
174 UInt m_numBitsRead;
|
|
175
|
|
176 public:
|
|
177 /**
|
|
178 * Create a new bitstream reader object that reads from #buf#. Ownership
|
|
179 * of #buf# remains with the callee, although the constructed object
|
|
180 * will hold a reference to #buf#
|
|
181 */
|
|
182 TComInputBitstream(std::vector<uint8_t>* buf);
|
|
183 ~TComInputBitstream();
|
|
184
|
|
185 // interface for decoding
|
|
186 Void pseudoRead ( UInt uiNumberOfBits, UInt& ruiBits );
|
|
187 Void read ( UInt uiNumberOfBits, UInt& ruiBits );
|
|
188 Void readByte ( UInt &ruiBits )
|
|
189 {
|
|
190 assert(m_fifo_idx < m_fifo->size());
|
|
191 ruiBits = (*m_fifo)[m_fifo_idx++];
|
|
192 }
|
|
193
|
|
194 Void peekPreviousByte( UInt &byte )
|
|
195 {
|
|
196 assert(m_fifo_idx > 0);
|
|
197 byte = (*m_fifo)[m_fifo_idx - 1];
|
|
198 }
|
|
199
|
|
200 UInt readOutTrailingBits ();
|
|
201 UChar getHeldBits () { return m_held_bits; }
|
|
202 TComOutputBitstream& operator= (const TComOutputBitstream& src);
|
|
203 UInt getByteLocation ( ) { return m_fifo_idx ; }
|
|
204
|
|
205 // Peek at bits in word-storage. Used in determining if we have completed reading of current bitstream and therefore slice in LCEC.
|
|
206 UInt peekBits (UInt uiBits) { UInt tmp; pseudoRead(uiBits, tmp); return tmp; }
|
|
207
|
|
208 // utility functions
|
|
209 UInt read(UInt numberOfBits) { UInt tmp; read(numberOfBits, tmp); return tmp; }
|
|
210 UInt readByte() { UInt tmp; readByte( tmp ); return tmp; }
|
|
211 UInt getNumBitsUntilByteAligned() { return m_num_held_bits & (0x7); }
|
|
212 UInt getNumBitsLeft() { return 8*((UInt)m_fifo->size() - m_fifo_idx) + m_num_held_bits; }
|
|
213 TComInputBitstream *extractSubstream( UInt uiNumBits ); // Read the nominated number of bits, and return as a bitstream.
|
|
214 Void deleteFifo(); // Delete internal fifo of bitstream.
|
|
215 UInt getNumBitsRead() { return m_numBitsRead; }
|
|
216 UInt readByteAlignment();
|
|
217
|
|
218 Void pushEmulationPreventionByteLocation ( UInt pos ) { m_emulationPreventionByteLocation.push_back( pos ); }
|
|
219 UInt numEmulationPreventionBytesRead () { return (UInt) m_emulationPreventionByteLocation.size(); }
|
|
220 std::vector<UInt> getEmulationPreventionByteLocation () { return m_emulationPreventionByteLocation; }
|
|
221 UInt getEmulationPreventionByteLocation ( UInt idx ) { return m_emulationPreventionByteLocation[ idx ]; }
|
|
222 Void clearEmulationPreventionByteLocation() { m_emulationPreventionByteLocation.clear(); }
|
|
223 Void setEmulationPreventionByteLocation ( std::vector<UInt> vec ) { m_emulationPreventionByteLocation = vec; }
|
|
224 };
|
|
225
|
|
226 //! \}
|
|
227
|
|
228 #endif
|