From 109ffe9a777658936a38d0c146579a67c60a0d17 Mon Sep 17 00:00:00 2001
From: xuxiuxi <xuxiuxi@454eff88-639b-444f-9e54-f578c98de674>
Date: 星期四, 11 五月 2017 17:48:48 +0800
Subject: [PATCH] 

---
 RtspFace/PL_AVFrameBGRA.cpp |  144 ++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 122 insertions(+), 22 deletions(-)

diff --git a/RtspFace/PL_AVFrameBGRA.cpp b/RtspFace/PL_AVFrameBGRA.cpp
index 9329f14..8e333ce 100644
--- a/RtspFace/PL_AVFrameBGRA.cpp
+++ b/RtspFace/PL_AVFrameBGRA.cpp
@@ -1,25 +1,31 @@
 #include "PL_AVFrameBGRA.h"
+#include "MaterialBuffer.h"
+#include "logger.h"
 
 extern "C"
 {
 	#include <libavcodec/avcodec.h>
 	#include <libavutil/frame.h>
 	#include <libavformat/avformat.h>
-	
-	#include <libyuv.h>
 }
+
+#include <libyuv.h>
 
 struct PL_AVFrameBGRA_Internal
 {
-	uint8_t buffer[1920*1080*4];
+	uint8_t buffer[1920*1080*4];//#todo from config
 	size_t buffSize;
 	size_t buffSizeMax;
+	MB_Frame lastFrame;
 
 	bool payError;
 	
+	PL_AVFrameBGRA_Config config;
+	
 	PL_AVFrameBGRA_Internal() : 
-		buffSize(0), buffSizeMax(sizeof(buffer)), 
-		payError(true)
+		buffSize(0), buffSizeMax(sizeof(buffer)), lastFrame(), 
+		payError(true),
+		config()
 	{
 	}
 	
@@ -31,6 +37,12 @@
 	{
 		buffSize = 0;
 		payError = true;
+		
+		MB_Frame _lastFrame;
+		lastFrame = _lastFrame;
+		
+		PL_AVFrameBGRA_Config _config;
+		config = _config;
 	}
 };
 
@@ -53,6 +65,12 @@
 {
 	PL_AVFrameBGRA_Internal* in = (PL_AVFrameBGRA_Internal*)internal;
 	in->reset();
+	
+	if (args != nullptr)
+	{
+		PL_AVFrameBGRA_Config* _config = (PL_AVFrameBGRA_Config*)args;
+		in->config = *_config;
+	}
 
 	return true;
 }
@@ -63,37 +81,118 @@
 	
 }
 
