From 0688756b71b40e0ac60c68af2fa1fe4aaeb1718d Mon Sep 17 00:00:00 2001
From: houxiao <houxiao@454eff88-639b-444f-9e54-f578c98de674>
Date: 星期一, 13 二月 2017 16:27:41 +0800
Subject: [PATCH] replace log to support android

---
 RtspFace/PL_SensetimeFaceTrack.cpp                  |   14 
 RtspFace/main.cpp                                   |   22 
 RtspFace/PipeLinePool.cpp                           |    4 
 RtspFace/PL_RTSPServer.cpp                          |   12 
 RtspFace/ev_server.cpp                              |   34 +-
 RtspFace/PL_H264Decoder.cpp                         |   10 
 RtspFace/PL_H264Encoder.cpp                         |   14 
 RtspFace/logger.h                                   |   58 ---
 RtspFace/live555/testProgs/testRTSPClient.hpp       |   62 ++--
 RtspFace/Logger/src/Makefile                        |   24 +
 RtspFace/main_dump_st_face.cpp                      |   14 
 RtspFace/Logger/src/test.cpp                        |   42 +++
 RtspFace/PL_AVFrameBGRA.cpp                         |    4 
 RtspFace/Logger/link.URL                            |    4 
 RtspFace/PL_AVFrameYUV420.cpp                       |    4 
 RtspFace/PL_Scale.cpp                               |   16 
 RtspFace/main_face_daemon.cpp                       |   22 
 RtspFace/live555/config.android                     |    1 
 RtspFace/Logger/src/logger.hpp                      |   83 ++++++
 RtspFace/PL_Payer.cpp                               |    2 
 RtspFace/PL_RTSPClient.cpp                          |    4 
 RtspFace/Logger/README.md                           |   46 +++
 RtspFace/PL_SensetimeFaceDetect.cpp                 |   10 
 RtspFace/PipeLine.cpp                               |    6 
 RtspFace/make.sh                                    |   14 
 RtspFace/PL_DlibFaceTrack.cpp                       |   14 
 RtspFace/PL_Fork.cpp                                |    6 
 RtspFace/SensetimeFaceAPIWrapper/src/FaceDBPool.cpp |    4 
 RtspFace/Logger/src/logger.cc                       |  133 ++++++++++
 RtspFace/Logger/LICENSE                             |   38 ++
 RtspFace/PL_Gainer.cpp                              |    4 
 31 files changed, 529 insertions(+), 196 deletions(-)

