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
}
}
}
}