-#define SUBSAMPLE(v, a) ((((v) + (a) - 1)) / (a))
-
 bool PL_AVFrameBGRA::pay(const PipeMaterial& pm)
 {
+#define SUBSAMPLE(v, a) ((((v) + (a) - 1)) / (a))
+
 	PL_AVFrameBGRA_Internal* in = (PL_AVFrameBGRA_Internal*)internal;
 	
-	AVFrame* pAVFrame = (AVFrame*)pm.buffer;
-	if (pAVFrame == nullptr)
+	if (pm.type != PipeMaterial::PMT_FRAME)
+	{
+		LOG_ERROR << "Only support PMT_FRAME" << std::endl;
 		return false;
-
-	int height = pAVFrame->height;
-	int width = pAVFrame->width;
+	}
+	
+	if (pm.buffer == nullptr)
+		return false;
+	
+	int src_height = 0;
+	int src_width = 0;
+	const uint8* src_y = nullptr;
+	const uint8* src_u = nullptr;
+    const uint8* src_v = nullptr;
+	
+	MB_Frame* frame = (MB_Frame*)pm.buffer;
+	if (frame->type == MB_Frame::MBFT_PTR_AVFRAME)
+	{
+		AVFrame* pAVFrame = (AVFrame*)frame->buffer;
+		if (pAVFrame == nullptr)
+			return false;
+		
+		src_height = pAVFrame->height;
+		src_width = pAVFrame->width;
+		
+		src_y = pAVFrame->data[0];
+		src_u = pAVFrame->data[1];
+		src_v = pAVFrame->data[2];
+	}
+	if (frame->type == MB_Frame::MBFT_YUV420)
+	{
+		if (frame->buffer == nullptr)
+			return false;
+		
+		src_height = frame->height;
+		src_width = frame->width;
+		
+		src_y = (const uint8*)(frame->buffer);
+		src_u = (const uint8*)(src_y + (src_height * src_width));
+		src_v = (const uint8*)(src_u + (src_height * src_width / 4));
+	}
+	else
+	{
+		LOG_ERROR << "Only support MBFT_PTR_AVFRAME" << std::endl;
+		return false;
+	}
 
 //int I420ToBGRA(const uint8* src_y, int src_stride_y,
 //               const uint8* src_u, int src_stride_u,
 //               const uint8* src_v, int src_stride_v,
 //               uint8* dst_argb, int dst_stride_argb,
-//			   int width, int height);
+//			   int width, int src_height);
 
-	libyuv::I420ToBGRA(pAVFrame->data[0], width, 
-						pAVFrame->data[1], SUBSAMPLE(width, 2), 
-						pAVFrame->data[2], SUBSAMPLE(width, 2), 
-						in->buffer, 4 * width, 
-						width, height);
+	if (in->config.convertTo == PL_AVFrameBGRA_Config::I420_TO_BGRA8888)
+	{
+		libyuv::I420ToBGRA(src_y, src_width, 
+							src_u, SUBSAMPLE(src_width, 2), 
+							src_v, SUBSAMPLE(src_width, 2), 
+							in->buffer, 4 * src_width, 
+							src_width, src_height);
 
-	in->buffSize = in->buffSizeMax;
+		in->buffSize = src_width * src_height * 4; // #todo use ret value?
+	}
+	else if (in->config.convertTo == PL_AVFrameBGRA_Config::I420_TO_ARGB8888)
+	{
+		libyuv::I420ToARGB(src_y, src_width, 
+							src_u, SUBSAMPLE(src_width, 2), 
+							src_v, SUBSAMPLE(src_width, 2), 
+							in->buffer, 4 * src_width, 
+							src_width, src_height);
+
+		in->buffSize = src_width * src_height * 4; // #todo use ret value?
+	}
+	else if (in->config.convertTo == PL_AVFrameBGRA_Config::I420_TO_RGBA8888)
+	{
+		libyuv::I420ToRGBA(src_y, src_width, 
+							src_u, SUBSAMPLE(src_width, 2), 
+							src_v, SUBSAMPLE(src_width, 2), 
+							in->buffer, 4 * src_width, 
+							src_width, src_height);
+
+		in->buffSize = src_width * src_height * 4; // #todo use ret value?
+	}
+	else if (in->config.convertTo == PL_AVFrameBGRA_Config::I420_TO_ARGB4444)
+	{
+		
+	}
+	else
+	{
+		LOG_ERROR << "PL_AVFrameBGRA_Config.convertTo not support" << std::endl;
+		return false;
+	}
+
 	//in->buffer readly
+	
+	in->lastFrame.type = MB_Frame::MBFT_BGRA;
+	in->lastFrame.buffer = in->buffer;
+	in->lastFrame.buffSize = in->buffSize;
+	in->lastFrame.width = src_width;
+	in->lastFrame.height = src_height;
+	in->lastFrame.pts = frame->pts;
 
+	//#test
 	static size_t f=0;
 	char fname[50];
-	sprintf(fname, "%u.bgra", ++f);
+	sprintf(fname, "%u.rgba", ++f);
 	FILE * pFile = fopen (fname,"wb");
 	fwrite (in->buffer , sizeof(char), in->buffSize, pFile);
 	fclose(pFile);
@@ -105,8 +204,9 @@
 {
 	PL_AVFrameBGRA_Internal* in = (PL_AVFrameBGRA_Internal*)internal;
 
-	pm.buffer = in->buffer;
-	pm.buffSize = in->buffSize;
+	pm.type = PipeMaterial::PMT_FRAME;
+	pm.buffer = &(in->lastFrame);
+	pm.buffSize = 0;
 	pm.former = this;
 	return true;
 }

--
Gitblit v1.8.0