• 2004-12-23

    读取码流的函数

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
    http://ffmpeg.blogbus.com/logs/553112.html

    讨论讨论位流(stream)的读取,其实很简单

    先看Bitstream的结构

    typedef struct
    {
     uint32_t curr;//位流访问中的当前字(32bits为一个字)
     uint32_t next;//要访问的下一个字,供跨字访问时使用
     uint32_t buf;//读bitstream的话,这个可不要
     uint32_t pos;//比特位置,在curr中读到哪一个位了
     uint32_t *tail; //位流缓冲区所指向的当前指针,读到哪一个字节
     uint32_t *start;//位流缓冲区的头
     uint32_t length;//缓冲区总的长度
    }Bitstream;

    //初始化位流结构
    static void __inline
    BitstreamInit(Bitstream * const bs,
         void *const bitstream,
         uint32_t length)
    {
     uint32_t tmp;

     bs->start = bs->tail = (uint32_t *) bitstream;

     tmp = *(uint32_t *) bitstream;
    #ifndef ARCH_IS_BIG_ENDIAN
     BSWAP(tmp);    //因为bitstream是bigendian的,所以在编译小尾程序时,需要swap一下
    #endif
     bs->curr = tmp;

     tmp = *((uint32_t *) bitstream + 1);
    #ifndef ARCH_IS_BIG_ENDIAN
     BSWAP(tmp);
    #endif
     bs->next = tmp;

     bs->buf = 0;
     bs->pos = 0; //因为还没开始读比特流,所以位置为0
     bs->length = length;
    }

    //取得将要读到的比特位数的指,不更改比特位置
    static uint32_t __inline
    BitstreamShowBits(Bitstream * const bs,
          const uint32_t bits)
    {
     //分析将要读出的比特位数,是否跨过一个字(32位)边界
     int nbit = (bits + bs->pos) - 32;

     if (nbit > 0) {//越界,则由curr和next的两部分拼出要读取的值
      return ((bs->curr & (0xffffffff >> bs->pos)) << nbit) | (bs->next >> (32 -nbit));
     } else {//没有越界,通过移位curr就能得到要取的值
      return (bs->curr & (0xffffffff >> bs->pos)) >> (32 - bs->pos - bits);
     }
    }

    //移动比特位位置,分越界和不越界两种情况
    static void __inline
    BitstreamSkip(Bitstream * const bs,
         const uint32_t bits)
    {
     bs->pos += bits;

     if (bs->pos >= 32) {
      uint32_t tmp;
      
      //如果越界了,自动修改curr和next
      bs->curr = bs->next;
      tmp = *((uint32_t *) bs->tail + 2);
    #ifndef ARCH_IS_BIG_ENDIAN
      BSWAP(tmp);
    #endif
      bs->next = tmp;
      bs->tail++;
      bs->pos -= 32;
     }
    }

    /* read n bits from bitstream */

    //将读值和修改位置,同时做
    static uint32_t __inline
    BitstreamGetBits(Bitstream * const bs,
         const uint32_t n)
    {
     uint32_t ret = BitstreamShowBits(bs, n);

     BitstreamSkip(bs, n);
     return ret;
    }

    结束,呵呵。很简单。


    收藏到:Del.icio.us




    评论

  • 你好,能否告知用ffmpeg实现视频解码的具体流程,并附加简单说明。呵呵 谢谢~
  • 你好,能否告知用ffmpeg实现视频解码的具体流程,并附加简单说明。呵呵 谢谢~