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

📄 qualitylevelassigner.cpp

📁 jsvm开发代码包括抽样,编码,抽取,解码等一系列功能,可以做工具或研究用
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    if( !bValid )
    {
      RNOK( pcReadBitStream->releasePacket( rpcBinData ) );
    }
  }

  return Err::m_nOK;
}

ErrVal
QualityLevelAssigner::xGetDistortion( UInt&         ruiDistortion,
                                      const UChar*  pucReconstruction,
                                      const UChar*  pucReference,
                                      UInt          uiHeight,
                                      UInt          uiWidth,
                                      UInt          uiStride )
{
  ruiDistortion = 0;
  for( UInt y = 0; y < uiHeight; y++ )
  {
    for( UInt x = 0; x < uiWidth; x++ )
    {
      Int iDiff      = ( pucReconstruction[x] - pucReference[x] );
      ruiDistortion += (UInt)( iDiff * iDiff );
    }
    pucReconstruction += uiStride;
    pucReference      += uiStride;
  }
  return Err::m_nOK;
}





ErrVal
QualityLevelAssigner::xInitDistortion( UInt*  auiDistortion,
                                       UInt   uiTopLayer,
                                       UInt   uiLayer,
                                       UInt   uiFGSLayer,
                                       UInt   uiLevel,
                                       Bool   bIndependent )
{
  ROT( m_pcParameter->getOriginalFileName( uiTopLayer ).empty() );

  if( uiLevel == MSYS_UINT_MAX )
    printf( "determine distortion (layer %d - FGS %d - base layer  ) ...", uiLayer, uiFGSLayer );
  else
    printf( "determine distortion (layer %d - FGS %d - lev%2d - %s ) ...", uiLayer, uiFGSLayer, uiLevel, bIndependent?"ind":"dep" );

#if WIN32
  Char              tmp_file_name[]   = "decout.tmp";
#endif
  Bool              bEOS              = false;
  Bool              bToDecode         = false;
  UInt              uiFrame           = 0;
  UInt              uiNalUnitType     = 0;
  UInt              uiMbX             = 0;
  UInt              uiMbY             = 0;
  UInt              uiSize            = 0;
  Bool    SuffixEnable; //bug-fix suffix

//  UInt              uiNonRequiredPic  = 0;  //NonRequired JVT-Q066

  UInt              uiLumOffset       = 0;
  UInt              uiCbOffset        = 0;
  UInt              uiCrOffset        = 0;
  Bool              bYuvDimSet        = false;
  PicBuffer*        pcPicBuffer       = 0;
  PicBuffer*        pcPicBufferOrig   = 0;
  WriteYuvIf*       pcWriteYuv        = 0;
  PicBufferList     cPicBufferOutputList;
  PicBufferList     cPicBufferUnusedList;
  PicBufferList     cPicBufferReleaseList;
  UInt              auiFrameNumAnalysis[MAX_LAYERS] = { MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX };
  UInt              auiFrameNumDecoding[MAX_LAYERS] = { MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX, MSYS_UINT_MAX };

  //===== init =====
  RNOK( m_pcH264AVCPacketAnalyzer->init() );
  RNOK( m_pcH264AVCDecoder       ->init( true ) );
  ReadBitstreamFile*  pcReadBitStream = 0;
  ReadYuvFile*        pcReadYuv       = 0;
  RNOK( ReadBitstreamFile ::create( pcReadBitStream ) );
  RNOK( ReadYuvFile       ::create( pcReadYuv       ) );
  RNOK( pcReadBitStream ->init( m_pcParameter->getInputBitStreamName() ) );
  RNOK( pcReadYuv       ->init( m_pcParameter->getOriginalFileName  ( uiTopLayer ), m_auiFrameHeight[uiTopLayer], m_auiFrameWidth[uiTopLayer] ) );

  if( m_bOutputReconstructions )
  {
    Char  acName[1024];
    sprintf( acName, "rec_Layer%d_FGS%d_Level%d_Mode%d", uiLayer, uiFGSLayer, uiLevel, (bIndependent?0:1) );
    RNOK( WriteYuvToFile::create( pcWriteYuv, std::string( acName ) ) );
  }


  //===== loop over packets =====
  while( ! bEOS )
  {
    Int             iPos;
    Bool            bFinishChecking;
    BinData*        pcBinData;
    BinDataAccessor cBinDataAccessor;

    //----- analyse access unit -----
    RNOK( pcReadBitStream->getPosition( iPos ) );
    do
    {
      RNOK( xGetNextValidPacket( pcBinData, pcReadBitStream, uiTopLayer, uiLayer, uiFGSLayer, uiLevel, bIndependent, bEOS, auiFrameNumAnalysis ) );
      pcBinData->setMemAccessor( cBinDataAccessor );

      bFinishChecking = false;

      RNOK( m_pcH264AVCDecoder->checkSliceLayerDependency( &cBinDataAccessor, bFinishChecking ) );
      RNOK( pcReadBitStream->releasePacket( pcBinData ) );

    } while( !bFinishChecking );


#define MAX_FRAGMENTS 10 // see H264AVCDecoderTest::go()

    Bool            bFragmented       = false;
    Bool            bDiscardable      = false;
    Bool            bStart            = false;
    Bool            bFirst            = true;
    Bool            bConcatenated     = false;
    UInt            uiTotalLength     = 0;
    UInt            uiFragmentNumber  = 0;
    BinData*        apcBinDataTmp       [MAX_FRAGMENTS];
    BinDataAccessor acBinDataAccessorTmp[MAX_FRAGMENTS];
    UInt            auiStartPos         [MAX_FRAGMENTS];
    UInt            auiEndPos           [MAX_FRAGMENTS];

    for( pcBinData = 0, bEOS = false; !bStart && !bEOS; )
    {
      if( bFirst )
      {
        RNOK( pcReadBitStream->setPosition( iPos ) );
        bFirst = false;
      }
      RNOK( xGetNextValidPacket( apcBinDataTmp[uiFragmentNumber], pcReadBitStream, uiTopLayer, uiLayer, uiFGSLayer, uiLevel, bIndependent, bEOS, auiFrameNumDecoding ) );
      ::memcpy( auiFrameNumAnalysis, auiFrameNumDecoding, MAX_LAYERS*sizeof(UInt) );
      apcBinDataTmp[uiFragmentNumber]->setMemAccessor( acBinDataAccessorTmp[uiFragmentNumber] );

      RNOK( m_pcH264AVCDecoder->initPacket( &acBinDataAccessorTmp[uiFragmentNumber],
                                            uiNalUnitType, uiMbX, uiMbY, uiSize,
                      //uiNonRequiredPic,  //NonRequired JVT-Q066
                      true, false, //FRAG_FIX_3
                                            bStart, auiStartPos[uiFragmentNumber], auiEndPos[uiFragmentNumber],
                                            bFragmented, bDiscardable ) );
//prefix unit{{
		  if(uiNalUnitType == 14)
		  {
				m_pcH264AVCDecoder->decreaseNumOfNALInAU();
				RNOK( pcReadBitStream->releasePacket( apcBinDataTmp[uiFragmentNumber] ) );
				break;
		  }
//prefix unit}}

//NonRequired JVT-Q066
    /*
    if( uiNonRequiredPic )
    {
      continue;
    }
*/
//NonRequired JVT-Q066

      uiTotalLength += ( auiEndPos[uiFragmentNumber] - auiStartPos[uiFragmentNumber] );

      if( !bStart )
      {
        uiFragmentNumber++;
      }
      else
      {
        if( apcBinDataTmp[0]->size() != 0 )
        {
          pcBinData = new BinData();
          pcBinData->set( new UChar[uiTotalLength], uiTotalLength );
          UInt uiOffset  = 0;
          for( UInt uiFragment = 0; uiFragment <= uiFragmentNumber; uiFragment++ )
          {
            ::memcpy  ( pcBinData->data()+uiOffset,
                        apcBinDataTmp[uiFragment]->data() + auiStartPos[uiFragment],
                        auiEndPos[uiFragment] - auiStartPos[uiFragment] );
            uiOffset += auiEndPos[uiFragment] - auiStartPos[uiFragment];
 
            RNOK( pcReadBitStream->releasePacket( apcBinDataTmp[uiFragment] ) );
            apcBinDataTmp[uiFragment] = 0;
            m_pcH264AVCDecoder->decreaseNumOfNALInAU();

            if( uiFragment > 0 )
            {
              bConcatenated = true;
            }
          }

          pcBinData->setMemAccessor( cBinDataAccessor );
          bToDecode = false;
          if( ( uiTotalLength != 0 ) && ( !bDiscardable || bFragmented ) )
          {
            if( ( uiNalUnitType == 20 ) || ( uiNalUnitType == 21 ) || ( uiNalUnitType == 1 ) || ( uiNalUnitType == 5 ) )
            {

              RNOK( m_pcH264AVCDecoder->initPacket( &cBinDataAccessor, uiNalUnitType,
                                                    uiMbX, uiMbY, uiSize,
                          //uiNonRequiredPic, //NonRequired JVT-Q066
                                                    false, bConcatenated, bStart,
                                                    auiStartPos[uiFragmentNumber+1], auiEndPos[uiFragmentNumber+1],
                                                    bFragmented, bDiscardable ) );
            }
            else
            {
              RNOK( m_pcH264AVCDecoder->initPacket( &cBinDataAccessor ) );
            }
            bToDecode = true;
          }
        }
       //manu.mathew@samsung : memory leak fix
        else
        {
            RNOK( pcReadBitStream->releasePacket( apcBinDataTmp[0] ) );
          apcBinDataTmp[0] = NULL;
        }
       //--
      }
    }


//prefix unit{{
		  if(uiNalUnitType == 14)
		  {
				continue;
		  }
//prefix unit}}
		Bool bWasAVCNALUnit = ( uiNalUnitType == 1 || uiNalUnitType == 5 );

//NonRequired JVT-Q066{
  if(m_pcH264AVCDecoder->isNonRequiredPic())
    continue;
//NonRequired JVT-Q066}

    if( bToDecode )
    {
      //----- get pic buffer -----
      pcPicBuffer = 0;
      if( uiNalUnitType == 1 || uiNalUnitType == 5 || uiNalUnitType == 20 || uiNalUnitType == 21 )
      {
        RNOK( xGetNewPicBuffer( pcPicBuffer, uiSize ) );
        if( !bYuvDimSet )
        {
          RNOK( xGetNewPicBuffer( pcPicBufferOrig, uiSize ) );
          UInt uiLumSize  = ((uiMbX<<3)+  YUV_X_MARGIN) * ((uiMbY<<3)    + YUV_Y_MARGIN ) * 4;
          uiLumOffset     = ((uiMbX<<4)+2*YUV_X_MARGIN) * YUV_Y_MARGIN   + YUV_X_MARGIN;
          uiCbOffset      = ((uiMbX<<3)+  YUV_X_MARGIN) * YUV_Y_MARGIN/2 + YUV_X_MARGIN/2 +   uiLumSize;
          uiCrOffset      = ((uiMbX<<3)+  YUV_X_MARGIN) * YUV_Y_MARGIN/2 + YUV_X_MARGIN/2 + 5*uiLumSize/4;
          bYuvDimSet      = true;
        }
      }

      //----- decode packet -----
      {
        //----- re-direct stdout -----
#if WIN32 // for linux, this have to be slightly re-formulated
        Int   orig_stdout     = _dup(1);
        FILE* stdout_copy     = freopen( tmp_file_name, "wt", stdout );
#endif
//bug-fix suffix{{
    if(uiNalUnitType == 1 || uiNalUnitType == 5)
    {
      SuffixEnable = true;
      RNOK(m_pcH264AVCDecoderSuffix->init( false ));
      RNOK( pcReadBitStream->getPosition( iPos ) );
      RNOK( pcReadBitStream->extractPacket( pcBinData, bEOS ) );
      pcBinData->setMemAccessor( cBinDataAccessor );
      RNOK( m_pcH264AVCDecoderSuffix->initPacketSuffix( &cBinDataAccessor, uiNalUnitType, true,
          false, //FRAG_FIX_3
          bStart, m_pcH264AVCDecoder,SuffixEnable
          )
        );

      RNOK( m_pcH264AVCDecoderSuffix->uninit( false ));

      if( !SuffixEnable )
      {
        RNOK( pcReadBitStream->setPosition( iPos ) );
        bEOS = false;
      }
      else
      {
      //  m_pcH264AVCDecoder->decreaseNumOfNALInAU(); //{suffix TL read
      }
    }
//bug-fix suffix}}
        //----- decode -----
        RNOK( m_pcH264AVCDecoder->process( pcPicBuffer,
                                           cPicBufferOutputList,
                                           cPicBufferUnusedList,
                                           cPicBufferReleaseList ) );

        if( bWasAVCNALUnit && m_pcH264AVCDecoder->getBaseSVCActive() )
        {
          RNOK( xGetNewPicBuffer( pcPicBuffer, uiSize ) );
          RNOK( m_pcH264AVCDecoder->process( pcPicBuffer, cPicBufferOutputList, cPicBufferUnusedList, cPicBufferReleaseList ) );
        }

        //---- restore stdout -----
#if WIN32 // for linux, this have to be slightly re-formulated
        fclose( stdout );
        _dup2( orig_stdout, 1 );
        _iob[1] = *fdopen( 1, "wt" );
        fclose(  fdopen( orig_stdout, "w" ) );
#endif
      }

      //----- determine distortion (and output for debugging) -----
      while( ! cPicBufferOutputList.empty() )
      {
        PicBuffer* pcPicBufferTmp = cPicBufferOutputList.front();
        cPicBufferOutputList.pop_front();
        if( pcPicBufferTmp )
        {
          //----- output (for debugging) -----
          if( pcWriteYuv )
          {
            RNOK( pcWriteYuv->writeFrame( *pcPicBufferTmp + uiLumOffset,
                                          *pcPicBufferTmp + uiCbOffset,
                                          *pcPicBufferTmp + uiCrOffset,
                                           uiMbY << 4,
                                           uiMbX << 4,
                                          (uiMbX << 4) + YUV_X_MARGIN*2 ) );
          }

          //----- read in reference picture ------
          RNOK( pcReadYuv->readFrame    ( *pcPicBufferOrig + uiLumOffset,
                                          *pcPicBufferOrig + uiCbOffset,
                                          *pcPicBufferOrig + uiCrOffset,
                                           uiMbY << 4,
                                           uiMbX << 4,
                                          (uiMbX << 4) + YUV_X_MARGIN*2 ) );

          //----- get distortion -----
          RNOK( xGetDistortion          (  auiDistortion[uiFrame],
                                          *pcPicBufferTmp  + uiLumOffset,
                                          *pcPicBufferOrig + uiLumOffset,
                                           uiMbY << 4,
                                           uiMbX << 4,
                                          (uiMbX << 4) + YUV_X_MARGIN*2 ) );

⌨️ 快捷键说明

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