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

📄 qualitylevelassigner.cpp

📁 JVT-Z203_jsvm.rar
💻 CPP
📖 第 1 页 / 共 5 页
字号:

  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
  UInt              uiFrame           = 0;
  UInt              uiMbX             = 0;
  UInt              uiMbY             = 0;
  UInt              uiSize            = 0;
  UInt              auiCropping[4];

  UInt              uiLumOffset       = 0;
  UInt              uiCbOffset        = 0;
  UInt              uiCrOffset        = 0;
  UInt              uiLumWidth        = 0;
  UInt              uiLumHeight       = 0;
  UInt              uiLumStride       = 0;
  PicBuffer*        pcPicBuffer       = 0;
  PicBuffer*        pcPicBufferOrig   = 0;
  WriteYuvToFile*   pcWriteYuv        = 0;
  PicBufferList     cPicBufferOutputList;
  PicBufferList     cPicBufferUnusedList;
  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 };

  //===== 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 ) );
    RNOK( pcWriteYuv->init( std::string( acName ) ) );
  }

  //-----------------------------------------------------------
  //=====                                                 =====
  //=====   L O O P   O V E R   A C C E S S   U N I T S   =====
  //=====                                                 =====
  //-----------------------------------------------------------
  Bool              bFirstAccessUnit = true;
  h264::AccessUnit  cAccessUnit;
  while( ! cAccessUnit.isEndOfStream() )
  {
    //===== read next access unit =====
    while( ! cAccessUnit.isComplete() )
    {
      BinData*  pcBinData = 0;
      Bool      bEOS      = false; // dummy
      RNOK( xGetNextValidPacket( pcBinData, pcReadBitStream, uiTopLayer, uiLayer, uiFGSLayer, uiLevel, bIndependent, bEOS, auiFrameNumAnalysis ) );
      RNOK( m_pcH264AVCDecoder->initNALUnit ( pcBinData, cAccessUnit ) );
      RNOK( pcReadBitStream->releasePacket  ( pcBinData ) );
    }

    //===== set dimensions =====
    if( bFirstAccessUnit )
    {
      const h264::SliceDataNALUnit* pcSliceDataNalUnit = cAccessUnit.getLastVCLNalUnit();
      ROF( pcSliceDataNalUnit );
      uiMbX             = pcSliceDataNalUnit->getFrameWidthInMb  ();
      uiMbY             = pcSliceDataNalUnit->getFrameHeightInMb ();
      UInt uiChromaSize = ( ( uiMbX << 3 ) + YUV_X_MARGIN     ) * ( ( uiMbY << 3 ) + YUV_Y_MARGIN );
      uiLumOffset       = ( ( uiMbX << 4 ) + YUV_X_MARGIN * 2 ) * YUV_Y_MARGIN     + YUV_X_MARGIN;
      uiCbOffset        = ( ( uiMbX << 3 ) + YUV_X_MARGIN     ) * YUV_Y_MARGIN / 2 + YUV_X_MARGIN / 2 + uiChromaSize * 4;
      uiCrOffset        = ( ( uiMbX << 3 ) + YUV_X_MARGIN     ) * YUV_Y_MARGIN / 2 + YUV_X_MARGIN / 2 + uiChromaSize * 5;
      uiLumHeight       =   ( uiMbY << 4 );
      uiLumWidth        =   ( uiMbX << 4 );
      uiLumStride       =   ( uiMbX << 4 ) + YUV_X_MARGIN * 2;
      uiSize            = 6 * uiChromaSize;
      auiCropping[0]    = pcSliceDataNalUnit->getCroppingRectangle ()[0];
      auiCropping[1]    = pcSliceDataNalUnit->getCroppingRectangle ()[1];
      auiCropping[2]    = pcSliceDataNalUnit->getCroppingRectangle ()[2];
      auiCropping[3]    = pcSliceDataNalUnit->getCroppingRectangle ()[3];
      bFirstAccessUnit  = false;
      RNOK( xGetNewPicBuffer( pcPicBufferOrig, uiSize ) );
    }

    //===== process access unit =====
    while( cAccessUnit.isComplete() )
    {
      //----- decode NAL unit -----
      BinDataList     cBinDataList; // dummy
      h264::NALUnit*  pcNalUnit  = 0;
      pcPicBuffer                = 0;
      RNOK( cAccessUnit.getAndRemoveNextNalUnit( pcNalUnit ) );
      RNOK( xGetNewPicBuffer( pcPicBuffer, uiSize ) );
#if WIN32 // for linux, this has to be slightly re-formulated
      // re-direct stdout 
      Int   orig_stdout     = _dup(1);
      FILE* stdout_copy     = freopen( tmp_file_name, "wt", stdout );
#endif
      RNOK( m_pcH264AVCDecoder->processNALUnit( pcPicBuffer, cPicBufferOutputList, cPicBufferUnusedList, cBinDataList, *pcNalUnit ) );
#if WIN32 // for linux, this have to be slightly re-formulated
      // restore stdout
      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.popFront();
        if( pcPicBufferTmp )
        {
          //----- output (for debugging) -----
          if( pcWriteYuv )
          {
            RNOK( pcWriteYuv->writeFrame( *pcPicBufferTmp + uiLumOffset,
                                          *pcPicBufferTmp + uiCbOffset,
                                          *pcPicBufferTmp + uiCrOffset,
                                          uiLumHeight, uiLumWidth, uiLumStride, auiCropping ) );
          }
          //----- read in reference picture ------
          RNOK( pcReadYuv->readFrame    ( *pcPicBufferOrig + uiLumOffset,
                                          *pcPicBufferOrig + uiCbOffset,
                                          *pcPicBufferOrig + uiCrOffset,
                                          uiLumHeight, uiLumWidth, uiLumStride ) );

          //----- get distortion -----
          RNOK( xGetDistortion          ( auiDistortion[uiFrame],
                                          *pcPicBufferTmp  + uiLumOffset,
                                          *pcPicBufferOrig + uiLumOffset,
                                          uiLumHeight, uiLumWidth, uiLumStride ) );

          //----- increment output picture number -----
          uiFrame++;
          if( uiLevel == MSYS_UINT_MAX )
            printf( "\rdetermine distortion (layer %d - FGS %d - base layer  ) --> frame %d completed", uiLayer, uiFGSLayer,                                    uiFrame );
          else
            printf( "\rdetermine distortion (layer %d - FGS %d - lev%2d - %s ) --> frame %d completed", uiLayer, uiFGSLayer, uiLevel, bIndependent?"ind":"dep", uiFrame );
        }
      }
 
      //----- free buffers and delete slice data NAL units -----
      RNOK( xRemovePicBuffer( cPicBufferUnusedList  ) );
      delete pcNalUnit;
    }
  }


  //----- remove original pic buffer -----
  PicBufferList cPicBufferListOrig; cPicBufferListOrig.push_back( pcPicBufferOrig );
  RNOK( xRemovePicBuffer( cPicBufferListOrig ) );
