VideoCodec/Modules/Transform/AANDCT.cpp

#include "AANDCT.h" // The Arai, Agui and Nakajima algorithm for evaluating the DCT by scaling results from the real part // of the Winograd DFT is implemented in the header file. namespace VideoCodec {    AANDCT::AANDCT() : Module(AAN_DCT_MODULE_ID)    {    }        AANDCT::~AANDCT()    {    }        ConfigurationStatus AANDCT::Configure(ConfigurationElement* configuration)    {       return MODULE_CONFIGURATION_OK;    }        // Execute an inverse DCT on the specified picture.    void AANDCT::PictureIDCT(PictureInfo* picture)    {       BlockCount blockRows = picture->GetBlockRows();       BlockCount blockColumns = picture->GetBlockColumns();              if (picture->GetPixelLayout() != PIXEL_LAYOUT_MB_FOUR_TWO_ZERO)          Logger::LogMessage("Warning: The fast IDCT supports only the 4:2:0 MB pixel layout.");              // Input to the IDCT is always signed.       // The output is signed if this is an inter frame.       SignedShort* mbData = picture->GetSignedShortData();       float temp[8][8];       if (picture->GetFrameType() == FRAME_TYPE_INTRA)       {          // Allocate unsigned data for the new values.          UnsignedByte* pixelValues = new UnsignedByte[8 * 8 * 6 * (blockRows * blockColumns)];          for (int index = 0; index < blockRows * blockColumns * 6 * 8 * 8; index += 64)          { #define SOURCE(x) mbData[index + (x << 3) + i] #define DESTINATION(x,y) temp[x][i] = (y) / 16.0f             for (int i = 0; i < 8; i++)                AAN_IDCT_1D #undef SOURCE #undef DESTINATION           #define SOURCE(x) temp[i][x] #define DESTINATION(x,y) pixelValues[index + (x << 3) + i] = ((y) > 4095.0f ? 4095 : ((y) < 0.0f ? 0 : lrintf(y))) >> 4;             for (int i = 0; i < 8; i++)                AAN_IDCT_1D #undef SOURCE #undef DESTINATION          }          picture->SetUnsignedByteData(pixelValues, blockRows * blockColumns * 6 * 64);       }       else       {          for (int index = 0; index < blockRows * blockColumns * 6 * 8 * 8; index += 64)          { #define SOURCE(x) mbData[index + (x << 3) + i] #define DESTINATION(x,y) temp[x][i] = (y) / 16.0f             for (int i = 0; i < 8; i++)                AAN_IDCT_1D #undef SOURCE #undef DESTINATION           #define SOURCE(x) temp[i][x] #define DESTINATION(x,y) mbData[index + (x << 3) + i] = ((y) > 4095.0f ? 4095 : ((y) < -4096.0f ? -4096 : lrintf(y))) >> 4;             for (int i = 0; i < 8; i++)                AAN_IDCT_1D #undef SOURCE #undef DESTINATION          }       }    }        void AANDCT::debugOutputMB(UnsignedByte* mb, const char* label)    {       Logger::BeginIncrementalLogMessage(label);              for (int y = 0; y < 8; y++)       {          for (int x = 0; x < 8; x++)          {             Logger::IncrementalLogMessage((int)mb[y * 8 + x]);             Logger::IncrementalLogMessage(" ");          }          Logger::IncrementalLogMessage("\n");       }              Logger::EndIncrementalLogMessage(label);    }    void AANDCT::debugOutputMB(SignedShort* mb, const char* label)    {       Logger::BeginIncrementalLogMessage(label);              for (int y = 0; y < 8; y++)       {          for (int x = 0; x < 8; x++)          {             Logger::IncrementalLogMessage((int)mb[y * 8 + x]);             Logger::IncrementalLogMessage(" ");          }          Logger::IncrementalLogMessage("\n");       }              Logger::EndIncrementalLogMessage(label);    }        // Execute an AAN DCT on the specified picture.    void AANDCT::PictureDCT(PictureInfo* picture)    {       int blockRows = picture->GetBlockRows();       int blockColumns = picture->GetBlockColumns();              if (picture->GetPixelLayout() != PIXEL_LAYOUT_MB_FOUR_TWO_ZERO)          Logger::LogMessage("Warning: The AAN DCT requires a 4:2:0 MB pixel layout.");              // Allocate temporary space for calculation of the DCT;       float temp[8][8];              // For intra frames use UnsignedBytes as input. For inter frames used SignedShort ints as input.       if (picture->GetFrameType() == FRAME_TYPE_INTRA)       {          // The output here goes into SignedShort data.          SignedShort* result = new SignedShort[blockRows * blockColumns * 6 * 64];          UnsignedByte* mbData = picture->GetUnsignedByteData();          // Loop over all the blocks in the picture.          for (int index = 0; index < blockRows * blockColumns * 6 * 64; index += 64)          { #define SOURCE(x) mbData[index + (x << 3) + i] #define DESTINATION(x,y) temp[x][i] = (y)             for (int i = 0; i < 8; i++)                AAN_DCT_1D #undef SOURCE #undef DESTINATION        #define SOURCE(x) temp[i][x] #define DESTINATION(x,y) result[index + (x << 3) + i] = (SignedShort)lrintf(y);             for (int i = 0; i < 8; i++)                AAN_DCT_1D #undef SOURCE #undef DESTINATION          }                    picture->SetSignedShortData(result, blockRows * blockColumns * 6 * 64);       }       else       {          SignedShort* signedMBData = picture->GetSignedShortData();                    // The output here goes back into the input array.          for (int index = 0; index < blockRows * blockColumns * 6 * 64; index += 64)          { #define SOURCE(x) signedMBData[index + (x << 3) + i] #define DESTINATION(x,y) temp[x][i] = (y)             for (int i = 0; i < 8; i++)                AAN_DCT_1D #undef SOURCE #undef DESTINATION        #define SOURCE(x) temp[i][x] #define DESTINATION(x,y) signedMBData[index + (x << 3) + i] = (SignedShort)lrintf(y);             for (int i = 0; i < 8; i++)                AAN_DCT_1D #undef SOURCE #undef DESTINATION          }       }    } }