⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bitstream.cpp

📁 gaca源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*****************************************************************************
 *
 *  XVID MPEG-4 VIDEO CODEC
 *  - Bitstream reader/writer -
 *
 *  Copyright (C) 2001-2003 Peter Ross <pross@xvid.org>
 *                     2003 Cristoph Lampert <gruel@web.de>
 *
 *  This program is free software ; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation ; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY ; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program ; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 *
 * $Id: bitstream.cpp,v 1.1.1.1 2005/07/13 14:36:12 jeanlf Exp $
 *
 ****************************************************************************/

#include "bitstream.h"
#include "quant_matrix.h"

#ifdef WIN32
#include <stdio.h>
#endif

//----------------------------

inline dword ByteSwap(dword a){
   return (a<<24) | ((a&0xff00) << 8) | ((a&0xff0000) >> 8) | (a>>24);
}

//----------------------------

void Bitstream::Init(const void *bitstream, dword _length){

   dword adjbitstream = (dword)bitstream;

   /*
    * Start the stream on a dword boundary, by rounding down to the
    * previous dword and skipping the intervening bytes.
    */
   long bitpos = ((sizeof(dword)-1) & (long)bitstream);
   adjbitstream = adjbitstream - bitpos;
   start = tail = (dword *) adjbitstream;

   if(_length){
      dword tmp = *start;
#ifndef ARCH_IS_BIG_ENDIAN
      tmp = ByteSwap(tmp);
#endif
      bufa = tmp;
      if(_length>4){
         tmp = *(start + 1);
#ifndef ARCH_IS_BIG_ENDIAN
         tmp = ByteSwap(tmp);
#endif
         bufb = tmp;
      }else
         bufb = 0;
   }else
      bufa = bufb = 0;

   buf = 0;
   pos = initpos = bitpos*8;
   length = _length;
}

//---------------------------

/* reads n bits from bitstream without changing the stream pos */

dword Bitstream::ShowBits(dword bits){

   int nbit = (bits + pos) - 32;
   if(nbit > 0)
      return ((bufa & (0xffffffff >> pos)) << nbit) | (bufb >> (32 - nbit));
   return (bufa & (0xffffffff >> pos)) >> (32 - pos - bits);
}

//---------------------------
// skip n bits forward in bitstream
void Bitstream::Skip(dword bits){

   pos += bits;
   if(pos >= 32){
      dword tmp;

      bufa = bufb;
      tmp = *((dword *) tail + 2);
#ifndef ARCH_IS_BIG_ENDIAN
      tmp = ByteSwap(tmp);
#endif
      bufb = tmp;
      tail++;
      pos -= 32;
   }
}

//---------------------------
/* show nbits from next byte alignment */
dword Bitstream::ShowBitsFromByteAlign(int bits){

   int bspos = pos + NumBitsToByteAlign();
   int nbit = (bits + bspos) - 32;

   if (bspos >= 32) {
      return bufb >> (32 - nbit);
   } else   if (nbit > 0) {
      return ((bufa & (0xffffffff >> bspos)) << nbit) | (bufb >> (32 - nbit));
   } else {
      return (bufa & (0xffffffff >> bspos)) >> (32 - bspos - bits);
   }

}

//---------------------------
/* read n bits from bitstream */
dword Bitstream::GetBits(dword n){
   dword ret = ShowBits(n);
   Skip(n);
   return ret;
}

//---------------------------

static const dword intra_dc_threshold_table[] = {
   32,                     /* never use */
   13,
   15,
   17,
   19,
   21,
   23,
   1,
};

//----------------------------

void Bitstream::get_matrix(byte * matrix){

   int i = 0;
   int last, value = 0;

   do {
      last = value;
      value = GetBits(8);
      matrix[scan_tables[0][i++]] = value;
   }
   while (value != 0 && i < 64);
        i--;    /* fix little bug at coeff not full */

   while (i < 64) {
      matrix[scan_tables[0][i++]] = last;
   }
}

//----------------------------
/*
 * for PVOP addbits == fcode - 1
 * for BVOP addbits == max(fcode,bcode) - 1
 * returns mbpos
 */
