From c60d61c48c7a1e7b693d4c3f6427e3b616d1f471 Mon Sep 17 00:00:00 2001
From: zhangmeng <775834166@qq.com>
Date: 星期一, 21 十月 2019 12:29:33 +0800
Subject: [PATCH] update ffmpeg

---
 gostream.go         |    2 
 cffmpeg.h           |    5 
 goenc.go            |    7 
 godecjpeg.go        |    2 
 csrc/wrapper.cpp    |   48 -------
 godec.go            |    4 
 csrc/worker/rec.cpp |   12 +-
 csrc/wrapper.hpp    |    4 
 goffmpeg.go         |   16 +-
 csrc/worker/rec.hpp |    6 
 goconv.go           |    8 
 libcffmpeg.c        |  176 +++++++++++++++++------------
 csrc/cffmpeg.cpp    |    8 -
 gorec.go            |   10 
 libcffmpeg.h        |   45 +++----
 15 files changed, 163 insertions(+), 190 deletions(-)

diff --git a/cffmpeg.h b/cffmpeg.h
index ef67716..8f8abeb 100644
--- a/cffmpeg.h
+++ b/cffmpeg.h
@@ -19,7 +19,7 @@
 void c_ffmepg_use_cpu(const cffmpeg h);
 /////////passive api
 void c_ffmpeg_set_record_duration(const cffmpeg h, const int min, const int max);
-void c_ffmpeg_build_recorder(const cffmpeg h, const char*id, const char *dir, int mind, int maxd, int audio);
+void c_ffmpeg_build_recorder(const cffmpeg h, const char*id, const char *dir, const int64_t fid, int mind, int maxd, int audio);
 void c_ffmpeg_fire_recorder(const cffmpeg h, const char*sid, const int64_t id);
 void c_ffmpeg_get_info_recorder(const cffmpeg h, int *index, char** recid, int *recidLen, char **fpath, int *pathLen);
 
@@ -40,9 +40,6 @@
                           const int dstW, const int dstH, const int dstFormat, const int flag);
 void c_ffmpeg_destroy_conv(void *h);
 void *c_ffmpeg_conv(void *h, uint8_t *in);
-
-// gpu conv
-void* c_gpu_conv(uint8_t *in, const int w, const int h, const int dst_w, const int dst_h, int *length);
 
 #ifdef __cplusplus
 }
diff --git a/csrc/cffmpeg.cpp b/csrc/cffmpeg.cpp
index 690f061..6e54de4 100644
--- a/csrc/cffmpeg.cpp
+++ b/csrc/cffmpeg.cpp
@@ -50,11 +50,11 @@
     s->SetRecMinCacheTime(min);
 }
 
