package goffmpeg
|
|
/*
|
#cgo LDFLAGS: -ldl
|
#include <stdlib.h>
|
#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 (h *GoFFMPEG) 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(h.ffmpeg, 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
|
}
|
|
///////////////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
|
}
|