From d4109b2cef809daba0f95f244029456613383f01 Mon Sep 17 00:00:00 2001
From: houxiao <houxiao@454eff88-639b-444f-9e54-f578c98de674>
Date: 星期五, 06 一月 2017 11:31:42 +0800
Subject: [PATCH] add pm list test

---
 RtspFace/PL_Fork.h                 |   61 ++++++
 RtspFace/make.sh                   |    6 
 RtspFace/PL_SensetimeFaceTrack.h   |   34 +++
 RtspFace/PipeLine.h                |   13 
 RtspFace/PL_SensetimeFaceTrack.cpp |   57 +++++
 RtspFace/PL_DlibFaceTrack.cpp      |    1 
 RtspFace/PL_H264Decoder.cpp        |    2 
 RtspFace/PL_Fork.cpp               |  151 +++++++++++---
 RtspFace/main.cpp                  |   58 +++--
 RtspFace/main_dump_st_face.cpp     |  110 +++++++++++
 RtspFace/PL_RTSPClient.cpp         |    4 
 RtspFace/PipeLine.cpp              |   67 +++++-
 12 files changed, 479 insertions(+), 85 deletions(-)

diff --git a/RtspFace/PL_DlibFaceTrack.cpp b/RtspFace/PL_DlibFaceTrack.cpp
index 5c5dcea..0f88a75 100644
--- a/RtspFace/PL_DlibFaceTrack.cpp
+++ b/RtspFace/PL_DlibFaceTrack.cpp
@@ -281,7 +281,6 @@
 		in->payError = false;
 	
 	//in->buffer readly
-in->payError = false;//#todo
 	in->lastFrame.type = MB_Frame::MBFT_YUV420;
 	in->lastFrame.buffer = frame->buffer;//#todo should copy
 	in->lastFrame.buffSize = frame->buffSize;
diff --git a/RtspFace/PL_Fork.cpp b/RtspFace/PL_Fork.cpp
index 9bf79c3..627a857 100644
--- a/RtspFace/PL_Fork.cpp
+++ b/RtspFace/PL_Fork.cpp
@@ -1,49 +1,122 @@
-#ifndef _PL_FORK_H_
-#define _PL_FORK_H_
+#include "PL_Fork.h"
+#include "MaterialBuffer.h"
+#include "logger.h"
 
-#include "PipeLine.h"
-
-struct PL_Fork_Config
+struct PL_Fork_Internal
 {
+	//uint8_t buffer[1920*1080*4];
+	//size_t buffSize;
+	//size_t buffSizeMax;
 
+	PipeMaterial lastPm;
+	
+	MB_Frame lastFrame;
+	
+	PL_Fork_Config config;
+
+	bool payError;
+
+	PL_Fork_Internal() : 
+		//buffSize(0), buffSizeMax(sizeof(buffer)), 
+		lastPm(), lastFrame(), config(), payError(true)
+	{
+	}
+	
+	~PL_Fork_Internal()
+	{
+	}
+	
+	void reset()
+	{
+		//buffSize = 0;
+		payError = true;
+		
+		PipeMaterial _lastPm;
+		lastPm = _lastPm;
+		
+		MB_Frame _lastFrame;
+		lastFrame = _lastFrame;
+		
+		PL_Fork_Config _config;
+		config = _config;
+	}
 };
 
