package goffmpeg /* #cgo LDFLAGS: -ldl #include #include "libcffmpeg.h" */ import "C" import ( "errors" "fmt" "unsafe" ) const ( // ScaleFastBilinear SWS_FAST_BILINEAR ScaleFastBilinear = 1 // ScaleBilinear SWS_BILINEAR ScaleBilinear = 2 // ScaleBicubic SWS_BICUBIC ScaleBicubic = 4 // ScaleX SWS_X ScaleX = 8 // ScalePoint SWS_POINT ScalePoint = 0x10 // ScaleArea SWS_AREA ScaleArea = 0x20 // ScaleBicublin SWS_BICUBLIN ScaleBicublin = 0x40 // ScaleGauss SWS_GAUSS ScaleGauss = 0x80 // ScaleSinc SWS_SINC ScaleSinc = 0x100 // ScaleLancZos SWS_LANCZOS ScaleLancZos = 0x200 // ScaleSpline SWS_SPLINE ScaleSpline = 0x400 ) var libcffmpeg C.libcffmpeg // InitFFmpeg init ffmepg func InitFFmpeg(soFileGo string) error { soFile := C.CString(soFileGo) defer C.free(unsafe.Pointer(soFile)) lib := C.init_libcffmpeg(soFile) if lib == nil { fmt.Println("open error: ", soFileGo) return errors.New("init ffmpeg error") } libcffmpeg = lib return nil } // FreeFFmpeg free ffmpeg func FreeFFmpeg() { if libcffmpeg != nil { C.release_libcffmpeg(libcffmpeg) } } // Config config type Config struct { Scale int Width int Height int GB bool CPU bool } // GoFFMPEG handle for c type GoFFMPEG struct { ffmpeg C.cffmpeg } // New 2nd new func New(conf Config) *GoFFMPEG { f := C.wrap_fn_create() if f == nil { return nil } if conf.Scale != 0 && conf.Width != 0 && conf.Height != 0 { C.wrap_fn_scale(f, C.int(conf.Width), C.int(conf.Height), C.int(conf.Scale)) } if conf.GB { C.wrap_fn_run_gb28181(f) } if conf.CPU { C.wrap_fn_use_cpu(f) } return &GoFFMPEG{ ffmpeg: f, } } // Free free handle func (h *GoFFMPEG) Free() { C.wrap_fn_destroy(h.ffmpeg) } // Run ffmpeg func (h *GoFFMPEG) Run(input string) { in := C.CString(input) defer C.free(unsafe.Pointer(in)) 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) defer C.free(unsafe.Pointer(csid)) C.wrap_fn_fire_recorder(h.ffmpeg, csid, C.long(id)) } // BuildRecorder build recorder func (h *GoFFMPEG) BuildRecorder(sid, output string, mind, maxd int) { 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)) } // GetInfoRecorder info func (h *GoFFMPEG) GetInfoRecorder() (string, int, string) { var i C.int = -1 var id *C.char var idl C.int var p *C.char var pl C.int C.wrap_fn_info_recorder(h.ffmpeg, &i, &id, &idl, &p, &pl) // if p == nil { // return -1, "" // } gID := C.GoString(id) C.free(unsafe.Pointer(id)) path := C.GoString(p) C.free(unsafe.Pointer(p)) // fmt.Println("Go get info : ", path, " len: ", l) return gID, int(i), path } // BuildDecoder build decoder func (h *GoFFMPEG) BuildDecoder() { C.wrap_fn_decoder(h.ffmpeg) } // GetPicDecoder get pic from decoder func (h *GoFFMPEG) GetPicDecoder() ([]byte, int, int, int64) { var width C.int var height C.int var fid C.long p := C.wrap_fn_decoder_pic(h.ffmpeg, &width, &height, &fid) if width == 0 && height == 0 { return nil, 0, 0, 0 } defer C.free(unsafe.Pointer(p)) d := C.GoBytes(p, width*height*3) wid := int(width) hei := int(height) gfid := int64(fid) return d, wid, hei, gfid } //GetAVPacket get AVPacket func (h *GoFFMPEG) GetAVPacket() ([]byte, int, int) { var key C.int var size C.int p := C.wrap_fn_get_avpacket(h.ffmpeg, &size, &key) if size <= 0 { return nil, 0, -1 } defer C.free(unsafe.Pointer(p)) d := C.GoBytes(p, size) s := int(size) k := int(key) return d, s, k } ///////////////for encoder // GoEncoder encoder type GoEncoder struct { enc C.cencoder } // NewEncoder encoder func NewEncoder(w, h, fps, br, sFlag, gi int) *GoEncoder { if w <= 0 || h <= 0 { return nil } 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)), } } // Free free func (e *GoEncoder) Free() { C.wrap_fn_destroy_encoder(e.enc) } // Encode pic func (e *GoEncoder) Encode(in []byte, w, h int) ([]byte, int, bool) { var size C.int var key C.int cin := C.CBytes(in) defer C.free(cin) p := C.wrap_fn_encode(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) isKey := false if key > 0 { isKey = true } return b, int(size), isKey } return nil, 0, false }