Skip to content

Commit 0061a3b

Browse files
AkimioJRDawningW
andauthored
feature: GO绑定优化 (#16)
1. 修复go多线程下创建清理问题 2. 使用defer清理资源 3. 修改Player方法为指针接收者 --------- Co-authored-by: Chen Wu <wc@mail.dawncraft.cc>
1 parent c69cfbd commit 0061a3b

File tree

1 file changed

+42
-19
lines changed

1 file changed

+42
-19
lines changed

binding/go/gcrp/gcrp.go

Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@ static int frame_get_width(struct Frame* frame) { return frame->width; }
1010
static int frame_get_height(struct Frame* frame) { return frame->height; }
1111
*/
1212
import "C"
13-
import "unsafe"
13+
import (
14+
"sync"
15+
"unsafe"
16+
)
1417

1518
type Transport int
1619

@@ -88,16 +91,24 @@ type Player struct {
8891
callbackId int
8992
}
9093

94+
var mutex sync.RWMutex
9195
var callbacks = make(map[int]Callback)
9296
var lastId = 0
9397

9498
//export goCallback
9599
func goCallback(event C.enum_Event, data unsafe.Pointer, userData unsafe.Pointer) {
96100
id := int(uintptr(userData))
101+
mutex.RLock()
102+
callback, ok := callbacks[id]
103+
mutex.RUnlock()
104+
if !ok {
105+
return
106+
}
107+
97108
if event == C.CRP_EV_NEW_FRAME {
98109
frame := (*C.struct_Frame)(data)
99110
height := C.frame_get_height(frame)
100-
callbacks[id].OnFrame(false, Frame{
111+
callback.OnFrame(false, Frame{
101112
int(C.frame_get_width(frame)),
102113
int(height),
103114
0, 0,
@@ -113,7 +124,7 @@ func goCallback(event C.enum_Event, data unsafe.Pointer, userData unsafe.Pointer
113124
})
114125
} else if event == C.CRP_EV_NEW_AUDIO {
115126
frame := (*C.struct_Frame)(data)
116-
callbacks[id].OnFrame(true, Frame{
127+
callback.OnFrame(true, Frame{
117128
0, 0,
118129
int(C.frame_get_width(frame)),
119130
int(C.frame_get_height(frame)),
@@ -129,39 +140,47 @@ func goCallback(event C.enum_Event, data unsafe.Pointer, userData unsafe.Pointer
129140
})
130141
} else if event == C.CRP_EV_VIDEO_EXTRADATA || event == C.CRP_EV_AUDIO_EXTRADATA {
131142
ed := (*C.struct_ExtraData)(data)
132-
callbacks[id].OnEvent(Event(event), C.GoBytes(unsafe.Pointer(ed.data), C.int(ed.size)))
143+
callback.OnEvent(Event(event), C.GoBytes(unsafe.Pointer(ed.data), C.int(ed.size)))
133144
} else {
134-
callbacks[id].OnEvent(Event(event), int64(uintptr(data)))
145+
callback.OnEvent(Event(event), int64(uintptr(data)))
135146
}
136147
}
137148

138-
func Create() Player {
139-
return Player{C.crp_create(), 0}
149+
func Create() *Player {
150+
return &Player{C.crp_create(), 0}
140151
}
141152

142-
func (player Player) Destroy() {
153+
func (player *Player) Destroy() {
143154
C.crp_destroy(player.handle)
144155
player.handle = nil
156+
157+
mutex.Lock()
145158
delete(callbacks, player.callbackId)
159+
mutex.Unlock()
146160
}
147161

148-
func (player Player) Auth(username, password string, isMd5 bool) {
162+
func (player *Player) Auth(username, password string, isMd5 bool) {
149163
cusername := C.CString(username)
164+
defer C.free(unsafe.Pointer(cusername))
150165
cpassword := C.CString(password)
166+
defer C.free(unsafe.Pointer(cpassword))
167+
151168
C.crp_auth(player.handle, cusername, cpassword, C.bool(isMd5))
152-
C.free(unsafe.Pointer(cusername))
153-
C.free(unsafe.Pointer(cpassword))
154169
}
155170

156-
func (player Player) Play(url string, option Option, callback Callback) {
171+
func (player *Player) Play(url string, option Option, callback Callback) {
157172
curl := C.CString(url)
173+
defer C.free(unsafe.Pointer(curl))
174+
chwdevice := C.CString(option.HWDevice)
175+
defer C.free(unsafe.Pointer(chwdevice))
176+
158177
coption := C.struct_Option{
159178
transport: C.int(option.Transport),
160179
video: C.struct___1{
161180
width: C.int(option.Width),
162181
height: C.int(option.Height),
163182
format: C.int(option.VideoFormat),
164-
hw_device: *(*[32]C.char)(unsafe.Pointer(C.CString(option.HWDevice))),
183+
hw_device: *(*[32]C.char)(unsafe.Pointer(chwdevice)),
165184
},
166185
enable_audio: C.bool(option.EnableAudio),
167186
audio: C.struct___2{
@@ -171,18 +190,22 @@ func (player Player) Play(url string, option Option, callback Callback) {
171190
},
172191
timeout: C.int64_t(option.Timeout),
173192
}
174-
player.callbackId = lastId
175-
callbacks[lastId] = callback
176-
C.crp_play(player.handle, curl, &coption, C.crp_callback(C.goCallback), unsafe.Pointer(uintptr(lastId)))
193+
194+
mutex.Lock()
195+
id := lastId
196+
player.callbackId = id
197+
callbacks[id] = callback
177198
lastId += 1
178-
C.free(unsafe.Pointer(curl))
199+
mutex.Unlock()
200+
201+
C.crp_play(player.handle, curl, &coption, C.crp_callback(C.goCallback), unsafe.Pointer(uintptr(id)))
179202
}
180203

181-
func (player Player) Replay() {
204+
func (player *Player) Replay() {
182205
C.crp_replay(player.handle)
183206
}
184207

185-
func (player Player) Stop() {
208+
func (player *Player) Stop() {
186209
C.crp_stop(player.handle)
187210
}
188211

0 commit comments

Comments
 (0)