diff --git a/RtspFace/Logger/LICENSE b/RtspFace/Logger/LICENSE
new file mode 100644
index 0000000..10f6572
--- /dev/null
+++ b/RtspFace/Logger/LICENSE
@@ -0,0 +1,38 @@
+Copyright (C) 2013-2017  Bryant Moscon - bmoscon@gmail.com
+ 
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to 
+ deal in the Software without restriction, including without limitation the 
+ rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ sell copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ 1. Redistributions of source code must retain the above copyright notice, 
+    this list of conditions, and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice, 
+    this list of conditions and the following disclaimer in the documentation 
+    and/or other materials provided with the distribution, and in the same 
+    place and form as other copyright, license and disclaimer information.
+
+ 3. The end-user documentation included with the redistribution, if any, must 
+    include the following acknowledgment: "This product includes software 
+    developed by Bryant Moscon (http://www.bryantmoscon.com/)", in the same 
+    place and form as other third-party acknowledgments. Alternately, this 
+    acknowledgment may appear in the software itself, in the same form and 
+    location as other such third-party acknowledgments.
+
+ 4. Except as contained in this notice, the name of the author, Bryant Moscon,
+    shall not be used in advertising or otherwise to promote the sale, use or 
+    other dealings in this Software without prior written authorization from 
+    the author.
+
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
+ THE SOFTWARE.
+
diff --git a/RtspFace/Logger/README.md b/RtspFace/Logger/README.md
new file mode 100644
index 0000000..9d75004
--- /dev/null
+++ b/RtspFace/Logger/README.md
@@ -0,0 +1,46 @@
+##Simple, Lightweight Logging
+
+[![License](https://img.shields.io/badge/license-XFree86-blue.svg)](LICENSE)
+
+Usage:
+
+
+Specify a filename when constructing:
+
+```c++
+Logger example("FILENAME");
+```
+
+Log lines will be written to this file. Use the << operator to 
+direct messages to the log stream and indicate the log level. 
+If the log level is omitted, it defaults to verbose:
+
+```c++
+example << ERROR << "Out of Memory!" << std::endl;
+```
+
+
+This line will look like this in the log file:
+
+```
+Sat Mar 15 08:06:58 2014 -- [ERROR] -- Out of Memory!
+```
+
+If you dont care for the formatting, change the code :)
+
+
+You must end the line with an ```endl```. This tells the logger 
+to write the line and prepend the timestamp to the line 
+as well. 
+
+
+You can change the logging level like so:
+
+```c++
+example.set_level(VERBOSE);
+```
+
+The level defaults to ```VERBOSE``` is one is never set, and this can be changed via ```set_default_line_level```
+
+
+Note: This library requires C++11 compiler support
diff --git a/RtspFace/Logger/link.URL b/RtspFace/Logger/link.URL
new file mode 100644
index 0000000..43085e9
--- /dev/null
+++ b/RtspFace/Logger/link.URL
@@ -0,0 +1,4 @@
+[InternetShortcut]
+URL=https://github.com/bmoscon/Logger
+IDList=
+HotKey=0
diff --git a/RtspFace/Logger/src/Makefile b/RtspFace/Logger/src/Makefile
new file mode 100644
index 0000000..1b5baa2
--- /dev/null
+++ b/RtspFace/Logger/src/Makefile
@@ -0,0 +1,24 @@
+CC = g++
+CCFLAGS = -Wall -Werror -std=c++14 -ggdb3 -fPIC
+AR = ar
+
+HEADERS = $(wildcard *.hpp)
+SRC     = $(wildcard *.cc)
+OBJ     = $(subst .cc,.o,$(SRC))
+NAME    = liblogger
+SO      = $(NAME).so
+A       = $(NAME).a
+
+all: liblogger
+
+clean:
+	rm -f $(OBJ) $(SO) $(A)
+
+liblogger: $(OBJ)
+	$(CC) -shared -o $(SO) -Wl,-soname,$(SO) $(OBJ)
+	$(AR) -cvq $(A) $(OBJ)
+
+%.o: %.cc $(HEADERS) Makefile
+	$(CC) $(CCFLAGS) -c $< -o $@
+
+
diff --git a/RtspFace/Logger/src/logger.cc b/RtspFace/Logger/src/logger.cc
new file mode 100644
index 0000000..06748f2
--- /dev/null
+++ b/RtspFace/Logger/src/logger.cc
@@ -0,0 +1,133 @@
+/*
+ * logger.cc
+ *
+ *
+ * Logger Library
+ *
+ *
+ * Copyright (C) 2013-2017  Bryant Moscon - bmoscon@gmail.com
+ * 
+ * Please see the LICENSE file for the terms and conditions 
+ * associated with this software.
+ *
+ */
+
+#include "logger.hpp"
+
+Logger::Logger(std::ostream& s) : _file(), 
+				_log(s),
+				_level(INFO),
+				_line_level(VERBOSE),
+				_default_line_level(VERBOSE)
+{
+}
+
+
+Logger::Logger(const char *f) : _file(f, std::ios::out | std::ios::app), 
+				_log(_file),
+				_level(INFO),
+				_line_level(VERBOSE),
+				_default_line_level(VERBOSE)
+{
+    assert(_file.is_open());
+}
+
+
+Logger::Logger(const std::string& f) : _file(f.c_str(), std::ios::out | std::ios::app), 
+				       _log(_file),
+				       _level(INFO),
+				       _line_level(VERBOSE),
+				       _default_line_level(VERBOSE)
+{
+    assert(_file.is_open());
+}
+
+
+Logger::~Logger()
+{
+    if (_file.is_open()) {
+	_log.flush();
+	_file.close();
+    }
+	else {
+		_log.flush();
+	}
+}
+
+
+void Logger::set_level(const logger_level& level)
+{
+    _level = level;
+}  
+
+
+void Logger::set_default_line_level(const logger_level& level)
+{
+    _default_line_level = level;
+}
+
+
+void Logger::flush()
+{
+    if (_line_level >= _level) {
+		_log << get_time() << " -- [" << level_str(_line_level) << "] -- " << str();
+		if (_file.is_open())
+			_log.flush();
+    }
+    
+    str("");
+    _line_level = _default_line_level;
+}
+
+
+Logger& Logger::operator<<(const logger_level& level)
+{
+    _line_level = level;
+    return (*this);
+}
+
+
+Logger& Logger::operator<<(LoggerManip m)
+{ 
+    return m(*this);
+}
+
+
+std::string Logger::get_time() const
+{
+    struct tm *timeinfo;
+    time_t rawtime;
+    char *time_buf;
+    
+    time(&rawtime);
+    timeinfo = localtime(&rawtime);
+    time_buf = asctime(timeinfo);
+    
+    std::string ret(time_buf);
+    if (!ret.empty() && ret[ret.length() - 1] == '\n') {
+	ret.erase(ret.length()-1);
+    }
+    
+    return (ret);
+}
+
+
+inline const char* Logger::level_str(const logger_level& level)
+{
+    switch (level) {
+    case VERBOSE:
+	return ("VRB");
+    case DEBUG:
+	return ("DBG");
+    case INFO:
+	return ("INF");
+    case WARNING:
+	return ("WRN");
+    case ERROR:
+	return ("ERR");
+    case CRITICAL:
+	return ("CRT");
+    default:
+	assert(false);
+    }
+}
diff --git a/RtspFace/Logger/src/logger.hpp b/RtspFace/Logger/src/logger.hpp
new file mode 100644
index 0000000..a39cea1
--- /dev/null
+++ b/RtspFace/Logger/src/logger.hpp
@@ -0,0 +1,83 @@
+/*
+ * logger.hpp
+ *
+ *
+ * Logger Library Header
+ *
+ *
+ * Copyright (C) 2013-2017  Bryant Moscon - bmoscon@gmail.com
+ *
+ * Please see the LICENSE file for the terms and conditions 
+ * associated with this software.
+ *
+ */
+
+#ifndef __LOGGER__
+#define __LOGGER__
+
+
+#include <fstream>
+#include <cassert>
+#include <ctime>
+#include <sstream>
+
+
+// Log levels
+typedef enum {
+  VERBOSE = 0,
+  DEBUG,
+  INFO,
+  WARNING,
+  ERROR,
+  CRITICAL
+} logger_level;
+
+
+
+class Logger : public std::ostringstream {
+public:
+	Logger(std::ostream& s);
+    Logger(const char *f);
+    Logger(const std::string& f);
+    Logger (const Logger &) = delete;
+    Logger &operator= (const Logger &) = delete;
+    ~Logger();
+    
+    
+    void set_level(const logger_level& level);
+    void set_default_line_level(const logger_level& level);
+    void flush();
+    template <typename T>
+    Logger& operator<<(const T& t)
+    {
+	*static_cast<std::ostringstream *>(this) << t;
+	return (*this);
+    }
+    
+    Logger& operator<<(const logger_level& level);
+    typedef Logger& (* LoggerManip)(Logger&);
+    Logger& operator<<(LoggerManip m);
+    
+private:
+    std::string get_time() const;
+    inline const char* level_str(const logger_level& level);
+    
+    std::ofstream  _file;
+    std::ostream&  _log; 
+    logger_level   _level;
+    logger_level   _line_level;
+    logger_level   _default_line_level;
+};
+
+
+namespace std { 
+    inline Logger& endl(Logger& out) 
+    { 
+	out.put('\n'); 
+	out.flush(); 
+	return (out); 
+    } 
+}
+
+
+#endif
diff --git a/RtspFace/Logger/src/test.cpp b/RtspFace/Logger/src/test.cpp
new file mode 100644
index 0000000..324657a
--- /dev/null
+++ b/RtspFace/Logger/src/test.cpp
@@ -0,0 +1,42 @@
+#include "Logger/src/logger.hpp"
+#include <string.h>
+#include <iostream>
+#include <unistd.h>
+
+#ifndef LOG_TAG
+#define LOG_TAG "logger"
+#endif
+
+Logger g_logger(std::cout);
+
+#define LOG(__level)  g_logger << __level << __FILE__ << ":" << __LINE__ << "\t" 
+#define LOGP(__level, __format, arg...)  { char msg[1024]; sprintf(msg, "%s:%d\t" __format, __FILE__, __LINE__, ##arg); g_logger << __level << msg << std::endl; }
+
+#define LOG_DEBUG    LOG(DEBUG) // Debug message do not care in any production environment
+#define LOG_INFO     LOG(INFO) // Not significant event but useful for deal with online problem
+#define LOG_NOTICE   LOG(NOTICE) // Important event
+#define LOG_WARN     LOG(WARN) // Important event or input which will lead to errors
+#define LOG_ERROR    LOG(ERROR) // Error message means program running in an abnormal (not expected) way
+
+
+int main()
+{
+	//Logger example(std::cout);
+	//example.set_level(VERBOSE);
+	//example << ERROR << "Out of Memory!" << std::endl;
+
+	//std::stringstream ss;
+	//Logger ex2(ss);
+	//ex2.set_level(VERBOSE);
+	//ex2 << ERROR << "aaaaaaaaa"<<std::endl;
+	//ex2 << ERROR << "bbbbbbb"<<std::endl;
+	//std::cout << ss.str().c_str();
+
+	//g_logger.set_level(VERBOSE);
+	//LOG_DEBUG << "aaaaa" << std::endl;
+	//LOG_DEBUG << "bbb" << std::endl;
+	//
+	//LOGP(INFO, "%d %d", 123, 456);
+
+	return 0;
+}
diff --git a/RtspFace/PL_AVFrameBGRA.cpp b/RtspFace/PL_AVFrameBGRA.cpp
index 0826c5b..816a3db 100644
--- a/RtspFace/PL_AVFrameBGRA.cpp
+++ b/RtspFace/PL_AVFrameBGRA.cpp
@@ -77,7 +77,7 @@
 	
 	if (pm.type != PipeMaterial::PMT_FRAME)
 	{
-		LOG_ERROR << "Only support PMT_FRAME";
+		LOG_ERROR << "Only support PMT_FRAME" << std::endl;
 		return false;
 	}
 	
@@ -87,7 +87,7 @@
 	MB_Frame* frame = (MB_Frame*)pm.buffer;
 	if (frame->type != MB_Frame::MBFT_PTR_AVFRAME)
 	{
-		LOG_ERROR << "Only support MBFT_PTR_AVFRAME";
+		LOG_ERROR << "Only support MBFT_PTR_AVFRAME" << std::endl;
 		return false;
 	}
 
diff --git a/RtspFace/PL_AVFrameYUV420.cpp b/RtspFace/PL_AVFrameYUV420.cpp
index 98bf843..3c61b7c 100644
--- a/RtspFace/PL_AVFrameYUV420.cpp
+++ b/RtspFace/PL_AVFrameYUV420.cpp
@@ -69,7 +69,7 @@
 	
 	if (pm.type != PipeMaterial::PMT_FRAME)
 	{
-		LOG_ERROR << "Only support PMT_FRAME";
+		LOG_ERROR << "Only support PMT_FRAME" << std::endl;
 		return false;
 	}
 	
@@ -79,7 +79,7 @@
 	MB_Frame* frame = (MB_Frame*)pm.buffer;
 	if (frame->type != MB_Frame::MBFT_PTR_AVFRAME)
 	{
-		LOG_ERROR << "Only support MBFT_PTR_AVFRAME";
+		LOG_ERROR << "Only support MBFT_PTR_AVFRAME" << std::endl;
 		return false;
 	}
 
diff --git a/RtspFace/PL_DlibFaceTrack.cpp b/RtspFace/PL_DlibFaceTrack.cpp
index 0f88a75..96964ab 100644
--- a/RtspFace/PL_DlibFaceTrack.cpp
+++ b/RtspFace/PL_DlibFaceTrack.cpp
@@ -75,18 +75,18 @@
 		in->config = *config;
 	
 #ifdef __AVX__
-	LOG_DEBUG << "AVX on";
+	LOG_DEBUG << "AVX on" << std::endl;
 	#ifdef DLIB_HAVE_SSE2
-		LOG_DEBUG << "DLIB_HAVE_SSE2 on";
+		LOG_DEBUG << "DLIB_HAVE_SSE2 on" << std::endl;
 	#endif
 	#ifdef DLIB_HAVE_SSE3
-		LOG_DEBUG << "DLIB_HAVE_SSE3 on";
+		LOG_DEBUG << "DLIB_HAVE_SSE3 on" << std::endl;
 	#endif
 	#ifdef DLIB_HAVE_SSE41
-		LOG_DEBUG << "DLIB_HAVE_SSE41 on";
+		LOG_DEBUG << "DLIB_HAVE_SSE41 on" << std::endl;
 	#endif
 	#ifdef DLIB_HAVE_AVX
-		LOG_DEBUG << "DLIB_HAVE_AVX on";
+		LOG_DEBUG << "DLIB_HAVE_AVX on" << std::endl;
 	#endif
 #endif
 	
@@ -256,7 +256,7 @@
 
 	if (pm.type != PipeMaterial::PMT_FRAME)
 	{
-		LOG_ERROR << "Only support PMT_FRAME";
+		LOG_ERROR << "Only support PMT_FRAME" << std::endl;
 		return false;
 	}
 	
@@ -266,7 +266,7 @@
 	MB_Frame* frame = (MB_Frame*)pm.buffer;
 	if (frame->type != MB_Frame::MBFT_YUV420)
 	{
-		LOG_ERROR << "Only support MBFT_YUV420";
+		LOG_ERROR << "Only support MBFT_YUV420" << std::endl;
 		return false;
 	}
 
diff --git a/RtspFace/PL_Fork.cpp b/RtspFace/PL_Fork.cpp
index 627a857..91af5a9 100644
--- a/RtspFace/PL_Fork.cpp
+++ b/RtspFace/PL_Fork.cpp
@@ -64,7 +64,7 @@
 
 	if (args == nullptr)
 	{
-		LOG_ERROR << "Config should give";
+		LOG_ERROR << "Config should give" << std::endl;
 		return false;
 	}
 
@@ -103,13 +103,13 @@
 	
 	if (this->pl != nullptr)
 	{
-		LOG_ERROR << "Has areadly attached pipe line";
+		LOG_ERROR << "Has areadly attached pipe line" << std::endl;
 		return;
 	}
 	
 	if (pl == nullptr)
 	{
-		LOG_NOTICE << "Detach pipe line";
+		LOG_NOTICE << "Detach pipe line" << std::endl;
 		this->pl->remove_elem(this);
 		this->pl = nullptr;
 		return;
diff --git a/RtspFace/PL_Gainer.cpp b/RtspFace/PL_Gainer.cpp
index 5e423dd..8e35880 100644
--- a/RtspFace/PL_Gainer.cpp
+++ b/RtspFace/PL_Gainer.cpp
@@ -88,7 +88,7 @@
 		break;
 		default:
 			//#todo support list or pm::copier operator
-			LOG_ERROR << "Only support PMT_BYTES / PMT_FRAME";
+			LOG_ERROR << "Only support PMT_BYTES / PMT_FRAME" << std::endl;
 			return;
 		}
 	}
@@ -130,7 +130,7 @@
 		break;
 		default:
 			//#todo support list or pm::copier operator
-			LOG_ERROR << "Only support PMT_BYTES / PMT_FRAME";
+			LOG_ERROR << "Only support PMT_BYTES / PMT_FRAME" << std::endl;
 			return false;
 		}
 		