int S_decoder::read_video_packet_header(Bitstream *bs, const int addbits, int *quant, int *fcode_forward, int *fcode_backward, int *intra_dc_threshold){

   int startcode_bits = NUMBITS_VP_RESYNC_MARKER + addbits;
   int mbnum_bits = log2bin(mb_width *  mb_height - 1);
   int mbnum;
   int hec = 0;

   bs->Skip(bs->NumBitsToByteAlign());
   bs->Skip(startcode_bits);

   DPRINTF(XVID_DEBUG_STARTCODE, "<video_packet_header>\n");

   if (shape != VIDOBJLAY_SHAPE_RECTANGULAR)
   {
      hec = bs->GetBit();     /* header_extension_code */
      if (hec && !(sprite_enable == SPRITE_STATIC /* && current_coding_type = I_VOP */))
      {
         bs->Skip(13);        /* vop_width */
         READ_MARKER();
         bs->Skip(13);        /* vop_height */
         READ_MARKER();
         bs->Skip(13);        /* vop_horizontal_mc_spatial_ref */
         READ_MARKER();
         bs->Skip(13);        /* vop_vertical_mc_spatial_ref */
         READ_MARKER();
      }
   }

   mbnum = bs->GetBits(mbnum_bits);    /* macroblock_number */
   DPRINTF(XVID_DEBUG_HEADER, "mbnum %i\n", mbnum);

   if (shape != VIDOBJLAY_SHAPE_BINARY_ONLY)
   {
      *quant = bs->GetBits(quant_bits);   /* quant_scale */
      DPRINTF(XVID_DEBUG_HEADER, "quant %i\n", *quant);
   }

   if (shape == VIDOBJLAY_SHAPE_RECTANGULAR)
      hec = bs->GetBit();     /* header_extension_code */


   DPRINTF(XVID_DEBUG_HEADER, "header_extension_code %i\n", hec);
   if (hec)
   {
      int time_base;
      int time_increment = 0;
      int coding_type;

      for (time_base=0; bs->GetBit()!=0; time_base++);      /* modulo_time_base */
      READ_MARKER();
      if (time_inc_bits)
         time_increment = (bs->GetBits(time_inc_bits));  /* vop_time_increment */
      READ_MARKER();
      //DPRINTF(XVID_DEBUG_HEADER,"time %i:%i\n", time_base, time_increment);

      coding_type = bs->GetBits(2);
      DPRINTF(XVID_DEBUG_HEADER,"coding_type %i\n", coding_type);

      if (shape != VIDOBJLAY_SHAPE_RECTANGULAR)
      {
         bs->Skip(1);   /* change_conv_ratio_disable */
         if (coding_type != I_VOP)
            bs->Skip(1);   /* vop_shape_coding_type */
      }

      if (shape != VIDOBJLAY_SHAPE_BINARY_ONLY)
      {
         *intra_dc_threshold = intra_dc_threshold_table[bs->GetBits(3)];

         if (sprite_enable == SPRITE_GMC && coding_type == S_VOP &&
            sprite_warping_points > 0)
         {
            /* TODO: sprite trajectory */
         }
         if(reduced_resolution_enable && shape == VIDOBJLAY_SHAPE_RECTANGULAR && (coding_type == P_VOP || coding_type == I_VOP)){
            bs->Skip(1); /* XXX: vop_reduced_resolution */
         }

         if (coding_type != I_VOP && fcode_forward)
         {
            *fcode_forward = bs->GetBits(3);
            DPRINTF(XVID_DEBUG_HEADER,"fcode_forward %i\n", *fcode_forward);
         }

         if (coding_type == B_VOP && fcode_backward)
         {
            *fcode_backward = bs->GetBits(3);
            DPRINTF(XVID_DEBUG_HEADER,"fcode_backward %i\n", *fcode_backward);
         }
      }

   }

   if (newpred_enable) {
      int vop_id;
      int vop_id_for_prediction;

      vop_id = bs->GetBits(MIN(time_inc_bits + 3, 15));
      DPRINTF(XVID_DEBUG_HEADER, "vop_id %i\n", vop_id);
      if (bs->GetBit()) /* vop_id_for_prediction_indication */
      {
         vop_id_for_prediction = bs->GetBits(MIN(time_inc_bits + 3, 15));
         DPRINTF(XVID_DEBUG_HEADER, "vop_id_for_prediction %i\n", vop_id_for_prediction);
      }
      READ_MARKER();
   }

   return mbnum;
}

