update ffmpeg decode and audio rec
| | |
| | | void* c_ffmpeg_get_avpacket(const cffmpeg h, int *size, int *key); |
| | | |
| | | //////test |
| | | void* c_ffmpeg_decode_jpeg(const char *file, int *wid, int *hei); |
| | | void* c_ffmpeg_decode(const char *file, const int gb, int *wid, int *hei); |
| | | |
| | | // pic encoder |
| | | void *c_ffmpeg_create_encoder(const int w, const int h, const int fps, const int br, const int scale_flag, const int gi); |
| | |
| | | } |
| | | |
| | | /////////////////////test |
| | | void* c_ffmpeg_decode_jpeg(const char *file, int *wid, int *hei){ |
| | | uint8_t *p = DecodeJPEG(file, wid, hei); |
| | | if(!p){ |
| | | *wid = *hei = 0; |
| | | } |
| | | return p; |
| | | void* c_ffmpeg_decode(const char *file, const int gb, int *wid, int *hei){ |
| | | return Decode(file, gb, wid, hei); |
| | | } |
| | | |
| | | // pic encoder |
| | |
| | | } // end class wrapper |
| | | /////////////////////////////////////////////////////////// |
| | | ///single decode or encoder |
| | | ////// decoder |
| | | ////// decoder |
| | | |
| | | #include "ffmpeg/data/FrameData.hpp" |
| | | |
| | | // return val: -1 open error; -2, find stream error; -3, converter create |
| | | namespace cffmpeg_wrap{ // start test functions |
| | | uint8_t* DecodeJPEG(const char *file, int *w, int *h){ |
| | | uint8_t* Decode(const char *file, const int gb, int *w, int *h){ |
| | | VideoProp prop; |
| | | prop.url_ = file; |
| | | prop.gpu_acc_ = false; |
| | | |
| | | std::unique_ptr<FormatIn> in(new FormatIn(prop.gpuAccl())); |
| | | int flag = in->open(file, NULL); |
| | | |
| | | int flag = -1; |
| | | if (gb){ |
| | | flag = in->openGb28181(file, NULL); |
| | | }else{ |
| | | flag = in->open(file, NULL); |
| | | } |
| | | |
| | | std::unique_ptr<cvbridge> bridge_(nullptr); |
| | | |
| | | if(flag == 0){ |
| | | if(!in->findStreamInfo(NULL)){ |
| | | logIt("yolo can't find video stream\n"); |
| | | *w = *h = -2; |
| | | return NULL; |
| | | } |
| | | auto flag = in->openCodec(NULL); |
| | |
| | | |
| | | }else{ |
| | | logIt("FormatIn openCodec Failed!"); |
| | | *w = *h = -3; |
| | | return NULL; |
| | | } |
| | | }else{ |
| | | logIt("open %s error", file); |
| | | *w = *h = -1; |
| | | return NULL; |
| | | } |
| | | |
| | | uint8_t *data = NULL; |
| | | AVPacket *pkt = av_packet_alloc(); |
| | | if(in->readPacket(pkt) == 0){ |
| | | AVFrame *frm = av_frame_alloc(); |
| | | if(in->decode(frm, pkt) == 0){ |
| | | *w = frm->width; |
| | | *h = frm->height; |
| | | data = (unsigned char*)malloc(frm->width * frm->height * 3); |
| | | bridge_->copyPicture(data, frm); |
| | | uint8_t *pic = NULL; |
| | | |
| | | int tryTime = 0; |
| | | while (tryTime++ < 100){ |
| | | |
| | | auto data(std::make_shared<CodedData>()); |
| | | if (in->readPacket(&data->getAVPacket()) == 0){ |
| | | |
| | | auto frame(std::make_shared<FrameData>()); |
| | | AVFrame *frm = frame->getAVFrame(); |
| | | if(in->decode(frm, &data->getAVPacket()) == 0){ |
| | | *w = frm->width; |
| | | *h = frm->height; |
| | | pic = (unsigned char*)malloc(frm->width * frm->height * 3); |
| | | bridge_->copyPicture(pic, frm); |
| | | break; |
| | | } |
| | | } |
| | | av_frame_free(&frm); |
| | | av_packet_free(&pkt); |
| | | } |
| | | return data; |
| | | |
| | | return pic; |
| | | } |
| | | /////// for encoder |
| | | typedef struct _PicEncoder{ |
| | |
| | | std::function<void(ffwrapper::FormatIn*)> fn_rec_lazy_; |
| | | }; |
| | | |
| | | uint8_t *DecodeJPEG(const char *file, int *w, int *h); |
| | | uint8_t* Decode(const char *file, const int gb, int *w, int *h); |
| | | void *CreateEncoder(const int w, const int h, const int fps, const int br, const int scale_flag, const int gi); |
| | | void DestroyEncoder(void *h); |
| | | int Encode(void *hdl, uint8_t *in, const int w, const int h, uint8_t **out, int *size, int *key); |
| | |
| | | C.wrap_fn_run(h.ffmpeg, in) |
| | | } |
| | | |
| | | // DecodeJPEG decode jpeg file |
| | | func DecodeJPEG(input string) ([]byte, int, int) { |
| | | in := C.CString(input) |
| | | defer C.free(unsafe.Pointer(in)) |
| | | |
| | | var width C.int |
| | | var height C.int |
| | | p := C.wrap_fn_decode_jpeg(in, &width, &height) |
| | | defer C.free(p) |
| | | |
| | | if width > 0 && height > 0 { |
| | | data := C.GoBytes(p, width*height*3) |
| | | wid := int(width) |
| | | hei := int(height) |
| | | return data, wid, hei |
| | | } |
| | | return nil, 0, 0 |
| | | } |
| | | |
| | | // FireRecorder fire recorder |
| | | func (h *GoFFMPEG) FireRecorder(sid string, id int64) { |
| | | csid := C.CString(sid) |
| | |
| | | } |
| | | |
| | | // BuildRecorder build recorder |
| | | func (h *GoFFMPEG) BuildRecorder(sid, output string, mind, maxd, audio int) { |
| | | func (h *GoFFMPEG) BuildRecorder(sid, output string, mind, maxd int, audio bool) { |
| | | out := C.CString(output) |
| | | defer C.free(unsafe.Pointer(out)) |
| | | csid := C.CString(sid) |
| | | defer C.free(unsafe.Pointer(csid)) |
| | | |
| | | C.wrap_fn_recorder(h.ffmpeg, csid, out, C.int(mind), C.int(maxd), C.int(audio)) |
| | | a := 0 |
| | | if audio { |
| | | a = 1 |
| | | } |
| | | C.wrap_fn_recorder(h.ffmpeg, csid, out, C.int(mind), C.int(maxd), C.int(a)) |
| | | } |
| | | |
| | | // GetInfoRecorder info |
| | |
| | | return d, s, k |
| | | } |
| | | |
| | | /////////////// for decoder |
| | | |
| | | // Decode decode jpeg file |
| | | // return val: -1 open error; -2, find stream error; -3, converter create error |
| | | func Decode(input string, gb bool) ([]byte, int, int) { |
| | | in := C.CString(input) |
| | | defer C.free(unsafe.Pointer(in)) |
| | | |
| | | withGB := 0 |
| | | if gb { |
| | | withGB = 1 |
| | | } |
| | | |
| | | var width C.int |
| | | var height C.int |
| | | p := C.wrap_fn_decode(in, C.int(withGB), &width, &height) |
| | | defer C.free(p) |
| | | |
| | | if width > 0 && height > 0 { |
| | | data := C.GoBytes(p, width*height*3) |
| | | wid := int(width) |
| | | hei := int(height) |
| | | return data, wid, hei |
| | | } |
| | | return nil, int(width), int(height) |
| | | } |
| | | |
| | | ///////////////for encoder |
| | | |
| | | // GoEncoder encoder |
| | |
| | | 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_dec_jpeg = (lib_cffmpeg_decode_jpeg)dlsym(lib, "c_ffmpeg_decode_jpeg"); |
| | | release_if_err(fn_dec_jpeg, 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); |
| | |
| | | return fn_get_avpacket(h, size, key); |
| | | } |
| | | |
| | | void* wrap_fn_decode_jpeg(const char* file, int* wid, int* hei){ |
| | | return fn_dec_jpeg(file, wid, hei); |
| | | // 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){ |
| | | return fn_decode(file, gb, wid, hei); |
| | | } |
| | | |
| | | // for encoder |
| | |
| | | typedef void (*lib_cffmpeg_decoder)(const cffmpeg); |
| | | typedef void*(*lib_cffmpeg_pic)(const cffmpeg, int*, int*, int64_t*); |
| | | typedef void*(*lib_cffmpeg_avpacket)(const cffmpeg, int*, int*); |
| | | typedef void*(*lib_cffmpeg_decode_jpeg)(const char*, int*, int*); |
| | | typedef void*(*lib_cffmpeg_decode)(const char*, const int, int*, int*); |
| | | |
| | | static lib_cffmpeg_create fn_create = NULL; |
| | | static lib_cffmpeg_destroy fn_destroy = NULL; |
| | |
| | | static lib_cffmpeg_decoder fn_decoder = NULL; |
| | | static lib_cffmpeg_pic fn_decoder_pic = NULL; |
| | | static lib_cffmpeg_avpacket fn_get_avpacket = NULL; |
| | | static lib_cffmpeg_decode_jpeg fn_dec_jpeg = NULL; |
| | | static lib_cffmpeg_decode fn_decode = NULL; |
| | | |
| | | typedef void* libcffmpeg; |
| | | libcffmpeg init_libcffmpeg(const char *so_file); |
| | |
| | | void wrap_fn_decoder(const cffmpeg h); |
| | | void* wrap_fn_decoder_pic(const cffmpeg h, int* wid, int* hei, int64_t *id); |
| | | void* wrap_fn_get_avpacket(const cffmpeg h, int* size, int* key); |
| | | void* wrap_fn_decode_jpeg(const char* file, int* wid, int* hei); |
| | | void* wrap_fn_decode(const char* file, const int gb, int* wid, int* hei); |
| | | |
| | | |
| | | // for encoder |