replace log to support android
git-svn-id: http://192.168.1.226/svn/proxy@107 454eff88-639b-444f-9e54-f578c98de674
New file |
| | |
| | | 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. |
| | | |
New file |
| | |
| | | ##Simple, Lightweight Logging |
| | | |
| | | [](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 |
New file |
| | |
| | | [InternetShortcut]
|
| | | URL=https://github.com/bmoscon/Logger
|
| | | IDList=
|
| | | HotKey=0
|
New file |
| | |
| | | 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 $@ |
| | | |
| | | |
New file |
| | |
| | | /* |
| | | * 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); |
| | | } |
| | | } |
New file |
| | |
| | | /* |
| | | * 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 |
New file |
| | |
| | | #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; |
| | | } |
| | |
| | |
|
| | | if (pm.type != PipeMaterial::PMT_FRAME)
|
| | | {
|
| | | LOG_ERROR << "Only support PMT_FRAME";
|
| | | LOG_ERROR << "Only support PMT_FRAME" << std::endl;
|
| | | return false;
|
| | | }
|
| | |
|
| | |
| | | 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;
|
| | | }
|
| | |
|
| | |
| | |
|
| | | if (pm.type != PipeMaterial::PMT_FRAME)
|
| | | {
|
| | | LOG_ERROR << "Only support PMT_FRAME";
|
| | | LOG_ERROR << "Only support PMT_FRAME" << std::endl;
|
| | | return false;
|
| | | }
|
| | |
|
| | |
| | | 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;
|
| | | }
|
| | |
|
| | |
| | | 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
|
| | |
|
| | |
| | |
|
| | | if (pm.type != PipeMaterial::PMT_FRAME)
|
| | | {
|
| | | LOG_ERROR << "Only support PMT_FRAME";
|
| | | LOG_ERROR << "Only support PMT_FRAME" << std::endl;
|
| | | return false;
|
| | | }
|
| | |
|
| | |
| | | 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;
|
| | | }
|
| | |
|
| | |
| | |
|
| | | if (args == nullptr)
|
| | | {
|
| | | LOG_ERROR << "Config should give";
|
| | | LOG_ERROR << "Config should give" << std::endl;
|
| | | return false;
|
| | | }
|
| | |
|
| | |
| | |
|
| | | 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;
|
| | |
| | | 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;
|
| | | }
|
| | | }
|
| | |
| | | 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;
|
| | | }
|
| | |
|
| | |
| | |
|
| | | if (!avCodec)
|
| | | {
|
| | | LOG_WARN << "codec not found!"; |
| | | LOG_WARN << "codec not found!" << std::endl; |
| | | return false;
|
| | | }
|
| | |
|
| | |
| | |
|
| | | 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;
|
| | | }
|
| | |
|
| | |
| | | }
|
| | | else
|
| | | {
|
| | | LOG_WARN << "incomplete frame";
|
| | | LOG_WARN << "incomplete frame" << std::endl;
|
| | | return false;
|
| | | }
|
| | | }
|
| | |
| | | SPropRecord *p_record = parseSPropParameterSets(fmtp.c_str(), numSPropRecords);
|
| | | if (numSPropRecords < 2)
|
| | | {
|
| | | LOG_WARN << "numSPropRecords < 2";
|
| | | LOG_WARN << "numSPropRecords < 2" << std::endl;
|
| | | return false;
|
| | | }
|
| | |
|
| | |
| | | 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
|
| | |
| | |
|
| | | if (!avCodec)
|
| | | {
|
| | | LOG_ERROR << "codec not found!"; |
| | | LOG_ERROR << "codec not found!" << std::endl; |
| | | return false;
|
| | | }
|
| | |
|
| | |
| | | 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;
|
| | | }
|
| | |
|
| | |
| | | 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;
|
| | | }
|
| | |
|
| | |
| | | bool ret = initH264EncoderEnv(in);
|
| | | if (!ret)
|
| | | {
|
| | | LOG_ERROR << "initH264EncoderEnv error";
|
| | | LOG_ERROR << "initH264EncoderEnv error" << std::endl;
|
| | | return false;
|
| | | }
|
| | | else
|
| | |
| | |
|
| | | if (pm.type != PipeMaterial::PMT_FRAME)
|
| | | {
|
| | | LOG_ERROR << "Only support PMT_FRAME";
|
| | | LOG_ERROR << "Only support PMT_FRAME" << std::endl;
|
| | | return false;
|
| | | }
|
| | |
|
| | |
| | | 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;
|
| | | }
|
| | |
| | | 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;
|
| | | }
|
| | | }
|
| | |
|
| | |
| | | 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;
|
| | | }
|
| | | }
|
| | |
|
| | |
| | | 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;
|
| | | }
|
| | | }
|
| | |
| | | *FrameBuffer = pBuffer;
|
| | | *FrameSize = newBufferSize;
|
| | |
|
| | | LOG_DEBUG << "send frame size=" << in.buffSize;
|
| | | LOG_DEBUG << "send frame size=" << in.buffSize << std::endl;
|
| | | }
|
| | |
|
| | | virtual char ReleaseFrame()
|
| | |
| | | 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;
|
| | | }
|
| | | }
|
| | |
| | | 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;
|
| | | }
|
| | | }
|
| | |
| | | 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;
|
| | | }
|
| | |
|
| | |
| | |
|
| | | 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)
|
| | |
| | |
|
| | | 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;
|
| | | }
|
| | |
|
| | |
| | | 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;
|
| | | }
|
| | |
|
| | |
| | | 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)
|
| | |
| | | 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;
|
| | | }
|
| | | }
|
| | |
| | | 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;
|
| | | }
|
| | |
|
| | |
| | | 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;
|
| | | }
|
| | |
|
| | |
| | | }
|
| | | break;
|
| | | default:
|
| | | LOG_ERROR << "Only support PMT_BYTES / PMT_FRAME";
|
| | | LOG_ERROR << "Only support PMT_BYTES / PMT_FRAME" << std::endl;
|
| | | }
|
| | |
|
| | | pm = newPm;
|
| | |
| | |
|
| | | 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;
|
| | | }
|
| | |
|
| | |
| | | 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;
|
| | | }
|
| | |
|
| | |
| | |
|
| | | if (! in->config.resultStructOnly)
|
| | | {
|
| | | LOG_ERROR << "Only support resultStructOnly";
|
| | | LOG_ERROR << "Only support resultStructOnly" << std::endl;
|
| | | return false;
|
| | | }
|
| | |
|
| | |
| | | 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;
|
| | | }
|
| | |
|
| | |
| | | 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;
|
| | | }
|
| | |
|
| | |
| | | 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;
|
| | | }
|
| | |
| | | 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;
|
| | | }
|
| | |
| | |
|
| | | if (pm.type != PipeMaterial::PMT_FRAME)
|
| | | {
|
| | | LOG_ERROR << "Only support PMT_FRAME";
|
| | | LOG_ERROR << "Only support PMT_FRAME" << std::endl;
|
| | | return false;
|
| | | }
|
| | |
|
| | |
| | | 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;
|
| | | }
|
| | |
|
| | |
| | | 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;
|
| | | }
|
| | | };
|
| | |
|
| | |
| | | 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; \
|
| | | } \
|
| | | }
|
| | |
| | | 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; \
|
| | | } \
|
| | | }
|
| | |
| | | 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; \
|
| | | } \
|
| | | }
|
| | |
| | | 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; \
|
| | | } \
|
| | | }
|
| | |
| | | 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);
|
| | |
| | | // 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;
|
| | |
|
| | |
| | | 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;
|
| | | }
|
| | |
| | | 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;
|
| | | }
|
| | |
| | | {
|
| | | 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;
|
| | |
| | |
|
| | | if (closeClient)
|
| | | {
|
| | | LOG_DEBUG << "server initiative close";
|
| | | LOG_DEBUG << "server initiative close" << std::endl;
|
| | | buffered_on_error(bufev, 0, arg);
|
| | | }
|
| | |
|
| | |
| | | // 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);
|
| | | }
|
| | | }
|
| | |
| | | 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;
|
| | |
| | | // 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)
|
| | |
| | | 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;
|
| | | }
|
| | |
|
| | |
| | | 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;
|
| | | }
|
| | |
|
| | |
| | | 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;
|
| | | }
|
| | |
|
| | |
| | | # ./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 |
| | |
| | | |
| | | 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; |
| | |
| | | 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; |
| | | } |
| | | |
| | |
| | | |
| | | 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; |
| | | } |
| | | |
| | |
| | | { |
| | | 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); |
| | |
| | | |
| | | 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, |
| | |
| | | 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); |
| | |
| | | |
| | | if (resultCode != 0) |
| | | { |
| | | LOG_ERROR << *rtspClient << "Failed to start playing session: " << resultString; |
| | | LOG_ERROR << *rtspClient << "Failed to start playing session: " << resultString << std::endl; |
| | | break; |
| | | } |
| | | |
| | |
| | | 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; |
| | | } |
| | |
| | | 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); |
| | |
| | | } |
| | | } |
| | | |
| | | 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. |
| | | |
| | |
| | | // 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 |
| | | |
| | |
| | | /* --------------------------------------------------------------------------- |
| | | ** 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 |
| | |
| | | #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 |
| | | |
| | |
| | |
|
| | | #include "logger.h"
|
| | |
|
| | | Logger g_logger(stdout);
|
| | |
|
| | | int main(int argc, char** argv)
|
| | | {
|
| | | initLogger(LV_DEBUG);
|
| | | g_logger.set_level(VERBOSE);
|
| | |
|
| | | PipeLine pipeLine;
|
| | |
|
| | |
| | | bool ret = rtspClient->init(&rtspConfig);
|
| | | if (!ret)
|
| | | {
|
| | | LOG_ERROR << "rtspClient.init error";
|
| | | LOG_ERROR << "rtspClient.init error" << std::endl;
|
| | | exit(EXIT_FAILURE);
|
| | | }
|
| | | }
|
| | |
| | | bool ret = h264Decoder->init(nullptr);
|
| | | if (!ret)
|
| | | {
|
| | | LOG_ERROR << "PL_H264Decoder.init error";
|
| | | LOG_ERROR << "PL_H264Decoder.init error" << std::endl;
|
| | | exit(EXIT_FAILURE);
|
| | | }
|
| | | }
|
| | |
| | | bool ret = avFrameYUV420->init(nullptr);
|
| | | if (!ret)
|
| | | {
|
| | | LOG_ERROR << "PL_AVFrameYUV420.init error";
|
| | | LOG_ERROR << "PL_AVFrameYUV420.init error" << std::endl;
|
| | | exit(EXIT_FAILURE);
|
| | | }
|
| | | }
|
| | |
| | | bool ret = ple->init(&config);
|
| | | if (!ret)
|
| | | {
|
| | | LOG_ERROR << "PL_Scale.init error";
|
| | | LOG_ERROR << "PL_Scale.init error" << std::endl;
|
| | | exit(EXIT_FAILURE);
|
| | | }
|
| | | }
|
| | |
| | | // bool ret = queue1->init(&config);
|
| | | // if (!ret)
|
| | | // {
|
| | | // LOG_ERROR << "queue1.init error";
|
| | | // LOG_ERROR << "queue1.init error" << std::endl;
|
| | | // exit(EXIT_FAILURE);
|
| | | // }
|
| | | //}
|
| | |
| | | bool ret = h264Encoder->init(&config);
|
| | | if (!ret)
|
| | | {
|
| | | LOG_ERROR << "PL_H264Encoder.init error";
|
| | | LOG_ERROR << "PL_H264Encoder.init error" << std::endl;
|
| | | exit(EXIT_FAILURE);
|
| | | }
|
| | | }
|
| | |
| | | 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;
|
| | | }
|
| | | }
|
| | |
| | | bool ret = rtspClient->init(&rtspConfig);
|
| | | if (!ret)
|
| | | {
|
| | | LOG_ERROR << "rtspClient.init error";
|
| | | LOG_ERROR << "rtspClient.init error" << std::endl;
|
| | | exit(EXIT_FAILURE);
|
| | | }
|
| | | }
|
| | |
| | | bool ret = h264Decoder->init(nullptr);
|
| | | if (!ret)
|
| | | {
|
| | | LOG_ERROR << "PL_H264Decoder.init error";
|
| | | LOG_ERROR << "PL_H264Decoder.init error" << std::endl;
|
| | | exit(EXIT_FAILURE);
|
| | | }
|
| | | }
|
| | |
| | | bool ret = avFrameYUV420->init(nullptr);
|
| | | if (!ret)
|
| | | {
|
| | | LOG_ERROR << "PL_AVFrameYUV420.init error";
|
| | | LOG_ERROR << "PL_AVFrameYUV420.init error" << std::endl;
|
| | | exit(EXIT_FAILURE);
|
| | | }
|
| | | }
|
| | |
| | | bool ret = ple->init(&config);
|
| | | if (!ret)
|
| | | {
|
| | | LOG_ERROR << "PL_Scale.init error";
|
| | | LOG_ERROR << "PL_Scale.init error" << std::endl;
|
| | | exit(EXIT_FAILURE);
|
| | | }
|
| | | }
|
| | |
| | |
|
| | | while(true)
|
| | | {
|
| | | //LOG_ERROR << "begin pipe";
|
| | | //LOG_ERROR << "begin pipe" << std::endl;
|
| | |
|
| | | PipeMaterial pm;
|
| | | if (pipeLine.pipe(&pm) == sensetimeFaceTrack);
|
| | |
| | | {
|
| | | 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;
|
| | | }
|
| | | }
|
| | |
| | |
|
| | | //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;
|
| | | }
|
| | |
| | | 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));
|
| | |
| | | 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;
|
| | | }
|
| | |
| | | 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;
|
| | | }
|
| | |
| | | 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;
|
| | | }
|
| | |
| | | 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;
|
| | | }
|
| | |
|
| | |
| | | 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;
|
| | |
| | | bool ret = ple->init(&config);
|
| | | if (!ret)
|
| | | {
|
| | | LOG_ERROR << "ple init error";
|
| | | LOG_ERROR << "ple init error" << std::endl;
|
| | | exit(EXIT_FAILURE);
|
| | | }
|
| | | }
|
| | |
| | | bool ret = ple->init(&config);
|
| | | if (!ret)
|
| | | {
|
| | | LOG_ERROR << "ple init error";
|
| | | LOG_ERROR << "ple init error" << std::endl;
|
| | | exit(EXIT_FAILURE);
|
| | | }
|
| | | }
|
| | |
| | | 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" |
| | | |
| | |
| | | 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 |
| | |
| | | |
| | | 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 \ |
| | |
| | | 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 |