乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      xvid靜態(tài)庫的封裝類(編碼和解碼)

       WWWo福oCOM 2007-07-19
       
      北京理工大學(xué) 20981 陳罡
      xvid靜態(tài)庫用起來雖然速度很快,但是很不方便,有必要用c++把它好好封裝一下,方便開發(fā)人員使用。下面的代碼已經(jīng)在p2p視頻會議中采用,很好用,速度也很快。
       
      xvid編碼器頭文件:
      #ifndef _XVID_ENCODE_H
      #define _XVID_ENCODE_H
      #include <xvid.h>
      class CXvidEncHandler {
      public:
       virtual void PostEncHandler(unsigned char * xvid, int key, int xvid_len) = 0 ;
      };
      class CXvidEnc {
      protected:
       // original encode routine in xvid lib
       int   enc_core(unsigned char *image, unsigned char *bitstream, int *key);
      public:
       CXvidEnc() ;
       ~CXvidEnc() ;
       bool            Open();
       bool            Close();
       static void     XVID_GLOBAL_INIT();
       void            Encode(unsigned char * image);
       void   AttachCaller(int width, int height, CXvidEncHandler * enc_caller) ;
      protected:
       CXvidEncHandler* m_enc_caller ;
       void *           m_enc_handle;
       unsigned char*   m_bitstream;
       bool             m_closed;
       int        m_key ;
       int     m_width ;
       int     m_height ;
      };
      #endif
       
      編碼器源文件:
      #include "StdAfx.h"
      #include ".\xvidenc.h"
      #include "xvid.h"
      static const int motion_presets[] = {
       /* quality 0 */
       0,
       /* quality 1 */
       XVID_ME_ADVANCEDDIAMOND16,
       /* quality 2 */
       XVID_ME_ADVANCEDDIAMOND16 | XVID_ME_HALFPELREFINE16,
       /* quality 3 */
       XVID_ME_ADVANCEDDIAMOND16 | XVID_ME_HALFPELREFINE16 |
       XVID_ME_ADVANCEDDIAMOND8 | XVID_ME_HALFPELREFINE8,
       /* quality 4 */
       XVID_ME_ADVANCEDDIAMOND16 | XVID_ME_HALFPELREFINE16 |
       XVID_ME_ADVANCEDDIAMOND8 | XVID_ME_HALFPELREFINE8 |
       XVID_ME_CHROMA_PVOP | XVID_ME_CHROMA_BVOP,
       /* quality 5 */
       XVID_ME_ADVANCEDDIAMOND16 | XVID_ME_HALFPELREFINE16 |
       XVID_ME_ADVANCEDDIAMOND8 | XVID_ME_HALFPELREFINE8 |
       XVID_ME_CHROMA_PVOP | XVID_ME_CHROMA_BVOP,
       /* quality 6 */
       XVID_ME_ADVANCEDDIAMOND16 | XVID_ME_HALFPELREFINE16 | XVID_ME_EXTSEARCH16 |
       XVID_ME_ADVANCEDDIAMOND8 | XVID_ME_HALFPELREFINE8 | XVID_ME_EXTSEARCH8 |
       XVID_ME_CHROMA_PVOP | XVID_ME_CHROMA_BVOP,
      };
      #define ME_ELEMENTS (sizeof(motion_presets)/sizeof(motion_presets[0]))
      static const int vop_presets[] = {
       /* quality 0 */
       0,
       /* quality 1 */
       0,
       /* quality 2 */
       XVID_VOP_HALFPEL,
       /* quality 3 */
       XVID_VOP_HALFPEL | XVID_VOP_INTER4V,
       /* quality 4 */
       XVID_VOP_HALFPEL | XVID_VOP_INTER4V,
       /* quality 5 */
       XVID_VOP_HALFPEL | XVID_VOP_INTER4V |
       XVID_VOP_TRELLISQUANT,
       /* quality 6 */
       XVID_VOP_HALFPEL | XVID_VOP_INTER4V |
       XVID_VOP_TRELLISQUANT | XVID_VOP_HQACPRED,
      };
      #define VOP_ELEMENTS (sizeof(vop_presets)/sizeof(vop_presets[0]))
      //////////////////////////////////////////////////////////////////////////
      #define MAX_ZONES   64
      /* Maximum number of frames to encode */
      #define ABS_MAXFRAMENR 9999
      static int ARG_STATS = 0;
      static int ARG_DUMP = 0;
      static int ARG_LUMIMASKING = 0;
      static int ARG_BITRATE = 0;
      static int ARG_SINGLE = 0;
      static char *ARG_PASS1 = 0;
      static char *ARG_PASS2 = 0;
      static int ARG_QUALITY = ME_ELEMENTS - 1;
      static float ARG_FRAMERATE = 25.00f;
      static int ARG_MAXFRAMENR = ABS_MAXFRAMENR;
      static int ARG_MAXKEYINTERVAL = 0;
      static char *ARG_INPUTFILE = NULL;
      static int ARG_INPUTTYPE = 0;
      static int ARG_SAVEMPEGSTREAM = 0;
      static int ARG_SAVEINDIVIDUAL = 0;
      static char *ARG_OUTPUTFILE = NULL;
      static int ARG_BQRATIO = 150;
      static int ARG_BQOFFSET = 100;
      static int ARG_MAXBFRAMES = 0;
      static int ARG_PACKED = 0;
      static int ARG_VOPDEBUG = 0;
      static int ARG_GMC = 0;
      static int ARG_INTERLACING = 0;
      static int ARG_QPEL = 0;
      static int ARG_CLOSED_GOP = 0;
      #ifndef READ_PNM
      #define IMAGE_SIZE(x,y) ((x)*(y)*3/2)
      #else
      #define IMAGE_SIZE(x,y) ((x)*(y)*3)
      #endif
      #define MAX(A,B) ( ((A)>(B)) ? (A) : (B) )
      #define SMALL_EPS (1e-10)
      #define SWAP(a) ( (((a)&0x000000ff)<<24) | (((a)&0x0000ff00)<<8) | (((a)&0x00ff0000)>>8)  | (((a)&0xff000000)>>24) )
      //////////////////////////////////////////////////////////////////////////
      CXvidEnc::CXvidEnc()
      {
       m_closed = true ;
       m_enc_caller = NULL ;
       m_enc_handle = NULL ;
       m_key = 0 ;
       m_width = 0 ;
       m_height = 0 ;
       m_bitstream = NULL ;
      }
      CXvidEnc::~CXvidEnc() {
       if(m_bitstream) free(m_bitstream) ;
       m_bitstream = NULL ;
      }
      bool CXvidEnc::Close() {
       int xerr = 0 ;
       m_closed = true;
       /* Destroy the encoder instance */
       xerr = xvid_encore(m_enc_handle, XVID_ENC_DESTROY, NULL, NULL);
       return (xerr) ? false : true ;
      }
      void CXvidEnc::AttachCaller(int width, int height, CXvidEncHandler * enc_caller)
      {
       m_width = width ;
       m_height = height ;
       m_enc_caller = enc_caller ;
       if(m_width > 0 && m_height > 0) {
        // max size
        int max = (m_width > m_height) ? m_width : m_height ;
        int xvid_len = (int)(max * max) ;
        m_bitstream = (unsigned char *)malloc(xvid_len) ;
        memset(m_bitstream, 0, xvid_len) ;
        CXvidEnc::XVID_GLOBAL_INIT() ;
       }
      }
      void CXvidEnc::XVID_GLOBAL_INIT(){
       /*------------------------------------------------------------------------
        * XviD core initialization
        *----------------------------------------------------------------------*/
       xvid_gbl_init_t xvid_gbl_init;
       memset(&xvid_gbl_init, 0, sizeof(xvid_gbl_init));
       xvid_gbl_init.version = XVID_VERSION;
       xvid_gbl_init.cpu_flags = XVID_CPU_FORCE | XVID_CPU_ASM ; // here we use asm optimized code
       /* Initialize XviD core -- Should be done once per __process__ */
       xvid_global(NULL, XVID_GBL_INIT, &xvid_gbl_init, NULL);
      }
      bool CXvidEnc::Open() {
       if(!m_enc_caller) return false ;
       static xvid_enc_create_t xvid_enc_create;
       int xerr = 0;
       m_closed = false;
       /*------------------------------------------------------------------------
       * XviD encoder initialization
       *----------------------------------------------------------------------*/
       memset(&xvid_enc_create, 0, sizeof(xvid_enc_create));
       xvid_enc_create.version = XVID_VERSION;
       /* Width and Height of input frames */
       xvid_enc_create.width = m_width ;
       xvid_enc_create.height = m_height ;
       xvid_enc_create.profile = XVID_PROFILE_AS_L4;
       /* init plugins  */
       /*
       xvid_enc_create.zones = ZONES;
       xvid_enc_create.num_zones = NUM_ZONES;
       xvid_enc_create.plugins = plugins;
       xvid_enc_create.num_plugins = 0;
       */
       /* No fancy thread tests */
       xvid_enc_create.num_threads = 0;
       /* Frame rate - Do some quick float fps = fincr/fbase hack */   
       xvid_enc_create.fincr = 1;
       xvid_enc_create.fbase = (int)10;
       /* Maximum key frame interval */
       xvid_enc_create.max_key_interval = (int)-1;    //--default 10s
       
       /* Bframes settings */
       xvid_enc_create.max_bframes = ARG_MAXBFRAMES;
       xvid_enc_create.bquant_ratio = ARG_BQRATIO;
       xvid_enc_create.bquant_offset = ARG_BQOFFSET;
       
       /* Dropping ratio frame -- we don‘t need that */
       xvid_enc_create.frame_drop_ratio = 0;
       
       /* Global encoder options */
       xvid_enc_create.global = 0;
       if (ARG_PACKED)
        xvid_enc_create.global |= XVID_GLOBAL_PACKED;
       if (ARG_CLOSED_GOP)
        xvid_enc_create.global |= XVID_GLOBAL_CLOSED_GOP;
       if (ARG_STATS)
        xvid_enc_create.global |= XVID_GLOBAL_EXTRASTATS_ENABLE;
       /* I use a small value here, since will not encode whole movies, but short clips */
       xerr = xvid_encore(NULL, XVID_ENC_CREATE, &xvid_enc_create, NULL);
       
       m_enc_handle = xvid_enc_create.handle;
       
       return true;
      }
      void CXvidEnc::Encode(unsigned char * image) {
       int ret = 0 ;   
       if(m_closed) return;
       ret = enc_core(image, m_bitstream, &m_key) ;
       // really encode some images into xvid data
       if (ret > 0)
        m_enc_caller->PostEncHandler(m_bitstream, m_key, ret) ;
       }
      /*
       raw CXvidEnc procedure
      */
      int CXvidEnc::enc_core(unsigned char *image,unsigned char *bitstream, int * key)
      {
       int ret;   
       xvid_enc_frame_t xvid_enc_frame;
       xvid_enc_stats_t xvid_enc_stats;
          
       /* Version for the frame and the stats */
       memset(&xvid_enc_frame, 0, sizeof(xvid_enc_frame));
       xvid_enc_frame.version = XVID_VERSION;
       memset(&xvid_enc_stats, 0, sizeof(xvid_enc_stats));
       xvid_enc_stats.version = XVID_VERSION;
       /* Bind output buffer */
       xvid_enc_frame.bitstream = bitstream;
       xvid_enc_frame.length = -1;
          
       /* Initialize input image fields */
       xvid_enc_frame.input.plane[0] = image;
       xvid_enc_frame.input.csp = XVID_CSP_BGR; // suppose we get data from usb web cam
       xvid_enc_frame.input.stride[0] = m_width*3;
       /* Set up core‘s general features */
       xvid_enc_frame.vol_flags = 0;
           
       /* Set up core‘s general features */
       xvid_enc_frame.vop_flags = vop_presets[ARG_QUALITY-2];
         
       /* Frame type -- let core decide for us */
       xvid_enc_frame.type = XVID_TYPE_AUTO;
          
       /* Force the right quantizer -- It is internally managed by RC plugins */
       xvid_enc_frame.quant = 0;
       /* Set up motion estimation flags */
       xvid_enc_frame.motion = motion_presets[ARG_QUALITY-2];
       /* We don‘t use special matrices */
       xvid_enc_frame.quant_intra_matrix = NULL;
       xvid_enc_frame.quant_inter_matrix = NULL;
       /* Encode the frame */
       ret = xvid_encore(m_enc_handle, XVID_ENC_ENCODE, &xvid_enc_frame,NULL);
       //    &xvid_enc_stats);
       //--判別是否是關(guān)鍵幀
       *key = (xvid_enc_frame.out_flags & XVID_KEYFRAME);
       //*stats_type = xvid_enc_stats.type;
       //*stats_quant = xvid_enc_stats.quant;
       //*stats_length = xvid_enc_stats.length;
       //sse[0] = xvid_enc_stats.sse_y;
       //sse[1] = xvid_enc_stats.sse_u;
       //sse[2] = xvid_enc_stats.sse_v;
          
       return (ret);
      }
       
      解碼器頭文件:
      #ifndef _XVID_DECODE_H
      #define _XVID_DECODE_H
       
      #include <xvid.h>
       
      class CXvidDecHandler {
      public:
       virtual void PostDecHandler(unsigned char * image, int used_bytes) = 0 ;
      };
      class CXvidDec {
      public:
       CXvidDec() ;
       ~CXvidDec() ;
       bool               Open();
       bool               Close();
       void               Decode(unsigned char* xvid, int xvid_len);
       static void     XVID_GLOBAL_INIT();
       void      AttachCaller(int width, int height, CXvidDecHandler * dec_caller) ;
      protected:
       int                dec_core(unsigned char *bitstream, unsigned char *image, int bs_size) ;
      protected:
       CXvidDecHandler*  m_dec_caller ;
       void*             m_dec_handle ;
       unsigned char *   m_image ;
       int      m_width ;
       int      m_height ;
      };
      #endif
       
      解碼器源文件:
      #include "StdAfx.h"
      #include ".\xviddec.h"
      #include "xvid.h"
      CXvidDec::CXvidDec() {
       m_width = 0 ;
       m_height = 0 ;
       m_image = NULL ;
       m_dec_handle = NULL ;
       m_dec_caller = NULL ;
      }
      CXvidDec::~CXvidDec()
      {
       if(m_image) free(m_image) ;
       m_image = NULL ;
      }
      void CXvidDec::AttachCaller(int width, int height, CXvidDecHandler * dec_caller)
      {
       m_width = width ;
       m_height = height ;
       m_dec_caller = dec_caller ;
       if((m_width > 0) && (m_height > 0)) {
        int image_len = m_width * m_height * 3 ;
        m_image = (unsigned char *)malloc(image_len) ;
        memset(m_image, 0, image_len) ;
        CXvidDec::XVID_GLOBAL_INIT() ;
       }
      }
      bool CXvidDec::Close(){
       int xerr = 0 ;
       /* Destroy the encoder instance */
       xerr = xvid_decore(m_dec_handle, XVID_ENC_DESTROY, NULL, NULL);
       return (xerr) ? false : true ;
      }
      void CXvidDec::XVID_GLOBAL_INIT() {
       /*------------------------------------------------------------------------
        * XviD core initialization
        *----------------------------------------------------------------------*/
       xvid_gbl_init_t xvid_gbl_init;
       memset(&xvid_gbl_init, 0, sizeof(xvid_gbl_init));
       xvid_gbl_init.version = XVID_VERSION;
       xvid_gbl_init.cpu_flags = XVID_CPU_FORCE | XVID_CPU_ASM ; // force to use asm optimized routine
       /* Initialize XviD core -- Should be done once per __process__ */
       xvid_global(NULL, XVID_GBL_INIT, &xvid_gbl_init, NULL);
      }
      bool CXvidDec::Open() {
       if(!m_dec_caller) return false ;
       static xvid_dec_create_t xvid_dec_create ;
       int ret = 0;
       /*------------------------------------------------------------------------
        * XviD encoder initialization
        *----------------------------------------------------------------------*/
       
       memset(&xvid_dec_create, 0, sizeof(xvid_dec_create_t));
       xvid_dec_create.version = XVID_VERSION;
       /* Width and Height of input frames */
       xvid_dec_create.width = m_width ;
       xvid_dec_create.height = m_height ;
       ret = xvid_decore(NULL, XVID_DEC_CREATE, &xvid_dec_create, NULL) ;
       m_dec_handle = xvid_dec_create.handle;
       return true;
      }
      void CXvidDec::Decode(unsigned char * xvid, int xvid_len) {
       int ret = 0;
       ret = dec_core(xvid, m_image, xvid_len);
       if (ret > 0)
        m_dec_caller->PostDecHandler(m_image, ret) ;  
       }
       /* raw xvid_encode procedure  */
      int CXvidDec::dec_core(unsigned char *bitstream,unsigned char *image, int bs_size)
      {
       int ret;
       xvid_dec_frame_t xvid_dec_frame;
       /* Reset all structures */
       memset(&xvid_dec_frame, 0, sizeof(xvid_dec_frame_t));
       
       /* Set version */
       xvid_dec_frame.version = XVID_VERSION;
       //xvid_dec_stats->version = XVID_VERSION;
       
       /* No general flags to set */
       xvid_dec_frame.general          = 0;
       
       /* Input stream */
       xvid_dec_frame.bitstream        = bitstream;
       xvid_dec_frame.length           = bs_size;
       
       /* Output frame structure */
       xvid_dec_frame.output.plane[0]  = image;
       xvid_dec_frame.output.stride[0] = m_width*3;
       xvid_dec_frame.output.csp = XVID_CSP_BGR;
       ret = xvid_decore(m_dec_handle, XVID_DEC_DECODE, &xvid_dec_frame, NULL);
       return(ret);   
      }
       
      大家關(guān)注到這里編解碼器有兩個(gè)虛基類:CXvidDecHandler和CXvidEncHandler,使用的時(shí)候從這兩個(gè)類派生,然后重載 它即可。注意,這里是為了配合攝像頭使用所以是直接對BGR24格式的數(shù)據(jù)進(jìn)行編解碼,如果對yuv420原始數(shù)據(jù)進(jìn)行編解碼,需要略微調(diào)整一下代碼。
       
      在這里我列一下使用流程:
      (1)重載虛基類:
      class CCapSvrDlg : public CDialog, 
             public CXvidEncHandler,  // xvid encode handler
             public CXvidDecHandler   // xvid decode handler
      { ...
       
      (2)重載純虛函數(shù):
      public: // override the CXvidEncHandler
       void PostEncHandler(unsigned char * xvid, int key, int xvid_len) ;
      public:
       void PostDecHandler(unsigned char * image, int used_bytes) ;
      這里的PostEncHandler和PostDecHandler分別代表編碼或者解碼完畢后的數(shù)據(jù)處理。
      比如:調(diào)用編碼,xvid編碼完畢后,會自動調(diào)用這里重載的PostEncHandler,這里的xvid就是編碼后的視頻數(shù)據(jù),xvid_len就是視頻數(shù)據(jù)的長度,這個(gè)key就是標(biāo)明當(dāng)前編碼是否為關(guān)鍵幀。
      解碼也是一樣,不在贅述。
       
      (3)定義編解碼器指針:
      CXvidEnc *  m_vdo_enc ;
      CXvidDec *  m_vdo_dec ;
       
      (4)在OnInitDialog中初始化:
       m_vdo_enc = new CXvidEnc() ;
       m_vdo_enc->AttachCaller(320, 240, this) ;
       m_vdo_enc->Open() ;
       
       m_vdo_dec = new CXvidDec() ;
       m_vdo_dec->AttachCaller(320, 240, this) ;
       m_vdo_dec->Open() ;
       
      (5)編解碼操作:
      編碼:
      m_vdo_enc->Encode(pBuffer) ; // 這里pBuffer是BGR24的320x240的數(shù)據(jù)
      編碼如果成功,就會自動調(diào)用PostEncHandler函數(shù),就可以得到編碼后的結(jié)果
       
      解碼:
      m_vdo_dec->Decode(xvid, xvid_len) ; // 傳入的存有xvid數(shù)據(jù)的buffer和長度
      解碼成功后,會自動調(diào)用PostDecHandler,注意對于流媒體數(shù)據(jù)而言,在這個(gè)函數(shù)中還有一個(gè)形參是標(biāo)明本次解碼用掉了多少個(gè)字節(jié)的xvid緩沖區(qū)的數(shù)據(jù),便于下一幀解碼的時(shí)候調(diào)整緩沖區(qū)指針
       
      (6)OnDestroy函數(shù)中,關(guān)閉編解碼器
       m_vdo_enc->Close() ;
       m_vdo_dec->Close() ;
       delete m_vdo_dec ;
       delete m_vdo_enc ;
       
      這些就是全部的xvid靜態(tài)庫的c++封裝了,是不是特簡單?只要編譯一下xvid-core1.1.2即可。
      鏈接的時(shí)候,需要libxvidcore.lib。
      注意,debug版的需要debug版的libxvidcore.lib,release版的需要release版的xvidcore庫。
        







        本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多