-class PL_Fork : public PipeLineElem
+PipeLineElem* create_PL_Fork()
 {
-public:
-	enum ForkBy
+	return new PL_Fork;
+}
+
+PL_Fork::PL_Fork() : internal(new PL_Fork_Internal), pl(nullptr)
+{
+}
+
+PL_Fork::~PL_Fork()
+{
+	delete (PL_Fork_Internal*)internal;
+	internal= nullptr;
+}
+
+bool PL_Fork::init(void* args)
+{
+	PL_Fork_Internal* in = (PL_Fork_Internal*)internal;
+	in->reset();
+
+	if (args == nullptr)
 	{
-		FB_NONE,
-		FB_TURNS,
-		FB_RANDOM,
-		FB_PM_TYPE,
-		FB_MB_TYPE,
-		FB_BREAK_LIST
-	};
+		LOG_ERROR << "Config should give";
+		return false;
+	}
+
+	PL_Fork_Config* config = (PL_Fork_Config*)args;
+	in->config = *config;
+
+	return true;
+}
+
+void PL_Fork::finit()
+{
+	PL_Fork_Internal* in = (PL_Fork_Internal*)internal;
+
+}
+
+bool PL_Fork::pay(const PipeMaterial& pm)
+{
+	PL_Fork_Internal* in = (PL_Fork_Internal*)internal;
+	PL_Fork_Config& config(in->config);
+
+	in->lastPm = pm;
 	
-	enum ForkSync
+	return false;
+}
+
+bool PL_Fork::gain(PipeMaterial& pm)
+{
+	PL_Fork_Internal* in = (PL_Fork_Internal*)internal;
+	
+	return false;
+}
+
+void PL_Fork::attach_pipe_line(PipeLine* pl)
+{
+	PL_Fork_Internal* in = (PL_Fork_Internal*)internal;
+	
+	if (this->pl != nullptr)
 	{
-		FS_NONE,
-		FS_SEQUENCE,
-		FS_PARALLEL,
-		FS_MAIN_PL_FIRST,
-		FS_MAIN_PL_LAST,
-	};
-
-public:
-	PL_Fork();
-	virtual ~PL_Fork();
-
-	virtual bool init(void* args);
-	virtual void finit();
-
-	virtual bool pay(const PipeMaterial& pm);
-	virtual bool gain(PipeMaterial& pm);
+		LOG_ERROR << "Has areadly attached pipe line";
+		return;
+	}
 	
-private:
-	void* internal;
-};
-
-PipeLineElem* create_PL_Paint();
-
-#endif
+	if (pl == nullptr)
+	{
+		LOG_NOTICE << "Detach pipe line";
+		this->pl->remove_elem(this);
+		this->pl = nullptr;
+		return;
+	}
+	
+	this->pl = pl;
+	PipeLine* mainPipeLineManager = this->manager;
+	pl->push_front_elem(this);
+	this->manager = mainPipeLineManager;
+}
diff --git a/RtspFace/PL_Fork.h b/RtspFace/PL_Fork.h
index 865044e..5eaaffe 100644
--- a/RtspFace/PL_Fork.h
+++ b/RtspFace/PL_Fork.h
@@ -3,8 +3,51 @@
 
 #include "PipeLine.h"
 
+// p1e1 p1e2<fork> p1e3 ... p1eN
+//                 p2e1  p2e2... p2eN
 class PL_Fork : public PipeLineElem
 {
+public:
+	enum ForkBy
+	{
+		// do nothing
+		FB_NONE,
+
+		// time 1: p1e1 p1e2 [p1e3 ... p1eN]
+		// time 2: p1e1 p1e2 [p2e1  p2e2... p2eN]
+		FB_TURNS,
+
+		// p1e1 p1e2 [p1e3 ... p1eN]|[p2e1  p2e2... p2eN]
+		FB_RANDOM,
+		
+		// supported now!
+		// p1e1 p1e2 TYPE1[p1e3 ... p1eN] TYPE2[p2e1  p2e2... p2eN]
+		// Sync behavior depends on ForkSync
+		FB_PM_TYPE,
+
+		// supported now!
+		FB_MB_TYPE,
+		
+		// FS_MAIN_PL_FIRST: p1e1 p1e2 [p1e3 p2e1] [p1e4 p2e2] ...
+		// FS_MAIN_PL_LAST : p1e1 p1e2 [p2e1 p1e3] [p2e2 p1e4] ...
+		FB_ALTERNATE
+	};
+	
+	enum ForkSync
+	{
+		// do nothing
+		FS_NONE,
+		
+		// supported now!
+		FS_PARALLEL,
+		
+		// Result of main pl will be paid to branch pl
+		FS_MAIN_PL_FIRST,
+		
+		// Result of branch pl will be paid to main pl
+		FS_BRANCH_PL_FIRST
+	};
+
 public:
 	PL_Fork();
 	virtual ~PL_Fork();
@@ -15,10 +58,26 @@
 	virtual bool pay(const PipeMaterial& pm);
 	virtual bool gain(PipeMaterial& pm);
 	
+	void attach_pipe_line(PipeLine* pl);
+	
 private:
 	void* internal;
+	PipeLine* pl;
 };
 
