From f04b2e05a32f810ebe66b7b3a15f37b532ce2dc0 Mon Sep 17 00:00:00 2001
From: houxiao <houxiao@454eff88-639b-444f-9e54-f578c98de674>
Date: 星期四, 22 十二月 2016 17:27:31 +0800
Subject: [PATCH] add pl emements

---
 RtspFace/PL_AVFrameBGRA.h     |   24 ++++
 RtspFace/make.sh              |   12 +
 RtspFace/PL_H264Decoder.cpp   |   67 +++-------
 RtspFace/main.cpp             |    8 
 RtspFace/PL_AVFrameBGRA.cpp   |  115 +++++++++++++++++++
 RtspFace/PL_AVFrameYUV420.cpp |   96 ++++++++-------
 RtspFace/PipeLine.cpp         |   24 ++-
 7 files changed, 243 insertions(+), 103 deletions(-)

diff --git a/RtspFace/PL_AVFrameBGRA.cpp b/RtspFace/PL_AVFrameBGRA.cpp
new file mode 100644
index 0000000..e59a8a7
--- /dev/null
+++ b/RtspFace/PL_AVFrameBGRA.cpp
@@ -0,0 +1,115 @@
+#include "PL_AVFrameBGRA.h"
+
+extern "C"
+{
+	#include <libavcodec/avcodec.h>
+	#include <libavutil/frame.h>
+	#include <libavformat/avformat.h>
+	
+	#include <libyuv.h>
+}
+
+struct PL_AVFrameBGRA_Internal
+{
+	uint8_t buffer[1920*1080*4];
+	size_t buffSize;
+	size_t buffSizeMax;
+	
+	AVFormatContext* pAVFormatContext;//#todo delete
+	bool payError;
+	
+	PL_AVFrameBGRA_Internal() : 
+		buffSize(0), buffSizeMax(sizeof(buffer)), 
+		pAVFormatContext(nullptr), payError(true)
+	{
+	}
+	
+	~PL_AVFrameBGRA_Internal()
+	{
+	}
+	
+	void reset()
+	{
+		buffSize = 0;
+		payError = true;
+	}
+};
+
+PipeLineElem* create_PL_AVFrameBGRA()
+{
+	return new PL_AVFrameBGRA;
+}
+
+PL_AVFrameBGRA::PL_AVFrameBGRA() : internal(new PL_AVFrameBGRA_Internal)
+{
+}
+
+PL_AVFrameBGRA::~PL_AVFrameBGRA()
+{
+	delete (PL_AVFrameBGRA_Internal*)internal;
+	internal= nullptr;
+}
+
+bool PL_AVFrameBGRA::init(void* args)
+{
+	PL_AVFrameBGRA_Internal* in = (PL_AVFrameBGRA_Internal*)internal;
+	in->reset();
+
+	in->pAVFormatContext = avformat_alloc_context();
+	
+	return true;
+}
+
+void PL_AVFrameBGRA::finit()
+{
+	PL_AVFrameBGRA_Internal* in = (PL_AVFrameBGRA_Internal*)internal;
+	
+}
+
+#define SUBSAMPLE(v, a) ((((v) + (a) - 1)) / (a))
+
+bool PL_AVFrameBGRA::pay(const PipeMaterial& pm)
+{
+	PL_AVFrameBGRA_Internal* in = (PL_AVFrameBGRA_Internal*)internal;
+	
+	AVFrame* pAVFrame = (AVFrame*)pm.buffer;
+	if (pAVFrame == nullptr)
+		return false;
+
+	int height = pAVFrame->height;
+	int width = pAVFrame->width;
+
+//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);
+
+	libyuv::I420ToBGRA(pAVFrame->data[0], width, 
+						pAVFrame->data[1], SUBSAMPLE(width, 2), 
+						pAVFrame->data[2], SUBSAMPLE(width, 2), 
+						in->buffer, 4 * width, 
+						width, height);
+
+	in->buffSize = in->buffSizeMax;
+	//in->buffer readly
+
+	static size_t f=0;
+	char fname[50];
+	sprintf(fname, "%u.bgra", ++f);
+	FILE * pFile = fopen (fname,"wb");
+	fwrite (in->buffer , sizeof(char), in->buffSize, pFile);
+	fclose(pFile);
+
+	return true;
+}
+
+bool PL_AVFrameBGRA::gain(PipeMaterial& pm)
+{
+	PL_AVFrameBGRA_Internal* in = (PL_AVFrameBGRA_Internal*)internal;
+
+	pm.buffer = in->buffer;
+	pm.buffSize = in->buffSize;
+	pm.former = this;
+	return true;
+}
diff --git a/RtspFace/PL_AVFrameBGRA.h b/RtspFace/PL_AVFrameBGRA.h
new file mode 100644
index 0000000..19c1381
--- /dev/null
+++ b/RtspFace/PL_AVFrameBGRA.h
@@ -0,0 +1,24 @@
+#ifndef _PL_PL_AVFrameBGRA_H_
+#define _PL_PL_AVFrameBGRA_H_
+
+#include "PipeLine.h"
+
+class PL_AVFrameBGRA : public PipeLineElem
+{
+public:
+	PL_AVFrameBGRA();
+	virtual ~PL_AVFrameBGRA();
+
+	virtual bool init(void* args);
+	virtual void finit();
+
+	virtual bool pay(const PipeMaterial& pm);
+	virtual bool gain(PipeMaterial& pm);
+	
+private:
+	void* internal;
+};
+
+PipeLineElem* create_PL_AVFrameBGRA();
+
+#endif
diff --git a/RtspFace/PL_AVFrameYUV420.cpp b/RtspFace/PL_AVFrameYUV420.cpp
index 5927ce5..1384218 100644
--- a/RtspFace/PL_AVFrameYUV420.cpp
+++ b/RtspFace/PL_AVFrameYUV420.cpp
@@ -12,11 +12,9 @@
 	uint8_t buffer[1920*1080*3];
 	size_t buffSize;
 	size_t buffSizeMax;
