From be1c28a5a6edd5a76b04d9ce3b6eaf7bcc3b818d Mon Sep 17 00:00:00 2001 From: xuxiuxi <xuxiuxi@454eff88-639b-444f-9e54-f578c98de674> Date: 星期一, 24 七月 2017 14:51:59 +0800 Subject: [PATCH] --- RtspFace/PL_Scale.cpp | 118 ++++++++++++++++++++++++++++++++++++++++++++--------------- 1 files changed, 88 insertions(+), 30 deletions(-) diff --git a/RtspFace/PL_Scale.cpp b/RtspFace/PL_Scale.cpp index bd6c507..8bc0574 100644 --- a/RtspFace/PL_Scale.cpp +++ b/RtspFace/PL_Scale.cpp @@ -1,8 +1,9 @@ #include "PL_Scale.h" #include "MaterialBuffer.h" #include "logger.h" - #include <libyuv.h> + +#define SUBSAMPLE(v, a) ((((v) + (a) - 1)) / (a)) struct PL_Scale_Internal { @@ -12,12 +13,12 @@ bool payError; PipeMaterial::PipeMaterialBufferType lastPmType; - MB_Frame lastFrame; + MB_Frame tempFrame; PL_Scale_Config config; PL_Scale_Internal() : buffer(nullptr), buffSize(0), buffSizeMax(0), payError(true), - lastPmType(PipeMaterial::PMT_NONE), lastFrame(), config() + lastPmType(PipeMaterial::PMT_NONE), tempFrame(), config() { } @@ -34,8 +35,8 @@ lastPmType = PipeMaterial::PMT_NONE; - MB_Frame _lastFrame; - lastFrame = _lastFrame; + MB_Frame _tempFrame; + tempFrame = _tempFrame; PL_Scale_Config _config; config = _config; @@ -77,7 +78,7 @@ if (in->config.toWidth <= 0 || in->config.toHeight <= 0) { - LOG_ERROR << "Config toWidth and toHeight should > 0"; + LOG_ERROR << "Config toWidth and toHeight should > 0" << std::endl; return false; } @@ -91,33 +92,32 @@ } bool image_scale(PL_Scale_Internal* in, - uint8_t* srcBuffer, int srcBuffSize, MB_Frame::MBFType srcType, uint16_t srcWidth, uint16_t srcHeight) + uint8_t* srcBuffer, MB_Frame::MBFType srcType, uint16_t srcWidth, uint16_t srcHeight) { -#define SUBSAMPLE(v, a) ((((v) + (a) - 1)) / (a)) const int dst_width = in->config.toWidth; const int dst_height = in->config.toHeight; - + size_t dstSizeMax = 0; - if (srcType == MB_Frame::MBFT_YUV420) + if (srcType == MB_Frame::MBFT_YUV420||srcType == MB_Frame::MBFT_NV12) dstSizeMax = in->config.toWidth * in->config.toHeight * 1.5; else if (srcType == MB_Frame::MBFT_BGRA) dstSizeMax = in->config.toWidth * in->config.toHeight * 4; else { - LOG_ERROR << "srcType only support MBFT_YUV420 and MBFT_BGRA"; + LOG_ERROR << "srcType only support MBFT_YUV420 and MBFT_BGRA" << std::endl; return false; } - + if (in->buffer == nullptr || in->buffSizeMax < dstSizeMax) { if (in->buffer != nullptr) delete[] in->buffer; in->buffer = new uint8_t[dstSizeMax]; in->buffSizeMax = dstSizeMax; - LOG_INFO << "image_scale alloc buffer size=" << dstSizeMax; + LOG_INFO << "image_scale alloc buffer size=" << dstSizeMax << std::endl; } - + if (srcType == MB_Frame::MBFT_YUV420) { uint8_t* src_y = srcBuffer; @@ -140,11 +140,42 @@ in->buffSize = dstSizeMax; } - else if (srcType == MB_Frame::MBFT_BGRA) + else if (srcType == MB_Frame::MBFT_NV12) { - //#todo - LOG_ERROR << "srcType only support MBFT_YUV420 and MBFT_BGRA"; - return false; + const uint8_t* src_y = (const uint8_t*)(srcBuffer); + const uint8_t* src_uv = (const uint8_t*)(src_y + (srcHeight * srcWidth)); + if (srcWidth != dst_width || srcHeight != dst_height) + { + // RK3288, 1920->640: 2.8~12ms, avg=4ms + + uint8_t* dst_y = (uint8_t*)(in->buffer); + uint8_t* dst_uv = (uint8_t*)(dst_y + (dst_height * dst_width)); + + libyuv::ScalePlane(src_y, srcWidth, + srcWidth, srcHeight, + dst_y, dst_width, + dst_width, dst_height, + libyuv::kFilterNone); + + libyuv::ScalePlane_16((uint16*)src_uv, SUBSAMPLE(srcWidth, 2), + SUBSAMPLE(srcWidth, 2), SUBSAMPLE(srcHeight, 2), + (uint16*)dst_uv, SUBSAMPLE(dst_width, 2), + SUBSAMPLE(dst_width, 2), SUBSAMPLE(dst_height, 2), + libyuv::kFilterNone); + in->buffSize = dstSizeMax; + } + else if (srcType == MB_Frame::MBFT_BGRA) + { + //#todo + LOG_ERROR << "srcType only support MBFT_YUV420 and MBFT_NV12" << std::endl; + return false; + } + else + { + LOG_ERROR << "srcType only support MBFT_YUV420 and MBFT_NV12" << std::endl; + return false; + } + return true; } } @@ -168,11 +199,11 @@ if (in->config.defaultBytesType <= 0 || in->config.defaultBytesWidth <= 0 || in->config.defaultBytesHeight <= 0) { - LOG_ERROR << "defaultBytesType/defaultBytesWidth/defaultBytesHeight not set"; + LOG_ERROR << "defaultBytesType/defaultBytesWidth/defaultBytesHeight not set" << std::endl; return false; } - ret = image_scale(in, (uint8_t*)pm.buffer, pm.buffSize, (MB_Frame::MBFType)(in->config.defaultBytesType), + ret = image_scale(in, (uint8_t*)pm.buffer, (MB_Frame::MBFType)(in->config.defaultBytesType), in->config.defaultBytesWidth, in->config.defaultBytesHeight); } break; @@ -183,18 +214,44 @@ { case MB_Frame::MBFT_YUV420: case MB_Frame::MBFT_BGRA: - in->lastFrame = *frame; - ret = image_scale(in, (uint8_t*)frame->buffer, frame->buffSize, frame->type, + in->tempFrame = *frame; + ret = image_scale(in, (uint8_t*)frame->buffer, frame->type, frame->width, frame->height); break; default: - LOG_ERROR << "Only support MBFT_YUV420 / MBFT_BGRA"; + LOG_ERROR << "Only support MBFT_YUV420 / MBFT_BGRA" << 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_YUV420: + case MB_Frame::MBFT_BGRA: + case MB_Frame::MBFT_NV12: + in->tempFrame = *frame; + ret = image_scale(in, (uint8_t*)frame->buffer,frame->type, + frame->width, frame->height); + break; + default: + LOG_ERROR << "Only support MBFT_YUV420 / MBFT_BGRA" << std::endl; + return false; + } + } + } + }break; default: - LOG_ERROR << "Only support PMT_BYTES / PMT_FRAME"; + LOG_ERROR << "Only support PMT_BYTES / PMT_FRAME" << std::endl; return false; } @@ -220,19 +277,20 @@ } break; case PipeMaterial::PMT_FRAME: + case PipeMaterial::PMT_PM_LIST: { newPm.type = PipeMaterial::PMT_FRAME; - newPm.buffer = &(in->lastFrame); + newPm.buffer = &(in->tempFrame); newPm.buffSize = 0; - in->lastFrame.buffer = in->buffer; - in->lastFrame.buffSize = in->buffSize; - in->lastFrame.width = in->config.toWidth; - in->lastFrame.height = in->config.toHeight; + in->tempFrame.buffer = in->buffer; + in->tempFrame.buffSize = in->buffSize; + in->tempFrame.width = in->config.toWidth; + in->tempFrame.height = in->config.toHeight; } break; default: - LOG_ERROR << "Only support PMT_BYTES / PMT_FRAME"; + LOG_ERROR << "Only support PMT_BYTES / PMT_FRAME" << std::endl; } pm = newPm; -- Gitblit v1.8.0