common.c
上传用户:jxp0626
上传日期:2007-01-08
资源大小:102k
文件大小:4k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Unix_Linux

  1. /*
  2.  * Common bit/dsp utils
  3.  * Copyright (c) 2000 Gerard Lantau.
  4.  *
  5.  * This program is free software; you can redistribute it and/or modify
  6.  * it under the terms of the GNU General Public License as published by
  7.  * the Free Software Foundation; either version 2 of the License, or
  8.  * (at your option) any later version.
  9.  *
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program; if not, write to the Free Software
  17.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  */
  19. #include <stdlib.h>
  20. #include <stdio.h>
  21. #include <string.h>
  22. #include <netinet/in.h>
  23. #include <math.h>
  24. #include "common.h"
  25. #define NDEBUG
  26. #include <assert.h>
  27. void init_put_bits(PutBitContext *s, 
  28.                    UINT8 *buffer, int buffer_size,
  29.                    void *opaque,
  30.                    void (*write_data)(void *, UINT8 *, int))
  31. {
  32.     s->buf = buffer;
  33.     s->buf_ptr = s->buf;
  34.     s->buf_end = s->buf + buffer_size;
  35.     s->bit_cnt=0;
  36.     s->bit_buf=0;
  37.     s->data_out_size = 0;
  38.     s->write_data = write_data;
  39.     s->opaque = opaque;
  40. }
  41. static void flush_buffer(PutBitContext *s)
  42. {
  43.     int size;
  44.     if (s->write_data) {
  45.         size = s->buf_ptr - s->buf;
  46.         if (size > 0)
  47.             s->write_data(s->opaque, s->buf, size);
  48.         s->buf_ptr = s->buf;
  49.         s->data_out_size += size;
  50.     }
  51. }
  52. void put_bits(PutBitContext *s, int n, unsigned int value)
  53. {
  54.     unsigned int bit_buf;
  55.     int bit_cnt;
  56.     //    printf("put_bits=%d %xn", n, value);
  57.     assert(n == 32 || value < (1U << n));
  58.     bit_buf = s->bit_buf;
  59.     bit_cnt = s->bit_cnt;
  60.     //    printf("n=%d value=%x cnt=%d buf=%xn", n, value, bit_cnt, bit_buf);
  61.     /* XXX: optimize */
  62.     if (n < (32-bit_cnt)) {
  63.         bit_buf |= value << (32 - n - bit_cnt);
  64.         bit_cnt+=n;
  65.     } else {
  66.         bit_buf |= value >> (n + bit_cnt - 32);
  67.         *(UINT32 *)s->buf_ptr = htonl(bit_buf);
  68.         //printf("bitbuf = %08xn", bit_buf);
  69.         s->buf_ptr+=4;
  70.         if (s->buf_ptr >= s->buf_end)
  71.             flush_buffer(s);
  72.         bit_cnt=bit_cnt + n - 32;
  73.         if (bit_cnt == 0) {
  74.             bit_buf = 0;
  75.         } else {
  76.             bit_buf = value << (32 - bit_cnt);
  77.         }
  78.     }
  79.     
  80.     s->bit_buf = bit_buf;
  81.     s->bit_cnt = bit_cnt;
  82. }
  83. /* return the number of bits output */
  84. long long get_bit_count(PutBitContext *s)
  85. {
  86.     return (s->buf_ptr - s->buf + s->data_out_size) * 8 + (long long)s->bit_cnt;
  87. }
  88. void align_put_bits(PutBitContext *s)
  89. {
  90.     put_bits(s,(8 - s->bit_cnt) & 7,0);
  91. }
  92. /* pad the end of the output stream with zeros */
  93. void flush_put_bits(PutBitContext *s)
  94. {
  95.     while (s->bit_cnt > 0) {
  96.         /* XXX: should test end of buffer */
  97.         *s->buf_ptr++=s->bit_buf >> 24;
  98.         s->bit_buf<<=8;
  99.         s->bit_cnt-=8;
  100.     }
  101.     flush_buffer(s);
  102.     s->bit_cnt=0;
  103.     s->bit_buf=0;
  104. }
  105. /* for jpeg : espace 0xff with 0x00 after it */
  106. void jput_bits(PutBitContext *s, int n, unsigned int value)
  107. {
  108.     unsigned int bit_buf, b;
  109.     int bit_cnt, i;
  110.     
  111.     assert(n == 32 || value < (1U << n));
  112.     bit_buf = s->bit_buf;
  113.     bit_cnt = s->bit_cnt;
  114.     //printf("n=%d value=%x cnt=%d buf=%xn", n, value, bit_cnt, bit_buf);
  115.     /* XXX: optimize */
  116.     if (n < (32-bit_cnt)) {
  117.         bit_buf |= value << (32 - n - bit_cnt);
  118.         bit_cnt+=n;
  119.     } else {
  120.         bit_buf |= value >> (n + bit_cnt - 32);
  121.         /* handle escape */
  122.         for(i=0;i<4;i++) {
  123.             b = (bit_buf >> 24);
  124.             *(s->buf_ptr++) = b;
  125.             if (b == 0xff)
  126.                 *(s->buf_ptr++) = 0;
  127.             bit_buf <<= 8;
  128.         }
  129.         /* we flush the buffer sooner to handle worst case */
  130.         if (s->buf_ptr >= (s->buf_end - 8))
  131.             flush_buffer(s);
  132.         bit_cnt=bit_cnt + n - 32;
  133.         if (bit_cnt == 0) {
  134.             bit_buf = 0;
  135.         } else {
  136.             bit_buf = value << (32 - bit_cnt);
  137.         }
  138.     }
  139.     
  140.     s->bit_buf = bit_buf;
  141.     s->bit_cnt = bit_cnt;
  142. }
  143. /* pad the end of the output stream with zeros */
  144. void jflush_put_bits(PutBitContext *s)
  145. {
  146.     unsigned int b;
  147.     while (s->bit_cnt > 0) {
  148.         b = s->bit_buf >> 24;
  149.         *s->buf_ptr++ = b;
  150.         if (b == 0xff)
  151.             *s->buf_ptr++ = 0;
  152.         s->bit_buf<<=8;
  153.         s->bit_cnt-=8;
  154.     }
  155.     flush_buffer(s);
  156.     s->bit_cnt=0;
  157.     s->bit_buf=0;
  158. }