From dc65b072a13994ff02cc7b54f3b00ba087e7f86a Mon Sep 17 00:00:00 2001
From: zhangmeng <775834166@qq.com>
Date: 星期三, 20 十一月 2019 14:05:52 +0800
Subject: [PATCH] add zerocopy

---
 godec.go     |   19 ++++++
 goffmpeg.go  |    8 ++
 gostream.go  |   21 ++++++
 goenc.go     |   26 +++++++-
 goconv.go    |   26 ++++++++
 godecjpeg.go |   27 +++++++++
 6 files changed, 121 insertions(+), 6 deletions(-)

diff --git a/goconv.go b/goconv.go
index 311bdd4..cbf48af 100644
--- a/goconv.go
+++ b/goconv.go
@@ -124,4 +124,28 @@
 	return c.ConvToPicture(src)
 }
 
-/////////////// for conv
+///////////////
+
+// ConvToPicture2 second
+func (c *GoConv) ConvToPicture2(src []byte) (unsafe.Pointer, []byte) {
+	if c.conv == nil {
+		return nil, nil
+	}
+
+	bgr := C.wrap_fn_conv(unsafe.Pointer(libcffmpeg), c.conv, (*C.uchar)(unsafe.Pointer(&src[0])))
+	if bgr != nil {
+		const maxLen = 0x7fffffff
+		size := int(c.size)
+		data := (*[maxLen]byte)(unsafe.Pointer(bgr))[:size:size]
+		return bgr, data
+	}
+	return nil, nil
+}
+
+// Resize2 resize2
+func (c *GoConv) Resize2(src []byte) (unsafe.Pointer, []byte) {
+	if c.SrcW == c.DstW && c.SrcH == c.DstH {
+		return nil, src
+	}
+	return c.ConvToPicture2(src)
+}
diff --git a/godec.go b/godec.go
index aab8c7a..25baa88 100644
--- a/godec.go
+++ b/godec.go
@@ -19,10 +19,27 @@
 	var srcW, srcH, srcF C.int
 
 	p := C.wrap_fn_decoder_pic(unsafe.Pointer(libcffmpeg), h.ffmpeg, &srcW, &srcH, &srcF, &length, &fid)
-	if srcW == 0 || srcH == 0 {
+	if p == nil || length == 0 || srcW == 0 || srcH == 0 {
 		return nil, 0, 0, 0
 	}
 	defer C.free(unsafe.Pointer(p))
 
 	return C.GoBytes(p, length), int(srcW), int(srcH), int64(fid)
 }
+
+// GetYUV2 get yuv data
+func (h *GoFFMPEG) GetYUV2() (unsafe.Pointer, []byte, int, int, int64) {
+	var fid C.long
+	var length C.int
+	var srcW, srcH, srcF C.int
+
+	p := C.wrap_fn_decoder_pic(unsafe.Pointer(libcffmpeg), h.ffmpeg, &srcW, &srcH, &srcF, &length, &fid)
+	if p == nil || length == 0 || srcW == 0 || srcH == 0 {
+		return nil, nil, 0, 0, 0
+	}
+	const maxLen = 0x7fffffff
+	size := int(length)
+	data := (*[maxLen]byte)(unsafe.Pointer(p))[:size:size]
+
+	return unsafe.Pointer(p), data, int(srcW), int(srcH), int64(fid)
+}
diff --git a/godecjpeg.go b/godecjpeg.go
index 6cef6af..ac1151f 100644
--- a/godecjpeg.go
+++ b/godecjpeg.go
@@ -34,3 +34,30 @@
 	}
 	return nil, int(width), int(height)
 }
