video analysis2.0拆分,ffmpeg封装go接口库
554325746@qq.com
2020-03-10 278634c0d2eeba9e3fcc3b4cd56ddfb3323277d7
compatible to local files
10个文件已修改
182 ■■■■■ 已修改文件
cffmpeg.h 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
csrc/cffmpeg.cpp 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
csrc/worker/decoder.cpp 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
csrc/wrapper.cpp 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
csrc/wrapper.hpp 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
godec.go 34 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
goffmpeg.go 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
gorec.go 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
libcffmpeg.c 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
libcffmpeg.h 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
cffmpeg.h
@@ -23,13 +23,14 @@
void c_ffmpeg_open_recorder(const cffmpeg h);
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, 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);
int c_ffmpeg_fire_recorder(const cffmpeg h, const char*sid, const int64_t id);
int c_ffmpeg_get_info_recorder(const cffmpeg h, int *index, char** recid, int *recidLen, char **fpath, int *pathLen);
void c_ffmpeg_build_decoder(const cffmpeg h);
void* c_ffmpeg_get_pic_decoder(const cffmpeg h, int *wid, int *hei, int *format, int *length, int64_t *id);
int c_ffmpeg_get_pic_decoder(const cffmpeg h, unsigned char **data, int *wid, int *hei, int *format, int *length, int64_t *id);
void c_ffmpeg_close_stream(const cffmpeg h);
void* c_ffmpeg_get_avpacket(const cffmpeg h, int *size, int *key);
int c_ffmpeg_get_avpacket2(const cffmpeg h, unsigned char **data, int *size, int *key);
// pic encoder
void *c_ffmpeg_create_encoder(const int w, const int h, const int fps, const int br, const int pix_fmt, const int scale_flag, const int gi);
csrc/cffmpeg.cpp
@@ -68,7 +68,7 @@
}
void c_ffmpeg_set_record_duration(const cffmpeg h, const int min, const int max){
    Wrapper *s = (Wrapper*)h;
    s->SetRecMinCacheTime(min);
    s->SetRecMinCacheTime(min, max);
}
void c_ffmpeg_build_recorder(const cffmpeg h, const char* id, const char *dir, const int64_t fid, int mind, int maxd, int audio){
@@ -78,16 +78,16 @@
    s->BuildRecorder(id, dir, fid, mind, maxd, a);
}
void c_ffmpeg_fire_recorder(const cffmpeg h, const char* sid, const int64_t id){
int c_ffmpeg_fire_recorder(const cffmpeg h, const char* sid, const int64_t id){
    Wrapper *s = (Wrapper*)h;
    s->FireRecorder(sid, id);
    return s->FireRecorder(sid, id);
}
void c_ffmpeg_get_info_recorder(const cffmpeg h, int *index, char** recid, int *recidLen, char **fpath, int *pathLen){
int c_ffmpeg_get_info_recorder(const cffmpeg h, int *index, char** recid, int *recidLen, char **fpath, int *pathLen){
    Wrapper *s = (Wrapper*)h;
    int i;
    std::string p(""), id("");
    s->GetInfoRecorder(id, i, p);
    int ret = s->GetInfoRecorder(id, i, p);
    // printf("cffmpeg get info : index : %d, file : %s, recid: %s\n", i, p.c_str(), id.c_str());
@@ -104,6 +104,7 @@
    memcpy(rid, id.c_str(), *recidLen);
    rid[*recidLen] = '\0';
    *recid = rid;    
    return ret;
}
void c_ffmpeg_build_decoder(const cffmpeg h){
@@ -111,11 +112,9 @@
    s->OpenDecoder();
}
void* c_ffmpeg_get_pic_decoder(const cffmpeg h, int *wid, int *hei, int *format, int *length, int64_t *id){
int c_ffmpeg_get_pic_decoder(const cffmpeg h, unsigned char **data, int *wid, int *hei, int *format, int *length, int64_t *id){
    Wrapper *s = (Wrapper*)h;
    unsigned char *data = NULL;
    s->GetPicDecoder(&data, wid, hei, format, length, id);
    return data;
    return s->GetPicDecoder(data, wid, hei, format, length, id);
}
void c_ffmpeg_close_stream(const cffmpeg h){
@@ -130,6 +129,11 @@
    return data;
}
int c_ffmpeg_get_avpacket2(const cffmpeg h, unsigned char **data, int *size, int *key){
    Wrapper *s = (Wrapper*)h;
    return s->GetPacket(data, size, key);
}
// pic encoder
void *c_ffmpeg_create_encoder(const int w, const int h, const int fps, const int br, const int pix_fmt, const int scale_flag, const int gi){
    return CreateEncoder(w, h, fps, br, pix_fmt, scale_flag, gi);
csrc/worker/decoder.cpp
@@ -65,6 +65,8 @@
    }
    void decoder::GetFrame(unsigned char **data, int *w, int *h, int *format, int *length, int64_t *id){
        *data = NULL;
        *length = 0;
        AVFrame *frame = NULL;
csrc/wrapper.cpp
@@ -56,6 +56,7 @@
    ,logit_(false)
    ,fps_(25)
    ,file_finished_(false)
    ,min_duration_(60)
    {
        makeTheWorld();
    }
@@ -76,6 +77,7 @@
    ,logit_(true)
    ,fps_(25)
    ,file_finished_(false)
    ,min_duration_(60)
    {
        makeTheWorld();
        logif::CreateLogger(logfile, true);
@@ -191,6 +193,8 @@
    void Wrapper::run_stream_thread(){
        
        int64_t rebootime = -1;
        while(!stop_stream_.load()){
            auto in = init_reader(input_url_.c_str());
            
@@ -199,6 +203,8 @@
                sleep(2);
                continue;
            }
            rebootime++;
            fps_ = in->getFPS();
            
@@ -219,6 +225,7 @@
            if (exist){
                wTime <<= 1;
            }
            int64_t file_frame = 0;
            logIt("WAIT TIME PER FRAME: %d", wTime);
@@ -232,6 +239,7 @@
                if (in->notVideoAudio(&data->getAVPacket())){
                    continue;
                }
                // 非国标跳过第一帧,测试第一帧有问题
                if (!gb_ && id < 0){
                    id++; v_id++; a_id++;
@@ -254,21 +262,30 @@
                //本地文件太快sleep一下
                if (exist){
                    usleep(wTime);
                    // 记录解码的文件有多少帧
                    file_frame++;
                }
            }
            deinit_worker();
            if (exist) {
                logIt("local file exist");
                if (file_frame == 0 && rebootime > 3){
                    file_finished_ = true;
                    break;
                }
                if (file_frame < min_duration_ * fps_){
                    continue;
                }
                logIt("libcffmpeg.so-> local file %s run %lld time, all frames %lld", input_url_.c_str(), rebootime, file_frame);
                file_finished_ = true;
                break;
            }
        }
    }
    void Wrapper::SetRecMinCacheTime(const int mind){
        rec_->SetRecMinCacheTime(mind);
    void Wrapper::SetRecMinCacheTime(const int mind, const int maxd){
        min_duration_ = mind;
    }
    void Wrapper::OpenRecorder(){
@@ -291,41 +308,39 @@
        if (rec_->Loaded()){
            rec_->FireRecSignal(sid, id);
        }
        return 0;
    }
    void Wrapper::GetInfoRecorder(std::string &recID, int &index, std::string &path){
    int Wrapper::GetInfoRecorder(std::string &recID, int &index, std::string &path){
        if (rec_){
            rec_->GetRecInfo(recID, index, path);
        }
        return 0;
    }
    ////////decoder
    void Wrapper::OpenDecoder(){
        run_dec_ = true;
    }
    void Wrapper::GetPicDecoder(unsigned char **data, int *w, int *h, int *format, int *length, int64_t *id){
    int Wrapper::GetPicDecoder(unsigned char **data, int *w, int *h, int *format, int *length, int64_t *id){
        if (file_finished_){
            *data = (unsigned char*)this;
            *w = 1080;
            *h = 720;
            *format = 23;
            *length = 12;
            *id = -10802020;
            return;
            return -1;
        }
        if (decoder_){
            decoder_->GetFrame(data, w, h, format, length, id);
        }
        return 0;
    }
    
    void Wrapper::CloseStream(){
        run_stream_ = false;
    }
    void Wrapper::GetPacket(unsigned char **pktData, int *size, int *key){
    int Wrapper::GetPacket(unsigned char **pktData, int *size, int *key){
        if (stream_){
            stream_->GetPacket(pktData, size, key);
        }
        return 0;
    }
} // end class wrapper
csrc/wrapper.hpp
@@ -43,21 +43,21 @@
    public: //recorder
        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);
        int GetInfoRecorder(std::string &recID, int &index, std::string &path);
    
    public:
        void GB28181(){gb_ = 1;}
        void CPUDec(){cpu_ = 1;}
        void AudioSwitch(const bool a);
        void SetRecMinCacheTime(const int mind);
        void SetRecMinCacheTime(const int mind, const int maxd);
        int GetFPS(){return fps_;}
    public: //decoder
        void OpenDecoder();
        void GetPicDecoder(unsigned char **data, int *w, int *h, int *format, int *length, int64_t *id);
        int GetPicDecoder(unsigned char **data, int *w, int *h, int *format, int *length, int64_t *id);
    public: // push stream
        void CloseStream();
        void GetPacket(unsigned char **pktData, int *size, int *key);
        int GetPacket(unsigned char **pktData, int *size, int *key);
    public: // recorder
        void OpenRecorder();
    private:
@@ -82,7 +82,9 @@
        std::function<void()> fn_rec_lazy_;
        bool logit_;
        int fps_;
        // 为兼容文件解码做的补丁
        bool file_finished_;
        int min_duration_;
    };
    void *CreateEncoder(const int w, const int h, const int fps, const int br, 
godec.go
@@ -18,13 +18,20 @@
    var length C.int
    var srcW, srcH, srcF C.int
    p := C.wrap_fn_decoder_pic(unsafe.Pointer(libcffmpeg), h.ffmpeg, &srcW, &srcH, &srcF, &length, &fid)
    if p == nil || length == 0 || srcW == 0 || srcH == 0 {
    var yuv *C.uchar
    r := C.wrap_fn_decoder_pic(unsafe.Pointer(libcffmpeg), h.ffmpeg, &yuv, &srcW, &srcH, &srcF, &length, &fid)
    if r < 0 {
        return nil, int(r), int(r), int64(r)
    }
    if yuv == nil || length == 0 || srcW == 0 || srcH == 0 {
        return nil, 0, 0, 0
    }
    defer C.free(unsafe.Pointer(p))
    return C.GoBytes(p, length), int(srcW), int(srcH), int64(fid)
    defer C.free(unsafe.Pointer(yuv))
    return C.GoBytes(yuv, length), int(srcW), int(srcH), int64(fid)
}
// GetYUV2 get yuv data
@@ -33,13 +40,26 @@
    var length C.int
    var srcW, srcH, srcF C.int
    p := C.wrap_fn_decoder_pic(unsafe.Pointer(libcffmpeg), h.ffmpeg, &srcW, &srcH, &srcF, &length, &fid)
    if p == nil || length == 0 || srcW == 0 || srcH == 0 {
        return nil, nil, 0, 0, 0
    var yuv *C.uchar
    r := C.wrap_fn_decoder_pic(unsafe.Pointer(libcffmpeg), h.ffmpeg, &yuv, &srcW, &srcH, &srcF, &length, &fid)
    if r < 0 {
        return nil, int(r), int(r), int64(r)
    }
    if yuv == nil || length == 0 || srcW == 0 || srcH == 0 {
        return nil, 0, 0, 0
    }
    const maxLen = 0x7fffffff
    size := int(length)
    data := (*[maxLen]byte)(unsafe.Pointer(p))[:size:size]
    return unsafe.Pointer(p), data, int(srcW), int(srcH), int64(fid)
}
// SetDecMinDuration min duration
// 主要是如果解码文件时长太短,可能在sdk收到解码数据前解码进程运行结束,所以设定一个最短的duration
func (h *GoFFMPEG) SetDecMinDuration(min, max int) {
    C.wrap_fn_rec_duration(unsafe.Pointer(libcffmpeg), h.ffmpeg, C.int(min), C.int(max))
}
goffmpeg.go
@@ -128,6 +128,14 @@
    C.wrap_fn_run(unsafe.Pointer(libcffmpeg), h.ffmpeg, in)
}
// Run2 ffmpeg
func (h *GoFFMPEG) Run2(input string, minDuration int) {
    in := C.CString(input)
    defer C.free(unsafe.Pointer(in))
    C.wrap_fn_run(unsafe.Pointer(libcffmpeg), h.ffmpeg, in)
}
// FPS fps
func (h *GoFFMPEG) FPS() int {
    return int(C.wrap_fn_fps(unsafe.Pointer(libcffmpeg), h.ffmpeg))
@@ -143,13 +151,13 @@
// GetGBJpg Get GB28181 Jpg
func GetGBJpg(rtspUrl string) []byte {
    rtsp := C.CString(rtspUrl)
    defer C.free(unsafe.Pointer(rtsp))
    var jpgLen C.int
    rtsp := C.CString(rtspUrl)
    defer C.free(unsafe.Pointer(rtsp))
    var jpgLen C.int
    pic := C.wrap_fn_get_gb28181_pic(unsafe.Pointer(libcffmpeg), rtsp, &jpgLen)
    defer C.free(unsafe.Pointer(pic))
    pic := C.wrap_fn_get_gb28181_pic(unsafe.Pointer(libcffmpeg), rtsp, &jpgLen)
    defer C.free(unsafe.Pointer(pic))
    retJpg := C.GoBytes(unsafe.Pointer(pic), jpgLen)
    return retJpg
}
    retJpg := C.GoBytes(unsafe.Pointer(pic), jpgLen)
    return retJpg
}
gorec.go
@@ -14,10 +14,11 @@
}
// FireRecorder fire recorder
func (h *GoFFMPEG) FireRecorder(sid string, id int64) {
func (h *GoFFMPEG) FireRecorder(sid string, id int64) int {
    csid := C.CString(sid)
    defer C.free(unsafe.Pointer(csid))
    C.wrap_fn_fire_recorder(unsafe.Pointer(libcffmpeg), h.ffmpeg, csid, C.long(id))
    ret := C.wrap_fn_fire_recorder(unsafe.Pointer(libcffmpeg), h.ffmpeg, csid, C.long(id))
    return int(ret)
}
// BuildRecorder build recorder
@@ -56,9 +57,4 @@
    // fmt.Println("Go get info : ", path, " len: ", l)
    return gID, int(i), path
}
// SetRecDurationForCache cache
func (h *GoFFMPEG) SetRecDurationForCache(min, max int) {
    C.wrap_fn_rec_duration(unsafe.Pointer(libcffmpeg), h.ffmpeg, C.int(min), C.int(max))
}
libcffmpeg.c
@@ -122,15 +122,15 @@
    fn_rec_duration(h, min, max);
}
void wrap_fn_fire_recorder(void *lib, const cffmpeg h, const char* sid, const int64_t id){
int 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);
    return fn_fire_recorder(h, sid, id);
}
void wrap_fn_info_recorder(void *lib, const cffmpeg h, int* index, char** recid, int* recidLen, char** fpath, int* pathLen){
int 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;
@@ -146,12 +146,12 @@
    fn_decoder(h);
}
void* wrap_fn_decoder_pic(void *lib, const cffmpeg h, int *wid, int *hei, int *format, int *length, int64_t *id){
int wrap_fn_decoder_pic(void *lib, const cffmpeg h, unsigned char** data, 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);
    return fn_decoder_pic(h, data, wid, hei, format, length, id);
}
void wrap_fn_close_stream(void *lib, const cffmpeg h){
@@ -170,6 +170,13 @@
    return fn_get_avpacket(h, size, key);
}
int wrap_fn_get_avpacket2(void *lib, const cffmpeg h, unsigned char **data, int* size, int* key){
    if(!fn_get_avpacket2){
        fn_get_avpacket2 = (lib_cffmpeg_avpacket2)dlsym(lib, "c_ffmpeg_get_avpacket2");
        release_if_err(fn_get_avpacket2, lib);
    }
    return fn_get_avpacket2(h, data, size, key);
}
// for encoder
cencoder wrap_fn_create_encoder(void *lib, const int w, const int h, const int fps, const int br, const int pix_fmt, const int scale_flag, const int gi){
    if (!fn_create_encoder){
libcffmpeg.h
@@ -21,12 +21,13 @@
typedef void (*lib_cffmpeg_open_recorder)(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*, 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 int (*lib_cffmpeg_fire_recorder)(const cffmpeg, const char*, const int64_t);
typedef int (*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 int (*lib_cffmpeg_pic)(const cffmpeg, unsigned char**, int*, int*, int*, int*, int64_t*);
typedef void (*lib_cffmpeg_close_stream)(const cffmpeg);
typedef void*(*lib_cffmpeg_avpacket)(const cffmpeg, int*, int*);
typedef int (*lib_cffmpeg_avpacket2)(const cffmpeg, unsigned char**, int*, int*);
static lib_cffmpeg_create              fn_create = NULL;
static lib_cffmpeg_create2             fn_create2 = NULL;
@@ -45,6 +46,7 @@
static lib_cffmpeg_pic                 fn_decoder_pic = NULL;
static lib_cffmpeg_close_stream        fn_close_stream = NULL;
static lib_cffmpeg_avpacket            fn_get_avpacket = NULL;
static lib_cffmpeg_avpacket2            fn_get_avpacket2 = NULL;
typedef void* libcffmpeg;
libcffmpeg init_libcffmpeg(const char *so_file);
@@ -61,12 +63,13 @@
void wrap_fn_open_rec(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);
int wrap_fn_fire_recorder(void *lib, const cffmpeg h, const char *sid, const int64_t id);
int 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);
int wrap_fn_decoder_pic(void *lib, const cffmpeg h, unsigned char** data, int *wid, int *hei, int *format, int *length, int64_t *id);
void wrap_fn_close_stream(void *lib, const cffmpeg h);
void* wrap_fn_get_avpacket(void *lib, const cffmpeg h, int* size, int* key);
int wrap_fn_get_avpacket2(void *lib, const cffmpeg h, unsigned char **data, int* size, int* key);
// 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 pix_fmt, const int scale_flag, const int gi);