From 5e85a7e80764e1a1eae39c8ce9bafed29d8773a9 Mon Sep 17 00:00:00 2001 From: chenshijun <csj_sky@126.com> Date: 星期二, 23 七月 2019 19:57:27 +0800 Subject: [PATCH] 增加支持推流的代码,并替换librtspclient.so --- csrc/ffmpeg/format/FormatIn.cpp | 6 csrc/thirdparty/gb28181/lib/librtspclient.so | 0 apipassive.go | 17 +++ csrc/wrapper.cpp | 29 +++++ csrc/wrapper.hpp | 11 ++ cffmpeg.h | 1 libcffmpeg.c | 6 + csrc/cffmpeg.cpp | 7 + libcffmpeg.h | 3 csrc/thirdparty/gb28181/include/PsToEs.hpp | 195 +++++++++++++++++++------------------- csrc/ffmpeg/format/FormatIn.hpp | 2 11 files changed, 177 insertions(+), 100 deletions(-) diff --git a/apipassive.go b/apipassive.go index 61e67cf..84dfda5 100644 --- a/apipassive.go +++ b/apipassive.go @@ -55,3 +55,20 @@ return d, wid, hei } + +//GetAVPacket get AVPacket +func (h *GoFFMPEG) GetAVPacket() ([]byte, int, int) { + var key C.int + var size C.int + + p := C.wrap_fn_get_avpacket(h.ffmpeg, &size, &key) + if size <= 0 { + return nil, 0, -1 + } + defer C.free(unsafe.Pointer(p)) + d := C.GoBytes(p, size) + s := int(size) + k := int(key) + + return d, s, k +} \ No newline at end of file diff --git a/cffmpeg.h b/cffmpeg.h index c7bf9d1..f992654 100644 --- a/cffmpeg.h +++ b/cffmpeg.h @@ -26,6 +26,7 @@ void c_ffmpeg_build_decoder(const cffmpeg h); void* c_ffmpeg_get_pic_decoder(const cffmpeg h, int *wid, int *hei); +void* c_ffmpeg_get_avpacket(const cffmpeg h, int *size, int *key); ////////////active api void c_ffmpeg_active_recorder(const cffmpeg h, const char *dir, int mind, int maxd, rec_func fn); void c_ffmpeg_active_decoder(const cffmpeg h, dec_func fn); diff --git a/csrc/cffmpeg.cpp b/csrc/cffmpeg.cpp index b78313e..423ef01 100644 --- a/csrc/cffmpeg.cpp +++ b/csrc/cffmpeg.cpp @@ -86,6 +86,13 @@ s->GetPicDecoder(&data, wid, hei); return data; } + +void* c_ffmpeg_get_avpacket(const cffmpeg h, int *size, int *key){ + Wrapper *s = (Wrapper*)h; + unsigned char *data = NULL; + s->GetPacket(&data, size, key); + return data; +} /////////////////////active api void c_ffmpeg_active_recorder(const cffmpeg h, const char *dir, int mind, int maxd, rec_func fn){ diff --git a/csrc/ffmpeg/format/FormatIn.cpp b/csrc/ffmpeg/format/FormatIn.cpp index d61fbc7..b0a577b 100644 --- a/csrc/ffmpeg/format/FormatIn.cpp +++ b/csrc/ffmpeg/format/FormatIn.cpp @@ -21,7 +21,6 @@ #include "../data/FrameData.hpp" #include "../../common/gpu/info.h" -#include "PsToEs.hpp" using namespace logif; @@ -90,9 +89,10 @@ int FormatIn::openGb28181(const char *filename, AVDictionary **options){ std::string fn = filename; - addCamera(fn); + //GB28181API gb28181(fn); + handle_gb28181.addCamera(fn); - int ret = openWithCustomIO(NULL, readData, options); + int ret = openWithCustomIO((void *)&handle_gb28181, handle_gb28181.readData, options); if(ret < 0){ logIt("do openWithCustomIO failed:%d",ret); } diff --git a/csrc/ffmpeg/format/FormatIn.hpp b/csrc/ffmpeg/format/FormatIn.hpp index a19d0fe..4155aae 100644 --- a/csrc/ffmpeg/format/FormatIn.hpp +++ b/csrc/ffmpeg/format/FormatIn.hpp @@ -3,6 +3,7 @@ #include <stdint.h> #include <memory> +#include "PsToEs.hpp" struct AVFormatContext; struct AVDictionary; @@ -62,6 +63,7 @@ AVIOContext *io_ctx_; uint8_t *read_io_buff_; const int read_io_buff_size_; + GB28181API handle_gb28181; }; } diff --git a/csrc/thirdparty/gb28181/include/PsToEs.hpp b/csrc/thirdparty/gb28181/include/PsToEs.hpp index 663fbdb..51f613a 100644 --- a/csrc/thirdparty/gb28181/include/PsToEs.hpp +++ b/csrc/thirdparty/gb28181/include/PsToEs.hpp @@ -67,7 +67,6 @@ while (!q.empty()) q.pop_front(); pthread_mutex_unlock(&mtx); } - private: deque<T> q; pthread_mutex_t mtx; @@ -80,111 +79,115 @@ int buffLen; } frameBuffInfo; -MyQueue<frameBuffInfo *> m_rtpQueue; -long Handle; +class GB28181API{ +public: + GB28181API(/*string rtspUrl*/){ +// handle = addCamera(rtspUrl); + } -bool pushInfo(unsigned char *data, int datalen) { + ~GB28181API(){ + printf("GB28181API end!\n"); + m_rtpQueue.clearAll(); + deleteCamera(); + } - frameBuffInfo *info = new frameBuffInfo(); - info->buff = new unsigned char[datalen]; - info->buffLen = datalen; - memcpy(info->buff, data, datalen); - - //printf(" m_rtpQueue.push befores "); - m_rtpQueue.push(info); - //printf(" m_rtpQueue.push after "); - - return true; -} - -int readData(void *opaque, unsigned char *buf, int bufsize) { - -// GB28181API *_this = (GB28181API *)opaque; - int len = bufsize; - int diff = 0; - do { - - //printf(" m_rtpQueue.pop before "); - //浠庣紦瀛樹腑鑾峰彇buffinfo - frameBuffInfo *buffinfo = m_rtpQueue.pop(); -// DBG(" m_rtpQueue.pop after "); - diff = len - buffinfo->buffLen; - - //甯ч暱澶т簬bufsize - if (diff < 0) { - printf("/甯ч暱澶т簬bufsize:%d\n", diff); - memcpy(buf + bufsize - len, buffinfo->buff, len); + bool pushInfo(unsigned char *data, int datalen) { frameBuffInfo *info = new frameBuffInfo(); - info->buffLen = buffinfo->buffLen - len; - info->buff = new unsigned char[buffinfo->buffLen - len]{}; - memcpy(info->buff, buffinfo->buff + len, buffinfo->buffLen - len); + info->buff = new unsigned char[datalen]; + info->buffLen = datalen; + memcpy(info->buff, data, datalen); - m_rtpQueue.push_front_one(info); - } else if (diff == 0) { - printf("/甯ч暱绛変簬bufsize:%d\n", diff); - memcpy(buf + bufsize - len, buffinfo->buff, buffinfo->buffLen); - } else if (diff > 0) { - printf("/甯ч暱灏忎簬bufsize:%d\n", diff); - memcpy(buf + bufsize - len, buffinfo->buff, buffinfo->buffLen); - len = len - buffinfo->buffLen; //杩橀渶瑕佸~鍏呯殑澶у皬 - memset(buf + bufsize - len, 0, len); - //涓嶇瓑寰呭~鍏咃紝鐩存帴杩涜瑙g爜 - diff = 0; - } - delete[] buffinfo->buff; - delete buffinfo; - } while (diff > 0); + //printf(" m_rtpQueue.push befores "); + m_rtpQueue.push(info); + //printf(" m_rtpQueue.push after "); - return bufsize; -} - -void streamCallBack(int datatype, int frametype, unsigned char *data, unsigned int datalen, long userdata) -{ - //GB28181API *_this = (GB28181API *)userdata; - printf("userdata:%ld,datatype:%d, frametype:%d, datalen:%d\n", userdata, datatype, frametype, datalen); - -// //debug=============== -// static int count = 0; -// static FILE *fp_write = NULL; -// if(count < 100) { -// count++; -// -// if (!fp_write) { -// fp_write = fopen("stream_callback.mp4", "wb+"); -// } -// -// fwrite(data, sizeof(char), datalen, fp_write); -// } -// if(count >= 100){ -// if (!fp_write) { -// fclose(fp_write); -// } -// } -// //debug=============== - - static bool startFlag = false; - if(frametype == GB_VIDEO_FRAME_I){ - startFlag = true; - } - if((data != NULL) && (startFlag == true)){ - pushInfo(data, datalen); + return true; } -} + static int readData(void *opaque, unsigned char *buf, int bufsize) { -long addCamera(string &rtsp){ - printf("RTSPSTREAM_Open\n"); - long userdata = 1001; - Handle = RTSPSTREAM_Open(rtsp.c_str(), streamCallBack, userdata); - return Handle; -} + GB28181API *_this = (GB28181API *)opaque; + int len = bufsize; + int diff = 0; + do { +// printf(" m_rtpQueue.pop before \n"); + //浠庣紦瀛樹腑鑾峰彇buffinfo + frameBuffInfo *buffinfo = _this->m_rtpQueue.pop(); +// printf(" m_rtpQueue.pop after \n"); + diff = len - buffinfo->buffLen; -void deleteCamera(void){ - m_rtpQueue.clearAll(); - RTSPSTREAM_Close(Handle); - Handle = 0; -} + //甯ч暱澶т簬bufsize + if (diff < 0) { +// printf("/甯ч暱澶т簬bufsize:%d\n", diff); + memcpy(buf + bufsize - len, buffinfo->buff, len); + frameBuffInfo *info = new frameBuffInfo(); + info->buffLen = buffinfo->buffLen - len; + info->buff = new unsigned char[buffinfo->buffLen - len]{}; + memcpy(info->buff, buffinfo->buff + len, buffinfo->buffLen - len); + +// printf("/甯ч暱澶т簬info->buffLen:%d\n", info->buffLen); + _this->m_rtpQueue.push_front_one(info); +// printf("/甯ч暱澶т簬info->buffLen\n"); + } else if (diff == 0) { +// printf("/甯ч暱绛変簬bufsize:%d\n", diff); + memcpy(buf + bufsize - len, buffinfo->buff, buffinfo->buffLen); + } else if (diff > 0) { +// printf("/甯ч暱灏忎簬bufsize:%d\n", diff); + memcpy(buf + bufsize - len, buffinfo->buff, buffinfo->buffLen); + len = len - buffinfo->buffLen; //杩橀渶瑕佸~鍏呯殑澶у皬 + memset(buf + bufsize - len, 0, len); + //涓嶇瓑寰呭~鍏咃紝鐩存帴杩涜瑙g爜 + diff = 0; + } + delete[] buffinfo->buff; + delete buffinfo; +// printf("/甯ч暱澶т簬info->buffLen1\n"); + } while (diff > 0); + + return bufsize; + } + + static void streamCallBack(int datatype, int frametype, unsigned char *data, unsigned int datalen, long userdata) + { + GB28181API *_this = (GB28181API *)userdata; + //printf("userdata:%ld,datatype:%d, frametype:%d, datalen:%d\n", userdata, datatype, frametype, datalen); + + /*static FILE* fp_write = NULL; + if (!fp_write) + + { + + fp_write = fopen("stream_callback.mp4", "wb+"); + + } + + fwrite(data, sizeof(char), datalen, fp_write); */ + + static bool startFlag = false; + if(frametype == GB_VIDEO_FRAME_I){ + startFlag = true; + } + if((data != NULL) && (startFlag == true)){ + _this->pushInfo(data, datalen); + } + } + + void addCamera(string &rtsp){ +// long userdata = 1001;// + printf("RTSPSTREAM_Open\n"); + handle = RTSPSTREAM_Open(rtsp.c_str(), streamCallBack, (long)this); +// return handle; + } + + void deleteCamera(){ + printf("RTSPSTREAM_Close\n"); + RTSPSTREAM_Close(handle); + } +private: + MyQueue<frameBuffInfo *> m_rtpQueue; + long handle; +}; diff --git a/csrc/thirdparty/gb28181/lib/librtspclient.so b/csrc/thirdparty/gb28181/lib/librtspclient.so index 6757f0f..f367065 100644 --- a/csrc/thirdparty/gb28181/lib/librtspclient.so +++ b/csrc/thirdparty/gb28181/lib/librtspclient.so Binary files differ diff --git a/csrc/wrapper.cpp b/csrc/wrapper.cpp index ec891ab..06eff0e 100644 --- a/csrc/wrapper.cpp +++ b/csrc/wrapper.cpp @@ -218,6 +218,9 @@ pkt.id = id++; } pkt.data = data; + if(data != nullptr) { + cacheAVPacket(data->getAVPacket()); + } run_worker(in.get(), pkt); if(!data){ @@ -334,6 +337,30 @@ auto p = list_pic_.front(); *data = p.data; *w = p.w; *h = p.h; list_pic_.pop_front(); + } + + void Wrapper::GetPacket(unsigned char **pktData, int *size, int *key){ + std::lock_guard<std::mutex> l(mutex_avpkt_); + if(list_avpkt_.empty()){ + return; + } + auto pkt = list_avpkt_.front(); + *key = pkt.flags & AV_PKT_FLAG_KEY; + *size = pkt.size; + *pktData = (unsigned char *)malloc(*size); + memcpy(*pktData, pkt.data, pkt.size); + + list_avpkt_.pop_front(); + } + void Wrapper::cacheAVPacket(const AVPacket &pkt){ + std::lock_guard<std::mutex> l(mutex_pic_); + while(list_avpkt_.size() > 10){ +// printf("cacheAVPacket drop packets!!!!!!!!!!\n"); + for(int i = 0; i < 5; i++){ + list_avpkt_.pop_front(); + } + } + list_avpkt_.emplace_back(pkt); } void Wrapper::run_worker(ffwrapper::FormatIn *in, avpacket &pkt){ @@ -523,7 +550,7 @@ } *size = pkt.size + extradata_size; *out = (unsigned char *)malloc(*size); - + memcpy(*out, extra, extradata_size); memcpy(*out + extradata_size, pkt.data, pkt.size); diff --git a/csrc/wrapper.hpp b/csrc/wrapper.hpp index c8d928b..db45ea7 100644 --- a/csrc/wrapper.hpp +++ b/csrc/wrapper.hpp @@ -1,6 +1,10 @@ #ifndef _cffmpeg_wrapper_hpp_ #define _cffmpeg_wrapper_hpp_ +extern "C"{ +#include <libavcodec/avcodec.h> +} + #include <stdint.h> #include <string> @@ -58,6 +62,8 @@ void cache_rec_info(int &index, std::string &path); void cache_pic(std::shared_ptr<ffwrapper::FrameData> &frame); + + void cacheAVPacket(const AVPacket &pkt); public: int RunStream(const char* input); private: @@ -78,6 +84,7 @@ public: //decoder void BuildDecoder(); void GetPicDecoder(unsigned char **data, int *w, int *h); + void GetPacket(unsigned char **pktData, int *size, int *key); //active api void ActiveDecoder(FUNC_DEC fn); @@ -106,6 +113,10 @@ std::list<pic_bgr24> list_pic_; std::mutex mutex_pic_; + + std::list<AVPacket> list_avpkt_; + std::mutex mutex_avpkt_; + // active api FUNC_REC func_rec_; FUNC_DEC func_dec_; diff --git a/libcffmpeg.c b/libcffmpeg.c index bd66a10..e33a376 100644 --- a/libcffmpeg.c +++ b/libcffmpeg.c @@ -39,6 +39,8 @@ release_if_err(fn_decoder, lib); fn_decoder_pic = (lib_cffmpeg_pic)dlsym(lib, "c_ffmpeg_get_pic_decoder"); release_if_err(fn_decoder_pic, lib); + fn_get_avpacket = (lib_cffmpeg_avpacket)dlsym(lib, "c_ffmpeg_get_avpacket"); + release_if_err(fn_get_avpacket, lib); fn_active_recorder = (lib_cffmpeg_active_recorder)dlsym(lib, "c_ffmpeg_active_recorder"); release_if_err(fn_active_recorder, lib); fn_active_decoder = (lib_cffmpeg_active_decoder)dlsym(lib, "c_ffmpeg_active_decoder"); @@ -109,6 +111,10 @@ return fn_decoder_pic(h, wid, hei); } +void* wrap_fn_get_avpacket(const cffmpeg h, int* size, int* key){ + return fn_get_avpacket(h, size, key); +} + void wrap_fn_active_recorder(const cffmpeg h, const char* dir, int mind, int maxd, rec_func fn){ fn_active_recorder(h, dir, mind, maxd, fn); } diff --git a/libcffmpeg.h b/libcffmpeg.h index d083536..1cfbaa5 100644 --- a/libcffmpeg.h +++ b/libcffmpeg.h @@ -24,6 +24,7 @@ typedef char*(*lib_cffmpeg_info_recorder)(const cffmpeg, int*, int*); typedef void (*lib_cffmpeg_decoder)(const cffmpeg); typedef void*(*lib_cffmpeg_pic)(const cffmpeg, int*, int*); +typedef void*(*lib_cffmpeg_avpacket)(const cffmpeg, int*, int*); typedef void (*lib_cffmpeg_active_recorder)(const cffmpeg, const char*, int, int, rec_func); typedef void (*lib_cffmpeg_active_decoder)(const cffmpeg, dec_func); typedef void*(*lib_cffmpeg_decode_jpeg)(const cffmpeg, const char*, int*, int*); @@ -39,6 +40,7 @@ static lib_cffmpeg_info_recorder fn_info_recorder = NULL; static lib_cffmpeg_decoder fn_decoder = NULL; static lib_cffmpeg_pic fn_decoder_pic = NULL; +static lib_cffmpeg_avpacket fn_get_avpacket = NULL; static lib_cffmpeg_active_recorder fn_active_recorder = NULL; static lib_cffmpeg_active_decoder fn_active_decoder = NULL; static lib_cffmpeg_decode_jpeg fn_dec_jpeg = NULL; @@ -58,6 +60,7 @@ char* wrap_fn_info_recorder(const cffmpeg, int*, int*); void wrap_fn_decoder(const cffmpeg h); void* wrap_fn_decoder_pic(const cffmpeg h, int* wid, int* hei); +void* wrap_fn_get_avpacket(const cffmpeg h, int* size, int* key); void wrap_fn_active_recorder(const cffmpeg h, const char* dir, int mind, int maxd, rec_func fn); void wrap_fn_active_decoder(const cffmpeg h, dec_func fn); void* wrap_fn_decode_jpeg(const cffmpeg h, const char* file, int* wid, int* hei); -- Gitblit v1.8.0