diff --git a/RtspFace/PL_H264Decoder.cpp b/RtspFace/PL_H264Decoder.cpp
index 7426bac..0391e6a 100644
--- a/RtspFace/PL_H264Decoder.cpp
+++ b/RtspFace/PL_H264Decoder.cpp
@@ -136,7 +136,7 @@
 
 	if (!avCodec)   
 	{  
-		LOG_WARN << "codec not found!";  
+		LOG_WARN << "codec not found!" << std::endl;  
 		return false;  
 	}  
 
@@ -185,7 +185,7 @@
 
 	if (av_packet_from_data(&packet, buffer, buffSize) != 0)
 	{  
-		LOG_WARN << "av_packet_from_data error";
+		LOG_WARN << "av_packet_from_data error" << std::endl;
 		return false;
 	}
 	
@@ -200,7 +200,7 @@
 	}
 	else
 	{
-		LOG_WARN << "incomplete frame";
+		LOG_WARN << "incomplete frame" << std::endl;
 		return false;
 	}
 }
@@ -224,7 +224,7 @@
 		SPropRecord *p_record = parseSPropParameterSets(fmtp.c_str(), numSPropRecords);
 		if (numSPropRecords < 2)
 		{
-			LOG_WARN << "numSPropRecords < 2";
+			LOG_WARN << "numSPropRecords < 2" << std::endl;
 			return false;
 		}
 
@@ -234,7 +234,7 @@
 		bool ret = initH264DecoderEnv(in, sps.sPropBytes, sps.sPropLength, pps.sPropBytes, pps.sPropLength);
 		if (!ret)
 		{
-			LOG_ERROR << "initH264DecoderEnv error";
+			LOG_ERROR << "initH264DecoderEnv error" << std::endl;
 			return false;
 		}
 		else
diff --git a/RtspFace/PL_H264Encoder.cpp b/RtspFace/PL_H264Encoder.cpp
index a4d3089..2af9e3e 100644
--- a/RtspFace/PL_H264Encoder.cpp
+++ b/RtspFace/PL_H264Encoder.cpp
@@ -122,7 +122,7 @@
 
 	if (!avCodec)   
 	{  
-		LOG_ERROR << "codec not found!";  
+		LOG_ERROR << "codec not found!" << std::endl;  
 		return false;  
 	}  
 
@@ -156,13 +156,13 @@
 							in->pAVCodecContext->pix_fmt, 16);  
 		if (ret < 0)
 		{  
-			LOG_ERROR << "av_image_alloc error";
+			LOG_ERROR << "av_image_alloc error" << std::endl;
 			return false;
 		} 
 	}
 	else
 	{
-		LOG_ERROR << "avcodec_open2 error";
+		LOG_ERROR << "avcodec_open2 error" << std::endl;
 		return false;
 	}
 
@@ -233,7 +233,7 @@
 	int ret = avcodec_encode_video2(in->pAVCodecContext, &pAVPacket, in->pAVFrame, &gotPacket);  
 	if (ret < 0)
 	{
-		LOG_WARN << "avcodec_encode_video2 (1) error=" << ret;
+		LOG_WARN << "avcodec_encode_video2 (1) error=" << ret << std::endl;
 		return false;
 	}
 	
@@ -327,7 +327,7 @@
 		bool ret = initH264EncoderEnv(in);
 		if (!ret)
 		{
-			LOG_ERROR << "initH264EncoderEnv error";
+			LOG_ERROR << "initH264EncoderEnv error" << std::endl;
 			return false;
 		}
 		else
@@ -336,7 +336,7 @@
 	
 	if (pm.type != PipeMaterial::PMT_FRAME)
 	{
-		LOG_ERROR << "Only support PMT_FRAME";
+		LOG_ERROR << "Only support PMT_FRAME" << std::endl;
 		return false;
 	}
 	
@@ -353,7 +353,7 @@
 		ret = encodeH264(in, (uint8_t*)(frame->buffer), frame->pts);
 	else
 	{
-		LOG_ERROR << "Only support MBFT_PTR_AVFRAME / MBFT_YUV420";
+		LOG_ERROR << "Only support MBFT_PTR_AVFRAME / MBFT_YUV420" << std::endl;
 		in->payError = true;
 		return false;
 	}
diff --git a/RtspFace/PL_Payer.cpp b/RtspFace/PL_Payer.cpp
index 8ec8239..1022f4d 100644
--- a/RtspFace/PL_Payer.cpp
+++ b/RtspFace/PL_Payer.cpp
@@ -101,7 +101,7 @@
 		break;
 		default:
 			//#todo support list or pm::copier operator
-			LOG_ERROR << "Only support PMT_BYTES / PMT_FRAME";
+			LOG_ERROR << "Only support PMT_BYTES / PMT_FRAME" << std::endl;
 		}
 	}
 
diff --git a/RtspFace/PL_RTSPClient.cpp b/RtspFace/PL_RTSPClient.cpp
index 759fc5d..8290f8a 100644
--- a/RtspFace/PL_RTSPClient.cpp
+++ b/RtspFace/PL_RTSPClient.cpp
@@ -231,7 +231,7 @@
 	int ret = pthread_mutex_unlock(in->frame_mutex);
 	if(ret != 0)
 	{
-		LOG_ERROR << "pthread_mutex_unlock frame_mutex: ", strerror(ret);
+		LOG_ERROR << "pthread_mutex_unlock frame_mutex: " << strerror(ret) << std::endl;
 	}
 }
 
@@ -246,6 +246,6 @@
 	int ret = pthread_mutex_lock(in->continue_mutex);
 	if(ret != 0)
 	{
-		printf("pthread_mutex_unlock continue_mutex: %s/n", strerror(ret));//#todo
+		LOG_ERROR << "pthread_mutex_unlock continue_mutex: " << strerror(ret) << std::endl;
 	}
 }
diff --git a/RtspFace/PL_RTSPServer.cpp b/RtspFace/PL_RTSPServer.cpp
index 6d31f34..6610e04 100644
--- a/RtspFace/PL_RTSPServer.cpp
+++ b/RtspFace/PL_RTSPServer.cpp
@@ -113,7 +113,7 @@
 		*FrameBuffer = pBuffer;
 		*FrameSize = newBufferSize;
 
-		LOG_DEBUG << "send frame size=" << in.buffSize;
+		LOG_DEBUG << "send frame size=" << in.buffSize << std::endl;
 	}
 	
 	virtual char ReleaseFrame()
@@ -125,7 +125,7 @@
 			int ret = pthread_mutex_unlock(in.frame_mutex);
 			if(ret != 0)
 			{
-				LOG_WARN << "pthread_mutex_unlock frame_mutex: " << strerror(ret);
+				LOG_WARN << "pthread_mutex_unlock frame_mutex: " << strerror(ret) << std::endl;
 				return 0;
 			}
 		}
@@ -143,7 +143,7 @@
 			int ret = pthread_mutex_lock(in.frame_mutex);
 			if(ret != 0)
 			{
-				LOG_WARN << "pthread_mutex_lock frame_mutex: " << strerror(ret);
+				LOG_WARN << "pthread_mutex_lock frame_mutex: " << strerror(ret) << std::endl;
 				return;
 			}
 		}
@@ -197,7 +197,7 @@
 	int ret = pthread_create(&(in->live_daemon_thid), NULL, live_daemon_thd, in);
 	if(ret != 0)
 	{
-		LOG_ERROR << "pthread_create: " << strerror(ret);
+		LOG_ERROR << "pthread_create: " << strerror(ret) << std::endl;
 		return false;
 	}
 
