feat: imagorvideo init
This commit is contained in:
commit
2451fa1b5a
20 changed files with 2601 additions and 0 deletions
100
ffmpeg/pointer/pointer.go
Normal file
100
ffmpeg/pointer/pointer.go
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
package pointer
|
||||
|
||||
// #include <stdlib.h>
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const blockSize = 1024
|
||||
|
||||
var (
|
||||
mutex sync.RWMutex
|
||||
store = map[unsafe.Pointer]interface{}{}
|
||||
free []unsafe.Pointer
|
||||
blocks []unsafe.Pointer
|
||||
)
|
||||
|
||||
func allocMem() {
|
||||
mem := C.malloc(blockSize)
|
||||
if mem == nil {
|
||||
panic("can't allocate memory block for C pointers")
|
||||
}
|
||||
blocks = append(blocks, mem)
|
||||
for i := 0; i < blockSize; i++ {
|
||||
p := unsafe.Pointer(uintptr(mem) + uintptr(blockSize-1-i))
|
||||
free = append(free, p)
|
||||
}
|
||||
}
|
||||
|
||||
func getPtr() unsafe.Pointer {
|
||||
// Generate real fake C pointer.
|
||||
// This pointer will not store any data, but will be used for indexing
|
||||
// purposes. Since Go doesn't allow to cast dangling pointer to
|
||||
// unsafe.Pointer, we do really allocate memory. Why we need indexing? Because
|
||||
// Go doest allow C code to store pointers to Go data.
|
||||
if len(free) == 0 {
|
||||
allocMem()
|
||||
}
|
||||
n := len(free) - 1
|
||||
p := free[n]
|
||||
free = free[:n]
|
||||
return p
|
||||
}
|
||||
|
||||
// Save an object in the storage and return an index pointer to it.
|
||||
func Save(v interface{}) unsafe.Pointer {
|
||||
if v == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
mutex.Lock()
|
||||
ptr := getPtr()
|
||||
store[ptr] = v
|
||||
mutex.Unlock()
|
||||
|
||||
return ptr
|
||||
}
|
||||
|
||||
// Restore an object from the storage by its index pointer.
|
||||
func Restore(ptr unsafe.Pointer) (v interface{}) {
|
||||
if ptr == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
mutex.RLock()
|
||||
v = store[ptr]
|
||||
mutex.RUnlock()
|
||||
return
|
||||
}
|
||||
|
||||
// Unref removes an object from the storage and returns the index pointer to the
|
||||
// pool for reuse.
|
||||
func Unref(ptr unsafe.Pointer) {
|
||||
if ptr == nil {
|
||||
return
|
||||
}
|
||||
|
||||
mutex.Lock()
|
||||
if _, ok := store[ptr]; ok {
|
||||
delete(store, ptr)
|
||||
free = append(free, ptr)
|
||||
}
|
||||
mutex.Unlock()
|
||||
}
|
||||
|
||||
// Clear storage and free all memory
|
||||
func Clear() {
|
||||
mutex.Lock()
|
||||
for p := range store {
|
||||
delete(store, p)
|
||||
}
|
||||
free = nil
|
||||
for _, p := range blocks {
|
||||
C.free(p)
|
||||
}
|
||||
blocks = nil
|
||||
mutex.Unlock()
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue