VideoCodec/Modules/Input/FrameInputModule.cpp

#include <Magick++.h> #include "FrameInputModule.h" using namespace Magick; namespace VideoCodec {    FrameInputModule::FrameInputModule() : Module(FRAME_INPUT_MODULE_ID)    {    }        FrameInputModule::~FrameInputModule()    {    }    ConfigurationStatus FrameInputModule::Configure(ConfigurationElement* configuration)    {       if (configuration != NULL && configuration->GetType() == CONFIGURATION_PAIRS)       {          configurationList* value = configuration->GetValue(std::string("files"))->GetList();          this->inputFrameFileNames = vector<std::string>();          this->unprocessedFrameFileNames = vector<std::string>();          this->processedFrameFileNames = vector<std::string>();                    // Get file names into a vector.          for (unsigned int i = 0; i < value->size(); i++)             this->inputFrameFileNames.insert(this->inputFrameFileNames.end(), *(*value)[i]->GetString());                       // Initially all frames are unprocessed.          for (unsigned int i = 0; i < value->size(); i++)             this->unprocessedFrameFileNames.insert(this->unprocessedFrameFileNames.end(), this->inputFrameFileNames[i]);                    // Deal with preloading all frames.          if (configuration->GetValue(std::string("preload")) != NULL && configuration->GetValue(std::string("preload"))->GetType() == CONFIGURATION_STRING && *(configuration->GetValue(std::string("preload"))->GetString()) == std::string("true"))             this->PreloadInputFrames();          else             this->preload = false;                       return MODULE_CONFIGURATION_OK;       }       else       {          return MODULE_CONFIGURATION_ERROR;       }    }        FrameCount FrameInputModule::GetTotalFrameCount()    {       return this->processedFrameFileNames.size() + this->unprocessedFrameFileNames.size();    }        void FrameInputModule::CleanUpPreloaded()    {       // Delete frame data.       for (unsigned int i = 0; i < this->preloadedFrames.size(); i++)          delete this->preloadedFrames.at(i);                 this->preload = false;    }        void FrameInputModule::PreloadInputFrames()    {       if (this->preload == true)          this->CleanUpPreloaded();              this->preload = true;       this->preloadedFrames = vector<PictureInfo*>();              for (unsigned int i = 0; i < this->inputFrameFileNames.size(); i++)          this->preloadedFrames.insert(this->preloadedFrames.end(), this->preloadFrame(this->inputFrameFileNames[i]));    }        PictureInfo* FrameInputModule::preloadFrame(std::string fileName)    {       Image image;       try       {          image.read(fileName.c_str());       }       catch (Exception& error)       {          Logger::LogMessage("Unable to preload all frames.");          return NULL;       }              int imageWidth = image.size().width();       int imageHeight = image.size().height();              const PixelPacket* pixels = image.getConstPixels(0, 0, imageWidth, imageHeight);              // Put all the component values into an unsigned byte array.       PictureInfo* picture = new PictureInfo();       UnsignedByte* components = new UnsignedByte[imageWidth * imageHeight * 3];       for (int y = 0, index = 0, componentIndex = 0; y < imageHeight; y++)          for (int x = 0; x < imageWidth; x++, index++, componentIndex += 3)          {             components[componentIndex] = pixels[index].red;             components[componentIndex + 1] = pixels[index].green;             components[componentIndex + 2] = pixels[index].blue;          }              // Initial frame data is in RGB format.       picture->SetPixelLayout(PIXEL_LAYOUT_SCAN);       picture->SetUnsignedByteData(components, 3 * imageWidth * imageHeight);       picture->SetPixelsX(imageWidth);       picture->SetPixelsY(imageHeight);       picture->SetColourFormat(COLOUR_FORMAT_RGB);              return picture;    }        PictureInfo* FrameInputModule::FetchNextFrame()    {       std::string fileName = (this->unprocessedFrameFileNames)[0];       this->processedFrameFileNames.insert(this->processedFrameFileNames.begin(), fileName);       this->unprocessedFrameFileNames.erase(this->unprocessedFrameFileNames.begin());              if (this->preload)       {          PictureInfo* thisFrame = NULL;          while (thisFrame == NULL)          {             thisFrame = (this->preloadedFrames)[0];             this->preloadedFrames.erase(this->preloadedFrames.begin());          }          return thisFrame;       }              Image image;       PictureInfo* picture = new PictureInfo();       try       {          image.read(fileName.c_str());       }       catch (Exception& error)       {          // Mark this frame invalid and skip to the next one.          Logger::LogMessage(("Could not open file " + fileName + ".").c_str());          return NULL;       }              int imageWidth = image.size().width();       int imageHeight = image.size().height();       // Do not deallocate pixels. (Magick++ documentation)       const PixelPacket* pixels = image.getConstPixels(0, 0, imageWidth, imageHeight);              // Put all the component values into an unsigned byte array.       UnsignedByte* components = new UnsignedByte[imageWidth * imageHeight * 3];       for (int y = 0, index = 0, componentIndex = 0; y < imageHeight; y++)          for (int x = 0; x < imageWidth; x++, index++, componentIndex += 3)          {             components[componentIndex] = pixels[index].red;             components[componentIndex + 1] = pixels[index].green;             components[componentIndex + 2] = pixels[index].blue;          }              // Initial frame data is in RGB format.       picture->SetPixelLayout(PIXEL_LAYOUT_SCAN);       picture->SetUnsignedByteData(components, 3 * imageWidth * imageHeight);       picture->SetPixelsX(imageWidth);       picture->SetPixelsY(imageHeight);       picture->SetColourFormat(COLOUR_FORMAT_RGB);              return picture;    }        bool FrameInputModule::HasFrames()    {       return (this->unprocessedFrameFileNames.size() > 0);    } }