-PipeLineElem* create_PL_Paint();
+struct PL_Fork_Config
+{
+	PL_Fork::ForkBy forkBy;
+	PL_Fork::ForkSync forkSync;
+	
+	int mainPLType;
+	int branchPLType;
+	
+	PL_Fork_Config() : 
+		forkBy(PL_Fork::FB_NONE), forkSync(PL_Fork::FS_NONE), mainPLType(0), branchPLType(0)
+	{ }
+};
+
+PipeLineElem* create_PL_Fork();
 
 #endif
diff --git a/RtspFace/PL_H264Decoder.cpp b/RtspFace/PL_H264Decoder.cpp
index 55a130c..7426bac 100644
--- a/RtspFace/PL_H264Decoder.cpp
+++ b/RtspFace/PL_H264Decoder.cpp
@@ -216,7 +216,7 @@
 		if (manager == NULL)
 			return false;
 		
-		std::string fmtp(manager->get_global_param(PLGP_RTSP_FMTP));
+		std::string fmtp(manager->get_param(PLGP_RTSP_FMTP));
 		if (fmtp.empty())
 			return false;
 		
diff --git a/RtspFace/PL_RTSPClient.cpp b/RtspFace/PL_RTSPClient.cpp
index 0a1b163..d169da2 100644
--- a/RtspFace/PL_RTSPClient.cpp
+++ b/RtspFace/PL_RTSPClient.cpp
@@ -197,7 +197,7 @@
 	if (client->manager == nullptr)
 		return;
 	
-	client->manager->set_global_param(PLGP_RTSP_SDP, val);
+	client->manager->set_param(PLGP_RTSP_SDP, val);
 }
 
 void rtsp_client_fmtp_callback(void* arg, const char* val)
@@ -210,7 +210,7 @@
 	if (client->manager == nullptr)
 		return;
 	
-	client->manager->set_global_param(PLGP_RTSP_FMTP, val);
+	client->manager->set_param(PLGP_RTSP_FMTP, val);
 }
 
 void rtsp_client_frame_callback(void* arg, uint8_t* buffer, size_t buffSize, timeval presentationTime)
diff --git a/RtspFace/PL_SensetimeFaceTrack.cpp b/RtspFace/PL_SensetimeFaceTrack.cpp
index 541c79c..7802631 100644
--- a/RtspFace/PL_SensetimeFaceTrack.cpp
+++ b/RtspFace/PL_SensetimeFaceTrack.cpp
@@ -11,7 +11,9 @@
 	//size_t buffSize;
 	//size_t buffSizeMax;
 	MB_Frame lastFrame;
+	PipeMaterial pmList[2];
 	SensetimeFaceTrackConfig config;
+	st_ff_vect_t faceFeatures;
 
 	bool payError;
 	
@@ -19,7 +21,7 @@
 	
 	PL_SensetimeFaceTrack_Internal() : 
 		//buffSize(0), buffSizeMax(sizeof(buffer)), 
-		lastFrame(), config(), payError(true), 
+		lastFrame(), pmList(), config(), faceFeatures(), payError(true), 
 		handle_track(nullptr)
 	{
 	}
@@ -35,6 +37,11 @@
 		
 		MB_Frame _lastFrame;
 		lastFrame = _lastFrame;
+		
+		PipeMaterial _pm;
+		pmList[0] = _pm;
+		pmList[1] = _pm;
+		
 		SensetimeFaceTrackConfig _config;
 		config = _config;
 		