@@ -220,12 +220,12 @@
 	
 	if (pm.type != PipeMaterial::PMT_FRAME)
 	{
-		LOG_ERROR << "PL_RTSPServer::pay only support PMT_FRAME";
+		LOG_ERROR << "PL_RTSPServer::pay only support PMT_FRAME" << std::endl;
 		return false;
 	}
 	
 	if (in->buffSize > 0)
-		LOG_WARN << "PL_RTSPServer::pay may lost data size=" << in->buffSize;
+		LOG_WARN << "PL_RTSPServer::pay may lost data size=" << in->buffSize << std::endl;
 	
 	MB_Frame* frame = (MB_Frame*)pm.buffer;
 	if (frame->buffer == nullptr)
diff --git a/RtspFace/PL_Scale.cpp b/RtspFace/PL_Scale.cpp
index bd6c507..c825591 100644
--- a/RtspFace/PL_Scale.cpp
+++ b/RtspFace/PL_Scale.cpp
@@ -77,7 +77,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;
 	}
 	
@@ -105,7 +105,7 @@
 		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;
 	}
 	
@@ -115,7 +115,7 @@
 			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)
@@ -143,7 +143,7 @@
 	else if (srcType == MB_Frame::MBFT_BGRA)
 	{
 		//#todo
-		LOG_ERROR << "srcType only support MBFT_YUV420 and MBFT_BGRA";
+		LOG_ERROR << "srcType only support MBFT_YUV420 and MBFT_BGRA" << std::endl;
 		return false;
 	}
 }
@@ -168,7 +168,7 @@
 		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;
 		}
 		
@@ -188,13 +188,13 @@
 				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;
 	default:
-		LOG_ERROR << "Only support PMT_BYTES / PMT_FRAME";
+		LOG_ERROR << "Only support PMT_BYTES / PMT_FRAME" << std::endl;
 		return false;
 	}
 	
@@ -232,7 +232,7 @@
 	}
 	break;
 	default:
-		LOG_ERROR << "Only support PMT_BYTES / PMT_FRAME";
+		LOG_ERROR << "Only support PMT_BYTES / PMT_FRAME" << std::endl;
 	}
 
 	pm = newPm;
diff --git a/RtspFace/PL_SensetimeFaceDetect.cpp b/RtspFace/PL_SensetimeFaceDetect.cpp
index ceae262..db9c257 100644
--- a/RtspFace/PL_SensetimeFaceDetect.cpp
+++ b/RtspFace/PL_SensetimeFaceDetect.cpp
@@ -81,7 +81,7 @@
 
 	if (pm.type != PipeMaterial::PMT_FRAME || !(in->config.payWithDbFrame))
 	{
-		LOG_ERROR << "Only support PMT_FRAME (SensetimeFaceDetectDbFrame)";
+		LOG_ERROR << "Only support PMT_FRAME (SensetimeFaceDetectDbFrame)" << std::endl;
 		return false;
 	}
 	
@@ -91,21 +91,21 @@
 	SensetimeFaceDetectDbFrame* frame = (SensetimeFaceDetectDbFrame*)pm.buffer;
 	if (frame->type != MB_Frame::MBFT_YUV420)
 	{
-		LOG_ERROR << "Only support MBFT_YUV420";
+		LOG_ERROR << "Only support MBFT_YUV420" << std::endl;
 		return false;
 	}
 
 	FaceDB* _faceDB = (FaceDB*)frame->_faceDB;
 	if (_faceDB == nullptr)
 	{
-		LOG_ERROR << "FaceDB is null";
+		LOG_ERROR << "FaceDB is null" << std::endl;
 		return false;
 	}
 	
 	const size_t expectedYUVSize = frame->width * frame->height * 1.5;
 	if (frame->buffSize < expectedYUVSize)
 	{
-		LOG_WARN << "image size not ok";
+		LOG_WARN << "image size not ok" << std::endl;
 		return false;
 	}
 	
@@ -134,7 +134,7 @@
 	
 	if (! in->config.resultStructOnly)
 	{
-		LOG_ERROR << "Only support resultStructOnly";
+		LOG_ERROR << "Only support resultStructOnly" << std::endl;
 		return false;
 	}
 	
diff --git a/RtspFace/PL_SensetimeFaceTrack.cpp b/RtspFace/PL_SensetimeFaceTrack.cpp
index 7802631..64dfa4f 100644
--- a/RtspFace/PL_SensetimeFaceTrack.cpp
+++ b/RtspFace/PL_SensetimeFaceTrack.cpp
@@ -77,7 +77,7 @@
 		in->config.point_size_config = CV_DETECT_ENABLE_ALIGN_106;
 	else
 	{
-		LOG_ERROR << "alignment point size must be 21 or 106";
+		LOG_ERROR << "alignment point size must be 21 or 106" << std::endl;
 		return false;
 	}
 
@@ -86,7 +86,7 @@
 								in->config.point_size_config | CV_FACE_TRACKING_TWO_THREAD);
 	if (cv_result != CV_OK)
 	{
-		LOG_ERROR << "cv_face_create_tracker failed, error code" << cv_result;
+		LOG_ERROR << "cv_face_create_tracker failed, error code" << cv_result << std::endl;
 		return false;
 	}
 
@@ -94,11 +94,11 @@
 	cv_result = cv_face_track_set_detect_face_cnt_limit(in->handle_track, in->config.detect_face_cnt_limit, &val);
 	if (cv_result != CV_OK)
 	{
-		LOG_ERROR << "cv_face_track_set_detect_face_cnt_limit failed, error : " << cv_result;
+		LOG_ERROR << "cv_face_track_set_detect_face_cnt_limit failed, error : " << cv_result << std::endl;
 		return false;
 	}
 	else
-		LOG_ERROR << "detect face count limit : " << val;
+		LOG_ERROR << "detect face count limit : " << val << std::endl;
 	
 	return true;
 }
@@ -127,7 +127,7 @@
 							CV_FACE_UP, &p_face, &face_count);
 	if (cv_result != CV_OK)
 	{
-		LOG_ERROR << "cv_face_track failed, error : " << cv_result;
+		LOG_ERROR << "cv_face_track failed, error : " << cv_result << std::endl;
 		cv_face_release_tracker_result(p_face, face_count);
 		return -1;
 	}
@@ -213,7 +213,7 @@
 
 	if (pm.type != PipeMaterial::PMT_FRAME)
 	{
-		LOG_ERROR << "Only support PMT_FRAME";
+		LOG_ERROR << "Only support PMT_FRAME" << std::endl;
 		return false;
 	}
 	
@@ -223,7 +223,7 @@
 	MB_Frame* frame = (MB_Frame*)pm.buffer;
 	if (frame->type != MB_Frame::MBFT_YUV420)
 	{
-		LOG_ERROR << "Only support MBFT_YUV420";
+		LOG_ERROR << "Only support MBFT_YUV420" << std::endl;
 		return false;
 	}
 
diff --git a/RtspFace/PipeLine.cpp b/RtspFace/PipeLine.cpp
index d74e148..0a5e73e 100644
--- a/RtspFace/PipeLine.cpp
+++ b/RtspFace/PipeLine.cpp
@@ -142,16 +142,16 @@
 	PipeDebugger(PipeLine* _pipeLine) : 
 		pipeLine(_pipeLine), retElem(nullptr), pm(nullptr)
 	{
-		//LOG_DEBUG << "pipe line begin";
+		//LOG_DEBUG << "pipe line begin" << std::endl;
 	}
 	
 	~PipeDebugger()
 	{
 		//bool retOK = (*(pipeLine->elems).rbegin() == retElem);
 		//if (retOK)
-		//	LOG_DEBUG << "pipe line end, ret OK";
+		//	LOG_DEBUG << "pipe line end, ret OK" << std::endl;
 		//else
-		//	LOG_WARN << "pipe line end, ret ERROR";
+		//	LOG_WARN << "pipe line end, ret ERROR" << std::endl;
 	}
 };
 
diff --git a/RtspFace/PipeLinePool.cpp b/RtspFace/PipeLinePool.cpp
index cba5a1b..d003a48 100644
--- a/RtspFace/PipeLinePool.cpp
+++ b/RtspFace/PipeLinePool.cpp
@@ -6,7 +6,7 @@
 	int ret = pthread_mutex_lock((pthread_mutex_t*)mut); \
 	if(ret != 0) \
 	{ \
-		LOG_ERROR << "pthread_mutex_lock " << #mut <<  ": " << ret; \
+		LOG_ERROR << "pthread_mutex_lock " << #mut <<  ": " << ret << std::endl; \
 		return _ret; \
 	} \
 }
@@ -15,7 +15,7 @@
 	int ret = pthread_mutex_unlock((pthread_mutex_t*)mut); \
 	if(ret != 0) \
 	{ \
-		LOG_ERROR << "pthread_mutex_unlock " << #mut <<  ": " << ret; \
+		LOG_ERROR << "pthread_mutex_unlock " << #mut <<  ": " << ret << std::endl; \
 		return _ret; \
 	} \
 }