-	bool payError;
 	
 	AVFrameYUV420_Internal() : 
-		buffSize(0), buffSizeMax(sizeof(buffer)), 
-		payError(false)
+		buffSize(0), buffSizeMax(sizeof(buffer))
 	{
 	}
 	
@@ -27,7 +25,6 @@
 	void reset()
 	{
 		buffSize = 0;
-		payError = false;
 	}
 };
 
@@ -64,52 +61,65 @@
 {
 	AVFrameYUV420_Internal* in = (AVFrameYUV420_Internal*)internal;
 	
-		int picSize = in->pAVCodecContext->height * in->pAVCodecContext->width;
-		in->buffSize = picSize * 1.5;
-
-		int height = in->pAVFrame->height;
-		int width = in->pAVFrame->width;
-
-		// write yuv420
-		int a=0;
-		for (int i = 0; i < height; i++)
-		{
-			memcpy(in->buffer + a, in->pAVFrame->data[0] + i * in->pAVFrame->linesize[0], width);
-			a += width;
-		}
-		for (int i=0; i<height/2; i++)
-		{
-			memcpy(in->buffer + a, in->pAVFrame->data[1] + i * in->pAVFrame->linesize[1], width / 2);
-			a += width / 2;
-		}
-		for (int i=0; i<height/2; i++)
-		{
-			memcpy(in->buffer + a, in->pAVFrame->data[2] + i * in->pAVFrame->linesize[2], width / 2);
-			a += width / 2;
-		}
-
-		//in->buffer readly
-
-		//static size_t f=0;
-		//char fname[50];
-		//sprintf(fname, "%u.yuv420", ++f);
-		//FILE * pFile = fopen (fname,"wb");
-		//fwrite (in->buffer , sizeof(char), in->buffSize, pFile);
-		//fclose(pFile);
+	AVFrame* pAVFrame = (AVFrame*)pm.buffer;
+	if (pAVFrame == nullptr)
+		return false;
 	
+	int picSize = pAVFrame->height * pAVFrame->width;
+	in->buffSize = picSize * 1.5;
+
+	int height = pAVFrame->height;
+	int width = pAVFrame->width;
+
+	uint8_t* pBuff = in->buffer;
 	
-	return in->payError;
+	memcpy(pBuff, pAVFrame->data[0], height * width);
+	pBuff += height * width;
+	
+	memcpy(pBuff, pAVFrame->data[1], height * width / 4);
+	pBuff += height * width / 4;
+	
+	memcpy(pBuff, pAVFrame->data[2], height * width / 4);
+	pBuff += height * width / 4;
+	
+	in->buffSize = pBuff - in->buffer;
+	
+	// write yuv420
+	//int a=0;
+	//for (int i = 0; i < height; i++)
+	//{
+	//	memcpy(in->buffer + a, pAVFrame->data[0] + i * pAVFrame->linesize[0], width);
+	//	a += width;
+	//}
+	//for (int i=0; i<height/2; i++)
+	//{
+	//	memcpy(in->buffer + a, pAVFrame->data[1] + i * pAVFrame->linesize[1], width / 2);
+	//	a += width / 2;//#todo 4
+	//}
+	//for (int i=0; i<height/2; i++)
+	//{
+	//	memcpy(in->buffer + a, pAVFrame->data[2] + i * pAVFrame->linesize[2], width / 2);
+	//	a += width / 2;
+	//}
+
+	//in->buffer readly
+
+	//static size_t f=0;
+	//char fname[50];
+	//sprintf(fname, "%u.yuv420", ++f);
+	//FILE * pFile = fopen (fname,"wb");
+	//fwrite (in->buffer , sizeof(char), in->buffSize, pFile);
+	//fclose(pFile);
+
+	return true;
 }
 
 bool PL_AVFrameYUV420::gain(PipeMaterial& pm)
 {
 	AVFrameYUV420_Internal* in = (AVFrameYUV420_Internal*)internal;
 
-	if (!in->payError)
-	{
-		pm.buffer = in->buffer;
-		pm.buffSize = in->buffSize;
-	}
+	pm.buffer = in->buffer;
+	pm.buffSize = in->buffSize;
 	pm.former = this;
-	return in->payError;
+	return true;
 }