+
+// Decode2 decode jpeg file
+// return val: -1 open error; -2, find stream error; -3, converter create error
+func Decode2(input string, gb bool) (unsafe.Pointer, []byte, int, int) {
+	in := C.CString(input)
+	defer C.free(unsafe.Pointer(in))
+
+	withGB := 0
+	if gb {
+		withGB = 1
+	}
+
+	var width C.int
+	var height C.int
+	p := C.wrap_fn_decode(unsafe.Pointer(libcffmpeg), in, C.int(withGB), &width, &height)
+
+	if width > 0 && height > 0 {
+		wid := int(width)
+		hei := int(height)
+		const maxLen = 0x7fffffff
+		size := int(width * height * 3)
+		data := (*[maxLen]byte)(unsafe.Pointer(p))[:size:size]
+
+		return p, data, wid, hei
+	}
+	return nil, nil, 0, 0
+}
diff --git a/goenc.go b/goenc.go
index d7a6b43..858ed98 100644
--- a/goenc.go
+++ b/goenc.go
@@ -37,10 +37,8 @@
 
 	var size C.int
 	var key C.int
-	cin := C.CBytes(in)
-	defer C.free(cin)
 
-	p := C.wrap_fn_encode(unsafe.Pointer(libcffmpeg), e.enc, cin, C.int(w), C.int(h), &size, &key)
+	p := C.wrap_fn_encode(unsafe.Pointer(libcffmpeg), e.enc, unsafe.Pointer(&in[0]), C.int(w), C.int(h), &size, &key)
 	defer C.free(p)
 	if p != nil && size > 0 {
 		b := C.GoBytes(p, size)
@@ -53,3 +51,25 @@
 	}
 	return nil, 0, false
 }
+
+// Encode2 pic
+func (e *GoEncoder) Encode2(in []byte, w, h int) (unsafe.Pointer, []byte, int, bool) {
+
+	var size C.int
+	var key C.int
+
+	p := C.wrap_fn_encode(unsafe.Pointer(libcffmpeg), e.enc, unsafe.Pointer(&in[0]), C.int(w), C.int(h), &size, &key)
+	if p != nil && size > 0 {
+
+		isKey := false
+		if key > 0 {
+			isKey = true
+		}
+		const maxLen = 0x7fffffff
+		length := int(size)
+		data := (*[maxLen]byte)(unsafe.Pointer(p))[:length:length]
+
+		return p, data, length, isKey
+	}
+	return nil, nil, 0, false
+}
diff --git a/goffmpeg.go b/goffmpeg.go
index efaf6cc..252e7a1 100644
--- a/goffmpeg.go
+++ b/goffmpeg.go
@@ -99,3 +99,11 @@
 func (h *GoFFMPEG) FPS() int {
 	return int(C.wrap_fn_fps(unsafe.Pointer(libcffmpeg), h.ffmpeg))
 }
+
+// ReleaseC release c memory
+func ReleaseC(p unsafe.Pointer) {
+	if p == nil {
+		return
+	}
+	C.free(unsafe.Pointer(p))
+}
diff --git a/gostream.go b/gostream.go
index dc94166..7ae6636 100644
--- a/gostream.go
+++ b/gostream.go
@@ -14,13 +14,32 @@
 	var size C.int
 
 	p := C.wrap_fn_get_avpacket(unsafe.Pointer(libcffmpeg), h.ffmpeg, &size, &key)
+	defer C.free(unsafe.Pointer(p))
 	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
 }
+
+//GetAVPacket2 get AVPacket
+func (h *GoFFMPEG) GetAVPacket2() (unsafe.Pointer, []byte, int, int) {
+	var key C.int
+	var size C.int
+
+	p := C.wrap_fn_get_avpacket(unsafe.Pointer(libcffmpeg), h.ffmpeg, &size, &key)
+	if size <= 0 {
+		return nil, nil, 0, -1
+	}
+
+	const maxLen = 0x7fffffff
+	length := int(size)
+	data := (*[maxLen]byte)(unsafe.Pointer(p))[:length:length]
+
+	k := int(key)
+
+	return p, data, length, k
+}

--
Gitblit v1.8.0