diff --git a/RtspFace/SensetimeFaceAPIWrapper/src/FaceDBPool.cpp b/RtspFace/SensetimeFaceAPIWrapper/src/FaceDBPool.cpp
index 1f87a5c..680d1e0 100644
--- a/RtspFace/SensetimeFaceAPIWrapper/src/FaceDBPool.cpp
+++ b/RtspFace/SensetimeFaceAPIWrapper/src/FaceDBPool.cpp
@@ -9,7 +9,7 @@
 	int ret = pthread_mutex_lock((pthread_mutex_t*)mut); \
 	if(ret != 0) \
 	{ \
-		LOG_ERROR << "pthread_mutex_lock " << #mut <<  ": " << ret; \
+		LOG_ERROR << "pthread_mutex_lock " << #mut <<  ": " << ret << std::endl; \
 		return _ret; \
 	} \
 }
@@ -18,7 +18,7 @@
 	int ret = pthread_mutex_unlock((pthread_mutex_t*)mut); \
 	if(ret != 0) \
 	{ \
-		LOG_ERROR << "pthread_mutex_unlock " << #mut <<  ": " << ret; \
+		LOG_ERROR << "pthread_mutex_unlock " << #mut <<  ": " << ret << std::endl; \
 		return _ret; \
 	} \
 }
diff --git a/RtspFace/ev_server.cpp b/RtspFace/ev_server.cpp
index 87f4294..2f423a2 100644
--- a/RtspFace/ev_server.cpp
+++ b/RtspFace/ev_server.cpp
@@ -69,11 +69,11 @@
 	if (what & EVBUFFER_EOF)
 	{
 		//Client disconnected, remove the read event and the free the client structure.
-		LOG_INFO << "Client disconnected.";
+		LOG_INFO << "Client disconnected." << std::endl;
 	}
 	else
 	{
-		LOG_WARN << "Client socket error, disconnecting.";
+		LOG_WARN << "Client socket error, disconnecting." << std::endl;
 	}
 	bufferevent_free(client->buf_ev);
 	close(client->fd);
@@ -89,12 +89,12 @@
 	// Write back the read buffer. It is important to note that
 	// bufferevent_write_buffer will drain the incoming data so it
 	// is effectively gone after we call it.
-	//LOG_DEBUG << (char*)bufev->input;
+	//LOG_DEBUG << (char*)bufev->input << std::endl;
 	//bufferevent_write_buffer(bufev, bufev->input);
 	
 	//char buff[100] = {'\0'};
 	//size_t readSize = bufferevent_read(bufev, buff, sizeof(buff));
-	//LOG_DEBUG << "readSize=" << readSize << "\t" << buff;
+	//LOG_DEBUG << "readSize=" << readSize << "\t" << buff << std::endl;
 
 	EVPHeader* evpHeader = (EVPHeader*)client->recvbuff;
 	
@@ -107,7 +107,7 @@
 			client->read_times = 1;
 			if (readSize != sizeof(headerBuff))
 			{
-				LOG_WARN << "client send incomplete header";
+				LOG_WARN << "client send incomplete header" << std::endl;
 				buffered_on_error(bufev, 0, arg);
 				return;
 			}
@@ -118,7 +118,7 @@
 			if (evpHeader->cmd <= EVPCommand::EVPC__FIRST || evpHeader->cmd >= EVPCommand::EVPC__LAST || 
 				evpHeader->size < sizeof(EVPHeader) || evpHeader->size > CLIENT_BUFFER_MAX)
 			{
-				LOG_WARN << "client send invalid header";
+				LOG_WARN << "client send invalid header" << std::endl;
 				buffered_on_error(bufev, 0, arg);
 				return;
 			}
@@ -169,7 +169,7 @@
 			{
 				size_t writeSize = bufferevent_write(bufev, cs.sendBuff, cs.sendBuffSize);
 				if (writeSize != cs.sendBuffSize)
-					LOG_WARN << "server send truncate " << (cs.sendBuffSize - writeSize) << " bytes";
+					LOG_WARN << "server send truncate " << (cs.sendBuffSize - writeSize) << " bytes" << std::endl;
 				
 				if (cs.deleteSendBuff)
 					delete[] cs.sendBuff;
@@ -178,7 +178,7 @@
 		
 		if (closeClient)
 		{
-			LOG_DEBUG << "server initiative close";
+			LOG_DEBUG << "server initiative close" << std::endl;
 			buffered_on_error(bufev, 0, arg);
 		}
 
@@ -190,7 +190,7 @@
 	// check read times
 	if (client->read_times > CLIENT_READ_TIMES_MAX)
 	{
-		LOG_WARN << "client read times to max";
+		LOG_WARN << "client read times to max" << std::endl;
 		buffered_on_error(bufev, 0, arg);
 	}
 }
@@ -209,19 +209,19 @@
 	int client_fd = accept(fd, (struct sockaddr *)&client_addr, &client_len);
 	if (client_fd < 0)
 	{
-		LOG_WARN << "accept failed";
+		LOG_WARN << "accept failed" << std::endl;
 		return;
 	}
 
 	// Set the client socket to non-blocking mode.
 	if (setnonblock(client_fd) < 0)
-		LOG_WARN << "failed to set client socket non-blocking";
+		LOG_WARN << "failed to set client socket non-blocking" << std::endl;
 
 	// We've accepted a new client, create a client object.
 	struct EVClient* client = new EVClient;
 	if (client == NULL)
 	{
-		LOG_ERROR << "malloc failed";
+		LOG_ERROR << "malloc failed" << std::endl;
 	}
 	client->fd = client_fd;
 	client->proc = evclient_proc;
@@ -232,7 +232,7 @@
 	// We have to enable it before our callbacks will be called.
 	bufferevent_enable(client->buf_ev, EV_READ);
 
-	LOG_INFO << "Accepted connection from " << inet_ntoa(client_addr.sin_addr);
+	LOG_INFO << "Accepted connection from " << inet_ntoa(client_addr.sin_addr) << std::endl;
 }
 
 int server_main(int argc, char **argv)
@@ -246,7 +246,7 @@
 	int listen_fd = socket(AF_INET, SOCK_STREAM, 0);
 	if (listen_fd < 0)
 	{
-		LOG_ERROR << "create socket failed";
+		LOG_ERROR << "create socket failed" << std::endl;
 		return EXIT_FAILURE;
 	}
 	
@@ -257,13 +257,13 @@
 	listen_addr.sin_port = htons(SERVER_PORT);
 	if (bind(listen_fd, (struct sockaddr *)&listen_addr, sizeof(listen_addr)) < 0)
 	{
-		LOG_ERROR << "bind failed";
+		LOG_ERROR << "bind failed" << std::endl;
 		return EXIT_FAILURE;
 	}
 	
 	if (listen(listen_fd, 5) < 0)
 	{
-		LOG_ERROR << "listen failed";
+		LOG_ERROR << "listen failed" << std::endl;
 		return EXIT_FAILURE;
 	}
 	
@@ -272,7 +272,7 @@
 	setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr_on, sizeof(reuseaddr_on));
 	if (setnonblock(listen_fd) < 0)
 	{
-		LOG_ERROR << "failed to set server socket to non-blocking";
+		LOG_ERROR << "failed to set server socket to non-blocking" << std::endl;
 		return EXIT_FAILURE;
 	}
 
diff --git a/RtspFace/live555/config.android b/RtspFace/live555/config.android
index 4c904e7..cca14b6 100644
--- a/RtspFace/live555/config.android
+++ b/RtspFace/live555/config.android
@@ -11,6 +11,7 @@
 # ./genMakefiles android
 # make NDKROOT="/opt/android-ndk-r13b" TOOLCHAINPREFIX="/opt/android-ndk-r13b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-" clean
 # make NDKROOT="/opt/android-ndk-r13b" TOOLCHAINPREFIX="/opt/android-ndk-r13b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-"
+# make NDKROOT="/opt/android-ndk-r13b" TOOLCHAINPREFIX="/opt/android-ndk-r13b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-" PREFIX="/opt/live.android/inst" install
 
 ARCH = arm
 NDKLEVEL = 22
diff --git a/RtspFace/live555/testProgs/testRTSPClient.hpp b/RtspFace/live555/testProgs/testRTSPClient.hpp
index ff4a861..f346165 100644
--- a/RtspFace/live555/testProgs/testRTSPClient.hpp
+++ b/RtspFace/live555/testProgs/testRTSPClient.hpp
@@ -75,8 +75,8 @@
 
 void usage(UsageEnvironment& env, char const* progName)
 {
-	LOG_DEBUG << "Usage: " << progName << " <rtsp-url-1> ... <rtsp-url-N>";
-	LOG_DEBUG << "\t(where each <rtsp-url-i> is a \"rtsp://\" URL)";
+	LOG_DEBUG << "Usage: " << progName << " <rtsp-url-1> ... <rtsp-url-N>" << std::endl;
+	LOG_DEBUG << "\t(where each <rtsp-url-i> is a \"rtsp://\" URL)" << std::endl;
 }
 
 char eventLoopWatchVariable = 0;