diff --git a/RtspFace/PL_H264Decoder.cpp b/RtspFace/PL_H264Decoder.cpp
index b27918c..9f51b43 100644
--- a/RtspFace/PL_H264Decoder.cpp
+++ b/RtspFace/PL_H264Decoder.cpp
@@ -12,18 +12,19 @@
 
 struct H264Decoder_Internal
 {
-	uint8_t buffer[1920*1080*3];
-	size_t buffSize;
-	size_t buffSizeMax;
+	//uint8_t buffer[1920*1080*3];
+	//size_t buffSize;
+	//size_t buffSizeMax;
 	bool fmtp_set_to_context;
 	bool payError;
 
 	AVCodecContext* pAVCodecContext;
-	AVFrame* pAVFrame;
+	AVFrame* pAVFrame;//#todo delete
 	
 	H264Decoder_Internal() : 
-		buffSize(0), buffSizeMax(sizeof(buffer)), fmtp_set_to_context(false), 
-		payError(false), 
+		//buffSize(0), buffSizeMax(sizeof(buffer)), 
+		fmtp_set_to_context(false), 
+		payError(true), 
 		pAVCodecContext(nullptr), pAVFrame(nullptr)
 	{
 	}
@@ -34,9 +35,9 @@
 	
 	void reset()
 	{
-		buffSize = 0;
+		//buffSize = 0;
 		fmtp_set_to_context = false;
-		payError = false;
+		payError = true;
 	}
 };
 
