video analysis2.0拆分,ffmpeg封装go接口库
zhangmeng
2019-10-21 c60d61c48c7a1e7b693d4c3f6427e3b616d1f471
update ffmpeg
15个文件已修改
353 ■■■■ 已修改文件
cffmpeg.h 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
csrc/cffmpeg.cpp 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
csrc/worker/rec.cpp 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
csrc/worker/rec.hpp 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
csrc/wrapper.cpp 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
csrc/wrapper.hpp 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
goconv.go 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
godec.go 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
godecjpeg.go 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
goenc.go 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
goffmpeg.go 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
gorec.go 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
gostream.go 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
libcffmpeg.c 176 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
libcffmpeg.h 45 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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
}
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);
}
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(){
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);
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);
    }
}
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
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 {
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
    }
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 {
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)
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)
}
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))
}
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
    }
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);
}
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
}