bitstream.c
上传用户:aoeyumen
上传日期:2007-01-06
资源大小:3329k
文件大小:5k
源码类别:

DVD

开发平台:

Unix_Linux

  1. /* 
  2.  *  bitstream.c
  3.  *
  4.  * Copyright (C) Aaron Holtzman - Dec 1999
  5.  *
  6.  *  This file is part of mpeg2dec, a free MPEG-2 video decoder
  7.  *
  8.  *  mpeg2dec is free software; you can redistribute it and/or modify
  9.  *  it under the terms of the GNU General Public License as published by
  10.  *  the Free Software Foundation; either version 2, or (at your option)
  11.  *  any later version.
  12.  *   
  13.  *  mpeg2dec is distributed in the hope that it will be useful,
  14.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.  *  GNU General Public License for more details.
  17.  *   
  18.  *  You should have received a copy of the GNU General Public License
  19.  *  along with GNU Make; see the file COPYING.  If not, write to
  20.  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
  21.  *
  22.  */
  23. #include <stdlib.h>
  24. #include <stdio.h>
  25. #include "mpeg2.h"
  26. #include "mpeg2_internal.h"
  27. #include "bitstream.h"
  28. uint_32 bits_left;
  29. uint_32 current_word;
  30. uint_32 next_word;
  31. uint_32 *buffer_start;
  32. uint_32 *buffer_end;
  33. void (*bitstream_fill_buffer)(uint_32**,uint_32**);
  34. uint_32 mask[33] = 
  35. {
  36. 0x0,
  37. 0x00000001, 0x00000003, 0x00000007, 0x0000000f, 
  38. 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff, 
  39. 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff, 
  40. 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff, 
  41. 0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff, 
  42. 0x00ffffff, 0x003fffff, 0x007fffff, 0x00ffffff, 
  43. 0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff, 
  44. 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff, 
  45. };
  46. uint_32 fast_count=0;
  47. uint_32 slow_count=0;
  48. inline uint_32 
  49. bitstream_show(uint_32 num_bits)
  50. {
  51. uint_32 result;
  52. //fprintf(stderr,"(show) buffer_start %p, buffer_end %p, current_word 0x%08x, next_word 0x%08x, num_bits %d, bits_left %dn",buffer_start,buffer_end,current_word,next_word,num_bits,bits_left);
  53. //fast path
  54. if(num_bits < bits_left)
  55. {
  56. //fast_count++;
  57. //printf("fast_count = %d slow_count = %d total = %dn",fast_count,slow_count, fast_count + slow_count);
  58. return (current_word  >> (bits_left - num_bits)) & mask[num_bits];
  59. }
  60. //slow_count++;
  61. //printf("fast_count = %d slow_count = %d total = %dn",fast_count,slow_count, fast_count + slow_count);
  62. //
  63. if(num_bits == bits_left)
  64. result = current_word & mask[num_bits];
  65. else
  66. {
  67. result = (current_word  << (num_bits - bits_left)) & mask[num_bits];
  68. result |= (next_word  >> (bits_left - num_bits)) & mask[num_bits];
  69. }
  70. return result;
  71. }
  72. static inline void
  73. bitstream_fill_next()
  74. {
  75. //fprintf(stderr,"(fill) buffer_start %p, buffer_end %p, current_word 0x%08x, bits_left %dn",buffer_start,buffer_end,current_word,bits_left);
  76. next_word = *buffer_start++;
  77. next_word = swab32(next_word);
  78. if(buffer_start == buffer_end)
  79. {
  80. bitstream_fill_buffer(&buffer_start,&buffer_end);
  81. }
  82. }
  83. // Fetches 1-32 bits bitstream buffer
  84. //
  85. // Minimized the number of writes by using a bitmask. 
  86. inline uint_32
  87. bitstream_get(uint_32 num_bits)
  88. {
  89. uint_32 result;
  90. //fprintf(stderr,"(get) buffer_start %p, buffer_end %p, current_word 0x%08x, next_word 0x%08x, num_bits %d,bits_left %dn",buffer_start,buffer_end,current_word,next_word,num_bits,bits_left);
  91. //fast path
  92. if(num_bits < bits_left)
  93. return (current_word  >> (bits_left -= num_bits)) & mask[num_bits];
  94. if(num_bits == bits_left)
  95. {
  96. result = current_word & mask[num_bits];
  97. current_word = next_word;
  98. bits_left = 32;
  99. bitstream_fill_next();
  100. }
  101. else
  102. {
  103. result = (current_word  << (num_bits - bits_left)) & mask[num_bits];
  104. current_word = next_word;
  105. result |= (next_word  >> (32 - num_bits + bits_left)) & mask[num_bits];
  106. bits_left = 32 - num_bits + bits_left;
  107. bitstream_fill_next();
  108. }
  109. return result;
  110. }
  111. inline void 
  112. bitstream_flush(uint_32 num_bits)
  113. {
  114. //fprintf(stderr,"(flush) buffer_start %p, buffer_end %p, current_word 0x%08x, next_word 0x%08x, num_bits %d,bits_left %dn",buffer_start,buffer_end,current_word,next_word,num_bits,bits_left);
  115. //fast path
  116. if(num_bits < bits_left)
  117. {
  118. bits_left -= num_bits;
  119. return;
  120. }
  121. if(num_bits == bits_left)
  122. {
  123. current_word = next_word;
  124. bits_left = 32;
  125. bitstream_fill_next();
  126. }
  127. else
  128. {
  129. current_word = next_word;
  130. bits_left = 32 - num_bits + bits_left;
  131. bitstream_fill_next();
  132. }
  133. }
  134. void 
  135. bitstream_byte_align(void)
  136. {
  137. //byte align the bitstream
  138. bits_left = bits_left & ~7;
  139. if(!bits_left)
  140. {
  141. current_word = next_word;
  142. bits_left = 32;
  143. bitstream_fill_next();
  144. }
  145. }
  146. void
  147. bitstream_init(void(*fill_function)(uint_32**,uint_32**))
  148. {
  149. //fprintf(stderr,"(fill_buffer) buffer buffer_start %p, buffer_end %p, current_word 0x%08x, bits_left %dn",buffer_start,buffer_end,current_word,bits_left);
  150. // Setup the buffer fill callback 
  151. bitstream_fill_buffer = fill_function;
  152. bitstream_fill_buffer(&buffer_start,&buffer_end);
  153. bits_left = 32;
  154. current_word = *buffer_start++;
  155. current_word = swab32(current_word);
  156. next_word    = *buffer_start++;
  157. next_word    = swab32(next_word);
  158. }
  159. uint_32 bitstream_done()
  160. {
  161. //FIXME
  162. return 0;
  163. }