mirror of
https://github.com/qrtc/ffmpeg-dev-go.git
synced 2025-09-26 20:01:22 +08:00
139 lines
3.3 KiB
Go
139 lines
3.3 KiB
Go
// Copyright (c) 2023 QRTC. All rights reserved.
|
|
// Use of this source code is governed by a MIT
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package ffmpeg
|
|
|
|
/*
|
|
#include <stdlib.h>
|
|
*/
|
|
import "C"
|
|
import (
|
|
"reflect"
|
|
"unsafe"
|
|
)
|
|
|
|
type Integer interface {
|
|
SingedInteger | UnsingedInteger
|
|
}
|
|
|
|
type SingedInteger interface {
|
|
~int | ~int8 | ~int16 | ~int32 | ~int64
|
|
}
|
|
|
|
type UnsingedInteger interface {
|
|
~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr
|
|
}
|
|
|
|
// CVoidPointer represents a (void*) type pointer in the C world.
|
|
type CVoidPointer any
|
|
|
|
// VoidPointer returns a unsafe.Pointer from CVoidPointer.
|
|
func VoidPointer(a CVoidPointer) unsafe.Pointer {
|
|
if a == nil {
|
|
return nil
|
|
}
|
|
return unsafe.Pointer(reflect.ValueOf(a).Pointer())
|
|
}
|
|
|
|
// CVoidPointer represents a (void**) type pointer in the C world.
|
|
type CVoidPointerPointer any
|
|
|
|
// VoidPointerPointer returns a *unsafe.Pointer from CVoidPointerPointer.
|
|
func VoidPointerPointer(a CVoidPointerPointer) *unsafe.Pointer {
|
|
if a == nil {
|
|
return nil
|
|
}
|
|
return (*unsafe.Pointer)(unsafe.Pointer(reflect.ValueOf(a).Pointer()))
|
|
}
|
|
|
|
// FreePointer frees memory allocated in the C world.
|
|
func FreePointer(ptr CVoidPointer) {
|
|
C.free(VoidPointer(ptr))
|
|
}
|
|
|
|
const NIL = "\\'<nil>'\\"
|
|
|
|
// StringCasting casts go string to c world char* with free function.
|
|
// Note: if input is a NIL string will return a nil pointer.
|
|
func StringCasting(s string) (allocPtr *C.char, freeFunc func()) {
|
|
if s == NIL {
|
|
return nil, func() {}
|
|
}
|
|
allocPtr = C.CString(s)
|
|
freeFunc = func() { FreePointer(allocPtr) }
|
|
return allocPtr, freeFunc
|
|
}
|
|
|
|
// StringSliceCasting casts go string slice to c world char* slice with free function.
|
|
func StringSliceCasting(ss []string) (allocPtrs []*C.char, freeFunc func()) {
|
|
var freeFns []func()
|
|
for _, s := range ss {
|
|
ptr, fn := StringCasting(s)
|
|
allocPtrs = append(allocPtrs, ptr)
|
|
freeFns = append(freeFns, fn)
|
|
}
|
|
return allocPtrs, func() {
|
|
for _, fn := range freeFns {
|
|
fn()
|
|
}
|
|
}
|
|
}
|
|
|
|
// SliceSlice returns a slice of slice from a pointer to pointer.
|
|
func SliceSlice[T any, X, Y Integer](data **T, x X, y Y) (v [][]T) {
|
|
for i := 0; i < int(x); i++ {
|
|
v = append(v, unsafe.Slice(*PointerOffset(data, i), y))
|
|
}
|
|
return v
|
|
}
|
|
|
|
// SliceTrunc return a slice from a sign-terminated array.
|
|
func SliceTrunc[T any](ptr *T, truncFunc func(T) bool) []T {
|
|
if ptr == nil {
|
|
return nil
|
|
}
|
|
for i := 0; ; i++ {
|
|
if truncFunc(*(*T)(unsafe.Pointer(uintptr(unsafe.Pointer(ptr)) +
|
|
uintptr(unsafe.Sizeof(*ptr))*uintptr(i)))) {
|
|
return unsafe.Slice(ptr, i)
|
|
}
|
|
}
|
|
}
|
|
|
|
// SliceTruncString returns a string slice from a NULL-terminated *C.char array.
|
|
func SliceTruncString(ptr **C.char) (v []string) {
|
|
if ptr == nil {
|
|
return nil
|
|
}
|
|
for *ptr != nil && **ptr != C.char(0x00) {
|
|
v = append(v, C.GoString(*ptr))
|
|
ptr = (**C.char)(unsafe.Pointer(uintptr(unsafe.Pointer(ptr)) +
|
|
uintptr(unsafe.Sizeof(*ptr))))
|
|
}
|
|
return v
|
|
}
|
|
|
|
// PointerOffset offset the pointer point.
|
|
func PointerOffset[U any, V Integer](ptr *U, offset V) *U {
|
|
if ptr == nil {
|
|
return nil
|
|
}
|
|
return (*U)(unsafe.Pointer(uintptr(unsafe.Pointer(ptr)) +
|
|
uintptr(unsafe.Sizeof(*ptr))*(uintptr(offset))))
|
|
}
|
|
|
|
// CondExpr is Conditional Operator like Ternary Operator in the C world.
|
|
func CondExpr[T any](cond bool, x, y T) T {
|
|
if cond {
|
|
return x
|
|
}
|
|
return y
|
|
}
|
|
|
|
// PlusPlus is ++ like operator.
|
|
func PlusPlus[T Integer](x *T) T {
|
|
defer func() { *x++ }()
|
|
return *x
|
|
}
|