From 3a5f09c61a87adb8dba2cc4a5366893886ba1c1d Mon Sep 17 00:00:00 2001 From: dupengyue <dupengyue@454eff88-639b-444f-9e54-f578c98de674> Date: 星期四, 20 七月 2017 17:31:40 +0800 Subject: [PATCH] 接口初步完成 --- RtspFace/PipeLine.cpp | 276 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 258 insertions(+), 18 deletions(-) diff --git a/RtspFace/PipeLine.cpp b/RtspFace/PipeLine.cpp index 6f53b19..aa22039 100644 --- a/RtspFace/PipeLine.cpp +++ b/RtspFace/PipeLine.cpp @@ -1,10 +1,129 @@ #include "PipeLine.h" +#include "MaterialBuffer.h" +#include "logger.h" -PipeMaterial::PipeMaterial() : buffer(nullptr), buffSize(0), former(nullptr) +PipeMaterial::PipeMaterial() : + type(PMT__FIRST), buffer(nullptr), buffSize(0), + former(nullptr), deleter(nullptr), args(nullptr) { } -PipeLine::PipeLine() : global_params_map(), elem_create_func_map(), elems() +void PipeMaterial::exec_deleter(bool lastRet) +{ + if (deleter != nullptr) + { + deleter(this, lastRet); + deleter = nullptr; + } +} + +int PipeMaterial::breake(PipeMaterialBufferType selectPmType, int _selectMbfType, + pm_breaker_func breaker, void* args /*= nullptr*/) const +{ + int called = 0; + const MB_Frame::MBFType selectMbfType = (MB_Frame::MBFType)_selectMbfType; + + switch(type) + { + case PMT_NONE: + if (selectPmType == PMT_NONE) + { + called++; + breaker(this, args); + } + break; + case PMT_BYTES: + if (selectPmType == PMT_BYTES) + { + called++; + breaker(this, args); + } + break; + case PMT_PTR: + if (selectPmType == PMT_PTR) + { + called++; + breaker(this, args); + } + break; + case PMT_FRAME: + if (selectPmType == PMT_FRAME || selectPmType == PipeMaterial::PMT__FIRST || selectPmType == PipeMaterial::PMT__LAST) + { + MB_Frame* mbf = (MB_Frame*)buffer; + if (selectMbfType == mbf->type || selectMbfType == MB_Frame::MBFT__FIRST || selectMbfType == MB_Frame::MBFT__LAST) + { + called++; + breaker(this, args); + } + } + break; + case PMT_PM_LIST: + { + // break pm list into single pm(s) + + PipeMaterial* pm = (PipeMaterial*)buffer; + for (size_t i = 0; i < buffSize; i++, pm++) + { + if (selectPmType == pm->type || selectPmType == PipeMaterial::PMT__FIRST || selectPmType == PipeMaterial::PMT__LAST) + { + if (pm->type == PipeMaterial::PMT_FRAME) + { + MB_Frame *mbf = (MB_Frame *) pm->buffer; + if (selectMbfType == mbf->type || selectMbfType == MB_Frame::MBFT__FIRST || selectMbfType == MB_Frame::MBFT__LAST) + { + called++; + if (!breaker(pm, args)) + break; + } + } + else + { + called++; + if (!breaker(pm, args)) + break; + } + } + } + } + break; + case PMT_FRAME_LIST: + { + // break mbf list into single pm(s) + + if (selectPmType == PMT_FRAME_LIST || selectPmType == PMT_FRAME || + selectPmType == PipeMaterial::PMT__FIRST || selectPmType == PipeMaterial::PMT__LAST) + { + MB_Frame* mbf = (MB_Frame*)buffer; + for (size_t i = 0; i < buffSize; i++, mbf++) + { + if (selectMbfType == mbf->type || selectMbfType == MB_Frame::MBFT__FIRST || selectMbfType == MB_Frame::MBFT__LAST) + { + PipeMaterial tmpPm; + tmpPm.type = PMT_FRAME; + tmpPm.buffer = mbf; + tmpPm.buffSize = 0; + tmpPm.former = former; + tmpPm.deleter = nullptr; + tmpPm.args = args; + + called++; + if (!breaker(&tmpPm, args)) + break; + } + } + } + } + break; + default: + break; + } + + return called; +} + +PipeLine::elem_create_func_map_t PipeLine::global_elem_create_func_map; + +PipeLine::PipeLine() : params_map(), elem_create_func_map(), elems() { } @@ -15,7 +134,7 @@ for(elem_vec_t::iterator iter = elems.begin(); iter != elems.end(); ++iter) { PipeLineElem* elem = *iter; - if (elem != nullptr) + if (elem != nullptr && elem->manager == this) { elem->finit(); delete *iter; @@ -38,6 +157,20 @@ return true; } +//static +bool PipeLine::register_global_elem_creator(const std::string& type, elem_create_func_t func) +{ + if (type.empty() || func == nullptr) + return false; + + elem_create_func_map_t::iterator iter = global_elem_create_func_map.find(type); + if (iter != global_elem_create_func_map.end()) + return false; + + global_elem_create_func_map.insert(std::make_pair(type, func)); + return true; +} + void PipeLine::push_elem(PipeLineElem* elem) { if(elem != nullptr) @@ -47,11 +180,74 @@ } } +void PipeLine::push_front_elem(PipeLineElem* elem) +{ + if(elem != nullptr) + { + elem->manager = this; + elems.insert(elems.begin(), elem); + } +} + +PipeLineElem* PipeLine::at(int idx) +{ + return elems[idx]; +} + +bool PipeLine::remove_elem(PipeLineElem* elem) +{ + if(elem != nullptr) + { + for(elem_vec_t::iterator iter = elems.begin(); iter != elems.end(); ++iter) + { + if (*iter == elem) + { + iter = elems.erase(iter); + return true; + } + } + } + + return false; +} + +void PipeLine::finit(elem_destory_func_t elem_destory_func) +{ + while (!elems.empty()) + { + PipeLineElem* elem = elems.back(); + + if (elem->manager == this) + { + elem->finit(); + if (elem_destory_func != nullptr) + elem_destory_func(elem); + } + + elems.pop_back(); + } + + elem_create_func_map.clear(); + params_map.clear(); +} + +bool PipeLine::check_pipe_complete(PipeLineElem* lastRetElem) const +{ + if (elems.empty()) + return lastRetElem == nullptr; + else + return lastRetElem == *elems.rbegin(); +} + PipeLineElem* PipeLine::push_elem(const std::string& type) { elem_create_func_map_t::iterator iter = elem_create_func_map.find(type); if (iter == elem_create_func_map.end()) - return nullptr; + { + iter = global_elem_create_func_map.find(type); + if (iter == global_elem_create_func_map.end()) + return nullptr; + } elem_create_func_t func = iter->second; if (func == nullptr) @@ -78,54 +274,98 @@ if (pm == nullptr) pm = new (pmPlacement) PipeMaterial; + bool lastRet = true; + if (elems.size() == 1) { - elem_begin->gain(*pm); + lastRet = elem_begin->gain(*pm); + pm->exec_deleter(lastRet); return elem_begin; } else if (elems.size() == 2) { - elem_begin->gain(*pm); - elem_last->pay(*pm); + if (elem_begin->gain(*pm)) + { + lastRet = elem_last->pay(*pm); + pm->exec_deleter(lastRet); + } + else + return elem_begin; return elem_last; } else { - elem_begin->gain(*pm); + if (!elem_begin->gain(*pm)) + return elem_begin; + lastRet = true; elem_vec_t::iterator iter = elems.begin(); + ++iter; + elem_begin = *iter; while (elem_begin != elem_last) { + if (lastRet && (lastRet = elem_begin->pay(*pm)) ) + { + pm->exec_deleter(lastRet); + lastRet = elem_begin->gain(*pm); + } + else + return elem_begin; + ++iter; elem_begin = *iter; - elem_begin->pay(*pm); - elem_begin->gain(*pm); } - elem_last->pay(*pm); + if (lastRet) + elem_last->pay(*pm); + pm->exec_deleter(lastRet); return elem_last; } return nullptr; } -void PipeLine::set_global_param(const std::string& name, const std::string& value) +void PipeLine::set_param(const std::string& name, const std::string& value) { if (name.empty()) return; - global_params_map_t::iterator iter = global_params_map.find(name); - if (iter == global_params_map.end()) - global_params_map.insert(std::make_pair(name, value)); + params_map_t::iterator iter = params_map.find(name); + if (iter == params_map.end()) + params_map.insert(std::make_pair(name, value)); else iter->second = value; } -std::string PipeLine::get_global_param(const std::string& name) const +std::string PipeLine::get_param(const std::string& name) const { - global_params_map_t::const_iterator iter = global_params_map.find(name); - if (iter == global_params_map.end()) + params_map_t::const_iterator iter = params_map.find(name); + if (iter == params_map.end()) return ""; else return iter->second; } + +#ifdef ENABLE_PIPELINE_ELEM_TIMING_DEBUGGER +#include <typeinfo> +#include <sys/time.h> +PipeLineElemTimingDebugger::PipeLineElemTimingDebugger(const PipeLineElem* _elem) : + elem(_elem), beginTime(0) +{ + struct timeval _beginTime; + gettimeofday(&_beginTime, NULL); + beginTime = 1000000 * _beginTime.tv_sec + _beginTime.tv_usec; +} + +PipeLineElemTimingDebugger::~PipeLineElemTimingDebugger() +{ + struct timeval _endTime; + gettimeofday(&_endTime, NULL); + const uint64_t endTime = 1000000 * _endTime.tv_sec + _endTime.tv_usec; + + LOGP(WARN, "elem=%s@%llu, dura=%llu(us)", typeid(elem).name(), uint64_t(elem), uint64_t(endTime - beginTime)); +} +#else +PipeLineElemTimingDebugger::PipeLineElemTimingDebugger(const PipeLineElem* _elem) { } +PipeLineElemTimingDebugger::~PipeLineElemTimingDebugger() { } +#endif -- Gitblit v1.8.0