#include "PL_ColorConv.h" #include "MaterialBuffer.h" #include "logger.h" #include #include struct PL_ColorConv_Internal { uint8_t* buffer; size_t buffSize; size_t buffSizeMax; bool payError; PipeMaterial::PipeMaterialBufferType lastPmType; MB_Frame tempFrame; PL_ColorConv_Config config; PL_ColorConv_Internal() : buffer(nullptr), buffSize(0), buffSizeMax(0), payError(true), lastPmType(PipeMaterial::PMT_NONE), tempFrame(), config() { } ~PL_ColorConv_Internal() { delete[] buffer; buffer = nullptr; } void reset() { buffSize = 0; payError = true; lastPmType = PipeMaterial::PMT_NONE; MB_Frame _tempFrame; tempFrame = _tempFrame; PL_ColorConv_Config _config; config = _config; if (buffer != nullptr) { delete[] buffer; buffer = nullptr; buffSizeMax = 0; } } }; PipeLineElem* create_PL_ColorConv() { return new PL_ColorConv; } PL_ColorConv::PL_ColorConv() : internal(new PL_ColorConv_Internal) { } PL_ColorConv::~PL_ColorConv() { delete (PL_ColorConv_Internal*)internal; internal= nullptr; } bool PL_ColorConv::init(void* args) { PL_ColorConv_Internal* in = (PL_ColorConv_Internal*)internal; in->reset(); if (args != nullptr) { PL_ColorConv_Config* config = (PL_ColorConv_Config*)args; in->config = *config; } return true; } void PL_ColorConv::finit() { PL_ColorConv_Internal* in = (PL_ColorConv_Internal*)internal; } bool image_to_rgb565(PL_ColorConv_Internal *in ,MB_Frame::MBFType srcType){ const int srcHeight = in->tempFrame.height; const int srcWidth = in->tempFrame.width; int dstSize = srcHeight * srcWidth * 2; if (in->buffer == nullptr || in->buffSizeMax buffer != nullptr) delete[] in->buffer; in->buffer = new uint8_t[dstSize]; in->buffSizeMax = dstSize; in->buffSize = dstSize; LOG_INFO << "image_to_rgb565 alloc buffer size=" << dstSize << std::endl; } if (srcType == MB_Frame::MBFT_YUV420) { //#todo LOG_ERROR << "srcType only support MBFT_NV12" << std::endl; return false; } else if (srcType == MB_Frame::MBFT_NV12) { const uint8_t* srcBuffer = (uint8_t*)in->tempFrame.buffer; const uint8_t* src_y = srcBuffer; const uint8_t* src_uv = src_y + (srcHeight * srcWidth); uint8_t* dst = (uint8_t*)(in->buffer); libyuv::NV12ToRGB565(src_y, srcWidth, src_uv, srcWidth, dst, srcWidth * 2, srcWidth, srcHeight); } else if (srcType == MB_Frame::MBFT_BGRA) { //#todo LOG_ERROR << "srcType only support MBFT_NV12" << std::endl; return false; } else { LOG_ERROR << "srcType only support MBFT_NV12" << std::endl; return false; } return true; } bool PL_ColorConv::pay(const PipeMaterial& pm) { PL_ColorConv_Internal* in = (PL_ColorConv_Internal*)internal; in->payError = true; if (pm.buffer == nullptr) return false; bool ret = false; in->lastPmType = pm.type; switch(pm.type) { case PipeMaterial::PMT_BYTES: LOG_ERROR << "PL_ColorConv unsupport type: PMT_BYTES" << std::endl; break; case PipeMaterial::PMT_FRAME: { MB_Frame* frame = (MB_Frame*)pm.buffer; switch(frame->type) { case MB_Frame::MBFT_NV12: in->tempFrame = *frame; ret = image_to_rgb565(in, frame->type); break; default: LOG_ERROR << "PL_ColorConv Only support MBFT_NV12" << std::endl; return false; } } break; case PipeMaterial::PMT_PM_LIST: { // break pm list into single pm(s) MB_Frame* ppm = (MB_Frame*)pm.buffer; for (size_t i = 0; i < pm.buffSize; i++, ppm++) { if (ppm->type== PipeMaterial::PMT_FRAME) { MB_Frame* frame = (MB_Frame*)ppm->buffer; switch(frame->type) { case MB_Frame::MBFT_NV12: in->tempFrame = *frame; image_to_rgb565(in, frame->type); break; default: LOG_ERROR << "PL_ColorConv Only support MBFT_NV12" << std::endl; return false; } } } }break; default: LOG_ERROR << "PL_ColorConv Only support MBFT_NV12" << std::endl; return false; } in->payError = !ret; return ret; } bool PL_ColorConv::gain(PipeMaterial& pm) { PL_ColorConv_Internal* in = (PL_ColorConv_Internal*)internal; PipeMaterial newPm; newPm.type = PipeMaterial::PMT_NONE; newPm.former = this; switch(in->lastPmType) { case PipeMaterial::PMT_FRAME: case PipeMaterial::PMT_PM_LIST: { newPm.type = PipeMaterial::PMT_FRAME; in->tempFrame.buffer = in->buffer; in->tempFrame.buffSize = in->buffSize; in->tempFrame.type = MB_Frame::MBFT_RGB565; newPm.buffer = &(in->tempFrame); newPm.buffSize = 0; } break; default: LOG_ERROR << "Only support PMT_FRAME and PMT_PM_LIST" << std::endl; } pm = newPm; return !in->payError; }