@@ -207,7 +207,7 @@
 	RTSPClient* rtspClient = ourRTSPClient::createNew(env, _rtspConfig);
 	if (rtspClient == NULL)
 		{
-			LOG_ERROR << "Failed to create a RTSP client for URL \"" << _rtspConfig.rtspURL.c_str() << "\": " << env.getResultMsg();
+			LOG_ERROR << "Failed to create a RTSP client for URL \"" << _rtspConfig.rtspURL.c_str() << "\": " << env.getResultMsg() << std::endl;
 			return;
 		}
 
@@ -231,25 +231,25 @@
 
 			if (resultCode != 0)
 				{
-					LOG_WARN << *rtspClient << "Failed to get a SDP description: " << resultString;
+					LOG_WARN << *rtspClient << "Failed to get a SDP description: " << resultString << std::endl;
 					delete[] resultString;
 					break;
 				}
 
 			char* const sdpDescription = resultString;
-			LOG_INFO << *rtspClient << "Got a SDP description:\n" << sdpDescription;
+			LOG_INFO << *rtspClient << "Got a SDP description:\n" << sdpDescription << std::endl;
 
 			// Create a media session object from this SDP description:
 			scs.session = MediaSession::createNew(env, sdpDescription);
 			delete[] sdpDescription; // because we don't need it anymore
 			if (scs.session == NULL)
 				{
-					LOG_ERROR << *rtspClient << "Failed to create a MediaSession object from the SDP description: " << env.getResultMsg();
+					LOG_ERROR << *rtspClient << "Failed to create a MediaSession object from the SDP description: " << env.getResultMsg() << std::endl;
 					break;
 				}
 			else if (!scs.session->hasSubsessions())
 				{
-					LOG_WARN << *rtspClient << "This session has no media subsessions (i.e., no \"m=\" lines)";
+					LOG_WARN << *rtspClient << "This session has no media subsessions (i.e., no \"m=\" lines)" << std::endl;
 					break;
 				}
 
@@ -276,17 +276,17 @@
 		{
 			if (!scs.subsession->initiate())
 				{
-					LOG_ERROR << *rtspClient << "Failed to initiate the \"" << *scs.subsession << "\" subsession: " << env.getResultMsg();
+					LOG_ERROR << *rtspClient << "Failed to initiate the \"" << *scs.subsession << "\" subsession: " << env.getResultMsg() << std::endl;
 					setupNextSubsession(rtspClient); // give up on this subsession; go to the next one
 				}
 			else
 				{
-					LOG_INFO <<  *rtspClient << "Initiated the \"" << *scs.subsession << "\" subsession (";
+					LOG_INFO <<  *rtspClient << "Initiated the \"" << *scs.subsession << "\" subsession (" << std::endl;
 					if (scs.subsession->rtcpIsMuxed())
-						LOG_INFO <<  "client port " << scs.subsession->clientPortNum();
+						LOG_INFO <<  "client port " << scs.subsession->clientPortNum() << std::endl;
 					else
-						LOG_INFO <<  "client ports " << scs.subsession->clientPortNum() << "-" << scs.subsession->clientPortNum()+1;
-					LOG_INFO <<  ")";
+						LOG_INFO <<  "client ports " << scs.subsession->clientPortNum() << "-" << scs.subsession->clientPortNum()+1 << std::endl;
+					LOG_INFO <<  ")" << std::endl;
 
 					// Continue setting up this subsession, by sending a RTSP "SETUP" command:
 					rtspClient->sendSetupCommand(*scs.subsession, continueAfterSETUP, False, REQUEST_STREAMING_OVER_TCP);
@@ -316,20 +316,20 @@
 
 			if (resultCode != 0)
 				{
-					LOG_ERROR << *rtspClient << "Failed to set up the \"" << *scs.subsession << "\" subsession: " << resultString;
+					LOG_ERROR << *rtspClient << "Failed to set up the \"" << *scs.subsession << "\" subsession: " << resultString << std::endl;
 					break;
 				}
 
-			LOG_INFO << *rtspClient << "Set up the \"" << *scs.subsession << "\" subsession (";
+			LOG_INFO << *rtspClient << "Set up the \"" << *scs.subsession << "\" subsession (" << std::endl;
 			if (scs.subsession->rtcpIsMuxed())
 				{
-					LOG_INFO << "client port " << scs.subsession->clientPortNum();
+					LOG_INFO << "client port " << scs.subsession->clientPortNum() << std::endl;
 				}
 			else
 				{
-					LOG_INFO << "client ports " << scs.subsession->clientPortNum() << "-" << scs.subsession->clientPortNum()+1;
+					LOG_INFO << "client ports " << scs.subsession->clientPortNum() << "-" << scs.subsession->clientPortNum()+1 << std::endl;
 				}
-			LOG_INFO << ")";
+			LOG_INFO << ")" << std::endl;
 
 			// Having successfully setup the subsession, create a data sink for it, and call "startPlaying()" on it.
 			// (This will prepare the data sink to receive data; the actual flow of data from the client won't start happening until later,
@@ -341,11 +341,11 @@
 			if (scs.subsession->sink == NULL)
 				{
 					LOG_ERROR << *rtspClient << "Failed to create a data sink for the \"" << *scs.subsession
-					    << "\" subsession: " << env.getResultMsg();
+					    << "\" subsession: " << env.getResultMsg() << std::endl;
 					break;
 				}
 
-			LOG_INFO << *rtspClient << "Created a data sink for the \"" << *scs.subsession << "\" subsession";
+			LOG_INFO << *rtspClient << "Created a data sink for the \"" << *scs.subsession << "\" subsession" << std::endl;
 			scs.subsession->miscPtr = rtspClient; // a hack to let subsession handler functions get the "RTSPClient" from the subsession
 			scs.subsession->sink->startPlaying(*(scs.subsession->readSource()),
 			                                   subsessionAfterPlaying, scs.subsession);
@@ -373,7 +373,7 @@
 
 			if (resultCode != 0)
 				{
-					LOG_ERROR << *rtspClient << "Failed to start playing session: " << resultString;
+					LOG_ERROR << *rtspClient << "Failed to start playing session: " << resultString << std::endl;
 					break;
 				}
 
@@ -389,12 +389,12 @@
 					scs.streamTimerTask = env.taskScheduler().scheduleDelayedTask(uSecsToDelay, (TaskFunc*)streamTimerHandler, rtspClient);
 				}
 
-			LOG_INFO << *rtspClient << "Started playing session";
+			LOG_INFO << *rtspClient << "Started playing session" << std::endl;
 			if (scs.duration > 0)
 				{
-					LOG_INFO << " (for up to " << scs.duration << " seconds)";
+					LOG_INFO << " (for up to " << scs.duration << " seconds)" << std::endl;
 				}
-			LOG_INFO << "...";
+			LOG_INFO << "..." << std::endl;
 
 			success = True;
 		}
@@ -438,7 +438,7 @@
 	RTSPClient* rtspClient = (RTSPClient*)subsession->miscPtr;
 	UsageEnvironment& env = rtspClient->envir(); // alias
 
-	LOG_INFO << *rtspClient << "Received RTCP \"BYE\" on \"" << *subsession << "\" subsession";
+	LOG_INFO << *rtspClient << "Received RTCP \"BYE\" on \"" << *subsession << "\" subsession" << std::endl;
 
 	// Now act as if the subsession had closed:
 	subsessionAfterPlaying(subsession);
@@ -491,7 +491,7 @@
 				}
 		}
 
-	LOG_NOTICE << *rtspClient << "Closing the stream.";
+	LOG_NOTICE << *rtspClient << "Closing the stream." << std::endl;
 	Medium::close(rtspClient);
 	// Note that this will also cause this stream's "StreamClientState" structure to get reclaimed.
 
@@ -602,20 +602,20 @@
 	// We've just received a frame of data.  (Optionally) print out information about it:
 #ifdef DEBUG_PRINT_EACH_RECEIVED_FRAME
 	if (fStreamId != NULL)
-		LOG_DEBUG << "Stream \"" << fStreamId << "\"; ";
-	LOG_DEBUG << "\t" << fSubsession.mediumName() << "/" << fSubsession.codecName() << ":\tReceived " << frameSize << " bytes";
+		LOG_DEBUG << "Stream \"" << fStreamId << "\"; " << std::endl;
+	LOG_DEBUG << "\t" << fSubsession.mediumName() << "/" << fSubsession.codecName() << ":\tReceived " << frameSize << " bytes" << std::endl;
 	if (numTruncatedBytes > 0)
-		LOG_DEBUG << " (with " << numTruncatedBytes << " bytes truncated)";
+		LOG_DEBUG << " (with " << numTruncatedBytes << " bytes truncated)" << std::endl;
 	
 	char uSecsStr[6+1]; // used to output the 'microseconds' part of the presentation time
 	sprintf(uSecsStr, "%06u", (unsigned)presentationTime.tv_usec);