@@ -171,47 +172,20 @@
 	if(frameFinished)
 	{
 		// decode ok
-
-		int picSize = in->pAVCodecContext->height * in->pAVCodecContext->width;
-		in->buffSize = picSize * 1.5;
-
-		int height = in->pAVFrame->height;
-		int width = in->pAVFrame->width;
-
-		// write yuv420
-		int a=0;
-		for (int i = 0; i < height; i++)
-		{
-			memcpy(in->buffer + a, in->pAVFrame->data[0] + i * in->pAVFrame->linesize[0], width);
-			a += width;
-		}
-		for (int i=0; i<height/2; i++)
-		{
-			memcpy(in->buffer + a, in->pAVFrame->data[1] + i * in->pAVFrame->linesize[1], width / 2);
-			a += width / 2;
-		}
-		for (int i=0; i<height/2; i++)
-		{
-			memcpy(in->buffer + a, in->pAVFrame->data[2] + i * in->pAVFrame->linesize[2], width / 2);
-			a += width / 2;
-		}
-
-		//in->buffer readly
-
-		//static size_t f=0;
-		//char fname[50];
-		//sprintf(fname, "%u.yuv420", ++f);
-		//FILE * pFile = fopen (fname,"wb");
-		//fwrite (in->buffer , sizeof(char), in->buffSize, pFile);
-		//fclose(pFile);
+		return true;
 	}
 	else
+	{
 		printf("incomplete frame\n");
+		return false;
+	}
 }
 
 bool PL_H264Decoder::pay(const PipeMaterial& pm)
 {
 	H264Decoder_Internal* in = (H264Decoder_Internal*)internal;
+	
+	in->payError = true;
 	
 	if (!in->fmtp_set_to_context)
 	{
@@ -237,8 +211,9 @@
 			in->fmtp_set_to_context = true;
 	}
 	
-	in->payError = decodeH264(in, pm.buffer, pm.buffSize);
-	return in->payError;
+	bool ret = decodeH264(in, pm.buffer, pm.buffSize);
+	in->payError = !ret;
+	return ret;
 }
 
 bool PL_H264Decoder::gain(PipeMaterial& pm)
@@ -247,9 +222,9 @@
 
 	if (!in->payError)
 	{
-		pm.buffer = in->buffer;
-		pm.buffSize = in->buffSize;
+		pm.buffer = (uint8_t*)in->pAVFrame;//in->buffer;
+		pm.buffSize = sizeof(uint8_t*);//in->buffSize;
 	}
 	pm.former = this;
-	return in->payError;
+	return !in->payError;
 }
diff --git a/RtspFace/PipeLine.cpp b/RtspFace/PipeLine.cpp
index 6f53b19..16f5ee1 100644
--- a/RtspFace/PipeLine.cpp
+++ b/RtspFace/PipeLine.cpp
@@ -77,7 +77,7 @@
 	uint8_t pmPlacement[sizeof(PipeMaterial)];
 	if (pm == nullptr)
 		pm = new (pmPlacement) PipeMaterial;
-	
+
 	if (elems.size() == 1)
 	{
 		elem_begin->gain(*pm);
@@ -85,24 +85,34 @@
 	}
 	else if (elems.size() == 2)
 	{
-		elem_begin->gain(*pm);
-		elem_last->pay(*pm);
+		if (elem_begin->gain(*pm))
+			elem_last->pay(*pm);
+		else
+			return elem_begin;
 		return elem_last;
 	}
 	else
 	{
-		elem_begin->gain(*pm);
+		if (!elem_begin->gain(*pm))
+			return elem_begin;
 		
+		bool lastRet = true;
 		elem_vec_t::iterator iter = elems.begin();
+		++iter;
+		elem_begin = *iter;
 		while (elem_begin != elem_last)
 		{
+			if (lastRet && (lastRet = elem_begin->pay(*pm)) )
+				lastRet = elem_begin->gain(*pm);
+			else
+				return elem_begin;
+			
 			++iter;
 			elem_begin = *iter;
-			elem_begin->pay(*pm);
-			elem_begin->gain(*pm);
 		}
 	
-		elem_last->pay(*pm);
+		if (lastRet)
+			elem_last->pay(*pm);
 		return elem_last;
 	}
 	
diff --git a/RtspFace/main.cpp b/RtspFace/main.cpp
index e9c6a48..f8e9875 100644
--- a/RtspFace/main.cpp
+++ b/RtspFace/main.cpp
@@ -1,7 +1,7 @@
 #include "PipeLine.h"
 #include "PL_RTSPClient.h"
 #include "PL_H264Decoder.h"