//----------------------------
/* vol estimation header */
void S_decoder::read_vol_complexity_estimation_header(Bitstream * bs){

   ESTIMATION * e = &estimation;

   e->method = bs->GetBits(2);   /* estimation_method */
   DPRINTF(XVID_DEBUG_HEADER,"+ complexity_estimation_header; method=%i\n", e->method);

   if (e->method == 0 || e->method == 1){
      if(!bs->GetBit()){
                              //shape_complexity_estimation_disable
         e->opaque = bs->GetBit();     /* opaque */
         e->transparent = bs->GetBit();      /* transparent */
         e->intra_cae = bs->GetBit();     /* intra_cae */
         e->inter_cae = bs->GetBit();     /* inter_cae */
         e->no_update = bs->GetBit();     /* no_update */
         e->upsampling = bs->GetBit();    /* upsampling */
      }

      if (!bs->GetBit())   /* texture_complexity_estimation_set_1_disable */
      {
         e->intra_blocks = bs->GetBit();     /* intra_blocks */
         e->inter_blocks = bs->GetBit();     /* inter_blocks */
         e->inter4v_blocks = bs->GetBit();      /* inter4v_blocks */
         e->not_coded_blocks = bs->GetBit();    /* not_coded_blocks */
      }
   }

   READ_MARKER();

   if (!bs->GetBit()){
                              //texture_complexity_estimation_set_2_disable
      e->dct_coefs = bs->GetBit();     /* dct_coefs */
      e->dct_lines = bs->GetBit();     /* dct_lines */
      e->vlc_symbols = bs->GetBit();      /* vlc_symbols */
      e->vlc_bits = bs->GetBit();      /* vlc_bits */
   }

   if (!bs->GetBit()){
                              //motion_compensation_complexity_disable
      e->apm = bs->GetBit();     /* apm */
      e->npm = bs->GetBit();     /* npm */
      e->interpolate_mc_q = bs->GetBit();    /* interpolate_mc_q */
      e->forw_back_mc_q = bs->GetBit();      /* forw_back_mc_q */
      e->halfpel2 = bs->GetBit();      /* halfpel2 */
      e->halfpel4 = bs->GetBit();      /* halfpel4 */
   }

   READ_MARKER();

   if (e->method == 1){
      if (!bs->GetBit()){
                              //version2_complexity_estimation_disable
         e->sadct = bs->GetBit();      /* sadct */
         e->quarterpel = bs->GetBit();    /* quarterpel */
      }
   }
}

//----------------------------
/* vop estimation header */
void S_decoder::read_vop_complexity_estimation_header(Bitstream * bs, int coding_type){

   ESTIMATION * e = &estimation;

   if (e->method == 0 || e->method == 1)
   {
      if (coding_type == I_VOP) {
         if (e->opaque)    bs->Skip(8);   /* dcecs_opaque */
         if (e->transparent) bs->Skip(8); /* */
         if (e->intra_cae) bs->Skip(8);   /* */
         if (e->inter_cae) bs->Skip(8);   /* */
         if (e->no_update) bs->Skip(8);   /* */
         if (e->upsampling)   bs->Skip(8);   /* */
         if (e->intra_blocks) bs->Skip(8);   /* */
         if (e->not_coded_blocks) bs->Skip(8);  /* */
         if (e->dct_coefs) bs->Skip(8);   /* */
         if (e->dct_lines) bs->Skip(8);   /* */
         if (e->vlc_symbols) bs->Skip(8); /* */
         if (e->vlc_bits)  bs->Skip(8);   /* */
         if (e->sadct)     bs->Skip(8);   /* */
      }

      if (coding_type == P_VOP) {
         if (e->opaque) bs->Skip(8);      /* */
         if (e->transparent) bs->Skip(8); /* */
         if (e->intra_cae) bs->Skip(8);   /* */
         if (e->inter_cae) bs->Skip(8);   /* */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -