H264PutBits.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. /*------------------------------------------------------------------------------
  2. -- --
  3. -- This software is confidential and proprietary and may be used --
  4. -- only as expressly authorized by a licensing agreement from --
  5. -- --
  6. -- Hantro Products Oy. --
  7. -- --
  8. -- (C) COPYRIGHT 2006 HANTRO PRODUCTS OY --
  9. -- ALL RIGHTS RESERVED --
  10. -- --
  11. -- The entire notice above must be reproduced --
  12. -- on all copies and should not be removed. --
  13. -- --
  14. --------------------------------------------------------------------------------
  15. --
  16. -- Abstract : Bit stream handling
  17. --
  18. ------------------------------------------------------------------------------*/
  19. /*------------------------------------------------------------------------------
  20. 1. Include headers
  21. ------------------------------------------------------------------------------*/
  22. #include "H264PutBits.h"
  23. #include "enccommon.h"
  24. /*------------------------------------------------------------------------------
  25. 2. External compiler flags
  26. --------------------------------------------------------------------------------
  27. --------------------------------------------------------------------------------
  28. 3. Module defines
  29. ------------------------------------------------------------------------------*/
  30. /*------------------------------------------------------------------------------
  31. 4. Local function prototypes
  32. ------------------------------------------------------------------------------*/
  33. static bool_e H264BufferStatus(stream_s * stream);
  34. /*------------------------------------------------------------------------------
  35. H264PutBits
  36. Write bits to stream. For example (value=2, number=4) write 0010 to the
  37. stream. Number of bits must be < 25, otherwise overflow occur. Four
  38. bytes is maximum number of bytes to put stream and there should be at
  39. least 5 byte free space available because of byte buffer.
  40. Used only for NAL unit headers!
  41. Input stream Pointer to the stream stucture
  42. value Bit pattern
  43. number Number of bits
  44. ------------------------------------------------------------------------------*/
  45. void H264PutBits(stream_s * buffer, i32 value, i32 number)
  46. {
  47. i32 bits;
  48. u32 byteBuffer = buffer->byteBuffer;
  49. u8 *stream = buffer->stream;
  50. if(H264BufferStatus(buffer) != ENCHW_OK)
  51. {
  52. return;
  53. }
  54. TRACE_BIT_STREAM(value, number);
  55. /* Debug: value is too big */
  56. ASSERT(value < (1 << number));
  57. ASSERT(number < 25);
  58. bits = number + buffer->bufferedBits;
  59. value <<= (32 - bits);
  60. byteBuffer = byteBuffer | value;
  61. while(bits > 7)
  62. {
  63. *stream = (u8) (byteBuffer >> 24);
  64. bits -= 8;
  65. byteBuffer <<= 8;
  66. stream++;
  67. buffer->byteCnt++;
  68. }
  69. buffer->byteBuffer = byteBuffer;
  70. buffer->bufferedBits = (u8) bits;
  71. buffer->stream = stream;
  72. return;
  73. }
  74. /*------------------------------------------------------------------------------
  75. H264PutNalBits
  76. Write bits to stream. For example (value=2, number=4) write 0010 to the
  77. stream. Number of bits must be < 25, otherwise overflow occur. Four
  78. bytes is maximum number of bytes to put stream and there should be at
  79. least 5 byte free space available because of byte buffer.
  80. Used only for NAL unit RBSP data!
  81. Input stream Pointer to the stream stucture
  82. value Bit pattern
  83. number Number of bits
  84. ------------------------------------------------------------------------------*/
  85. void H264PutNalBits(stream_s * buffer, i32 value, i32 number)
  86. {
  87. i32 bits;
  88. u8 *stream = buffer->stream;
  89. u32 byteBuffer = buffer->byteBuffer;
  90. ASSERT(value < (1<<number));
  91. ASSERT(number < 25);
  92. TRACE_BIT_STREAM(value, number);
  93. bits = number + buffer->bufferedBits;
  94. byteBuffer = byteBuffer | ((u32) value << (32 - bits));
  95. while(bits > 7)
  96. {
  97. i32 zeroBytes = buffer->zeroBytes;
  98. i32 byteCnt = buffer->byteCnt;
  99. if(H264BufferStatus(buffer) != ENCHW_OK)
  100. return;
  101. *stream = (u8) (byteBuffer >> 24);
  102. byteCnt++;
  103. if((zeroBytes == 2) && (*stream < 4))
  104. {
  105. *stream++ = 3;
  106. *stream = (u8) (byteBuffer >> 24);
  107. byteCnt++;
  108. zeroBytes = 0;
  109. buffer->emulCnt++;
  110. }
  111. if(*stream == 0)
  112. zeroBytes++;
  113. else
  114. zeroBytes = 0;
  115. bits -= 8;
  116. byteBuffer <<= 8;
  117. stream++;
  118. buffer->zeroBytes = zeroBytes;
  119. buffer->byteCnt = byteCnt;
  120. buffer->stream = stream;
  121. }
  122. buffer->bufferedBits = (u8) bits;
  123. buffer->byteBuffer = byteBuffer;
  124. }
  125. /*------------------------------------------------------------------------------
  126. EncSetBuffer
  127. Set stream buffer.
  128. Input buffer Pointer to the stream_s structure.
  129. stream Pointer to stream buffer.
  130. size Size of stream buffer.
  131. ------------------------------------------------------------------------------*/
  132. bool_e H264SetBuffer(stream_s * buffer, u8 * stream, i32 size)
  133. {
  134. buffer->stream = stream;
  135. buffer->size = size;
  136. buffer->byteCnt = 0;
  137. buffer->overflow = ENCHW_NO;
  138. buffer->zeroBytes = 0;
  139. buffer->byteBuffer = 0;
  140. buffer->bufferedBits = 0;
  141. if(H264BufferStatus(buffer) != ENCHW_OK)
  142. {
  143. return ENCHW_NOK;
  144. }
  145. buffer->stream[0] = 0;
  146. buffer->stream[1] = 0;
  147. return ENCHW_OK;
  148. }
  149. /*------------------------------------------------------------------------------
  150. BufferStatus
  151. Check fullness of stream buffer.
  152. Input stream Pointer to the stream stucture.
  153. Return ENCHW_OK Buffer status is ENCHW_OK.
  154. ENCHW_NOK Buffer overflow.
  155. ------------------------------------------------------------------------------*/
  156. bool_e H264BufferStatus(stream_s * stream)
  157. {
  158. if(stream->byteCnt + 5 > stream->size)
  159. {
  160. stream->overflow = ENCHW_YES;
  161. return ENCHW_NOK;
  162. }
  163. return ENCHW_OK;
  164. }
  165. /*------------------------------------------------------------------------------
  166. H264ExpGolombUnsigned
  167. ------------------------------------------------------------------------------*/
  168. void H264ExpGolombUnsigned(stream_s * stream, u32 val)
  169. {
  170. u32 numBits = 0;
  171. val++;
  172. while(val >> ++numBits);
  173. if(numBits > 12)
  174. {
  175. u32 tmp;
  176. tmp = numBits-1;
  177. if(tmp > 24)
  178. {
  179. tmp -= 24;
  180. H264NalBits(stream, 0, 24);
  181. }
  182. H264NalBits(stream, 0, tmp);
  183. COMMENT("++");
  184. if(numBits > 24)
  185. {
  186. numBits -= 24;
  187. H264NalBits(stream, val >> numBits, 24);
  188. val = val >> numBits;
  189. }
  190. H264NalBits(stream, val, numBits);
  191. }
  192. else
  193. {
  194. H264NalBits(stream, val , 2*numBits - 1);
  195. }
  196. }
  197. /*------------------------------------------------------------------------------
  198. H264ExpGolombSigned
  199. ------------------------------------------------------------------------------*/
  200. void H264ExpGolombSigned(stream_s * stream, i32 val)
  201. {
  202. u32 tmp;
  203. if (val > 0)
  204. tmp = (u32) (2 * val - 1);
  205. else
  206. tmp = (u32) (-2 * val);
  207. H264ExpGolombUnsigned(stream, tmp);
  208. }
  209. /*------------------------------------------------------------------------------
  210. H264RbspTrailingBits
  211. Function add rbsp_stop_one_bit and p_alignment_zero_bit until next byte
  212. aligned if needed. Note that stream->stream[1] is bits in byte bufer.
  213. Input stream Pointer to the stream structure.
  214. ------------------------------------------------------------------------------*/
  215. void H264RbspTrailingBits(stream_s * stream)
  216. {
  217. H264PutNalBits(stream, 1, 1);
  218. COMMENT("rbsp_stop_one_bit");
  219. if(stream->bufferedBits > 0)
  220. {
  221. H264PutNalBits(stream, 0, 8 - stream->bufferedBits);
  222. COMMENT("bsp_alignment_zero_bit(s)");
  223. }
  224. return;
  225. }