Skip to content
Snippets Groups Projects
Picture.cpp 41.5 KiB
Newer Older
  • Learn to ignore specific revisions
  •   {
        const int destID = scheduler.getSplitPicId( tId );
    
        M_BUFS( destID, PIC_RECONSTRUCTION ).subBuf( clipdArea ).copyFrom( M_BUFS( sourceID, PIC_RECONSTRUCTION ).subBuf( clipdArea ) );
      }
    }
    
    #if ENABLE_WPP_PARALLELISM
    void Picture::finishCtuPart( const UnitArea& ctuArea )
    {
      const UnitArea clipdArea = clipArea( ctuArea, *this );
      const int      sourceID  = scheduler.getSplitPicId( 0 );
      // distribute the reconstruction across all of the parallel workers
      for( int dataId = 0; dataId < scheduler.getNumPicInstances(); dataId++ )
      {
        if( dataId == sourceID ) continue;
    
        M_BUFS( dataId, PIC_RECONSTRUCTION ).subBuf( clipdArea ).copyFrom( M_BUFS( sourceID, PIC_RECONSTRUCTION ).subBuf( clipdArea ) );
      }
    }
    #endif
    
    #endif
    
    
    #if JVET_O1164_RPR
    const TFilterCoeff InterpolationFilterSRC[16][8] =
    {
      {  0, 0,   0, 64,  0,   0,  0,  0 },
      {  0, 1,  -3, 63,  4,  -2,  1,  0 },
      { -1, 2,  -5, 62,  8,  -3,  1,  0 },
      { -1, 3,  -8, 60, 13,  -4,  1,  0 },
      { -1, 4, -10, 58, 17,  -5,  1,  0 },
      { -1, 4, -11, 52, 26,  -8,  3, -1 },
      { -1, 3,  -9, 47, 31, -10,  4, -1 },
      { -1, 4, -11, 45, 34, -10,  4, -1 },
      { -1, 4, -11, 40, 40, -11,  4, -1 },
      { -1, 4, -10, 34, 45, -11,  4, -1 },
      { -1, 4, -10, 31, 47,  -9,  3, -1 },
      { -1, 3,  -8, 26, 52, -11,  4, -1 },
      {  0, 1,  -5, 17, 58, -10,  4, -1 },
      {  0, 1,  -4, 13, 60,  -8,  3, -1 },
      {  0, 1,  -3,  8, 62,  -5,  2, -1 },
      {  0, 1,  -2,  4, 63,  -3,  1,  0 }
    };
    
    const TFilterCoeff DownsamplingFilterSRC[16][12] =
    {
          //{   0,   0,    0,   0,   0,  128,   0,   0,      0,    0,  0,   0}, //0
          {   0,   5,   -6,  -10,  37,  76,   37,  -10,  -6,    5,  0,   0}, //0
          {   0,   5,   -4,  -11,  33,  76,   40,  -9,    -7,    5,  0,   0}, //1
          //{   0,   5,   -3,  -12,  28,  75,   44,  -7,    -8,    5,  1,   0}, //2
          {  -1,   5,   -3,  -12,  29,  75,   45,  -7,    -8,   5,  0,   0}, //2 new coefficients in m24499
          {  -1,   4,   -2,  -13,  25,  75,   48,  -5,    -9,    5,  1,   0}, //3
          {  -1,   4,   -1,  -13,  22,  73,   52,  -3,    -10,  4,  1,   0}, //4
          {  -1,   4,   0,    -13,  18,  72,   55,  -1,    -11,  4,  2,  -1}, //5
          {  -1,   4,   1,    -13,  14,  70,   59,  2,    -12,  3,  2,  -1}, //6
          {  -1,   3,   1,    -13,  11,  68,   62,  5,    -12,  3,  2,  -1}, //7
          {  -1,   3,   2,    -13,  8,  65,   65,  8,    -13,  2,  3,  -1}, //8
          {  -1,   2,   3,    -12,  5,  62,   68,  11,    -13,  1,  3,  -1}, //9
          {  -1,   2,   3,    -12,  2,  59,   70,  14,    -13,  1,  4,  -1}, //10
          {  -1,   2,   4,    -11,  -1,  55,   72,  18,    -13,  0,  4,  -1}, //11
          {   0,   1,   4,    -10,  -3,  52,   73,  22,    -13,  -1,  4,  -1}, //12
          {   0,   1,   5,    -9,    -5,  48,   75,  25,    -13,  -2,  4,  -1}, //13
          //{   0,   1,   5,    -8,    -7,  44,   75,  28,    -12,  -3,  5,   0}, //14
          {    0,   0,   5,    -8,   -7,  45,   75,  29,    -12,  -3,  5,  -1}  , //14 new coefficients in m24499  
          {   0,   0,   5,    -7,    -9,  40,   76,  33,    -11,  -4,  5,   0}, //15
    };
    
    void Picture::sampleRateConv( const Pel* orgSrc, SizeType orgWidth, SizeType orgHeight, SizeType orgStride, Pel* scaledSrc, SizeType scaledWidth, SizeType scaledHeight, SizeType scaledStride, int bitDepth, const bool downsampling )
    {
      if( orgWidth == scaledWidth && orgHeight == scaledHeight )
      {
        for( int j = 0; j < orgHeight; j++ )
        {
          memcpy( scaledSrc + j * scaledStride, orgSrc + j * orgStride, sizeof( Pel ) * orgWidth );
        }
    
        return;
      }
    
      const TFilterCoeff* filter = downsampling ? &DownsamplingFilterSRC[0][0] : &InterpolationFilterSRC[0][0];
      const int filerLength = downsampling ? 12 : 8;
      const int log2Norm = downsampling ? 14 : 12;
    
      int *buf = new int[orgHeight * scaledWidth];
      int maxVal = ( 1 << bitDepth ) - 1;
    
      CHECK( bitDepth > 17, "Overflow may happen!" );
    
      for( int i = 0; i < scaledWidth; i++ )
      {
        const Pel* org = orgSrc;
        int integer = ( i * orgWidth ) / scaledWidth;
        int frac = ( ( i * orgWidth << 4 ) / scaledWidth ) & 15;
    
        int* tmp = buf + i;
    
        for( int j = 0; j < orgHeight; j++ )
        {
          int sum = 0;
          const TFilterCoeff* f = filter + frac * filerLength;
    
          for( int k = 0; k < filerLength; k++ )
          {
            int xInt = std::min<int>( std::max( 0, integer + k - filerLength / 2 + 1 ), orgWidth - 1 );
            sum += f[k] * org[xInt]; // postpone horizontal filtering gain removal after vertical filtering
          }
    
          *tmp = sum;
    
          tmp += scaledWidth;
          org += orgStride;
        }
      }
    
      Pel* dst = scaledSrc;
    
      for( int j = 0; j < scaledHeight; j++ )
      {
        int integer = ( j * orgHeight ) / scaledHeight;
        int frac = ( ( j * orgHeight << 4 ) / scaledHeight ) & 15;
    
        for( int i = 0; i < scaledWidth; i++ )
        {
          int sum = 0;
          int* tmp = buf + i;
          const TFilterCoeff* f = filter + frac * filerLength;
    
          for( int k = 0; k < filerLength; k++ )
          {
            int yInt = std::min<int>( std::max( 0, integer + k - filerLength / 2 + 1 ), orgHeight - 1 );
            sum += f[k] * tmp[yInt*scaledWidth];
          }
    
          dst[i] = std::min<int>( std::max( 0, ( sum + ( 1 << ( log2Norm - 1 ) ) ) >> log2Norm ), maxVal );
        }
    
        dst += scaledStride;
      }
    
      delete[] buf;
    }
    
    void Picture::rescalePicture( const CPelUnitBuf& beforeScaling, const PelUnitBuf& afterScaling, const ChromaFormat chromaFormatIDC, const BitDepths& bitDepths, const bool downsampling )
    {
      for( int comp = 0; comp < ::getNumberValidComponents( chromaFormatIDC ); comp++ )
      {
        const CPelBuf& beforeScale = beforeScaling.get( ComponentID( comp ) );
        const PelBuf& afterScale = afterScaling.get( ComponentID( comp ) );
    
        Picture::sampleRateConv( beforeScale.buf, beforeScale.width, beforeScale.height, beforeScale.stride, afterScale.buf, afterScale.width, afterScale.height, afterScale.stride, bitDepths.recon[comp], downsampling );
      }
    }
    #endif
    
    
    void Picture::extendPicBorder()
    {
      if ( m_bIsBorderExtended )
      {
        return;
      }
    
      for(int comp=0; comp<getNumberValidComponents( cs->area.chromaFormat ); comp++)
      {
        ComponentID compID = ComponentID( comp );
        PelBuf p = M_BUFS( 0, PIC_RECONSTRUCTION ).get( compID );
        Pel *piTxt = p.bufAt(0,0);
        int xmargin = margin >> getComponentScaleX( compID, cs->area.chromaFormat );
        int ymargin = margin >> getComponentScaleY( compID, cs->area.chromaFormat );
    
        Pel*  pi = piTxt;
        // do left and right margins
    
    Philippe Hanhart's avatar
    Philippe Hanhart committed
          for (int y = 0; y < p.height; y++)
          {
            for (int x = 0; x < xmargin; x++ )
            {
              pi[ -xmargin + x ] = pi[0];
              pi[  p.width + x ] = pi[p.width-1];
            }
            pi += p.stride;
          }
    
    
        // pi is now the (0,height) (bottom left of image within bigger picture
        pi -= (p.stride + xmargin);
        // pi is now the (-marginX, height-1)
        for (int y = 0; y < ymargin; y++ )
        {
          ::memcpy( pi + (y+1)*p.stride, pi, sizeof(Pel)*(p.width + (xmargin << 1)));
        }
    
        // pi is still (-marginX, height-1)
        pi -= ((p.height-1) * p.stride);
        // pi is now (-marginX, 0)
        for (int y = 0; y < ymargin; y++ )
        {
          ::memcpy( pi - (y+1)*p.stride, pi, sizeof(Pel)*(p.width + (xmargin<<1)) );
        }
    
        // reference picture with horizontal wrapped boundary
        if (cs->sps->getWrapAroundEnabledFlag())
        {
          p = M_BUFS( 0, PIC_RECON_WRAP ).get( compID );
          p.copyFrom(M_BUFS( 0, PIC_RECONSTRUCTION ).get( compID ));
          piTxt = p.bufAt(0,0);
          pi = piTxt;
          int xoffset = cs->sps->getWrapAroundOffset() >> getComponentScaleX( compID, cs->area.chromaFormat );
          for (int y = 0; y < p.height; y++)
          {
            for (int x = 0; x < xmargin; x++ )
            {
    
              if( x < xoffset )
    
              {
                pi[ -x - 1 ] = pi[ -x - 1 + xoffset ];
                pi[  p.width + x ] = pi[ p.width + x - xoffset ];
              }
    
              {
                pi[ -x - 1 ] = pi[ 0 ];
                pi[  p.width + x ] = pi[ p.width - 1 ];
              }
            }
            pi += p.stride;
          }
          pi -= (p.stride + xmargin);
          for (int y = 0; y < ymargin; y++ )
          {
            ::memcpy( pi + (y+1)*p.stride, pi, sizeof(Pel)*(p.width + (xmargin << 1)));
          }
          pi -= ((p.height-1) * p.stride);
          for (int y = 0; y < ymargin; y++ )
          {
            ::memcpy( pi - (y+1)*p.stride, pi, sizeof(Pel)*(p.width + (xmargin<<1)) );
          }
        }
    
      }
    
      m_bIsBorderExtended = true;
    }
    
    PelBuf Picture::getBuf( const ComponentID compID, const PictureType &type )
    {
    
      return M_BUFS( ( type == PIC_ORIGINAL || type == PIC_TRUE_ORIGINAL ) ? 0 : scheduler.getSplitPicId(), type ).getBuf( compID );
    
    }
    
    const CPelBuf Picture::getBuf( const ComponentID compID, const PictureType &type ) const
    {
    
      return M_BUFS( ( type == PIC_ORIGINAL || type == PIC_TRUE_ORIGINAL ) ? 0 : scheduler.getSplitPicId(), type ).getBuf( compID );
    
    }
    
    PelBuf Picture::getBuf( const CompArea &blk, const PictureType &type )
    {
      if( !blk.valid() )
      {
        return PelBuf();
      }
    
    #if ENABLE_SPLIT_PARALLELISM
    
      const int jId = ( type == PIC_ORIGINAL || type == PIC_TRUE_ORIGINAL ) ? 0 : scheduler.getSplitPicId();
    
    
    #endif
    #if !KEEP_PRED_AND_RESI_SIGNALS
      if( type == PIC_RESIDUAL || type == PIC_PREDICTION )
      {
        CompArea localBlk = blk;
        localBlk.x &= ( cs->pcv->maxCUWidthMask  >> getComponentScaleX( blk.compID, blk.chromaFormat ) );
        localBlk.y &= ( cs->pcv->maxCUHeightMask >> getComponentScaleY( blk.compID, blk.chromaFormat ) );
    
        return M_BUFS( jId, type ).getBuf( localBlk );
      }
    #endif
    
      return M_BUFS( jId, type ).getBuf( blk );
    }
    
    const CPelBuf Picture::getBuf( const CompArea &blk, const PictureType &type ) const
    {
      if( !blk.valid() )
      {
        return PelBuf();
      }
    
    #if ENABLE_SPLIT_PARALLELISM
    
      const int jId = ( type == PIC_ORIGINAL || type == PIC_TRUE_ORIGINAL ) ? 0 : scheduler.getSplitPicId();
    
    
    #endif
    #if !KEEP_PRED_AND_RESI_SIGNALS
      if( type == PIC_RESIDUAL || type == PIC_PREDICTION )
      {
        CompArea localBlk = blk;
        localBlk.x &= ( cs->pcv->maxCUWidthMask  >> getComponentScaleX( blk.compID, blk.chromaFormat ) );
        localBlk.y &= ( cs->pcv->maxCUHeightMask >> getComponentScaleY( blk.compID, blk.chromaFormat ) );
    
        return M_BUFS( jId, type ).getBuf( localBlk );
      }
    #endif
    
      return M_BUFS( jId, type ).getBuf( blk );
    }
    
    PelUnitBuf Picture::getBuf( const UnitArea &unit, const PictureType &type )
    {
      if( chromaFormat == CHROMA_400 )
      {
        return PelUnitBuf( chromaFormat, getBuf( unit.Y(), type ) );
      }
      else
      {
        return PelUnitBuf( chromaFormat, getBuf( unit.Y(), type ), getBuf( unit.Cb(), type ), getBuf( unit.Cr(), type ) );
      }
    }
    
    const CPelUnitBuf Picture::getBuf( const UnitArea &unit, const PictureType &type ) const
    {
      if( chromaFormat == CHROMA_400 )
      {
        return CPelUnitBuf( chromaFormat, getBuf( unit.Y(), type ) );
      }
      else
      {
        return CPelUnitBuf( chromaFormat, getBuf( unit.Y(), type ), getBuf( unit.Cb(), type ), getBuf( unit.Cr(), type ) );
      }
    }
    
    Pel* Picture::getOrigin( const PictureType &type, const ComponentID compID ) const
    {
    #if ENABLE_SPLIT_PARALLELISM
    
      const int jId = ( type == PIC_ORIGINAL || type == PIC_TRUE_ORIGINAL ) ? 0 : scheduler.getSplitPicId();
    
    
    void Picture::createSpliceIdx(int nums)
    {
      m_ctuNums = nums;
      m_spliceIdx = new int[m_ctuNums];
      memset(m_spliceIdx, 0, m_ctuNums * sizeof(int));
    }
    
    bool Picture::getSpliceFull()
    {
      int count = 0;
      for (int i = 0; i < m_ctuNums; i++)
      {
        if (m_spliceIdx[i] != 0)
          count++;
      }
      if (count < m_ctuNums * 0.25)
        return false;
      return true;
    }
    
    
    void Picture::addPictureToHashMapForInter()
    {
    
    #if JVET_O1164_PS
      int picWidth = slices[0]->getPPS()->getPicWidthInLumaSamples();
      int picHeight = slices[0]->getPPS()->getPicHeightInLumaSamples();
    #else
    
      int picWidth = slices[0]->getSPS()->getPicWidthInLumaSamples();
      int picHeight = slices[0]->getSPS()->getPicHeightInLumaSamples();
    
      uint32_t* blockHashValues[2][2];
    
      bool* bIsBlockSame[2][3];
    
      for (int i = 0; i < 2; i++)
      {
        for (int j = 0; j < 2; j++)
        {
    
          blockHashValues[i][j] = new uint32_t[picWidth*picHeight];
    
        }
    
        for (int j = 0; j < 3; j++)
        {
          bIsBlockSame[i][j] = new bool[picWidth*picHeight];
        }
      }
    
      m_hashMap.create(picWidth, picHeight);
    
      m_hashMap.generateBlock2x2HashValue(getOrigBuf(), picWidth, picHeight, slices[0]->getSPS()->getBitDepths(), blockHashValues[0], bIsBlockSame[0]);//2x2
      m_hashMap.generateBlockHashValue(picWidth, picHeight, 4, 4, blockHashValues[0], blockHashValues[1], bIsBlockSame[0], bIsBlockSame[1]);//4x4
      m_hashMap.addToHashMapByRowWithPrecalData(blockHashValues[1], bIsBlockSame[1][2], picWidth, picHeight, 4, 4);
    
      m_hashMap.generateBlockHashValue(picWidth, picHeight, 8, 8, blockHashValues[1], blockHashValues[0], bIsBlockSame[1], bIsBlockSame[0]);//8x8
      m_hashMap.addToHashMapByRowWithPrecalData(blockHashValues[0], bIsBlockSame[0][2], picWidth, picHeight, 8, 8);
    
      m_hashMap.generateBlockHashValue(picWidth, picHeight, 16, 16, blockHashValues[0], blockHashValues[1], bIsBlockSame[0], bIsBlockSame[1]);//16x16
      m_hashMap.addToHashMapByRowWithPrecalData(blockHashValues[1], bIsBlockSame[1][2], picWidth, picHeight, 16, 16);
    
      m_hashMap.generateBlockHashValue(picWidth, picHeight, 32, 32, blockHashValues[1], blockHashValues[0], bIsBlockSame[1], bIsBlockSame[0]);//32x32
      m_hashMap.addToHashMapByRowWithPrecalData(blockHashValues[0], bIsBlockSame[0][2], picWidth, picHeight, 32, 32);
    
      m_hashMap.generateBlockHashValue(picWidth, picHeight, 64, 64, blockHashValues[0], blockHashValues[1], bIsBlockSame[0], bIsBlockSame[1]);//64x64
      m_hashMap.addToHashMapByRowWithPrecalData(blockHashValues[1], bIsBlockSame[1][2], picWidth, picHeight, 64, 64);
    
      m_hashMap.setInitial();
    
      for (int i = 0; i < 2; i++)
      {
        for (int j = 0; j < 2; j++)
        {
          delete[] blockHashValues[i][j];
        }
    
        for (int j = 0; j < 3; j++)
        {
          delete[] bIsBlockSame[i][j];
        }
      }
    }