EasyVQD/pkg/decoder/core.go
2026-01-27 10:42:21 +08:00

89 lines
2.3 KiB
Go

package decoder
/*
#cgo CFLAGS: -w -I${SRCDIR}/include -fPIC
#cgo CPPFLAGS: -w -I${SRCDIR}/include -fPIC
#cgo windows LDFLAGS: -L${SRCDIR}/include -L${SRCDIR}/../ -lez_decoder
#cgo linux LDFLAGS: -Wl,-rpath=./ -L${SRCDIR}/include/linux -L${SRCDIR}/include/RTSP/lib -lez_decoder -lavfilter -lavformat -lavcodec -lavdevice -lswscale -lpostproc -lswresample -lavutil -lx264 -lm -ldl -lstdc++ -pthread -lrt -lssl -lcrypto -lz -lbz2
#include "ez_decoder.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void CToBytes(unsigned char *dst, unsigned char *src, int src_len)
{
//memset(dst, 0, src_len);
memcpy(dst, src, src_len);
}
*/
import "C"
import (
"fmt"
"log/slog"
"sync"
"unsafe"
)
type VideoDecoder struct {
handle C.EZ_DECODER_HANDLE
sync.RWMutex
IsStart bool
}
func (v *VideoDecoder) Create() error {
v.Lock()
defer v.Unlock()
if v.IsStart {
return nil
}
ret := int(C.ez_decoder_create(&v.handle))
v.IsStart = true
return IsReturnErrorf(ret, "ez_decoder_create")
}
func (v *VideoDecoder) Destroy() error {
v.Lock()
defer v.Unlock()
if !v.IsStart {
return nil
}
v.IsStart = false
slog.Info("====>>ez_decoder_destroy", "v", v)
ret := int(C.ez_decoder_destroy(&v.handle))
return IsReturnErrorf(ret, "ez_decoder_destroy")
}
func (v *VideoDecoder) PushDataEx(buf []byte, codec int) (w, h int, data []byte, err error) {
v.Lock()
defer v.Unlock()
if !v.IsStart {
return 0, 0, nil, fmt.Errorf("decoder fail")
}
cBytes := C.CBytes(buf)
defer C.free(unsafe.Pointer(cBytes)) // 必须手动释放
info := &C.EZDecoderInfo{}
var out_data *C.uchar
ret := int(C.ez_decoder_push_data(v.handle, (*C.uchar)(cBytes), C.int(len(buf)), C.int(codec), &out_data, info))
//return 0, 0, nil, fmt.Errorf("test") // 252
if ret == 0 {
data_size := int(info.data_size)
_w := int(info.width)
_h := int(info.height)
yuv := C.GoBytes(unsafe.Pointer(out_data), info.data_size)
_data := make([]byte, data_size)
copy(_data, yuv)
return _w, _h, _data, nil
//_data := make([]byte, data_size)
//C.CToBytes((*C.uchar)(unsafe.Pointer(&_data[0])), out_data, C.int(data_size))
//return _w, _h, _data, nil
}
return 0, 0, nil, fmt.Errorf("ez_decoder_push_data fail %d", ret)
}
func IsReturnErrorf(ret int, str string) error {
if int(ret) != 0 {
return fmt.Errorf("%s error:%d", str, ret)
}
return nil
}