-	LOG_DEBUG << "\tPresentation time: " << (int)presentationTime.tv_sec << "." << uSecsStr;
+	LOG_DEBUG << "\tPresentation time: " << (int)presentationTime.tv_sec << "." << uSecsStr << std::endl;
 	if (fSubsession.rtpSource() != NULL && !fSubsession.rtpSource()->hasBeenSynchronizedUsingRTCP())
 		{
-			LOG_DEBUG << "\tPTS not RTCP-synchronized"; // mark the debugging output to indicate that this presentation time is not RTCP-synchronized
+			LOG_DEBUG << "\tPTS not RTCP-synchronized" << std::endl; // mark the debugging output to indicate that this presentation time is not RTCP-synchronized
 		}
 #ifdef DEBUG_PRINT_NPT
-	LOG_DEBUG << "\tNPT: " << fSubsession.getNormalPlayTime(presentationTime);
+	LOG_DEBUG << "\tNPT: " << fSubsession.getNormalPlayTime(presentationTime) << std::endl;
 #endif
 #endif
 
diff --git a/RtspFace/logger.h b/RtspFace/logger.h
index b0b0ffa..d541876 100644
--- a/RtspFace/logger.h
+++ b/RtspFace/logger.h
@@ -1,32 +1,18 @@
-/* ---------------------------------------------------------------------------
-** This software is in the public domain, furnished "as is", without technical
-** support, and with no warranty, express or implied, as to its usefulness for
-** any purpose.
-**
-** logger.h
-** 
-** -------------------------------------------------------------------------*/
-
 #ifndef LOGGER_H
 #define LOGGER_H
 
+#include <Logger/src/logger.hpp>
+#include <string.h>
 #include <unistd.h>
 
-#include "log4cpp/Category.hh"
-#include "log4cpp/FileAppender.hh"
-#include "log4cpp/PatternLayout.hh"
+#ifndef LOG_TAG
+#define LOG_TAG "logger"
+#endif
 
-enum LoggerVerbose
-{
-	LV_ERROR,
-	LV_WARN,
-	LV_NOTICE,
-	LV_INFO,
-	LV_DEBUG
-};
+extern Logger g_logger;
 
-#define LOG(__level)  log4cpp::Category::getRoot() << log4cpp::Priority::__level << __FILE__ << ":" << __LINE__ << "\t" 
-#define LOGP(__level, __format, arg...) log4cpp::Category::getRoot().log(log4cpp::Priority::__level, "%s:%d\t" __format, __FILE__, __LINE__, ##arg);
+#define LOG(__level)  g_logger << __level << __FILE__ << ":" << __LINE__ << "\t" 
+#define LOGP(__level, __format, arg...)  { char msg[1024]; sprintf(msg, "%s:%d\t" __format, __FILE__, __LINE__, ##arg); g_logger << __level << msg << std::endl; }
 
 #define LOG_DEBUG    LOG(DEBUG) // Debug message do not care in any production environment
 #define LOG_INFO     LOG(INFO) // Not significant event but useful for deal with online problem
@@ -34,33 +20,5 @@
 #define LOG_WARN     LOG(WARN) // Important event or input which will lead to errors
 #define LOG_ERROR    LOG(ERROR) // Error message means program running in an abnormal (not expected) way
 
-inline void initLogger(LoggerVerbose verbose)
-{
-	// initialize log4cpp
-	log4cpp::Category &log = log4cpp::Category::getRoot();
-	log4cpp::Appender *app = new log4cpp::FileAppender("root", fileno(stdout));
-	if (app)
-	{
-		log4cpp::PatternLayout *plt = new log4cpp::PatternLayout();
-		if (plt)
-		{
-			plt->setConversionPattern("%d [%-6p] - %m%n");
-			app->setLayout(plt);
-		}
-		log.addAppender(app);
-	}
-	switch (verbose)
-	{
-		case LV_DEBUG: log.setPriority(log4cpp::Priority::DEBUG); break;
-		case LV_INFO: log.setPriority(log4cpp::Priority::INFO); break;
-		case LV_NOTICE: log.setPriority(log4cpp::Priority::NOTICE); break;
-		case LV_WARN: log.setPriority(log4cpp::Priority::WARN); break;
-		case LV_ERROR: log.setPriority(log4cpp::Priority::ERROR); break;
-		default: log.setPriority(log4cpp::Priority::NOTICE); break;
-		
-	}
-	LOG_INFO << "level:" << log4cpp::Priority::getPriorityName(log.getPriority()); 
-}
-	
 #endif
 
diff --git a/RtspFace/main.cpp b/RtspFace/main.cpp
index e1d0cd3..bbedf4d 100644
--- a/RtspFace/main.cpp
+++ b/RtspFace/main.cpp
@@ -15,9 +15,11 @@
 
 #include "logger.h"
 
+Logger g_logger(stdout);
+
 int main(int argc, char** argv)
 {
-	initLogger(LV_DEBUG);
+	g_logger.set_level(VERBOSE);
 
 	PipeLine pipeLine;
 	
@@ -46,7 +48,7 @@
 		bool ret = rtspClient->init(&rtspConfig);
 		if (!ret)
 		{
-			LOG_ERROR << "rtspClient.init error";
+			LOG_ERROR << "rtspClient.init error" << std::endl;
 			exit(EXIT_FAILURE);
 		}
 	}
@@ -56,7 +58,7 @@
 		bool ret = h264Decoder->init(nullptr);
 		if (!ret)
 		{
-			LOG_ERROR << "PL_H264Decoder.init error";
+			LOG_ERROR << "PL_H264Decoder.init error" << std::endl;
 			exit(EXIT_FAILURE);
 		}
 	}
@@ -66,7 +68,7 @@
 		bool ret = avFrameYUV420->init(nullptr);
 		if (!ret)
 		{
-			LOG_ERROR << "PL_AVFrameYUV420.init error";
+			LOG_ERROR << "PL_AVFrameYUV420.init error" << std::endl;
 			exit(EXIT_FAILURE);
 		}
 	}
@@ -79,7 +81,7 @@
 		bool ret = ple->init(&config);
 		if (!ret)
 		{
-			LOG_ERROR << "PL_Scale.init error";
+			LOG_ERROR << "PL_Scale.init error" << std::endl;
 			exit(EXIT_FAILURE);
 		}
 	}
@@ -119,7 +121,7 @@
 	//	bool ret = queue1->init(&config);
 	//	if (!ret)
 	//	{
-	//		LOG_ERROR << "queue1.init error";
+	//		LOG_ERROR << "queue1.init error" << std::endl;
 	//		exit(EXIT_FAILURE);
 	//	}
 	//}
@@ -130,7 +132,7 @@
 		bool ret = h264Encoder->init(&config);
 		if (!ret)
 		{
-			LOG_ERROR << "PL_H264Encoder.init error";
+			LOG_ERROR << "PL_H264Encoder.init error" << std::endl;
 			exit(EXIT_FAILURE);
 		}
 	}
@@ -140,15 +142,15 @@
 		bool ret = rtspServer->init(nullptr);
 		if (!ret)
 		{
-			LOG_ERROR << "rtspServer.init error";
+			LOG_ERROR << "rtspServer.init error" << std::endl;
 			exit(EXIT_FAILURE);
 		}
 	}
 	
 	while(true)
 	{
-		//LOG_ERROR << "begin pipe";
+		//LOG_ERROR << "begin pipe" << std::endl;
 		pipeLine.pipe();
-		//LOG_ERROR << "end pipe";
+		//LOG_ERROR << "end pipe" << std::endl;
 	}
 }
diff --git a/RtspFace/main_dump_st_face.cpp b/RtspFace/main_dump_st_face.cpp
index 1285a81..eee3bf1 100644
--- a/RtspFace/main_dump_st_face.cpp
+++ b/RtspFace/main_dump_st_face.cpp
@@ -44,7 +44,7 @@
 		bool ret = rtspClient->init(&rtspConfig);
 		if (!ret)
 		{
-			LOG_ERROR << "rtspClient.init error";
+			LOG_ERROR << "rtspClient.init error" << std::endl;
 			exit(EXIT_FAILURE);
 		}
 	}
@@ -54,7 +54,7 @@
 		bool ret = h264Decoder->init(nullptr);
 		if (!ret)
 		{
-			LOG_ERROR << "PL_H264Decoder.init error";
+			LOG_ERROR << "PL_H264Decoder.init error" << std::endl;
 			exit(EXIT_FAILURE);
 		}
 	}
@@ -64,7 +64,7 @@
 		bool ret = avFrameYUV420->init(nullptr);
 		if (!ret)
 		{
-			LOG_ERROR << "PL_AVFrameYUV420.init error";
+			LOG_ERROR << "PL_AVFrameYUV420.init error" << std::endl;
 			exit(EXIT_FAILURE);
 		}
 	}
@@ -77,7 +77,7 @@
 		bool ret = ple->init(&config);
 		if (!ret)
 		{
-			LOG_ERROR << "PL_Scale.init error";
+			LOG_ERROR << "PL_Scale.init error" << std::endl;
 			exit(EXIT_FAILURE);
 		}
 	}
