EasyVQD/pkg/decoder/core.go
2026-01-23 18:05:36 +08:00

122 lines
3.6 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"
"os"
"sync"
"unsafe"
)
type VideoDecoder struct {
handle C.EZ_DECODER_HANDLE
sync.RWMutex
IsStart bool
file *os.File
}
func (v *VideoDecoder) WriteFile(data string) {
if v.file != nil {
v.file.WriteString(data)
}
}
func (v *VideoDecoder) Create() error {
v.Lock()
defer v.Unlock()
if v.IsStart {
return nil
}
//if v.file == nil {
// filename := filepath.Join(utils.CWD(), "logs", fmt.Sprintf("%016p_decoder.log", v))
// file, err := os.OpenFile(filename, os.O_APPEND|os.O_CREATE|os.O_WRONLY, os.ModePerm)
// if err == nil {
// v.file = file
// v.file.WriteString("↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓\r\n")
// } else {
// llog.Info("创建文件失败:%s", filename)
// }
//}
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
if v.file != nil {
v.file.WriteString("↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑\r\n")
v.file.Close()
v.file = nil
}
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 uintptr, size, 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")
}
if v.file != nil {
v.file.WriteString(fmt.Sprintf("[start] function:PushData;buf len:%d; codec:%x\r\n", size, codec))
}
info := &C.EZDecoderInfo{}
var out_data *C.uchar
//llog.Info("=======================>>>>>>:%v:%d", buf, size)
ret := int(C.ez_decoder_push_data(v.handle, (*C.uchar)(unsafe.Pointer(buf)), C.int(size), C.int(codec), &out_data, info))
//var out_data uintptr
//ret := int(C.ez_decoder_push_data(v.handle, (*C.char)(unsafe.Pointer(buf)), C.int(size), C.int(codec), (**C.char)(unsafe.Pointer(&out_data)), info))
if v.file != nil {
v.file.WriteString(fmt.Sprintf("[end] function:PushData;buf len:%d; codec:%x; ret:%d\r\n", size, codec, ret))
}
//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)
//llog.Info("=======================>>>>>>789:%v:%p:%d", out_data, v, data_size)
yuv := C.GoBytes(unsafe.Pointer(out_data), info.data_size)
_data := make([]byte, data_size)
copy(_data, yuv)
//llog.Info("=======================>>>>>>22222")
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
}