#if WIN32
  remove( tmp_file_name );
#endif


  //===== uninit =====
  RNOK( m_pcH264AVCPacketAnalyzer ->uninit  () );
  RNOK( m_pcH264AVCDecoder        ->uninit  ( true ) );
  RNOK( pcReadBitStream           ->uninit  () );
  RNOK( pcReadYuv                 ->uninit  () );
  RNOK( pcReadBitStream           ->destroy () );
  RNOK( pcReadYuv                 ->destroy () );
  if( pcWriteYuv )
  {
    RNOK( pcWriteYuv->destroy() );
  }

  //---- re-create decoder (there's something wrong) -----
  RNOK( m_pcH264AVCDecoder->destroy() );
  RNOK( CreaterH264AVCDecoder::create( m_pcH264AVCDecoder ) );

  printf("\n");

  return Err::m_nOK;
}


ErrVal
QualityLevelAssigner::xWriteDataFile( const std::string&  cFileName )
{
  printf( "write data to file \"%s\" ...", cFileName.c_str() );

  FILE* pFile = fopen( cFileName.c_str(), "wt" );
  if( !pFile )
  {
    fprintf( stderr, "\nERROR: Cannot open file \"%s\" for writing!\n\n", cFileName.c_str() );
    return Err::m_nERR;
  }

  for( UInt uiLayer = 0; uiLayer <  m_uiNumLayers;               uiLayer ++ )
  for( UInt uiFGS   = 0; uiFGS   <= m_auiNumFGSLayers[uiLayer];  uiFGS   ++ )
  for( UInt uiFrame = 0; uiFrame <  m_auiNumFrames   [uiLayer];  uiFrame ++ )
  {
    fprintf( pFile,
             "%d  %d  %5d  %6d  %lf\n",
              uiLayer, uiFGS, uiFrame,
              m_aaauiPacketSize [uiLayer][uiFGS][uiFrame],
              m_aaadDeltaDist   [uiLayer][uiFGS][uiFrame] );

  }

  fclose( pFile );

  printf("\n");
  return Err::m_nOK;
}


