diff --git a/binding/go/gcrp/gcrp.go b/binding/go/gcrp/gcrp.go index 0d0ab87..52e6d50 100644 --- a/binding/go/gcrp/gcrp.go +++ b/binding/go/gcrp/gcrp.go @@ -11,7 +11,7 @@ static int frame_get_height(struct Frame* frame) { return frame->height; } */ import "C" import ( - "sync" + "runtime/cgo" "unsafe" ) @@ -87,25 +87,17 @@ type Callback interface { } type Player struct { - handle C.crp_handle - callbackId int + handle C.crp_handle + cbHandle cgo.Handle } -var mutex sync.RWMutex -var callbacks = make(map[int]Callback) -var lastId = 0 - //export goCallback func goCallback(event C.enum_Event, data unsafe.Pointer, userData unsafe.Pointer) { - id := int(uintptr(userData)) - mutex.RLock() - callback, ok := callbacks[id] - mutex.RUnlock() - if !ok { - return - } - if event == C.CRP_EV_NEW_FRAME { + callback := cgo.Handle(uintptr(userData)).Value().(Callback) + + switch event { + case C.CRP_EV_NEW_FRAME: frame := (*C.struct_Frame)(data) height := C.frame_get_height(frame) callback.OnFrame(false, Frame{ @@ -122,7 +114,7 @@ func goCallback(event C.enum_Event, data unsafe.Pointer, userData unsafe.Pointer [4]int{int(frame.stride[0]), int(frame.stride[1]), int(frame.stride[2]), int(frame.stride[3])}, uint64(frame.pts), }) - } else if event == C.CRP_EV_NEW_AUDIO { + case C.CRP_EV_NEW_AUDIO: frame := (*C.struct_Frame)(data) callback.OnFrame(true, Frame{ 0, 0, @@ -138,10 +130,10 @@ func goCallback(event C.enum_Event, data unsafe.Pointer, userData unsafe.Pointer [4]int{int(frame.stride[0]), int(frame.stride[1]), int(frame.stride[2]), int(frame.stride[3])}, uint64(frame.pts), }) - } else if event == C.CRP_EV_VIDEO_EXTRADATA || event == C.CRP_EV_AUDIO_EXTRADATA { + case C.CRP_EV_VIDEO_EXTRADATA, C.CRP_EV_AUDIO_EXTRADATA: ed := (*C.struct_ExtraData)(data) callback.OnEvent(Event(event), C.GoBytes(unsafe.Pointer(ed.data), C.int(ed.size))) - } else { + default: callback.OnEvent(Event(event), int64(uintptr(data))) } } @@ -154,9 +146,10 @@ func (player *Player) Destroy() { C.crp_destroy(player.handle) player.handle = nil - mutex.Lock() - delete(callbacks, player.callbackId) - mutex.Unlock() + if player.cbHandle != 0 { + player.cbHandle.Delete() + player.cbHandle = 0 + } } func (player *Player) Auth(username, password string, isMd5 bool) { @@ -191,14 +184,12 @@ func (player *Player) Play(url string, option Option, callback Callback) { timeout: C.int64_t(option.Timeout), } - mutex.Lock() - id := lastId - player.callbackId = id - callbacks[id] = callback - lastId += 1 - mutex.Unlock() + if player.cbHandle != 0 { + player.cbHandle.Delete() + } + player.cbHandle = cgo.NewHandle(callback) - C.crp_play(player.handle, curl, &coption, C.crp_callback(C.goCallback), unsafe.Pointer(uintptr(id))) + C.crp_play(player.handle, curl, &coption, C.crp_callback(C.goCallback), unsafe.Pointer(player.cbHandle)) } func (player *Player) Replay() {