@@ -130,6 +137,17 @@
 	cv::Mat yMat(cv::Size(width,height), CV_8UC1, buffer);
 	for (int i = 0; i < face_count; i++)
 	{
+		SensetimeFaceFeature faceFeature;
+		faceFeature.rect.leftTop.x = p_face[i].rect.left;
+		faceFeature.rect.leftTop.y = p_face[i].rect.top;
+		faceFeature.rect.rightBottom.x = p_face[i].rect.right;
+		faceFeature.rect.rightBottom.y = p_face[i].rect.bottom;
+		faceFeature.id = p_face[i].ID;
+		faceFeature.yaw = p_face[i].yaw;
+		faceFeature.pitch = p_face[i].pitch;
+		faceFeature.roll = p_face[i].roll;
+		faceFeature.eyeDistance = p_face[i].eye_dist;
+		
 		LOGP(DEBUG, "face: %d-----[%d, %d, %d, %d]-----id: %d", i,
 			p_face[i].rect.left, p_face[i].rect.top,
 			p_face[i].rect.right, p_face[i].rect.bottom, p_face[i].ID);
@@ -156,7 +174,10 @@
 
 		for (int j = 0; j < p_face[i].points_count; j++)
 		{
-			
+			FacePoint featurePoint;
+			featurePoint.x = p_face[i].points_array[j].x;
+			featurePoint.y = p_face[i].points_array[j].y;
+			faceFeature.featurePoints.push_back(featurePoint);
 			
 			if (in->config.draw_face_feature_point)
 			{
@@ -164,6 +185,9 @@
 					p_face[i].points_array[j].y), 1, cv::Scalar(255, 255, 255));
 			}
 		}
+		
+		if (in->config.generate_face_feature)
+			in->faceFeatures.push_back(faceFeature);
 	}
 
 	//if (face_count > 0)
@@ -203,6 +227,7 @@
 		return false;
 	}
 
+	in->faceFeatures.clear();
 	int face_count = doFaceTrack(
 						in, (uint8_t*)frame->buffer, frame->width, frame->height, frame->width, CV_PIX_FMT_YUV420P);
 	if (face_count < 0)
@@ -229,13 +254,35 @@
 {
 	PL_SensetimeFaceTrack_Internal* in = (PL_SensetimeFaceTrack_Internal*)internal;
 
-	if (!in->payError)
+	if (in->payError)
+	{
+		pm.former = this;
+		return false;
+	}
+
+	if (!in->config.generate_face_feature)
 	{
 		pm.type = PipeMaterial::PMT_FRAME;
 		pm.buffer = &(in->lastFrame);
 		pm.buffSize = 0;
-		pm.former = this;
 	}
+	else
+	{
+		in->pmList[0].type = PipeMaterial::PMT_FRAME;
+		in->pmList[0].buffer = &(in->lastFrame);
+		in->pmList[0].buffSize = 0;
+		in->pmList[0].former = this;
+		
+		in->pmList[1].type = PipeMaterial::PMT_BYTES;
+		in->pmList[1].buffer = &(in->faceFeatures);
+		in->pmList[1].buffSize = 0;
+		in->pmList[1].former = this;
+		
+		pm.type = PipeMaterial::PMT_PM_LIST;
+		pm.buffer = in->pmList;
+		pm.buffSize = sizeof(in->pmList) / sizeof(PipeMaterial);
+	}
+	
 	pm.former = this;
-	return !in->payError;
+	return true;
 }
diff --git a/RtspFace/PL_SensetimeFaceTrack.h b/RtspFace/PL_SensetimeFaceTrack.h
index 48030e8..c3bf593 100644
--- a/RtspFace/PL_SensetimeFaceTrack.h
+++ b/RtspFace/PL_SensetimeFaceTrack.h
@@ -2,6 +2,40 @@
 #define _PL_SENSETIMEFACETRACK_H_
 
 #include "PipeLine.h"
+#include <vector>
+
+struct FacePoint
+{
+	int x;
+	int y;
+	
+	FacePoint() : x(0), y(0) { }
+};
+
+struct FaceRect
+{
+	FacePoint leftTop;
+	FacePoint rightBottom;
+	
+	FaceRect() : leftTop(), rightBottom() { }
+};
+
+struct SensetimeFaceFeature
+{
+	FaceRect rect;
+	int id;
+	float yaw;
+	float pitch;
+	float roll;
+	float eyeDistance;
+	std::vector<FacePoint> featurePoints;
+	
+	SensetimeFaceFeature() : 
+		rect(), id(0), yaw(0.0), pitch(0.0), roll(0.0), eyeDistance(0.0), featurePoints()
+	{}
+};
+
+typedef std::vector<SensetimeFaceFeature> st_ff_vect_t;
 
 struct SensetimeFaceTrackConfig
 {
diff --git a/RtspFace/PipeLine.cpp b/RtspFace/PipeLine.cpp
index 1f3aba9..0aabd47 100644
--- a/RtspFace/PipeLine.cpp
+++ b/RtspFace/PipeLine.cpp
@@ -16,7 +16,9 @@
 	}
 }
 
-PipeLine::PipeLine() : global_params_map(), elem_create_func_map(), elems()
+PipeLine::elem_create_func_map_t PipeLine::global_elem_create_func_map;
+
+PipeLine::PipeLine() : params_map(), elem_create_func_map(), elems()
 {
 }
 
@@ -27,7 +29,7 @@
 	for(elem_vec_t::iterator iter = elems.begin(); iter != elems.end(); ++iter)
 	{
 		PipeLineElem* elem = *iter;
-		if (elem != nullptr)
+		if (elem != nullptr && elem->manager == this)
 		{
 			elem->finit();
 			delete *iter;
@@ -50,6 +52,21 @@
 	return true;
 }
 
+
+//static
+bool PipeLine::register_global_elem_creator(const std::string& type, elem_create_func_t func)
+{
+	if (type.empty() || func == nullptr)
+		return false;
+
+	elem_create_func_map_t::iterator iter = global_elem_create_func_map.find(type);
+	if (iter != global_elem_create_func_map.end())
+		return false;
+	
+	global_elem_create_func_map.insert(std::make_pair(type, func));
+	return true;
+}
+
 void PipeLine::push_elem(PipeLineElem* elem)
 {
 	if(elem != nullptr)
@@ -59,11 +76,41 @@
 	}
 }
 
+void PipeLine::push_front_elem(PipeLineElem* elem)
+{
+	if(elem != nullptr)
+	{
+		elem->manager = this;
+		elems.insert(elems.begin(), elem);
+	}
+}
+
+bool PipeLine::remove_elem(PipeLineElem* elem)
+{
+	if(elem != nullptr)
+	{
+		for(elem_vec_t::iterator iter = elems.begin(); iter != elems.end(); ++iter)
+		{
+			if (*iter == elem)
+			{
+				iter = elems.erase(iter);
+				return true;
+			}
+		}
+	}
+	
+	return false;
+}
+
 PipeLineElem* PipeLine::push_elem(const std::string& type)
 {
 	elem_create_func_map_t::iterator iter = elem_create_func_map.find(type);
 	if (iter == elem_create_func_map.end())
-		return nullptr;
+	{
+		iter = global_elem_create_func_map.find(type);
+		if (iter == global_elem_create_func_map.end())
+			return nullptr;
+	}
 	
 	elem_create_func_t func = iter->second;
 	if (func == nullptr)
@@ -170,22 +217,22 @@
 	return nullptr;
 }
 
-void PipeLine::set_global_param(const std::string& name, const std::string& value)
+void PipeLine::set_param(const std::string& name, const std::string& value)
 {
 	if (name.empty())
 		return;
 
-	global_params_map_t::iterator iter = global_params_map.find(name);
-	if (iter == global_params_map.end())
-		global_params_map.insert(std::make_pair(name, value));
+	params_map_t::iterator iter = params_map.find(name);
+	if (iter == params_map.end())
+		params_map.insert(std::make_pair(name, value));
 	else
 		iter->second = value;
 }
 
-std::string PipeLine::get_global_param(const std::string& name) const
+std::string PipeLine::get_param(const std::string& name) const
 {
-	global_params_map_t::const_iterator iter = global_params_map.find(name);
-	if (iter == global_params_map.end())
+	params_map_t::const_iterator iter = params_map.find(name);
+	if (iter == params_map.end())
 		return "";
 	else
 		return iter->second;
diff --git a/RtspFace/PipeLine.h b/RtspFace/PipeLine.h
index 79e1984..b208240 100644
--- a/RtspFace/PipeLine.h
+++ b/RtspFace/PipeLine.h
@@ -76,8 +76,12 @@
 	~PipeLine();
 	
 	bool register_elem_creator(const std::string& type, elem_create_func_t func);
+	static bool register_global_elem_creator(const std::string& type, elem_create_func_t func);
+	
 	void push_elem(PipeLineElem* elem);
 	PipeLineElem* push_elem(const std::string& type);
+	void push_front_elem(PipeLineElem* elem);
+	bool remove_elem(PipeLineElem* elem);
 	
 	// do pipe sync. returns the element who returns false, or the last one.
 	// if false return, the element should deal with pm, clean up.
@@ -88,18 +92,19 @@
 	void pipe_notify(PipeLineElem*);
 	void pipe_stop();
 	
-	void set_global_param(const std::string& name, const std::string& value);
-	std::string get_global_param(const std::string& name) const;
+	void set_param(const std::string& name, const std::string& value);
+	std::string get_param(const std::string& name) const;
 	
 private:
 	typedef std::map<const std::string, elem_create_func_t> elem_create_func_map_t;
 	elem_create_func_map_t elem_create_func_map;
+	static elem_create_func_map_t global_elem_create_func_map;
 	
 	typedef std::vector<PipeLineElem*> elem_vec_t;
 	elem_vec_t elems;
 
-	typedef std::map<const std::string, std::string> global_params_map_t;
-	global_params_map_t global_params_map;
+	typedef std::map<const std::string, std::string> params_map_t;
+	params_map_t params_map;
 };
 
 #endif
diff --git a/RtspFace/main.cpp b/RtspFace/main.cpp
index 738b9b1..f900b8e 100644
--- a/RtspFace/main.cpp
+++ b/RtspFace/main.cpp
@@ -7,6 +7,7 @@
 #include "PL_AVFrameBGRA.h"
 #include "PL_Queue.h"
 #include "PL_Scale.h"
+#include "PL_Fork.h"
 
 #include "PL_SensetimeFaceTrack.h"
 
@@ -20,13 +21,14 @@
 
 	PipeLine pipeLine;
 	
-	pipeLine.register_elem_creator("PL_RTSPClient", create_PL_RTSPClient);
-	pipeLine.register_elem_creator("PL_RTSPServer", create_PL_RTSPServer);
-	pipeLine.register_elem_creator("PL_H264Decoder", create_PL_H264Decoder);
-	pipeLine.register_elem_creator("PL_AVFrameYUV420", create_PL_AVFrameYUV420);
-	pipeLine.register_elem_creator("PL_H264Encoder", create_PL_H264Encoder);
-	pipeLine.register_elem_creator("PL_Queue", create_PL_Queue);
-	pipeLine.register_elem_creator("PL_Scale", create_PL_Scale);
+	PipeLine::register_global_elem_creator("PL_RTSPClient", create_PL_RTSPClient);
+	PipeLine::register_global_elem_creator("PL_RTSPServer", create_PL_RTSPServer);
+	PipeLine::register_global_elem_creator("PL_H264Decoder", create_PL_H264Decoder);
+	PipeLine::register_global_elem_creator("PL_AVFrameYUV420", create_PL_AVFrameYUV420);
+	PipeLine::register_global_elem_creator("PL_H264Encoder", create_PL_H264Encoder);
+	PipeLine::register_global_elem_creator("PL_Queue", create_PL_Queue);
+	PipeLine::register_global_elem_creator("PL_Scale", create_PL_Scale);
+	PipeLine::register_global_elem_creator("PL_Fork", create_PL_Scale);
 	
 	pipeLine.register_elem_creator("PL_SensetimeFaceTrack", create_PL_SensetimeFaceTrack);
 	
@@ -73,8 +75,8 @@
 		PL_Scale_Config config;
 		config.toWidth = 800;
 		config.toHeight = 600;
-		PL_Scale* pl = (PL_Scale*)pipeLine.push_elem("PL_Scale");
-		bool ret = pl->init(&config);
+		PL_Scale* ple = (PL_Scale*)pipeLine.push_elem("PL_Scale");
+		bool ret = ple->init(&config);
 		if (!ret)
 		{
 			LOG_ERROR << "PL_Scale.init error";
@@ -82,19 +84,34 @@
 		}
 	}
 
+	{
+		SensetimeFaceTrackConfig config;
+		//config.generate_face_feature = true;
+		PL_SensetimeFaceTrack* ple = (PL_SensetimeFaceTrack*)pipeLine.push_elem("PL_SensetimeFaceTrack");
+		ple->init(&config);
+	}
+	
+	//PipeLine pipeLine2;
 	//{