-void c_ffmpeg_build_recorder(const cffmpeg h, const char* id, const char *dir, int mind, int maxd, int audio){
+void c_ffmpeg_build_recorder(const cffmpeg h, const char* id, const char *dir, const int64_t fid, int mind, int maxd, int audio){
     Wrapper *s = (Wrapper*)h;
 
     bool a = audio == 0 ? false : true;
-    s->BuildRecorder(id, dir, mind, maxd, a);
+    s->BuildRecorder(id, dir, fid, mind, maxd, a);
 }
 
 void c_ffmpeg_fire_recorder(const cffmpeg h, const char* sid, const int64_t id){
@@ -134,7 +134,3 @@
 void c_ffmpeg_destroy_conv(void *h){
     DestoryConvertor(h);
 }
-
-void* c_gpu_conv(uint8_t *in, const int w, const int h, const int dst_w, const int dst_h, int *length){
-    return ConvertYUV2BGR(in, w, h, dst_w, dst_h, length);
-}
\ No newline at end of file
diff --git a/csrc/worker/rec.cpp b/csrc/worker/rec.cpp
index 2e02903..36d837c 100644
--- a/csrc/worker/rec.cpp
+++ b/csrc/worker/rec.cpp
@@ -20,8 +20,7 @@
 {
     rec::rec()
     :recRef_(NULL)
-    ,min_cache_len_(125)
-    ,time_offset_(5)
+    ,min_cache_len_(10 * 60 * 25) // 鏈�灏忕紦瀛�?鍒嗛挓鐨勮棰�,鍥犱负鏁翠釜娴佺▼浼氭湁寤惰繜,鏆傚畾?鍒嗛挓
     {}
 
     rec::~rec()
@@ -44,7 +43,7 @@
         list_recInfo_.emplace_back(info);
     }
 
-    std::unique_ptr<buz::Recorder> rec::startRec(std::string id, std::string dir, const int mind, const int maxd, const bool audio){
+    std::unique_ptr<buz::Recorder> rec::startRec(std::string id, std::string dir, const int64_t &frameID, const int mind, const int maxd, const bool audio){
         if(!recRef_){
             logIt("Init wrapper first");
             return nullptr;
@@ -62,6 +61,7 @@
             if(ret == 0) break;
             usleep(200000);
         }
+        
         if (trycnt < 100){
             std::lock_guard<std::mutex> locker(mtx_pkt_);
             rec->PushPackets(list_pkt_);
@@ -137,7 +137,7 @@
         return recRef_ != NULL;
     }
     
-    void rec::NewRec(const char* id, const char *output, const int mindur, const int maxdur, const bool audio){
+    void rec::NewRec(const char* id, const char *output, const int64_t &frameID, const int mindur, const int maxdur, const bool audio){
         std::string rid(id);
         std::string dir(output);
         
@@ -146,7 +146,7 @@
             if (map_rec_.find(rid) != map_rec_.end()){
                 map_rec_.erase(rid);
             }
-            map_rec_[rid] = startRec(rid, dir, mindur, maxdur, audio);
+            map_rec_[rid] = startRec(rid, dir, frameID, mindur, maxdur, audio);
         }
         
     }
@@ -200,7 +200,7 @@
         if (recRef_){
             fps = recRef_->getFPS();
         }
-        min_cache_len_ = (min + time_offset_) * fps;
+        min_cache_len_ += min * fps;
     }
 
     int rec::shrinkCache(){
diff --git a/csrc/worker/rec.hpp b/csrc/worker/rec.hpp
index c802d9a..e79e332 100644
--- a/csrc/worker/rec.hpp
+++ b/csrc/worker/rec.hpp
@@ -24,8 +24,6 @@
     private:
         ffwrapper::FormatIn *recRef_;
         int min_cache_len_;
-        // 鏁翠釜娴佺▼鑰楁椂琛ュ伩褰曞埗鏃堕棿,2s榛樿
-        const int time_offset_;
         // 褰曞儚鐨勫疄渚�,瀵瑰簲浠诲姟
         std::unordered_map<std::string, std::unique_ptr<buz::Recorder> > map_rec_;
         // 澶氱嚎绋嬫坊鍔犱换鍔″疄渚�,鍦ㄨ娴佺嚎绋嬩娇鐢ㄥ綍鍍�,浣嗘槸娣诲姞鍦ㄥ彟涓�涓嚎绋�
@@ -54,11 +52,11 @@
         // 涓㈠純缂撳瓨
         int shrinkCache();
         // 鍒涘缓褰曞儚瀹炰緥寮�濮嬪綍鍍�
-        std::unique_ptr<buz::Recorder> startRec(std::string id, std::string dir, const int mind, const int maxd, const bool audio);
+        std::unique_ptr<buz::Recorder> startRec(std::string id, std::string dir, const int64_t &frameID, const int mind, const int maxd, const bool audio);
         // 娓呴櫎缂撳瓨,鏂嚎閲嶈繛鏃堕渶瑕�
         void clear();
     public:
-        void NewRec(const char* id, const char *output, const int mindur, const int maxdur, const bool audio);
+        void NewRec(const char* id, const char *output, const int64_t &frameID, const int mindur, const int maxdur, const bool audio);
 
         // 鍑嗗濂藉綍鍍�
         void Load(ffwrapper::FormatIn *in);
diff --git a/csrc/wrapper.cpp b/csrc/wrapper.cpp
index fe6d576..9d0c679 100644
--- a/csrc/wrapper.cpp
+++ b/csrc/wrapper.cpp
@@ -25,8 +25,6 @@
 #include "worker/decoder.hpp"
 #include "worker/rec.hpp"
 
-#include "CUDALERP.h"
-
 using namespace logif;
 using namespace ffwrapper;
 
@@ -235,16 +233,16 @@
         rec_->SetRecMinCacheTime(mind);
     }
 
-    void Wrapper::BuildRecorder(const char* id, const char *output, const int mindur, const int maxdur, const bool audio){
+    void Wrapper::BuildRecorder(const char* id, const char *output, const int64_t &fid, const int mindur, const int maxdur, const bool audio){
         bool a = audio;
         if (gb_) a = false;
 
         if (rec_->Loaded()){
-            rec_->NewRec(id, output, mindur, maxdur, a);
+            rec_->NewRec(id, output, fid, mindur, maxdur, a);
         }else{
             std::string rid(id), dir(output);
             fn_rec_lazy_ = 
-            [=]{rec_->NewRec(rid.c_str(), dir.c_str(), mindur, maxdur, a);};
+            [=]{rec_->NewRec(rid.c_str(), dir.c_str(), fid, mindur, maxdur, a);};
         }
     }
 
@@ -488,45 +486,5 @@
         free(c);
     }
 
-
-    uint8_t* ConvertYUV2BGR(uint8_t *src, const int w, const int h, const int dst_w, const int dst_h, int *length){
-        return NULL;
-
-        // int oldw = w, oldh = h, neww = dst_w, newh = dst_h;
-        // 	// setting cache and shared modes
-	    // cudaDeviceSetCacheConfig(cudaFuncCachePreferL1);
-	    // cudaDeviceSetSharedMemConfig(cudaSharedMemBankSizeFourByte);
-
-	    // // allocating and transferring image and binding to texture object
-	    // cudaChannelFormatDesc chandesc_img = cudaCreateChannelDesc(8, 0, 0, 0, cudaChannelFormatKindUnsigned);
-	    // cudaArray* d_img_arr;
-	    // cudaMallocArray(&d_img_arr, &chandesc_img, oldw, oldh, cudaArrayTextureGather);
-	    // cudaMemcpyToArray(d_img_arr, 0, 0, image, oldh * oldw, cudaMemcpyHostToDevice);
-	    // struct cudaResourceDesc resdesc_img;
-	    // memset(&resdesc_img, 0, sizeof(resdesc_img));
-	    // resdesc_img.resType = cudaResourceTypeArray;
-	    // resdesc_img.res.array.array = d_img_arr;
-	    // struct cudaTextureDesc texdesc_img;
-	    // memset(&texdesc_img, 0, sizeof(texdesc_img));
-	    // texdesc_img.addressMode[0] = cudaAddressModeClamp;
-	    // texdesc_img.addressMode[1] = cudaAddressModeClamp;
-	    // texdesc_img.readMode = cudaReadModeNormalizedFloat;
-	    // texdesc_img.filterMode = cudaFilterModePoint;
-	    // texdesc_img.normalizedCoords = 0;
-	    // cudaTextureObject_t d_img_tex = 0;
-	    // cudaCreateTextureObject(&d_img_tex, &resdesc_img, &texdesc_img, nullptr);
-
-	    // uint8_t* d_out = nullptr;
-	    // cudaMalloc(&d_out, total);
-
-	    // for (int i = 0; i < warmups; ++i) CUDALERP(d_img_tex, oldw, oldh, d_out, neww, newh);
-	    // auto start = high_resolution_clock::now();
-	    // for (int i = 0; i < runs; ++i) CUDALERP(d_img_tex, oldw, oldh, d_out, neww, newh);
-	    // auto end = high_resolution_clock::now();
-	    // auto sum = (end - start) / runs;
-
-	    // auto h_out = new uint8_t[neww * newh];
-	    // cudaMemcpy(h_out, d_out, total, cudaMemcpyDeviceToHost);
-    }
 }
 
diff --git a/csrc/wrapper.hpp b/csrc/wrapper.hpp
index 4ae1a4f..3e68b46 100644
--- a/csrc/wrapper.hpp
+++ b/csrc/wrapper.hpp
@@ -41,7 +41,7 @@
     private: 
         void run_stream_thread();
     public: //recorder
-        void BuildRecorder(const char* id,const char *dir, const int mind, const int maxd, const bool audio);
+        void BuildRecorder(const char* id, const char *dir, const int64_t &fid, const int mind, const int maxd, const bool audio);
         int FireRecorder(const char* sid,const int64_t &id);
         void GetInfoRecorder(std::string &recID, int &index, std::string &path);
     
@@ -86,8 +86,6 @@
                           const int dstW, const int dstH, const int dstFormat, const int flag);
     uint8_t *Convert(void *h, uint8_t *src);
     void DestoryConvertor(void *h);
-
-    uint8_t* ConvertYUV2BGR(uint8_t *src, const int w, const int h, const int dst_w, const int dst_h, int *length);
 }
 
 #endif
