chenke
2017-07-20 41bc5a329c73e3b43695f73f11c47c97c44cc1b6
RtspFace/PL_Scale.cpp
@@ -1,7 +1,6 @@
#include "PL_Scale.h"
#include "MaterialBuffer.h"
#include "logger.h"
#include <libyuv.h>
struct PL_Scale_Internal
@@ -77,7 +76,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 +90,33 @@
}
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 +139,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 +198,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;
@@ -184,17 +214,43 @@
      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,
         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->lastFrame = *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,6 +276,7 @@
   }
   break;
   case PipeMaterial::PMT_FRAME:
   case PipeMaterial::PMT_PM_LIST:
   {
      newPm.type = PipeMaterial::PMT_FRAME;
      newPm.buffer = &(in->lastFrame);
@@ -232,7 +289,7 @@
   }
   break;
   default:
      LOG_ERROR << "Only support PMT_BYTES / PMT_FRAME";
      LOG_ERROR << "Only support PMT_BYTES / PMT_FRAME" << std::endl;
   }
   pm = newPm;