theonlineoasis

VideoCodec/Modules/Prediction/FrameDifference.cpp

#include "FrameDifference.h" namespace VideoCodec {    FrameDifference::FrameDifference() : Module(FRAME_DIFFERENCE_MODULE_ID)    {    }        FrameDifference::~FrameDifference()    {    }        ConfigurationStatus FrameDifference::Configure(ConfigurationElement* configuration)    {       return MODULE_CONFIGURATION_OK;    }        void FrameDifference::SubtractFrame(PictureInfo* current, PictureInfo* previous)    {       if (current->GetPixelLayout() != previous->GetPixelLayout() || current->GetPixelLayout() != PIXEL_LAYOUT_SCAN ||             current->GetBlockRows() != previous->GetBlockRows() ||             current->GetBlockColumns() != previous->GetBlockColumns())          Logger::LogMessage("Warning: Mismatched frames for frame difference.");              // Get information from the supplied frames.       PixelCount pixelsX = current->GetPixelsX();       PixelCount pixelsY = current->GetPixelsY();       UnsignedByte* currentData = current->GetUnsignedByteData();       UnsignedByte* previousData = previous->GetUnsignedByteData();              // The result has a new range of -256 to 255, so needs to be stored in a signed integer.       SignedShort* result = new SignedShort[pixelsX * pixelsY * 3];              for (int index = 0; index < pixelsX * pixelsY * 3; index++)          result[index] = currentData[index] - previousData[index];              // Store the result of the subtraction.       current->SetSignedShortData(result, pixelsX * pixelsY * 3);    }        void FrameDifference::AddFrame(PictureInfo* reference, PictureInfo* residual)    {       // Add the residual to the reference picture.       if (reference->GetPixelLayout() != residual->GetPixelLayout() || reference->GetPixelLayout() != PIXEL_LAYOUT_SCAN ||             reference->GetBlockRows() != residual->GetBlockRows() ||             reference->GetBlockColumns() != residual->GetBlockColumns())          Logger::LogMessage("Warning: Mismatched frames for frame difference.");              // Get information for the supplied frames.       PixelCount pixelsX = reference->GetPixelsX();       PixelCount pixelsY = reference->GetPixelsY();       UnsignedByte* referenceData = reference->GetUnsignedByteData();       SignedShort* residualData = residual->GetSignedShortData();              // Create an array to store the result.       UnsignedByte* result = new UnsignedByte[pixelsX * pixelsY * 3];              // The resulting values will be clipped into the range 0 to 255.       for (int index = 0; index < pixelsX * pixelsY * 3; index++)       {          SignedShort newValue = referenceData[index] + residualData[index];                    // Clip the value.          if (newValue > 255)             newValue = 255;          else if (newValue < 0)             newValue = 0;                    result[index] = (UnsignedByte)newValue;       }              reference->SetUnsignedByteData(result, pixelsX * pixelsY * 3);    }        void FrameDifference::DiagnosticResidual(PictureInfo* residual)    {       // Add the residual to a flat picture.       PixelCount pixelsX = residual->GetPixelsX();       PixelCount pixelsY = residual->GetPixelsY();       SignedShort* residualData = residual->GetSignedShortData();              // Create an array to store the result.       UnsignedByte* result = new UnsignedByte[pixelsX * pixelsY * 3];              // The resulting values will be clipped into the range 0 to 255.       for (int index = 0; index < pixelsX * pixelsY * 3; index++)       {          SignedShort newValue = 128 + (residualData[index] >> 1);                    // Clip the value.          if (newValue > 255)             newValue = 255;          else if (newValue < 0)             newValue = 0;                    result[index] = (UnsignedByte)newValue;       }              residual->SetUnsignedByteData(result, pixelsX * pixelsY * 3);    } }