From b3ec17d859e6a833fd4949bc093d510b571efe3e Mon Sep 17 00:00:00 2001 From: AkimioJR Date: Fri, 6 Feb 2026 13:22:00 +0800 Subject: [PATCH 1/7] =?UTF-8?q?fix:=20=E5=A2=9E=E5=8A=A0=E8=AF=BB=E5=86=99?= =?UTF-8?q?=E9=94=81=EF=BC=8C=E9=81=BF=E5=85=8D=E5=A4=9A=E7=BA=BF=E7=A8=8B?= =?UTF-8?q?=E4=B8=AD=E5=90=8C=E6=97=B6=E6=93=8D=E4=BD=9Ccallbacks=E5=92=8C?= =?UTF-8?q?lastId?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- binding/go/gcrp/gcrp.go | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/binding/go/gcrp/gcrp.go b/binding/go/gcrp/gcrp.go index d956314..632ae68 100644 --- a/binding/go/gcrp/gcrp.go +++ b/binding/go/gcrp/gcrp.go @@ -10,7 +10,10 @@ static int frame_get_width(struct Frame* frame) { return frame->width; } static int frame_get_height(struct Frame* frame) { return frame->height; } */ import "C" -import "unsafe" +import ( + "sync" + "unsafe" +) type Transport int @@ -88,12 +91,16 @@ type Player struct { callbackId int } +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() + defer mutex.RUnlock() + if event == C.CRP_EV_NEW_FRAME { frame := (*C.struct_Frame)(data) height := C.frame_get_height(frame) @@ -142,6 +149,9 @@ func Create() Player { func (player Player) Destroy() { C.crp_destroy(player.handle) player.handle = nil + + mutex.Lock() + defer mutex.Unlock() delete(callbacks, player.callbackId) } @@ -171,6 +181,10 @@ func (player Player) Play(url string, option Option, callback Callback) { }, timeout: C.int64_t(option.Timeout), } + + mutex.Lock() + defer mutex.Unlock() + player.callbackId = lastId callbacks[lastId] = callback C.crp_play(player.handle, curl, &coption, C.crp_callback(C.goCallback), unsafe.Pointer(uintptr(lastId))) From c768dec1c160417a3d4e5b15a2a2bab713a96c16 Mon Sep 17 00:00:00 2001 From: AkimioJR Date: Fri, 6 Feb 2026 13:24:14 +0800 Subject: [PATCH 2/7] =?UTF-8?q?perfect:=20=E4=BD=BF=E7=94=A8defer=E6=93=8D?= =?UTF-8?q?=E4=BD=9C=E6=B8=85=E7=90=86=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- binding/go/gcrp/gcrp.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/binding/go/gcrp/gcrp.go b/binding/go/gcrp/gcrp.go index 632ae68..809b6da 100644 --- a/binding/go/gcrp/gcrp.go +++ b/binding/go/gcrp/gcrp.go @@ -157,14 +157,17 @@ func (player Player) Destroy() { func (player Player) Auth(username, password string, isMd5 bool) { cusername := C.CString(username) + defer C.free(unsafe.Pointer(cusername)) cpassword := C.CString(password) + defer C.free(unsafe.Pointer(cpassword)) + C.crp_auth(player.handle, cusername, cpassword, C.bool(isMd5)) - C.free(unsafe.Pointer(cusername)) - C.free(unsafe.Pointer(cpassword)) } func (player Player) Play(url string, option Option, callback Callback) { curl := C.CString(url) + defer C.free(unsafe.Pointer(curl)) + coption := C.struct_Option{ transport: C.int(option.Transport), video: C.struct___1{ @@ -189,7 +192,6 @@ func (player Player) Play(url string, option Option, callback Callback) { callbacks[lastId] = callback C.crp_play(player.handle, curl, &coption, C.crp_callback(C.goCallback), unsafe.Pointer(uintptr(lastId))) lastId += 1 - C.free(unsafe.Pointer(curl)) } func (player Player) Replay() { From 246dd83510d04243cf27d94650fb9022e5bd9e79 Mon Sep 17 00:00:00 2001 From: AkimioJR Date: Fri, 6 Feb 2026 14:27:40 +0800 Subject: [PATCH 3/7] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20=20C.CString(op?= =?UTF-8?q?tion.HWDevice)=20=E5=86=85=E5=AD=98=E6=B3=84=E6=BC=8F=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- binding/go/gcrp/gcrp.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/binding/go/gcrp/gcrp.go b/binding/go/gcrp/gcrp.go index 809b6da..f9a43e6 100644 --- a/binding/go/gcrp/gcrp.go +++ b/binding/go/gcrp/gcrp.go @@ -168,13 +168,16 @@ func (player Player) Play(url string, option Option, callback Callback) { curl := C.CString(url) defer C.free(unsafe.Pointer(curl)) + cHWDevice := C.CString(option.HWDevice) + defer C.free(unsafe.Pointer(cHWDevice)) + coption := C.struct_Option{ transport: C.int(option.Transport), video: C.struct___1{ width: C.int(option.Width), height: C.int(option.Height), format: C.int(option.VideoFormat), - hw_device: *(*[32]C.char)(unsafe.Pointer(C.CString(option.HWDevice))), + hw_device: *(*[32]C.char)(unsafe.Pointer(cHWDevice)), }, enable_audio: C.bool(option.EnableAudio), audio: C.struct___2{ From e3c81ac3ba4906ffec96b685698918da04d6802a Mon Sep 17 00:00:00 2001 From: Chen Wu Date: Sat, 7 Feb 2026 09:47:26 +0800 Subject: [PATCH 4/7] =?UTF-8?q?refactor:=20=E4=BB=85=E5=AF=B9callbacks?= =?UTF-8?q?=E5=8A=A0=E9=94=81=EF=BC=8C=E9=98=B2=E6=AD=A2=E5=BD=B1=E5=93=8D?= =?UTF-8?q?=E6=80=A7=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- binding/go/gcrp/gcrp.go | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/binding/go/gcrp/gcrp.go b/binding/go/gcrp/gcrp.go index f9a43e6..9dddda2 100644 --- a/binding/go/gcrp/gcrp.go +++ b/binding/go/gcrp/gcrp.go @@ -99,12 +99,16 @@ var lastId = 0 func goCallback(event C.enum_Event, data unsafe.Pointer, userData unsafe.Pointer) { id := int(uintptr(userData)) mutex.RLock() - defer mutex.RUnlock() + callback, ok := callbacks[id] + mutex.RUnlock() + if !ok { + return + } if event == C.CRP_EV_NEW_FRAME { frame := (*C.struct_Frame)(data) height := C.frame_get_height(frame) - callbacks[id].OnFrame(false, Frame{ + callback.OnFrame(false, Frame{ int(C.frame_get_width(frame)), int(height), 0, 0, @@ -120,7 +124,7 @@ func goCallback(event C.enum_Event, data unsafe.Pointer, userData unsafe.Pointer }) } else if event == C.CRP_EV_NEW_AUDIO { frame := (*C.struct_Frame)(data) - callbacks[id].OnFrame(true, Frame{ + callback.OnFrame(true, Frame{ 0, 0, int(C.frame_get_width(frame)), int(C.frame_get_height(frame)), @@ -136,9 +140,9 @@ func goCallback(event C.enum_Event, data unsafe.Pointer, userData unsafe.Pointer }) } else if event == C.CRP_EV_VIDEO_EXTRADATA || event == C.CRP_EV_AUDIO_EXTRADATA { ed := (*C.struct_ExtraData)(data) - callbacks[id].OnEvent(Event(event), C.GoBytes(unsafe.Pointer(ed.data), C.int(ed.size))) + callback.OnEvent(Event(event), C.GoBytes(unsafe.Pointer(ed.data), C.int(ed.size))) } else { - callbacks[id].OnEvent(Event(event), int64(uintptr(data))) + callback.OnEvent(Event(event), int64(uintptr(data))) } } @@ -151,8 +155,8 @@ func (player Player) Destroy() { player.handle = nil mutex.Lock() - defer mutex.Unlock() delete(callbacks, player.callbackId) + mutex.Unlock() } func (player Player) Auth(username, password string, isMd5 bool) { @@ -167,9 +171,8 @@ func (player Player) Auth(username, password string, isMd5 bool) { func (player Player) Play(url string, option Option, callback Callback) { curl := C.CString(url) defer C.free(unsafe.Pointer(curl)) - - cHWDevice := C.CString(option.HWDevice) - defer C.free(unsafe.Pointer(cHWDevice)) + chwdevice := C.CString(option.HWDevice) + defer C.free(unsafe.Pointer(chwdevice)) coption := C.struct_Option{ transport: C.int(option.Transport), @@ -177,7 +180,7 @@ func (player Player) Play(url string, option Option, callback Callback) { width: C.int(option.Width), height: C.int(option.Height), format: C.int(option.VideoFormat), - hw_device: *(*[32]C.char)(unsafe.Pointer(cHWDevice)), + hw_device: *(*[32]C.char)(unsafe.Pointer(chwdevice)), }, enable_audio: C.bool(option.EnableAudio), audio: C.struct___2{ @@ -189,12 +192,12 @@ func (player Player) Play(url string, option Option, callback Callback) { } mutex.Lock() - defer mutex.Unlock() - player.callbackId = lastId callbacks[lastId] = callback - C.crp_play(player.handle, curl, &coption, C.crp_callback(C.goCallback), unsafe.Pointer(uintptr(lastId))) lastId += 1 + mutex.Unlock() + + C.crp_play(player.handle, curl, &coption, C.crp_callback(C.goCallback), unsafe.Pointer(uintptr(id))) } func (player Player) Replay() { From 12db156ace67588f8409dc8801052a75b3d788ca Mon Sep 17 00:00:00 2001 From: Chen Wu Date: Sat, 7 Feb 2026 10:19:11 +0800 Subject: [PATCH 5/7] =?UTF-8?q?fix:=20=E4=BF=AE=E6=94=B9Player=E6=96=B9?= =?UTF-8?q?=E6=B3=95=E4=B8=BA=E6=8C=87=E9=92=88=E6=8E=A5=E6=94=B6=E8=80=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- binding/go/gcrp/gcrp.go | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/binding/go/gcrp/gcrp.go b/binding/go/gcrp/gcrp.go index 9dddda2..0d0ab87 100644 --- a/binding/go/gcrp/gcrp.go +++ b/binding/go/gcrp/gcrp.go @@ -146,11 +146,11 @@ func goCallback(event C.enum_Event, data unsafe.Pointer, userData unsafe.Pointer } } -func Create() Player { - return Player{C.crp_create(), 0} +func Create() *Player { + return &Player{C.crp_create(), 0} } -func (player Player) Destroy() { +func (player *Player) Destroy() { C.crp_destroy(player.handle) player.handle = nil @@ -159,7 +159,7 @@ func (player Player) Destroy() { mutex.Unlock() } -func (player Player) Auth(username, password string, isMd5 bool) { +func (player *Player) Auth(username, password string, isMd5 bool) { cusername := C.CString(username) defer C.free(unsafe.Pointer(cusername)) cpassword := C.CString(password) @@ -168,7 +168,7 @@ func (player Player) Auth(username, password string, isMd5 bool) { C.crp_auth(player.handle, cusername, cpassword, C.bool(isMd5)) } -func (player Player) Play(url string, option Option, callback Callback) { +func (player *Player) Play(url string, option Option, callback Callback) { curl := C.CString(url) defer C.free(unsafe.Pointer(curl)) chwdevice := C.CString(option.HWDevice) @@ -192,19 +192,20 @@ func (player Player) Play(url string, option Option, callback Callback) { } mutex.Lock() - player.callbackId = lastId - callbacks[lastId] = callback + id := lastId + player.callbackId = id + callbacks[id] = callback lastId += 1 mutex.Unlock() C.crp_play(player.handle, curl, &coption, C.crp_callback(C.goCallback), unsafe.Pointer(uintptr(id))) } -func (player Player) Replay() { +func (player *Player) Replay() { C.crp_replay(player.handle) } -func (player Player) Stop() { +func (player *Player) Stop() { C.crp_stop(player.handle) } From b24bac41726889f5cfa255b646d5f955821fe032 Mon Sep 17 00:00:00 2001 From: AkimioJR Date: Sat, 7 Feb 2026 17:37:09 +0800 Subject: [PATCH 6/7] =?UTF-8?q?perfect:=20=E9=80=9A=E8=BF=87=20cgo.Handle?= =?UTF-8?q?=20=E5=9C=A8c=E5=92=8Cgo=E4=B9=8B=E9=97=B4=E4=BC=A0=E9=80=92?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E4=BB=A5=E5=AE=9E=E7=8E=B0=E5=9B=9E=E8=B0=83?= =?UTF-8?q?=E7=9A=84=E4=BC=A0=E9=80=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- binding/go/gcrp/gcrp.go | 38 ++++++++++++++------------------------ 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/binding/go/gcrp/gcrp.go b/binding/go/gcrp/gcrp.go index 0d0ab87..fc33872 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,23 +87,14 @@ 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 - } + + callback := cgo.Handle(uintptr(userData)).Value().(Callback) if event == C.CRP_EV_NEW_FRAME { frame := (*C.struct_Frame)(data) @@ -154,9 +145,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 +183,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() { From 07835cfd33ef4601befc3cc1d47ff59b35bde774 Mon Sep 17 00:00:00 2001 From: AkimioJR Date: Sat, 7 Feb 2026 17:39:42 +0800 Subject: [PATCH 7/7] =?UTF-8?q?refactor:=20=E4=BD=BF=E7=94=A8=20swich=20?= =?UTF-8?q?=E4=BC=98=E5=8C=96=20goCallback=20=E5=87=BD=E6=95=B0=E7=9A=84?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- binding/go/gcrp/gcrp.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/binding/go/gcrp/gcrp.go b/binding/go/gcrp/gcrp.go index fc33872..52e6d50 100644 --- a/binding/go/gcrp/gcrp.go +++ b/binding/go/gcrp/gcrp.go @@ -96,7 +96,8 @@ func goCallback(event C.enum_Event, data unsafe.Pointer, userData unsafe.Pointer callback := cgo.Handle(uintptr(userData)).Value().(Callback) - if event == C.CRP_EV_NEW_FRAME { + switch event { + case C.CRP_EV_NEW_FRAME: frame := (*C.struct_Frame)(data) height := C.frame_get_height(frame) callback.OnFrame(false, Frame{ @@ -113,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, @@ -129,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))) } }