@@ -92,7 +92,7 @@
 
 	while(true)
 	{
-		//LOG_ERROR << "begin pipe";
+		//LOG_ERROR << "begin pipe" << std::endl;
 		
 		PipeMaterial pm;
 		if (pipeLine.pipe(&pm) == sensetimeFaceTrack);
@@ -102,9 +102,9 @@
 		{
 			PipeMaterial& facePM = ((PipeMaterial*)(pm.buffer))[1];
 			st_ff_vect_t& faceFeatures = *((st_ff_vect_t*)facePM.buffer);
-			LOG_NOTICE << "faceFeatures " << faceFeatures.size();
+			LOG_NOTICE << "faceFeatures " << faceFeatures.size() << std::endl;
 		}
 		
-		//LOG_ERROR << "end pipe";
+		//LOG_ERROR << "end pipe" << std::endl;
 	}
 }
diff --git a/RtspFace/main_face_daemon.cpp b/RtspFace/main_face_daemon.cpp
index 2867f70..9058ee4 100644
--- a/RtspFace/main_face_daemon.cpp
+++ b/RtspFace/main_face_daemon.cpp
@@ -68,12 +68,12 @@
 
 	//PipeMaterial& facePM = ((PipeMaterial*)(lastPm.buffer))[1];
 	//st_ff_vect_t& faceFeatures = *((st_ff_vect_t*)facePM.buffer);
-	//LOG_NOTICE << "faceFeatures " << faceFeatures.size();
+	//LOG_NOTICE << "faceFeatures " << faceFeatures.size() << std::endl;
 	//#todo send result packet
 
 	if (lastPm.buffer == nullptr || lastPm.type != PipeMaterial::PMT_BYTES || lastPm.buffSize != sizeof(SensetimeFaceDetectResult))
 	{
-		LOG_WARN << "pm not available";
+		LOG_WARN << "pm not available" << std::endl;
 		ev_send_status_packet(client, EVPStatus::EVPS_INTERNAL_ERROR);
 		return false;
 	}
@@ -98,7 +98,7 @@
 bool ev_proc_SensetimeFaceDetect(EVClientStub& client)
 {
 	//#test send 01000B0000004142434445
-	//LOG_DEBUG << "cmd=" << evpHeader->cmd << ", size=" << evpHeader->size << ", \t" << (char*)(evpHeader + sizeof(EVPHeader));
+	//LOG_DEBUG << "cmd=" << evpHeader->cmd << ", size=" << evpHeader->size << ", \t" << (char*)(evpHeader + sizeof(EVPHeader)) << std::endl;
 	//return true;
 	
 	FDP_Image* fdpImage = (FDP_Image*)(client.recvBuff + sizeof(EVPHeader));
@@ -106,7 +106,7 @@
 	FaceDB* _faceDB = g_faceAPIPool.get_free(fdpImage->school_id);
 	if (_faceDB == nullptr)
 	{
-		LOG_WARN << "can't get face db";
+		LOG_WARN << "can't get face db" << std::endl;
 		ev_send_status_packet(client, EVPStatus::EVPS_PARAMETER_ERROR);
 		return false;
 	}
@@ -116,7 +116,7 @@
 	PipeLine* pipeLine = g_PipeLinePool.get_free();
 	if (pipeLine == nullptr)
 	{
-		LOG_WARN << "can't get free pipeline";
+		LOG_WARN << "can't get free pipeline" << std::endl;
 		ev_send_status_packet(client, EVPStatus::EVPS_INTERNAL_ERROR);
 		return false;
 	}
@@ -143,14 +143,14 @@
 	PipeLineElem* plElem = pipeLine->pipe(&pm);
 	if (! pipeLine->check_pipe_complete(plElem))
 	{
-		LOG_WARN << "pipeline not complete";
+		LOG_WARN << "pipeline not complete" << std::endl;
 		ev_send_status_packet(client, EVPStatus::EVPS_INTERNAL_ERROR);
 		return false;
 	}
 	
 	if (!plElem->gain(pm))
 	{
-		LOG_WARN << "pipeline gain error";
+		LOG_WARN << "pipeline gain error" << std::endl;
 		ev_send_status_packet(client, EVPStatus::EVPS_INTERNAL_ERROR);
 		return false;
 	}
@@ -166,7 +166,7 @@
 	EVPHeader* evpHeader = (EVPHeader*)client.recvBuff;
 	if (evpHeader->size != client.recvBuffSize)
 	{
-		LOG_WARN << "Truncated buffer " << (evpHeader->size - client.recvBuffSize) << " bytes";
+		LOG_WARN << "Truncated buffer " << (evpHeader->size - client.recvBuffSize) << " bytes" << std::endl;
 		return false;
 	}
 
@@ -176,7 +176,7 @@
 		return ev_proc_SensetimeFaceDetect(client);
 	break;
 	default:
-		LOG_WARN << "Unknown command";
+		LOG_WARN << "Unknown command" << std::endl;
 		ev_send_status_packet(client, EVPStatus::EVPS_PARAMETER_ERROR);
 		return false;
 	break;
@@ -206,7 +206,7 @@
 			bool ret = ple->init(&config);
 			if (!ret)
 			{
-				LOG_ERROR << "ple init error";
+				LOG_ERROR << "ple init error" << std::endl;
 				exit(EXIT_FAILURE);
 			}
 		}
@@ -220,7 +220,7 @@
 			bool ret = ple->init(&config);
 			if (!ret)
 			{
-				LOG_ERROR << "ple init error";
+				LOG_ERROR << "ple init error" << std::endl;
 				exit(EXIT_FAILURE);
 			}
 		}
diff --git a/RtspFace/make.sh b/RtspFace/make.sh
index f534195..1fa56b8 100644
--- a/RtspFace/make.sh
+++ b/RtspFace/make.sh
@@ -33,13 +33,12 @@
 DLIB_INC="-I$DLIB_BASE"
 DLIB_LIB="-L$DLIB_BASE/build/dlib -ldlib"
 
-LIBLOG4CPP_BASE=/opt/log4cpp/inst
-LIBLOG4CPP_INC="-I$LIBLOG4CPP_BASE/include"
-LIBLOG4CPP_LIB="-L$LIBLOG4CPP_BASE/lib -llog4cpp"
+LOGGER_BASE=./Logger/src
+LOGGER_OBJ="logger.o"
 
 # -O3
-CPPFLAGS+="-g -mavx -c -std=c++11 -pthread $LIVEMEDIA_INC $FFMPEG_INC $LIBBASE64_INC $LIBYUV_INC $SENSETIMEFACESDK_INC $LIBLOG4CPP_INC $DLIB_INC "
-LDFLAGS+="-pthread -levent $LIVEMEDIA_LIB $FFMPEG_LIB $LIBBASE64_LIB $LIBYUV_LIB $LIBX264_LIB $SENSETIMEFACESDK_LIB $OPENCV_LIB $LIBLOG4CPP_LIB $DLIB_LIB "
+CPPFLAGS+="-g -mavx -c -std=c++11 -pthread $LIVEMEDIA_INC $FFMPEG_INC $LIBBASE64_INC $LIBYUV_INC $SENSETIMEFACESDK_INC $LIBLOG4CPLUS_INC $DLIB_INC "
+LDFLAGS+="-pthread -levent $LIVEMEDIA_LIB $FFMPEG_LIB $LIBBASE64_LIB $LIBYUV_LIB $LIBX264_LIB $SENSETIMEFACESDK_LIB $OPENCV_LIB $LIBLOG4CPLUS_LIB $DLIB_LIB "
 
 CFLAGS+="-D__STDC_CONSTANT_MACROS"
 
@@ -56,6 +55,8 @@
 g++ ev_server.cpp $CFLAGS $CPPFLAGS
 g++ PipeLine.cpp $CFLAGS $CPPFLAGS
 g++ PipeLinePool.cpp $CFLAGS $CPPFLAGS
+
+g++ $LOGGER_BASE/logger.cc $CFLAGS $CPPFLAGS
 
 g++ PL_RTSPClient.cpp $CFLAGS $CPPFLAGS
 g++ PL_RTSPServer.cpp $CFLAGS $CPPFLAGS
@@ -83,6 +84,7 @@
 
 g++ -g -std=c++11 \
   main.o PipeLine.o PipeLinePool.o \
+  $LOGGER_OBJ \
   ev_server.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_Payer.o PL_Gainer.o \
   PL_SensetimeFaceTrack.o PL_SensetimeFaceDetect.o \
@@ -91,6 +93,6 @@
   FaceDBPool.o faceAPI.o \
   $LDFLAGS -o rtsp_face
 
-#export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$LIBX264_BASE/lib:$FFMPEG_BASE/lib:$SENSETIMEFACESDK_BASE/libs/linux-x86_64:$LIBLOG4CPP_BASE/lib:$DLIB_BASE/build/dlib
+#export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$LIBX264_BASE/lib:$FFMPEG_BASE/lib:$SENSETIMEFACESDK_BASE/libs/linux-x86_64:$LOGGER_BASE/lib64:$DLIB_BASE/build/dlib
 #./rtsp_face rtsp://admin:admin12345@192.168.1.70:554/h264/ch1/main/av_stream
 #rtsp://admin:a1234567@192.168.1.68:554/h264/ch1/main/av_stream

--
Gitblit v1.8.0