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

📄 h263_enc_misc.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* ///////////////////////////////////////////////////////////////////////
//
//               INTEL CORPORATION PROPRIETARY INFORMATION
//  This software is supplied under the terms of a license agreement or
//  nondisclosure agreement with Intel Corporation and may not be copied
//  or disclosed except in accordance with the terms of that agreement.
//        Copyright (c) 2005-2007 Intel Corporation. All Rights Reserved.
//
//  Description:    class ippVideoEncoderH263
//  Contents:
//                  ~ippVideoEncoderH263
//                  ippVideoEncoderH263(h263e_Param)
//                  Close
//                  Init
//                  ExpandFrame
//
*/

#include <math.h>
#include "h263_enc.hpp"

ippVideoEncoderH263::ippVideoEncoderH263(h263e_Param *par)
{
    Init(par);
}

ippVideoEncoderH263::~ippVideoEncoderH263()
{
    Close();
}

void ippVideoEncoderH263::Close()
{
  if (mIsInit) {
    // free
    if (mMBinfo)
      delete [] mMBinfo;
    if (mbsAlloc && cBS.mBuffer)
      ippsFree(cBS.mBuffer);
    if (mBuffer_1)
      ippsFree(mBuffer_1);
    if (mBuffer_2)
      ippsFree(mBuffer_2);
    if (mMEfastSAD)
      ippsFree(mMEfastSAD);
    if (mRTPdata.GOBstartPos)
      ippsFree(mRTPdata.GOBstartPos);
    if (mRTPdata.MBpos)
      ippsFree(mRTPdata.MBpos);
    if (mRTPdata.MBquant)
      ippsFree(mRTPdata.MBquant);
    if (mRTPdata.MBpredMV)
      ippsFree(mRTPdata.MBpredMV);
    if (mRTPdata.MBpredMV1)
      ippsFree(mRTPdata.MBpredMV1);
    if (mFrame)
      delete [] mFrame;
  }
  mIsInit = false;
}