-#include "PL_AVFrameYUV420.h"
+#include "PL_AVFrameBGRA.h"
 
 #include <iostream>
 using namespace std;
@@ -12,7 +12,7 @@
 	
 	pipeLine.register_elem_creator("PL_RTSPClient", create_PL_RTSPClient);
 	pipeLine.register_elem_creator("PL_H264Decoder", create_PL_H264Decoder);
-	pipeLine.register_elem_creator("PL_AVFrameYUV420", create_PL_H264Decoder);
+	pipeLine.register_elem_creator("PL_AVFrameBGRA", create_PL_AVFrameBGRA);
 	
 	PL_RTSPClient* rtspClient = (PL_RTSPClient*)pipeLine.push_elem("PL_RTSPClient");
 	RTSPConfig rtspConfig;
@@ -28,8 +28,8 @@
 	PL_H264Decoder* h264Decoder = (PL_H264Decoder*)pipeLine.push_elem("PL_H264Decoder");
 	h264Decoder->init(nullptr);
 	
-	PL_AVFrameYUV420* AVFrameYUV420 = (PL_AVFrameYUV420*)pipeLine.push_elem("PL_AVFrameYUV420");
-	AVFrameYUV420->init(nullptr);
+	PL_AVFrameBGRA* avFrameBGRA = (PL_AVFrameBGRA*)pipeLine.push_elem("PL_AVFrameBGRA");
+	avFrameBGRA->init(nullptr);
 	
 	while(true)
 	{
diff --git a/RtspFace/make.sh b/RtspFace/make.sh
index 3568267..4749d56 100644
--- a/RtspFace/make.sh
+++ b/RtspFace/make.sh
@@ -10,8 +10,12 @@
 LIBBASE64_INC="-I$LIBBASE64_BASE/include"
 LIBBASE64_LIB="$LIBBASE64_BASE/lib/libbase64.o"
 
-CPPFLAGS+="-pthread $LIVEMEDIA_INC $FFMPEG_INC $LIBBASE64_INC"
-LDFLAGS+="-pthread $LIVEMEDIA_LIB $FFMPEG_LIB $LIBBASE64_LIB"
+LIBYUV_BASE=/opt/libyuv
+LIBYUV_INC="-I$LIBYUV_BASE/include"
+LIBYUV_LIB="-L$LIBYUV_BASE -lyuv"
+
+CPPFLAGS+="-pthread $LIVEMEDIA_INC $FFMPEG_INC $LIBBASE64_INC $LIBYUV_INC"
+LDFLAGS+="-pthread $LIVEMEDIA_LIB $FFMPEG_LIB $LIBBASE64_LIB $LIBYUV_LIB"
 
 CFLAGS+="-D__STDC_CONSTANT_MACROS"
 
@@ -21,8 +25,10 @@
 g++ -g -c -std=c++11 main.cpp $CFLAGS $CPPFLAGS
 g++ -g -c -std=c++11 PL_RTSPClient.cpp $CFLAGS $CPPFLAGS
 g++ -g -c -std=c++11 PL_H264Decoder.cpp $CFLAGS $CPPFLAGS
+g++ -g -c -std=c++11 PL_AVFrameYUV420.cpp $CFLAGS $CPPFLAGS
+g++ -g -c -std=c++11 PL_AVFrameBGRA.cpp $CFLAGS $CPPFLAGS
 g++ -g -c -std=c++11 PipeLine.cpp $CFLAGS $CPPFLAGS
-g++ -g -std=c++11 main.o PL_RTSPClient.o PL_H264Decoder.o PipeLine.o $LDFLAGS -o rtsp_face
+g++ -g -std=c++11 main.o PL_RTSPClient.o PL_H264Decoder.o PL_AVFrameYUV420.o PL_AVFrameBGRA.o PipeLine.o $LDFLAGS -o rtsp_face
 
 #export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$FFMPEG_BASE/lib
 #./rtsp_face rtsp://admin:admin12345@192.168.1.63:554/h264/ch1/main/av_stream

--
Gitblit v1.8.0