-	//	SensetimeFaceTrackConfig config;
-	//	PL_SensetimeFaceTrack* pl = (PL_SensetimeFaceTrack*)pipeLine.push_elem("PL_SensetimeFaceTrack");
-	//	pl->init(&config);
+	//	PL_Fork_Config config;
+	//	config.forkBy = PL_Fork::FB_MB_TYPE;
+	//	config.forkSync = PL_Fork::FS_PARALLEL;
+	//	PL_Fork* ple = (PL_Fork*)pipeLine.push_elem("PL_Fork");
+	//	ple->init(&config);
+	//	ple->attach_pipe_line(&pipeLine2);
+	//	
+	//	{
+	//		//pipeLine2.push_elem();
+	//	}
 	//}
 	
-	{
-		PL_DlibFaceTrack_Config config;
-		config.pyramid_down_layers = 2;
-		config.pyramid_down_n = 1;
-		PL_DlibFaceTrack* pl = (PL_DlibFaceTrack*)pipeLine.push_elem("PL_DlibFaceTrack");
-		pl->init(&config);
-	}
+	//{
+	//	PL_DlibFaceTrack_Config config;
+	//	config.pyramid_down_layers = 2;
+	//	config.pyramid_down_n = 1;
+	//	PL_DlibFaceTrack* ple = (PL_DlibFaceTrack*)pipeLine.push_elem("PL_DlibFaceTrack");
+	//	ple->init(&config);
+	//}
 
 	//{//#todo queue should support deep copy
 	//	PL_Queue_Config config;
