compatible to local files
| | |
| | | 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); |
| | |
| | | } |
| | | 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){ |
| | |
| | | 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()); |
| | | |
| | |
| | | memcpy(rid, id.c_str(), *recidLen); |
| | | rid[*recidLen] = '\0'; |
| | | *recid = rid; |
| | | return ret; |
| | | } |
| | | |
| | | void c_ffmpeg_build_decoder(const cffmpeg h){ |
| | |
| | | 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){ |
| | |
| | | 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); |
| | |
| | | } |
| | | |
| | | void decoder::GetFrame(unsigned char **data, int *w, int *h, int *format, int *length, int64_t *id){ |
| | | *data = NULL; |
| | | *length = 0; |
| | | |
| | | AVFrame *frame = NULL; |
| | | |
| | |
| | | ,logit_(false) |
| | | ,fps_(25) |
| | | ,file_finished_(false) |
| | | ,min_duration_(60) |
| | | { |
| | | makeTheWorld(); |
| | | } |
| | |
| | | ,logit_(true) |
| | | ,fps_(25) |
| | | ,file_finished_(false) |
| | | ,min_duration_(60) |
| | | { |
| | | makeTheWorld(); |
| | | logif::CreateLogger(logfile, true); |
| | |
| | | |
| | | void Wrapper::run_stream_thread(){ |
| | | |
| | | int64_t rebootime = -1; |
| | | |
| | | while(!stop_stream_.load()){ |
| | | auto in = init_reader(input_url_.c_str()); |
| | | |
| | |
| | | sleep(2); |
| | | continue; |
| | | } |
| | | |
| | | rebootime++; |
| | | |
| | | fps_ = in->getFPS(); |
| | | |
| | |
| | | if (exist){ |
| | | wTime <<= 1; |
| | | } |
| | | int64_t file_frame = 0; |
| | | |
| | | logIt("WAIT TIME PER FRAME: %d", wTime); |
| | | |
| | |
| | | if (in->notVideoAudio(&data->getAVPacket())){ |
| | | continue; |
| | | } |
| | | |
| | | // 非国标跳过第一帧,测试第一帧有问题 |
| | | if (!gb_ && id < 0){ |
| | | id++; v_id++; a_id++; |
| | |
| | | //本地文件太快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(){ |
| | |
| | | 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 |
| | |
| | | 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: |
| | |
| | | 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, |
| | |
| | | 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 |
| | |
| | | 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)) |
| | | } |
| | |
| | | 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)) |
| | |
| | | |
| | | // 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 |
| | | } |
| | |
| | | } |
| | | |
| | | // 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 |
| | |
| | | // 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)) |
| | | } |
| | |
| | | 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; |
| | |
| | | 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){ |
| | |
| | | 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){ |
| | |
| | | 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; |
| | |
| | | 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); |
| | |
| | | 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); |