Ipp32s ippVideoEncoderH263::Init(h263e_Param *par)
{
    Ipp32s  i, j;
    IppStatus stsAlloc = ippStsNoErr;

    // check parameters correctness
    if (par->Width < 1 || par->Width > 8191) {
        ErrorMessage(VM_STRING("Width must be between 1 and 8191"));
        return H263_STS_ERR_PARAM;
    }
    if (par->Width & 1) {
        ErrorMessage(VM_STRING("Width must be a even"));
        return H263_STS_ERR_PARAM;
    }
    if (par->Height < 1 || par->Height > 8191) {
        ErrorMessage(VM_STRING("Height must be between 1 and 8191"));
        return H263_STS_ERR_PARAM;
    }
    if (par->Height & 1) {
        ErrorMessage(VM_STRING("Height must be a even"));
        return H263_STS_ERR_PARAM;
    }
    if (!par->RateControl && (par->quantIPic < 1 || par->quantIPic > 31)) {
        ErrorMessage(VM_STRING("quantIPic must be between 1 and 31"));
        return H263_STS_ERR_PARAM;
    }
    if (!par->RateControl && (par->quantPPic < 1 || par->quantPPic > 31)) {
        ErrorMessage(VM_STRING("quantPPic must be between 1 and 31"));
        return H263_STS_ERR_PARAM;
    }
/*
    if (!par->RateControl && (par->quantBPic < 1 || par->quantBPic > 31)) {
        ErrorMessage(VM_STRING("quantBPic must be between 1 and 31"));
        return H263_STS_ERR_PARAM;
    }
*/
    if (par->IPicdist < 1) {
        ErrorMessage(VM_STRING("IPicdist must be positive"));
        return H263_STS_ERR_PARAM;
    }
    if (par->RateControl && par->BitRate <= 0) {
        ErrorMessage(VM_STRING("BitRate must be positive"));
        return H263_STS_ERR_PARAM;
    }
    if (par->SceneChangeThreshold < 0 || par->SceneChangeThreshold > 100) {
        ErrorMessage(VM_STRING("SceneChangeThreshold must be between 0 and 100"));
        return H263_STS_ERR_PARAM;
    }
    if (0) { // ??? tmp
        if (par->TimeResolution != 30000) {
            ErrorMessage(VM_STRING("TimeResolution must equal 30000 in the current implementation")); // ???
            return H263_STS_ERR_PARAM;
        }
        if ((par->TimeIncrement % 1001) || par->TimeIncrement < 1001 || par->TimeIncrement > 256 * 1001) {
            ErrorMessage(VM_STRING("TimeIncrement must equal i*1001 (i=1,256) in the current implementation")); // ???
            return H263_STS_ERR_PARAM;
        }
    } else {
        if (par->TimeResolution < 1) {
            ErrorMessage(VM_STRING("TimeResolution must be positive"));
            return H263_STS_ERR_PARAM;
        }
        if (par->TimeIncrement < 1) {
            ErrorMessage(VM_STRING("TimeIncrement must be positive"));
            return H263_STS_ERR_PARAM;
        }
        if (par->PPicdist < 1) {
            ErrorMessage(VM_STRING("PPicdist must be positive"));
            return H263_STS_ERR_PARAM;
        }
        if (par->IPicdist % par->PPicdist != 0) {
            ErrorMessage(VM_STRING("IPicdist must be an integer multiple of PPicdist"));
            return H263_STS_ERR_PARAM;
        }
        if (par->PPicsearchWidth < 1 || par->PPicsearchWidth > IPP_MIN(1023, par->Width)) {
            ErrorMessage(VM_STRING("PPicsearchWidth must be between 1 and MIN(1023, Width)"));
            return H263_STS_ERR_PARAM;
        }
        if (par->PPicsearchHeight < 1 || par->PPicsearchHeight > IPP_MIN(1023, par->Height)) {
            ErrorMessage(VM_STRING("PPicsearchWidth must be between 1 and MIN(1023, Height)"));
            return H263_STS_ERR_PARAM;
        }
/*
        if (par->BPicsearchWidthForw < 1 || par->BPicsearchWidthForw > IPP_MIN(1023, par->Width)) {
            ErrorMessage(VM_STRING("BPicsearchWidthForw must be between 1 and MIN(1023, Width)"));
            return H263_STS_ERR_PARAM;
        }
        if (par->BPicsearchHeightForw < 1 || par->BPicsearchHeightForw > IPP_MIN(1023, par->Height)) {
            ErrorMessage(VM_STRING("BPicsearchWidthForw must be between 1 and MIN(1023, Height)"));
            return H263_STS_ERR_PARAM;
        }
        if (par->BPicsearchWidthBack < 1 || par->BPicsearchWidthBack > IPP_MIN(1023, par->Width)) {
            ErrorMessage(VM_STRING("BPicsearchWidthBack must be between 1 and MIN(1023, Width)"));
            return H263_STS_ERR_PARAM;
        }
        if (par->BPicsearchHeightBack < 1 || par->BPicsearchHeightBack > IPP_MIN(1023, par->Height)) {
            ErrorMessage(VM_STRING("BPicsearchWidthBack must be between 1 and MIN(1023, Height)"));
            return H263_STS_ERR_PARAM;
        }
*/
    }
    Close();

    memset(&mVideoSequence, 0, sizeof(mVideoSequence));
    memset(&mVideoPicture, 0, sizeof(mVideoPicture));
    mVideoSequence.pic_time_increment_resolution = par->TimeResolution;
    mVideoSequence.fixed_pic_time_increment = par->TimeIncrement;

    {
      Ipp64f finc = mVideoSequence.fixed_pic_time_increment * 0.001;
      if (finc == (Ipp32s)finc || mVideoSequence.pic_time_increment_resolution != 30000) {
        mVideoPicture.PCF = 1;
        mVideoPicture.temporal_reference_increment = 1;
        if (finc == (Ipp32s)finc) {
          mVideoPicture.clock_conversion_code = 1000;
          mVideoPicture.clock_divisor = (Ipp32s)finc;
        } else {
          mVideoPicture.clock_conversion_code = 1001;
          mVideoPicture.clock_divisor = mVideoSequence.fixed_pic_time_increment / mVideoPicture.clock_conversion_code;
        }
        if (mVideoPicture.clock_divisor > 127) {
          mVideoPicture.temporal_reference_increment = mVideoPicture.clock_divisor;
          mVideoPicture.clock_divisor = 1;
          if (mVideoPicture.temporal_reference_increment > 1023) {
            Ipp64f fcld = sqrt((Ipp64f)mVideoPicture.temporal_reference_increment);
            Ipp32s tinc, cld, prod, bestdiff;
            finc = fcld;
            if (fcld > 127.0) {
              finc = finc * fcld / 127.0;
              fcld = 127.0;
            }
            tinc = (Ipp32s)finc + 1;
            if (tinc > 1023)
              tinc = 1023;
            cld = (Ipp32s)fcld;
            prod = tinc * cld;
            bestdiff = h263e_Abs(mVideoPicture.temporal_reference_increment - prod);
            if (cld < 127 && bestdiff > h263e_Abs(mVideoPicture.temporal_reference_increment - prod - tinc))
              cld++;
            else if (bestdiff > h263e_Abs(mVideoPicture.temporal_reference_increment - prod + cld))
              tinc--;

            mVideoPicture.temporal_reference_increment = tinc;
            mVideoPicture.clock_divisor = cld;
            mVideoSequence.fixed_pic_time_increment = par->TimeIncrement = tinc * cld * mVideoPicture.clock_conversion_code;
          }
        }
      } else {
        mVideoPicture.PCF = 0;
        mVideoPicture.temporal_reference_increment = mVideoSequence.fixed_pic_time_increment / 1001;
//        if (mVideoPicture.temporal_reference_increment > 255) // checked earlier
//          mVideoPicture.temporal_reference_increment = 255;
      }
    }

    {
      Ipp32s picSize = par->Width * par->Height;
      // H.263 Spec, Table 1
      if (picSize < 25360)
        mBPPmax = 64 << 10;
      else if (picSize < 101392)
        mBPPmax = 256 << 10;
      else if (picSize < 405520)
        mBPPmax = 512 << 10;
      else
        mBPPmax = 1024 << 10;
    }

    //mNumOfFrames = par->NumOfFrames;
//    mNumOfFrames = -1; ???
    mSkipFrame = 0;
    mRateControl = par->RateControl;
    mFrameSkipEnabled = par->FrameSkip;

    mBitsEncodedTotal = 0;
    if (mRateControl) {
      mBitRate = par->BitRate;
      mBitsDesiredFrame = (Ipp32s)((Ipp64s)mBitRate * par->TimeIncrement / par->TimeResolution);
      if (mBitsDesiredFrame > mBPPmax) // ??? mBPPmax can be larger if negotiated by external means
        mBitsDesiredFrame = mBPPmax;
      mBitsDesiredTotal = 0;
      mQuantIPic = mQuantPPic = (par->Width * par->Height  / mBitsDesiredFrame) + 1;
      h263e_Clip(mQuantIPic, 2, 31); // 3,31 ???
      h263e_Clip(mQuantPPic, 2, 31); // 3,31 ???
      mQuantBPic = (mQuantPPic * 5 >> 2) + 1;
      h263e_Clip(mQuantBPic, 2, 31);

      mRCfa = mBitsDesiredFrame;
      mRCfap = 10;
//      mRCfap = par->TimeResolution / par->TimeIncrement;
      mRCqap = 100;
      mRCbap = 10;
      mRCq = mQuantIPic;
      mRCqa = 1. / (Ipp64f)mRCq;
    } else {
        mQuantIPic = par->quantIPic;
        mQuantPPic = par->quantPPic;
//        mQuantBPic = par->quantBPic;
    }
    mIPicdist = par->IPicdist;
    mPPicdist = par->PPicdist;
    mBPicdist = mPPicdist - 1;
    mMEalgorithm = par->MEalgorithm;
    mMEaccuracy = par->MEaccuracy;
    mMEfastHP = 0;  // using fast algorithm for halfpel MVs (faster but with lower PSNR and compression)

    mGOBheaders = par->GOBheaders;
    mGSTUF = par->GOBheaders >= 2;

    mCalcPSNR = par->calcPSNR;
    mFrameCount = 0;
    mLastIPic = -mIPicdist;

    mVideoSequence.aspect_ratio_info = H263e_ASPECT_RATIO_1_1;

    mVideoPicture.pic_width = par->Width;
    mVideoPicture.pic_height = par->Height;

    mVideoPicture.advIntra = par->advIntra ? 1 : 0;
    mVideoPicture.UMV = par->UMV;
    mVideoPicture.advPred = par->advPred ? 1 : 0;
    mVideoPicture.modQuant = par->modQuant ? 1 : 0;
//    mVideoPicture.deblockFilt = par->deblockFilt;
    mVideoPicture.deblockFilt = 0;

//    mVideoSequence.newpred_enable = 0;
    //f mVideoSequence.requested_upstream_message_type;
    //f mVideoSequence.newpred_segment_type;
//    mVideoSequence.reduced_resolution_pic_enable = 0;
//    mVideoSequence.scalability = 0;
    //f mVideoSequence.ScalabilityParameters;
    mVideoPicture.pic_time_increment = 0;
    mVideoPicture.pic_rounding_type = 0;
    mPPicsearchHor = par->PPicsearchWidth;
    mPPicsearchVer = par->PPicsearchHeight;
    // calc pic_fcode_forward for PPics
    i = IPP_MAX(mPPicsearchHor, mPPicsearchVer);
//    j = i << 1;
//    mPPicfcodeForw = 1;
//    while (j > ((16 << mPPicfcodeForw) - 1))
//        mPPicfcodeForw ++;
    {
        mPPicdist = 1;
        mBPicdist = 0;
        mVideoSequence.data_partitioned = 0;
//        mVideoSequence.scalability = 0;
        mVideoPicture.pic_rounding_type = 0;
        mVideoPicture.split_screen_indicator = 0;
        mVideoPicture.document_camera_indicator = 0;
        mVideoPicture.full_picture_freeze_release = 0;
        if (par->Width == 128 && par->Height == 96) {
            mVideoPicture.source_format = 1;
            mVideoPicture.num_gobs_in_pic = 6;
            mVideoPicture.num_macroblocks_in_gob = 8;
            mVideoPicture.num_MBrows_in_gob = 1;
        } else if (par->Width == 176 && par->Height == 144) {
            mVideoPicture.source_format = 2;
            mVideoPicture.num_gobs_in_pic = 9;
            mVideoPicture.num_macroblocks_in_gob = 11;
            mVideoPicture.num_MBrows_in_gob = 1;
        } else if (par->Width == 352 && par->Height == 288) {
            mVideoPicture.source_format = 3;
            mVideoPicture.num_gobs_in_pic = 18;
            mVideoPicture.num_macroblocks_in_gob = 22;
            mVideoPicture.num_MBrows_in_gob = 1;
        } else if (par->Width == 704 && par->Height == 576) {
            mVideoPicture.source_format = 4;
            mVideoPicture.num_gobs_in_pic = 18;
            mVideoPicture.num_macroblocks_in_gob = 88;
            mVideoPicture.num_MBrows_in_gob = 2;
        } else if (par->Width == 1408 && par->Height == 1152) {
            mVideoPicture.source_format = 5;
            mVideoPicture.num_gobs_in_pic = 18;
            mVideoPicture.num_macroblocks_in_gob = 352;
            mVideoPicture.num_MBrows_in_gob = 4;
        } else {
            ErrorMessage(VM_STRING("Currently unsupported picture size"));
            return H263_STS_ERR_PARAM;
        }
//        mVideoPicture.temporal_reference_increment = mVideoSequence.fixed_pic_time_increment / 1001;


        if (mMEaccuracy > 2)
            mMEaccuracy = 2;
//        mBPicsearchHorForw = mBPicsearchVerForw = mBPicsearchHorBack = mBPicsearchVerBack = 0;
        mME4mv = 0;
    }
#if 0
    else {
        mBPicsearchHorForw = par->BPicsearchWidthForw;
        mBPicsearchVerForw = par->BPicsearchHeightForw;

⌨️ 快捷键说明

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