You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
joy4/cgo/ffmpeg/gocv.go

68 lines
1.8 KiB
Go

// +build gocv
package ffmpeg
// #cgo !windows pkg-config: opencv4
//#cgo LDFLAGS: -lavformat -lavutil -lavcodec -lavresample -lswscale
// #cgo CXXFLAGS: --std=c++1z
// #cgo windows CPPFLAGS: -IC:/opencv/build/install/include
// #cgo windows LDFLAGS: -LC:/opencv/build/install/x64/mingw/lib -lopencv_core420 -lopencv_face420 -lopencv_videoio420 -lopencv_imgproc420 -lopencv_highgui420 -lopencv_imgcodecs420 -lopencv_objdetect420 -lopencv_features2d420 -lopencv_video420 -lopencv_dnn420 -lopencv_xfeatures2d420 -lopencv_plot420 -lopencv_tracking420 -lopencv_img_hash420 -lopencv_calib3d420
// #include <stdlib.h>
// #include <stdint.h>
// #include "gocv.h"
// #include "ffmpeg.h"
import "C"
import (
"errors"
"fmt"
"unsafe"
"gocv.io/x/gocv"
)
func (self *VideoDecoder) DecodeMat(pkt []byte) (img gocv.Mat, err error) {
data, w, h, err := self.DecodeMatRaw(pkt)
if err == nil {
img, err = gocv.NewMatFromBytes(h, w, gocv.MatTypeCV8UC3, data)
return
} else {
return
}
return img, errors.New("no image")
}
func (self *VideoDecoder) DecodeMatRaw(pkt []byte) (raw []byte, w, h int, err error) {
ff := &self.ff.ff
cgotimg := C.int(0)
frame := C.av_frame_alloc()
defer C.av_frame_free(&frame)
cerr := C.decode(ff.codecCtx, frame, (*C.uchar)(unsafe.Pointer(&pkt[0])), C.int(len(pkt)), &cgotimg)
if cerr < C.int(0) {
err = fmt.Errorf("ffmpeg: decode failed: %d", cerr)
return
}
if cgotimg != C.int(0) {
w = int(frame.width)
h = int(frame.height)
sz := C.int(0)
nframe := C.av_frame_alloc()
defer C.av_frame_free(&nframe)
cdata := C.avcodec_encode_to_mat(ff.codecCtx, frame, nframe, &sz)
if cerr != C.int(0) {
err = fmt.Errorf("ffmpeg: avcodec_encode_jpeg failed: %d", cerr)
return
}
defer C.free(unsafe.Pointer(cdata))
raw = make([]byte, int(sz))
copy(raw, *(*[]byte)(unsafe.Pointer(&cdata)))
}
return
}