@@ -108,8 +125,9 @@
 	//}
 
 	{
+		PL_H264Encoder_Config config;
 		PL_H264Encoder* h264Encoder = (PL_H264Encoder*)pipeLine.push_elem("PL_H264Encoder");
-		bool ret = h264Encoder->init(nullptr);
+		bool ret = h264Encoder->init(&config);
 		if (!ret)
 		{
 			LOG_ERROR << "PL_H264Encoder.init error";
diff --git a/RtspFace/main_dump_st_face.cpp b/RtspFace/main_dump_st_face.cpp
new file mode 100644
index 0000000..1285a81
--- /dev/null
+++ b/RtspFace/main_dump_st_face.cpp
@@ -0,0 +1,110 @@
+#include "PipeLine.h"
+#include "PL_RTSPClient.h"
+#include "PL_RTSPServer.h"
+#include "PL_H264Decoder.h"
+#include "PL_H264Encoder.h"
+#include "PL_AVFrameYUV420.h"
+#include "PL_AVFrameBGRA.h"
+#include "PL_Queue.h"
+#include "PL_Scale.h"
+#include "PL_Fork.h"
+
+#include "PL_SensetimeFaceTrack.h"
+
+#include "PL_DlibFaceTrack.h"
+
+#include "logger.h"
+
+int main(int argc, char** argv)
+{
+	initLogger(LV_INFO);
+
+	PipeLine pipeLine;
+	
+	PipeLine::register_global_elem_creator("PL_RTSPClient", create_PL_RTSPClient);
+	//PipeLine::register_global_elem_creator("PL_RTSPServer", create_PL_RTSPServer);
+	PipeLine::register_global_elem_creator("PL_H264Decoder", create_PL_H264Decoder);
+	PipeLine::register_global_elem_creator("PL_AVFrameYUV420", create_PL_AVFrameYUV420);
+	//PipeLine::register_global_elem_creator("PL_H264Encoder", create_PL_H264Encoder);
+	//PipeLine::register_global_elem_creator("PL_Queue", create_PL_Queue);
+	PipeLine::register_global_elem_creator("PL_Scale", create_PL_Scale);
+	//PipeLine::register_global_elem_creator("PL_Fork", create_PL_Scale);
+	
+	pipeLine.register_elem_creator("PL_SensetimeFaceTrack", create_PL_SensetimeFaceTrack);
+	
+	{
+		PL_RTSPClient* rtspClient = (PL_RTSPClient*)pipeLine.push_elem("PL_RTSPClient");
+		PL_RTSPClient_Config rtspConfig;
+		rtspConfig.progName = argv[0];
+		rtspConfig.rtspURL = argv[1];
+		rtspConfig.aux = true; // ffmpeg need aux, but live555 not
+		rtspConfig.verbosityLevel = 1;
+		rtspConfig.tunnelOverHTTPPortNum = 0;
+		rtspConfig.args = nullptr;
+		bool ret = rtspClient->init(&rtspConfig);
+		if (!ret)
+		{
+			LOG_ERROR << "rtspClient.init error";
+			exit(EXIT_FAILURE);
+		}
+	}
+
+	{
+		PL_H264Decoder* h264Decoder = (PL_H264Decoder*)pipeLine.push_elem("PL_H264Decoder");
+		bool ret = h264Decoder->init(nullptr);
+		if (!ret)
+		{
+			LOG_ERROR << "PL_H264Decoder.init error";
+			exit(EXIT_FAILURE);
+		}
+	}
+
+	{
+		PL_AVFrameYUV420* avFrameYUV420 = (PL_AVFrameYUV420*)pipeLine.push_elem("PL_AVFrameYUV420");
+		bool ret = avFrameYUV420->init(nullptr);
+		if (!ret)
+		{
+			LOG_ERROR << "PL_AVFrameYUV420.init error";
+			exit(EXIT_FAILURE);
+		}
+	}
+	
+	{
+		PL_Scale_Config config;
+		config.toWidth = 800;
+		config.toHeight = 600;
+		PL_Scale* ple = (PL_Scale*)pipeLine.push_elem("PL_Scale");
+		bool ret = ple->init(&config);
+		if (!ret)
+		{
+			LOG_ERROR << "PL_Scale.init error";
+			exit(EXIT_FAILURE);
+		}
+	}
+
+	PL_SensetimeFaceTrack* sensetimeFaceTrack;
+	{
+		SensetimeFaceTrackConfig config;
+		config.generate_face_feature = true;
+		sensetimeFaceTrack = (PL_SensetimeFaceTrack*)pipeLine.push_elem("PL_SensetimeFaceTrack");
+		sensetimeFaceTrack->init(&config);
+	}
+
+	while(true)
+	{
+		//LOG_ERROR << "begin pipe";
+		
+		PipeMaterial pm;
+		if (pipeLine.pipe(&pm) == sensetimeFaceTrack);
+			sensetimeFaceTrack->gain(pm);
+		
+		if (pm.type == PipeMaterial::PMT_PM_LIST)
+		{
+			PipeMaterial& facePM = ((PipeMaterial*)(pm.buffer))[1];
+			st_ff_vect_t& faceFeatures = *((st_ff_vect_t*)facePM.buffer);
+			LOG_NOTICE << "faceFeatures " << faceFeatures.size();
+		}
+		
+		//LOG_ERROR << "end pipe";
+	}
+}
diff --git a/RtspFace/make.sh b/RtspFace/make.sh
index c15d0d2..05baf7f 100644
--- a/RtspFace/make.sh
+++ b/RtspFace/make.sh
@@ -46,7 +46,8 @@
 rm rtsp_face
 rm *.o
 
-g++ main.cpp $CFLAGS $CPPFLAGS
+#g++ main.cpp $CFLAGS $CPPFLAGS -o main.o
+g++ main_dump_st_face.cpp $CFLAGS $CPPFLAGS -o main.o
 g++ PipeLine.cpp $CFLAGS $CPPFLAGS
 
 g++ PL_RTSPClient.cpp $CFLAGS $CPPFLAGS
@@ -57,6 +58,7 @@
 g++ PL_AVFrameBGRA.cpp $CFLAGS $CPPFLAGS
 g++ PL_Queue.cpp $CFLAGS $CPPFLAGS
 g++ PL_Scale.cpp $CFLAGS $CPPFLAGS
+g++ PL_Fork.cpp $CFLAGS $CPPFLAGS
 
 g++ PL_SensetimeFaceTrack.cpp $CFLAGS $CPPFLAGS
 
@@ -68,7 +70,7 @@
 
 g++ -g -std=c++11 \
   main.o PipeLine.o \
-  PL_RTSPClient.o PL_H264Decoder.o PL_H264Encoder.o PL_AVFrameYUV420.o PL_AVFrameBGRA.o PL_Queue.o PL_Scale.o \
+  PL_RTSPClient.o PL_H264Decoder.o PL_H264Encoder.o PL_AVFrameYUV420.o PL_AVFrameBGRA.o PL_Queue.o PL_Scale.o PL_Fork.o \
   PL_SensetimeFaceTrack.o \
   PL_DlibFaceTrack.o \
   $FFMPEGRTSPSERVER_OBJ PL_RTSPServer.o \

--
Gitblit v1.8.0