ErrVal
QualityLevelAssigner::xReadDataFile( const std::string&  cFileName )
{
  printf( "read data from file \"%s\" ...", cFileName.c_str() );

  FILE* pFile = fopen( cFileName.c_str(), "rt" );
  if( !pFile )
  {
    fprintf( stderr, "\nERROR: Cannot open file \"%s\" for reading!\n\n", cFileName.c_str() );
    return Err::m_nERR;
  }

  Bool    bEOS    = false;
  UInt    uiLayer, uiFGS, uiFrame, uiPacketSize, uiNumPackets;
  Double  dDeltaDist;
  for( uiNumPackets = 0; !bEOS; uiNumPackets++ )
  {
    Int iNumRead = fscanf( pFile,
                           " %d %d %d %d %lf",
                           &uiLayer, &uiFGS, &uiFrame, &uiPacketSize, &dDeltaDist );
    if( iNumRead == 5 )
    {
      ROF( uiLayer <  m_uiNumLayers );
      ROF( uiFGS   <= m_auiNumFGSLayers[uiLayer] );
      ROF( uiFrame <  m_auiNumFrames   [uiLayer] );
      m_aaauiPacketSize [uiLayer][uiFGS][uiFrame]  = uiPacketSize;
      m_aaadDeltaDist   [uiLayer][uiFGS][uiFrame]  = dDeltaDist;
    }
    else
    {
      bEOS = true;
      uiNumPackets--;
    }
  }

  //----- check number of elements -----
  UInt uiTargetPackets = 0;
  for( uiLayer = 0; uiLayer < m_uiNumLayers; uiLayer++ )
  {
    uiTargetPackets += ( 1 + m_auiNumFGSLayers[uiLayer] ) * m_auiNumFrames[uiLayer];
  }
  if( uiTargetPackets != uiNumPackets )
  {
    fprintf( stderr, "\nERROR: File \"%s\" contains incomplete data!\n\n", cFileName.c_str() );
    return Err::m_nERR;
  }

  fclose( pFile );

  printf("\n");
  return Err::m_nOK;
}



ErrVal
QualityLevelAssigner::xDetermineQualityIDs()
{
  printf( "determine quality levels ..." );

  //===== determine minimum and maximum quality level id's =====
  UInt  auiMinQualityLevel[MAX_LAYERS];
  UInt  auiMaxQualityLevel[MAX_LAYERS];
  {
    for( Int iLayer = (Int)m_uiNumLayers-1; iLayer >= 0; iLayer-- )
    {
      UInt  uiMinQLLayer          = ( iLayer == (Int)m_uiNumLayers-1 ? 0 : auiMaxQualityLevel[iLayer+1]+1 );
      UInt  uiNumQLInLayer        = ( 63 - uiMinQLLayer ) / ( iLayer + 1 );
      auiMinQualityLevel[iLayer]  = uiMinQLLayer;
      auiMaxQualityLevel[iLayer]  = uiMinQLLayer + uiNumQLInLayer - 1;
    }
  }

  //===== determine optimized quality levels per layer =====
  for( UInt uiLayer = 0; uiLayer < m_uiNumLayers; uiLayer++ )
  {
    //----- create quality estimation object -----
    QualityLevelEstimation  cQualityLevelEstimation;
    RNOK( cQualityLevelEstimation.init( m_uiNumLayers, m_auiNumFGSLayers, m_auiNumFrames ) );

    //----- initialize with packets -----
    {
      for( UInt uiFGSLayer = 1; uiFGSLayer <= m_auiNumFGSLayers[uiLayer]; uiFGSLayer++ )
      for( UInt uiFrame    = 0; uiFrame    <  m_auiNumFrames   [uiLayer]; uiFrame   ++ )
      {
        RNOK( cQualityLevelEstimation.addPacket( uiLayer, uiFGSLayer, uiFrame,
                                                 m_aaauiPacketSize [uiLayer][uiFGSLayer][uiFrame],
                                                 m_aaadDeltaDist   [uiLayer][uiFGSLayer][uiFrame] ) );
      }
    }

    //----- determine quality levels -----
    RNOK( cQualityLevelEstimation.optimizeQualityLevel( uiLayer, uiLayer, auiMinQualityLevel[uiLayer], auiMaxQualityLevel[uiLayer] ) );

    //----- assign quality levels -----
    {
      for( UInt uiFGSLayer = 0; uiFGSLayer <= m_auiNumFGSLayers[uiLayer]; uiFGSLayer++ )
      for( UInt uiFrame    = 0; uiFrame    <  m_auiNumFrames   [uiLayer]; uiFrame   ++ )
      {
        m_aaauiQualityID[uiLayer][uiFGSLayer][uiFrame] = ( uiFGSLayer ? cQualityLevelEstimation.getQualityId( uiLayer, uiFGSLayer, uiFrame ) : 63 );
      }
    }
  }

  printf("\n");
  return Err::m_nOK;
}

//JVT-S043
ErrVal
QualityLevelAssigner::xDetermineMultiLayerQualityIDs()
{
  printf( "determine ML quality levels ..." );

  //===== determine minimum and maximum quality level id's =====
  UInt  uiMinQualityLevel = 0;
  UInt  uiMaxQualityLevel = 62;

  UInt uiLayer;

 //----- create quality estimation object -----
  QualityLevelEstimation  cQualityLevelEstimation;
  RNOK( cQualityLevelEstimation.init( m_uiNumLayers, m_auiNumFGSLayers, m_auiNumFrames ) );

  //===== determine optimized quality levels per layer =====
  for( uiLayer = 0; uiLayer < m_uiNumLayers; uiLayer++ )
  {
    //----- initialize with packets -----
    {
      for( UInt uiFGSLayer = 1; uiFGSLayer <= m_auiNumFGSLayers[uiLayer]; uiFGSLayer++ )

⌨️ 快捷键说明

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