\ No newline at end of file
diff --git a/goconv.go b/goconv.go
index 55869ba..06dba30 100644
--- a/goconv.go
+++ b/goconv.go
@@ -52,7 +52,7 @@
 
 // NewConv new conv
 func NewConv(srcW, srcH, dstW, dstH, scaleFlag int) *GoConv {
-	c := C.wrap_fn_create_conv(C.int(srcW), C.int(srcH), C.int(SrcFormat),
+	c := C.wrap_fn_create_conv(unsafe.Pointer(libcffmpeg), C.int(srcW), C.int(srcH), C.int(SrcFormat),
 		C.int(dstW), C.int(dstH), C.int(DstFormat), C.int(scaleFlag))
 
 	if c == nil {
@@ -70,7 +70,7 @@
 
 // NewResizer resize
 func NewResizer(srcW, srcH, format, dstW, dstH, scaleFlag int) *GoConv {
-	c := C.wrap_fn_create_conv(C.int(srcW), C.int(srcH), C.int(format),
+	c := C.wrap_fn_create_conv(unsafe.Pointer(libcffmpeg), C.int(srcW), C.int(srcH), C.int(format),
 		C.int(dstW), C.int(dstH), C.int(format), C.int(scaleFlag))
 
 	if c == nil {
@@ -89,7 +89,7 @@
 // Free free
 func (c *GoConv) Free() {
 	if c.conv != nil {
-		C.wrap_fn_destroy_conv(c.conv)
+		C.wrap_fn_destroy_conv(unsafe.Pointer(libcffmpeg), c.conv)
 	}
 }
 
@@ -102,7 +102,7 @@
 	cin := C.CBytes(src)
 	defer C.free(cin)
 
-	bgr := C.wrap_fn_conv(c.conv, (*C.uchar)(cin))
+	bgr := C.wrap_fn_conv(unsafe.Pointer(libcffmpeg), c.conv, (*C.uchar)(cin))
 	defer C.free(unsafe.Pointer(bgr))
 
 	if bgr != nil {
diff --git a/godec.go b/godec.go
index a232618..aab8c7a 100644
--- a/godec.go
+++ b/godec.go
@@ -9,7 +9,7 @@
 
 // BuildDecoder build decoder
 func (h *GoFFMPEG) BuildDecoder() {
-	C.wrap_fn_decoder(h.ffmpeg)
+	C.wrap_fn_decoder(unsafe.Pointer(libcffmpeg), h.ffmpeg)
 }
 
 // GetYUV get yuv data
@@ -18,7 +18,7 @@
 	var length C.int
 	var srcW, srcH, srcF C.int
 
-	p := C.wrap_fn_decoder_pic(h.ffmpeg, &srcW, &srcH, &srcF, &length, &fid)
+	p := C.wrap_fn_decoder_pic(unsafe.Pointer(libcffmpeg), h.ffmpeg, &srcW, &srcH, &srcF, &length, &fid)
 	if srcW == 0 || srcH == 0 {
 		return nil, 0, 0, 0
 	}
diff --git a/godecjpeg.go b/godecjpeg.go
index 6cc855d..6cef6af 100644
--- a/godecjpeg.go
+++ b/godecjpeg.go
@@ -23,7 +23,7 @@
 
 	var width C.int
 	var height C.int
-	p := C.wrap_fn_decode(in, C.int(withGB), &width, &height)
+	p := C.wrap_fn_decode(unsafe.Pointer(libcffmpeg), in, C.int(withGB), &width, &height)
 	defer C.free(p)
 
 	if width > 0 && height > 0 {
diff --git a/goenc.go b/goenc.go
index 3d00996..d7a6b43 100644
--- a/goenc.go
+++ b/goenc.go
@@ -5,6 +5,7 @@
 #include "libcffmpeg.h"
 */
 import "C"
+import "unsafe"
 
 ///////////////for encoder
 
@@ -20,14 +21,14 @@
 	}
 
 	return &GoEncoder{
-		enc: C.wrap_fn_create_encoder(C.int(w), C.int(h), C.int(fps), C.int(br), C.int(sFlag), C.int(gi)),
+		enc: C.wrap_fn_create_encoder(unsafe.Pointer(libcffmpeg), C.int(w), C.int(h), C.int(fps), C.int(br), C.int(sFlag), C.int(gi)),
 	}
 }
 
 // Free free
 func (e *GoEncoder) Free() {
 	if e.enc != nil {
-		C.wrap_fn_destroy_encoder(e.enc)
+		C.wrap_fn_destroy_encoder(unsafe.Pointer(libcffmpeg), e.enc)
 	}
 }
 
@@ -39,7 +40,7 @@
 	cin := C.CBytes(in)
 	defer C.free(cin)
 
-	p := C.wrap_fn_encode(e.enc, cin, C.int(w), C.int(h), &size, &key)
+	p := C.wrap_fn_encode(unsafe.Pointer(libcffmpeg), e.enc, cin, C.int(w), C.int(h), &size, &key)
 	defer C.free(p)
 	if p != nil && size > 0 {
 		b := C.GoBytes(p, size)
diff --git a/goffmpeg.go b/goffmpeg.go
index dedb2bf..4fb54af 100644
--- a/goffmpeg.go
+++ b/goffmpeg.go
@@ -42,16 +42,16 @@
 // New 2nd new
 func New(GB, CPU bool) *GoFFMPEG {
 
-	f := C.wrap_fn_create()
+	f := C.wrap_fn_create(unsafe.Pointer(libcffmpeg))
 
 	if f == nil {
 		return nil
 	}
 	if GB {
-		C.wrap_fn_run_gb28181(f)
+		C.wrap_fn_run_gb28181(unsafe.Pointer(libcffmpeg), f)
 	}
 	if CPU {
-		C.wrap_fn_use_cpu(f)
+		C.wrap_fn_use_cpu(unsafe.Pointer(libcffmpeg), f)
 	}
 
 	return &GoFFMPEG{
@@ -64,15 +64,15 @@
 	lf := C.CString(ffmpegLog)
 	defer C.free(unsafe.Pointer(lf))
 
-	f := C.wrap_fn_create2(lf)
+	f := C.wrap_fn_create2(unsafe.Pointer(libcffmpeg), lf)
 	if f == nil {
 		return nil
 	}
 	if GB {
-		C.wrap_fn_run_gb28181(f)
+		C.wrap_fn_run_gb28181(unsafe.Pointer(libcffmpeg), f)
 	}
 	if CPU {
-		C.wrap_fn_use_cpu(f)
+		C.wrap_fn_use_cpu(unsafe.Pointer(libcffmpeg), f)
 	}
 
 	return &GoFFMPEG{
@@ -83,7 +83,7 @@
 // Free free handle
 func (h *GoFFMPEG) Free() {
 	if h.ffmpeg != nil {
-		C.wrap_fn_destroy(h.ffmpeg)
+		C.wrap_fn_destroy(unsafe.Pointer(libcffmpeg), h.ffmpeg)
 	}
 }
 
@@ -92,5 +92,5 @@
 	in := C.CString(input)
 	defer C.free(unsafe.Pointer(in))
 
-	C.wrap_fn_run(h.ffmpeg, in)
+	C.wrap_fn_run(unsafe.Pointer(libcffmpeg), h.ffmpeg, in)
 }
diff --git a/gorec.go b/gorec.go
index 17bcfd8..eb44575 100644
--- a/gorec.go
+++ b/gorec.go
@@ -12,11 +12,11 @@
 func (h *GoFFMPEG) FireRecorder(sid string, id int64) {
 	csid := C.CString(sid)
 	defer C.free(unsafe.Pointer(csid))
-	C.wrap_fn_fire_recorder(h.ffmpeg, csid, C.long(id))
+	C.wrap_fn_fire_recorder(unsafe.Pointer(libcffmpeg), h.ffmpeg, csid, C.long(id))
 }
 
 // BuildRecorder build recorder
-func (h *GoFFMPEG) BuildRecorder(sid, output string, mind, maxd int, audio bool) {
+func (h *GoFFMPEG) BuildRecorder(sid, output string, id int64, mind, maxd int, audio bool) {
 	out := C.CString(output)
 	defer C.free(unsafe.Pointer(out))
 	csid := C.CString(sid)
@@ -26,7 +26,7 @@
 	if audio {
 		a = 1
 	}
-	C.wrap_fn_recorder(h.ffmpeg, csid, out, C.int(mind), C.int(maxd), C.int(a))
+	C.wrap_fn_recorder(unsafe.Pointer(libcffmpeg), h.ffmpeg, csid, out, C.long(id), C.int(mind), C.int(maxd), C.int(a))
 }
 
 // GetInfoRecorder info
@@ -39,7 +39,7 @@
 	var p *C.char
 	var pl C.int
 
-	C.wrap_fn_info_recorder(h.ffmpeg, &i, &id, &idl, &p, &pl)
+	C.wrap_fn_info_recorder(unsafe.Pointer(libcffmpeg), h.ffmpeg, &i, &id, &idl, &p, &pl)
 	// if p == nil {
 	// 	return -1, ""
 	// }
@@ -55,5 +55,5 @@
 
 // SetRecDurationForCache cache
 func (h *GoFFMPEG) SetRecDurationForCache(min, max int) {
-	C.wrap_fn_rec_duration(h.ffmpeg, C.int(min), C.int(max))
+	C.wrap_fn_rec_duration(unsafe.Pointer(libcffmpeg), h.ffmpeg, C.int(min), C.int(max))
 }
diff --git a/gostream.go b/gostream.go
index 6345ebd..dc94166 100644
--- a/gostream.go
+++ b/gostream.go
@@ -13,7 +13,7 @@
 	var key C.int
 	var size C.int
 
-	p := C.wrap_fn_get_avpacket(h.ffmpeg, &size, &key)
+	p := C.wrap_fn_get_avpacket(unsafe.Pointer(libcffmpeg), h.ffmpeg, &size, &key)
 	if size <= 0 {
 		return nil, 0, -1
 	}
diff --git a/libcffmpeg.c b/libcffmpeg.c
index 0486921..edc7b5c 100644
--- a/libcffmpeg.c
+++ b/libcffmpeg.c
@@ -17,58 +17,9 @@
 libcffmpeg init_libcffmpeg(const char *so_file){
     libcffmpeg lib = dlopen(so_file, RTLD_LAZY);
     if(lib){
-        fn_create = (lib_cffmpeg_create)dlsym(lib, "c_ffmpeg_create");
-        release_if_err(fn_create, lib);
-        fn_create2 = (lib_cffmpeg_create)dlsym(lib, "c_ffmpeg_create2");
-        release_if_err(fn_create2, lib);
 
         fn_destroy = (lib_cffmpeg_destroy)dlsym(lib, "c_ffmpeg_destroy");
         release_if_err(fn_destroy, lib);
-
-        fn_run = (lib_cffmpeg_run)dlsym(lib, "c_ffmpeg_run");
-        release_if_err(fn_run, lib);
-        fn_gb28181 = (lib_cffmpeg_gb28181)dlsym(lib, "c_ffmpeg_run_gb28181");
-        release_if_err(fn_gb28181, lib);
-
-        fn_cpu = (lib_cffmpeg_cpu)dlsym(lib, "c_ffmepg_use_cpu");
-        release_if_err(fn_cpu, lib);
-
-        fn_rec_duration = (lib_cffmpeg_rec_duration)dlsym(lib, "c_ffmpeg_set_record_duration");
-        release_if_err(fn_rec_duration, lib);
-        fn_recorder = (lib_cffmpeg_recorder)dlsym(lib, "c_ffmpeg_build_recorder");
-        release_if_err(fn_recorder, lib);
-        fn_fire_recorder = (lib_cffmpeg_fire_recorder)dlsym(lib, "c_ffmpeg_fire_recorder");
-        release_if_err(fn_fire_recorder, lib);
-        fn_info_recorder = (lib_cffmpeg_info_recorder)dlsym(lib, "c_ffmpeg_get_info_recorder");
-        release_if_err(fn_info_recorder, lib);
-
-        fn_decoder = (lib_cffmpeg_decoder)dlsym(lib, "c_ffmpeg_build_decoder");
-        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_decode = (lib_cffmpeg_decode)dlsym(lib, "c_ffmpeg_decode");
-        release_if_err(fn_decode, lib);
-
-        fn_create_encoder = (lib_cffmpeg_create_encoder)dlsym(lib, "c_ffmpeg_create_encoder");
-        release_if_err(fn_create_encoder, lib);
-        fn_destroy_encoder = (lib_cffmpeg_destroy_encoder)dlsym(lib, "c_ffmpeg_destroy_encoder");
-        release_if_err(fn_destroy_encoder, lib);
-        fn_encode = (lib_cffmpeg_encode)dlsym(lib, "c_ffmpeg_encode");
-        release_if_err(fn_encode, lib);
-
-        fn_create_conv = (lib_cffmpeg_create_conv)dlsym(lib, "c_ffmpeg_create_conv");
-        release_if_err(fn_create_conv, lib);
-        fn_destroy_conv = (lib_cffmpeg_destroy_conv)dlsym(lib, "c_ffmpeg_destroy_conv");
-        release_if_err(fn_destroy_conv, lib);
-        fn_conv = (lib_cffmpeg_conv)dlsym(lib, "c_ffmpeg_conv");
-        release_if_err(fn_conv, lib);
-
-        fn_gpu_conv = (lib_gpu_conv)dlsym(lib, "c_gpu_conv");
-        release_if_err(fn_gpu_conv, lib);
 
     }else{
         printf("dlopen - %s\n", dlerror());  
@@ -82,77 +33,140 @@
     }
 }
 
-cffmpeg wrap_fn_create(){
+cffmpeg wrap_fn_create(void *lib){
+    if (!fn_create){
+        fn_create = (lib_cffmpeg_create)dlsym(lib, "c_ffmpeg_create");
+        release_if_err(fn_create, lib);
+    }
+
     return fn_create();
 }
 
-cffmpeg wrap_fn_create2(const char *logfile){
+cffmpeg wrap_fn_create2(void *lib, const char *logfile){
+    if (!fn_create2){
+        fn_create2 = (lib_cffmpeg_create)dlsym(lib, "c_ffmpeg_create2");
+        release_if_err(fn_create2, lib);
+    }
     return fn_create2(logfile);
 }
 
-void wrap_fn_destroy(const cffmpeg h){
+void wrap_fn_destroy(void *lib, const cffmpeg h){
     fn_destroy(h);
 }
 
-void wrap_fn_run(const cffmpeg h, const char* input){
+void wrap_fn_run(void *lib, const cffmpeg h, const char* input){
+    if (!fn_run){
+        fn_run = (lib_cffmpeg_run)dlsym(lib, "c_ffmpeg_run");
+        if (!fn_run) return;
+    }
+
     fn_run(h, input);
 }
 
-void wrap_fn_run_gb28181(const cffmpeg h){
+void wrap_fn_run_gb28181(void *lib, const cffmpeg h){
+    if (!fn_gb28181){
+        fn_gb28181 = (lib_cffmpeg_gb28181)dlsym(lib, "c_ffmpeg_run_gb28181");
+        if (!fn_gb28181) return;
+    }
     fn_gb28181(h);
 }
 
-void wrap_fn_use_cpu(const cffmpeg h){
+void wrap_fn_use_cpu(void *lib, const cffmpeg h){
+    if (!fn_cpu){
+        fn_cpu = (lib_cffmpeg_cpu)dlsym(lib, "c_ffmepg_use_cpu");
+        if (!fn_cpu) return;
+    }
     fn_cpu(h);
 }
 
-void wrap_fn_recorder(const cffmpeg h, const char* id, const char* dir, int mind, int maxd, int audio){
-    fn_recorder(h, id, dir, mind, maxd, audio);
+void wrap_fn_recorder(void *lib, const cffmpeg h, const char* id, const char* dir, const int64_t fid, int mind, int maxd, int audio){
+    if (!fn_recorder){
+        fn_recorder = (lib_cffmpeg_recorder)dlsym(lib, "c_ffmpeg_build_recorder");
+        if (!fn_recorder) return;
+    }
+    fn_recorder(h, id, dir, fid, mind, maxd, audio);
 }
 
-void wrap_fn_rec_duration(const cffmpeg h, const int min, const int max){
+void wrap_fn_rec_duration(void *lib, const cffmpeg h, const int min, const int max){
+    if (!fn_rec_duration){
+        fn_rec_duration = (lib_cffmpeg_rec_duration)dlsym(lib, "c_ffmpeg_set_record_duration");
+        if (!fn_rec_duration) return;
+    }
     fn_rec_duration(h, min, max);
 }
 
-void wrap_fn_fire_recorder(const cffmpeg h, const char* sid, const int64_t id){
+void wrap_fn_fire_recorder(void *lib, const cffmpeg h, const char* sid, const int64_t id){
+    if (!fn_fire_recorder){
+        fn_fire_recorder = (lib_cffmpeg_fire_recorder)dlsym(lib, "c_ffmpeg_fire_recorder");
+        if (!fn_fire_recorder) return;
+    }
     fn_fire_recorder(h, sid, id);
 }
 
-void wrap_fn_info_recorder(const cffmpeg h, int* index, char** recid, int* recidLen, char** fpath, int* pathLen){
+void wrap_fn_info_recorder(void *lib, const cffmpeg h, int* index, char** recid, int* recidLen, char** fpath, int* pathLen){
+    if (!fn_info_recorder){
+        fn_info_recorder = (lib_cffmpeg_info_recorder)dlsym(lib, "c_ffmpeg_get_info_recorder");
+        if (!fn_info_recorder) return;
+    }
     return fn_info_recorder(h, index, recid, recidLen, fpath, pathLen);
 }
 
-void wrap_fn_decoder(const cffmpeg h){
+void wrap_fn_decoder(void *lib, const cffmpeg h){
+    if (!fn_decoder){
+        fn_decoder = (lib_cffmpeg_decoder)dlsym(lib, "c_ffmpeg_build_decoder");
+        if (!fn_decoder) return;
+    }
     fn_decoder(h);
 }
 
-void* wrap_fn_decoder_pic(const cffmpeg h, int *wid, int *hei, int *format, int *length, int64_t *id){
+void* wrap_fn_decoder_pic(void *lib, const cffmpeg h, int *wid, int *hei, int *format, int *length, int64_t *id){
+    if (!fn_decoder_pic){
+        fn_decoder_pic = (lib_cffmpeg_pic)dlsym(lib, "c_ffmpeg_get_pic_decoder");
+        release_if_err(fn_decoder_pic, lib);
+    }
     return fn_decoder_pic(h, wid, hei, format, length, id);
 }
 
-void* wrap_fn_get_avpacket(const cffmpeg h, int* size, int* key){
+void* wrap_fn_get_avpacket(void *lib, const cffmpeg h, int* size, int* key){
+    if(!fn_get_avpacket){
+        fn_get_avpacket = (lib_cffmpeg_avpacket)dlsym(lib, "c_ffmpeg_get_avpacket");
+        release_if_err(fn_get_avpacket, lib);
+    }
     return fn_get_avpacket(h, size, key);
 }
 
 // return val: -1 open error; -2, find stream error; -3, converter create error
-void* wrap_fn_decode(const char* file, const int gb, int* wid, int* hei){
+void* wrap_fn_decode(void *lib, const char* file, const int gb, int* wid, int* hei){
+    if (!fn_decode){
+        fn_decode = (lib_cffmpeg_decode)dlsym(lib, "c_ffmpeg_decode");
+        release_if_err(fn_decode, lib);
+    }
     return fn_decode(file, gb, wid, hei);
 }
 
-void* wran_fn_gpu_conv(void *in, const int w, const int h, const int dst_w, const int dst_h, int *length){
-    return fn_gpu_conv(in, w, h, dst_w, dst_h, length);
-}
-
 // for encoder
-cencoder wrap_fn_create_encoder(const int w, const int h, const int fps, const int br, const int scale_flag, const int gi){
+cencoder wrap_fn_create_encoder(void *lib, const int w, const int h, const int fps, const int br, const int scale_flag, const int gi){
+    if (!fn_create_encoder){
+        fn_create_encoder = (lib_cffmpeg_create_encoder)dlsym(lib, "c_ffmpeg_create_encoder");
+        release_if_err(fn_create_encoder, lib);
+    }
     return fn_create_encoder(w, h, fps, br, scale_flag, gi);
 }
 
-void wrap_fn_destroy_encoder(const cencoder h){
+void wrap_fn_destroy_encoder(void *lib, const cencoder h){
+    if (!fn_destroy_encoder){
+        fn_destroy_encoder = (lib_cffmpeg_destroy_encoder)dlsym(lib, "c_ffmpeg_destroy_encoder");
+        if(!fn_destroy_encoder) return;
+    }
     fn_destroy_encoder(h);
 }
 
-void* wrap_fn_encode(cencoder hdl, void *in, const int w, const int h, int *out_size, int *key){
+void* wrap_fn_encode(void *lib, cencoder hdl, void *in, const int w, const int h, int *out_size, int *key){
+    if (!fn_encode){
+        fn_encode = (lib_cffmpeg_encode)dlsym(lib, "c_ffmpeg_encode");
+        release_if_err(fn_encode, lib);
+    }
+    
     uint8_t *out = NULL;
     const int flag = fn_encode(hdl, (uint8_t*)in, w, h, &out, out_size, key);
     if (flag > 0 && out != NULL) {
@@ -164,14 +178,28 @@
 }
 
 // for conv
-cconv wrap_fn_create_conv(const int srcW, const int srcH, const int srcFormat,
+cconv wrap_fn_create_conv(void *lib, const int srcW, const int srcH, const int srcFormat,
                           const int dstW, const int dstH, const int dstFormat, const int flag){
+    if (!fn_create_conv){
+        fn_create_conv = (lib_cffmpeg_create_conv)dlsym(lib, "c_ffmpeg_create_conv");
+        release_if_err(fn_create_conv, lib);
+    }
     return fn_create_conv(srcW, srcH, srcFormat, dstW, dstH, dstFormat, flag);
 }
 
-void wrap_fn_destroy_conv(const cconv h){
+void wrap_fn_destroy_conv(void *lib, const cconv h){
+    if (!fn_destroy_conv){
+        fn_destroy_conv = (lib_cffmpeg_destroy_conv)dlsym(lib, "c_ffmpeg_destroy_conv");
+        if(!fn_destroy_conv) return;
+    }
     fn_destroy_conv(h);
 }
-void* wrap_fn_conv(const cconv h, uint8_t *in){
+
+void* wrap_fn_conv(void *lib, const cconv h, uint8_t *in){
+    if (!fn_conv){
+        fn_conv = (lib_cffmpeg_conv)dlsym(lib, "c_ffmpeg_conv");
+        release_if_err(fn_conv, lib);
+    }
+
     return fn_conv(h, in);
 }
diff --git a/libcffmpeg.h b/libcffmpeg.h
index 231ff64..10ebfd6 100644
--- a/libcffmpeg.h
+++ b/libcffmpeg.h
@@ -17,14 +17,13 @@
 typedef void (*lib_cffmpeg_gb28181)(const cffmpeg);
 typedef void (*lib_cffmpeg_cpu)(const cffmpeg);
 typedef void (*lib_cffmpeg_rec_duration)(const cffmpeg, const int, const int);
-typedef void (*lib_cffmpeg_recorder)(const cffmpeg, const char*, const char*, int, int, int);
+typedef void (*lib_cffmpeg_recorder)(const cffmpeg, const char*, const char*, const int64_t, int, int, int);
 typedef void (*lib_cffmpeg_fire_recorder)(const cffmpeg, const char*, const int64_t);
 typedef void (*lib_cffmpeg_info_recorder)(const cffmpeg, int*, char**, int*, char**, int*);
 typedef void (*lib_cffmpeg_decoder)(const cffmpeg);
 typedef void*(*lib_cffmpeg_pic)(const cffmpeg, int*, int*, int*, int*, int64_t*);
 typedef void*(*lib_cffmpeg_avpacket)(const cffmpeg, int*, int*);
 typedef void*(*lib_cffmpeg_decode)(const char*, const int, int*, int*);
-typedef void*(*lib_gpu_conv)(void*, const int, const int, const int, const int, int *);
 
 static lib_cffmpeg_create              fn_create = NULL;
 static lib_cffmpeg_create2             fn_create2 = NULL;
@@ -40,27 +39,25 @@
 static lib_cffmpeg_pic                 fn_decoder_pic = NULL;
 static lib_cffmpeg_avpacket            fn_get_avpacket = NULL;
 static lib_cffmpeg_decode              fn_decode = NULL;
-static lib_gpu_conv                    fn_gpu_conv = NULL;
 
 typedef void* libcffmpeg;
 libcffmpeg init_libcffmpeg(const char *so_file);
 void release_libcffmpeg(libcffmpeg lib);
 
-cffmpeg wrap_fn_create();
-cffmpeg wrap_fn_create2(const char *logfile);
-void wrap_fn_destroy(const cffmpeg h);
-void wrap_fn_run(const cffmpeg h, const char* input);
-void wrap_fn_run_gb28181(const cffmpeg h);
-void wrap_fn_use_cpu(const cffmpeg h);
-void wrap_fn_rec_duration(const cffmpeg h, const int min, const int max);
-void wrap_fn_recorder(const cffmpeg h, const char* id, const char* dir, int mind, int maxd, int audio);
-void wrap_fn_fire_recorder(const cffmpeg h, const char *sid, const int64_t id);
-void wrap_fn_info_recorder(const cffmpeg, int* index, char** recid, int* recidLen, char** fpath, int* pathLen);
-void wrap_fn_decoder(const cffmpeg h);
-void* wrap_fn_decoder_pic(const cffmpeg h, int *wid, int *hei, int *format, int *length, int64_t *id);
-void* wrap_fn_get_avpacket(const cffmpeg h, int* size, int* key);
-void* wrap_fn_decode(const char* file, const int gb, int* wid, int* hei);
-void* wran_fn_gpu_conv(void *in, const int w, const int h, const int dst_w, const int dst_h, int *length);
+cffmpeg wrap_fn_create(void *lib);
+cffmpeg wrap_fn_create2(void *lib, const char *logfile);
+void wrap_fn_destroy(void *lib, const cffmpeg h);
+void wrap_fn_run(void *lib, const cffmpeg h, const char* input);
+void wrap_fn_run_gb28181(void *lib, const cffmpeg h);
+void wrap_fn_use_cpu(void *lib, const cffmpeg h);
+void wrap_fn_rec_duration(void *lib, const cffmpeg h, const int min, const int max);
+void wrap_fn_recorder(void *lib, const cffmpeg h, const char* id, const char* dir, const int64_t fid, int mind, int maxd, int audio);
+void wrap_fn_fire_recorder(void *lib, const cffmpeg h, const char *sid, const int64_t id);
+void wrap_fn_info_recorder(void *lib, const cffmpeg, int* index, char** recid, int* recidLen, char** fpath, int* pathLen);
+void wrap_fn_decoder(void *lib, const cffmpeg h);
+void* wrap_fn_decoder_pic(void *lib, const cffmpeg h, int *wid, int *hei, int *format, int *length, int64_t *id);
+void* wrap_fn_get_avpacket(void *lib, const cffmpeg h, int* size, int* key);
+void* wrap_fn_decode(void *lib, const char* file, const int gb, int* wid, int* hei);
 // for encoder
 typedef void* cencoder;
 typedef cencoder (*lib_cffmpeg_create_encoder)(const int w, const int h, const int fps, const int br, const int scale_flag, const int gi);
@@ -71,9 +68,9 @@
 static lib_cffmpeg_destroy_encoder fn_destroy_encoder = NULL;
 static lib_cffmpeg_encode fn_encode = NULL;
 
-cencoder wrap_fn_create_encoder(const int w, const int h, const int fps, const int br, const int scale_flag, const int gi);
-void wrap_fn_destroy_encoder(const cencoder h);
-void* wrap_fn_encode(cencoder hdl, void *in, const int w, const int h, int *out_size, int *key);
+cencoder wrap_fn_create_encoder(void *lib, const int w, const int h, const int fps, const int br, const int scale_flag, const int gi);
+void wrap_fn_destroy_encoder(void *lib, const cencoder h);
+void* wrap_fn_encode(void *lib, cencoder hdl, void *in, const int w, const int h, int *out_size, int *key);
 
 
 // for conv
@@ -86,10 +83,10 @@
 static lib_cffmpeg_destroy_conv fn_destroy_conv = NULL;
 static lib_cffmpeg_conv fn_conv = NULL;
 
-cconv wrap_fn_create_conv(const int srcW, const int srcH, const int srcFormat,
+cconv wrap_fn_create_conv(void *lib, const int srcW, const int srcH, const int srcFormat,
                           const int dstW, const int dstH, const int dstFormat, const int flag);
-void wrap_fn_destroy_conv(const cconv h);
-void* wrap_fn_conv(const cconv h, uint8_t *in);
+void wrap_fn_destroy_conv(void *lib, const cconv h);
+void* wrap_fn_conv(void *lib, const cconv h, uint8_t *in);
 
 #ifdef __cplusplus
 }

--
Gitblit v1.8.0