From dd2b244b71d64c909cffcf040315d35138e85aab Mon Sep 17 00:00:00 2001
From: chenke <chenke@454eff88-639b-444f-9e54-f578c98de674>
Date: 星期三, 19 七月 2017 15:41:43 +0800
Subject: [PATCH] 图像缩放模块

---
 RtspFace/PL_Scale.cpp |   90 ++++++++++++++++++++++++++++++++++++--------
 1 files changed, 73 insertions(+), 17 deletions(-)

diff --git a/RtspFace/PL_Scale.cpp b/RtspFace/PL_Scale.cpp
index c825591..69b0866 100644
--- a/RtspFace/PL_Scale.cpp
+++ b/RtspFace/PL_Scale.cpp
@@ -1,9 +1,8 @@
 #include "PL_Scale.h"
 #include "MaterialBuffer.h"
 #include "logger.h"
-
 #include <libyuv.h>
-
+#include <android/native_window.h>
 struct PL_Scale_Internal
 {
 	uint8_t* buffer;
@@ -91,15 +90,15 @@
 }
 
 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;
-	
+    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;
@@ -108,7 +107,7 @@
 		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)
@@ -117,7 +116,7 @@
 		in->buffSizeMax = dstSizeMax;
 		LOG_INFO << "image_scale alloc buffer size=" << dstSizeMax << std::endl;
 	}
-	
+
 	if (srcType == MB_Frame::MBFT_YUV420)
 	{
 		uint8_t* src_y = srcBuffer;
@@ -140,12 +139,42 @@
 			
 		in->buffSize = dstSizeMax;
 	}
-	else if (srcType == MB_Frame::MBFT_BGRA)
-	{
-		//#todo
-		LOG_ERROR << "srcType only support MBFT_YUV420 and MBFT_BGRA" << std::endl;
-		return false;
-	}
+    else if (srcType == MB_Frame::MBFT_NV12)
+    {
+        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;
+    }
 }
 
 bool PL_Scale::pay(const PipeMaterial& pm)
@@ -172,7 +201,7 @@
 			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,7 +213,7 @@
 		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:
@@ -193,6 +222,32 @@
 		}
 	}
 	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" << std::endl;
 		return false;
@@ -220,6 +275,7 @@
 	}
 	break;
 	case PipeMaterial::PMT_FRAME:
+    case PipeMaterial::PMT_PM_LIST:
 	{
 		newPm.type = PipeMaterial::PMT_FRAME;
 		newPm.buffer = &(in->lastFrame);

--
Gitblit v1.8.0