mirror of
https://github.com/go-gst/go-gst.git
synced 2025-09-26 20:11:18 +08:00
144 lines
4.8 KiB
Go
144 lines
4.8 KiB
Go
package gst
|
|
|
|
/*
|
|
#include "gst.go.h"
|
|
*/
|
|
import "C"
|
|
|
|
import (
|
|
"runtime"
|
|
"unsafe"
|
|
|
|
"github.com/go-gst/go-glib/glib"
|
|
)
|
|
|
|
// Memory is a go representation of GstMemory. This object is implemented in a read-only fashion
|
|
// currently primarily for reference, and as such you should not really use it. You can create new
|
|
// memory blocks, but there are no methods implemented yet for modifying ones already in existence.
|
|
//
|
|
// Use the Buffer and its Map methods to interact with memory in both a read and writable way.
|
|
type Memory struct {
|
|
ptr *C.GstMemory
|
|
mapInfo *MapInfo
|
|
}
|
|
|
|
// FromGstMemoryUnsafe wraps the given C GstMemory in the go type. It is meant for internal usage
|
|
// and exported for visibility to other packages.
|
|
func FromGstMemoryUnsafe(mem unsafe.Pointer) *Memory {
|
|
wrapped := wrapMemory((*C.GstMemory)(mem))
|
|
wrapped.Ref()
|
|
runtime.SetFinalizer(wrapped, (*Memory).Unref)
|
|
return wrapped
|
|
}
|
|
|
|
// FromGstMemoryUnsafeNone is an alias to FromGstMemoryUnsafe.
|
|
func FromGstMemoryUnsafeNone(mem unsafe.Pointer) *Memory {
|
|
return FromGstMemoryUnsafe(mem)
|
|
}
|
|
|
|
// FromGstMemoryUnsafeFull wraps the given memory without taking an additional reference.
|
|
func FromGstMemoryUnsafeFull(mem unsafe.Pointer) *Memory {
|
|
wrapped := wrapMemory((*C.GstMemory)(mem))
|
|
runtime.SetFinalizer(wrapped, (*Memory).Unref)
|
|
return wrapped
|
|
}
|
|
|
|
// NewMemoryWrapped allocates a new memory block that wraps the given data.
|
|
//
|
|
// The prefix/padding must be filled with 0 if flags contains MemoryFlagZeroPrefixed
|
|
// and MemoryFlagZeroPadded respectively.
|
|
func NewMemoryWrapped(flags MemoryFlags, data []byte, maxSize, offset int64) *Memory {
|
|
mem := C.gst_memory_new_wrapped(
|
|
C.GstMemoryFlags(flags),
|
|
(C.gpointer)(unsafe.Pointer(&data[0])),
|
|
C.gsize(maxSize),
|
|
C.gsize(offset),
|
|
C.gsize(len(data)),
|
|
nil, // TODO: Allow user to set userdata for destroy notify function
|
|
nil, // TODO: Allow user to set destroy notify function
|
|
)
|
|
return FromGstMemoryUnsafeFull(unsafe.Pointer(mem))
|
|
}
|
|
|
|
// Instance returns the underlying GstMemory instance.
|
|
func (m *Memory) Instance() *C.GstMemory { return C.toGstMemory(unsafe.Pointer(m.ptr)) }
|
|
|
|
// Ref increases the ref count on this memory block by one.
|
|
func (m *Memory) Ref() *Memory {
|
|
return wrapMemory(C.gst_memory_ref(m.Instance()))
|
|
}
|
|
|
|
// Unref decreases the ref count on this memory block by one. When the refcount reaches
|
|
// zero the memory is freed.
|
|
func (m *Memory) Unref() { C.gst_memory_unref(m.Instance()) }
|
|
|
|
// Allocator returns the allocator for this memory.
|
|
func (m *Memory) Allocator() *Allocator {
|
|
return wrapAllocator(&glib.Object{GObject: glib.ToGObject(unsafe.Pointer(m.Instance().allocator))})
|
|
}
|
|
|
|
// Parent returns this memory block's parent.
|
|
func (m *Memory) Parent() *Memory { return wrapMemory(m.Instance().parent) }
|
|
|
|
// MaxSize returns the maximum size allocated for this memory block.
|
|
func (m *Memory) MaxSize() int64 { return int64(m.Instance().maxsize) }
|
|
|
|
// Alignment returns the alignment of the memory.
|
|
func (m *Memory) Alignment() int64 { return int64(m.Instance().align) }
|
|
|
|
// Offset returns the offset where valid data starts.
|
|
func (m *Memory) Offset() int64 { return int64(m.Instance().offset) }
|
|
|
|
// Size returns the size of valid data.
|
|
func (m *Memory) Size() int64 { return int64(m.Instance().size) }
|
|
|
|
// Copy returns a copy of size bytes from mem starting from offset. This copy is
|
|
// guaranteed to be writable. size can be set to -1 to return a copy from offset
|
|
// to the end of the memory region.
|
|
func (m *Memory) Copy(offset, size int64) *Memory {
|
|
mem := C.gst_memory_copy(m.Instance(), C.gssize(offset), C.gssize(size))
|
|
return FromGstMemoryUnsafeFull(unsafe.Pointer(mem))
|
|
}
|
|
|
|
// Map the data inside the memory. This function can return nil if the memory is not read or writable.
|
|
// It is safe to call this function multiple times on the same Memory, however it will retain the flags
|
|
// used when mapping the first time. To change between read and write access first unmap and then remap the
|
|
// memory with the appropriate flags, or map initially with both read/write access.
|
|
//
|
|
// Unmap the Memory after usage.
|
|
func (m *Memory) Map(flags MapFlags) *MapInfo {
|
|
if m.mapInfo != nil {
|
|
return m.mapInfo
|
|
}
|
|
mapInfo := C.malloc(C.sizeof_GstMapInfo)
|
|
C.gst_memory_map(
|
|
(*C.GstMemory)(m.Instance()),
|
|
(*C.GstMapInfo)(mapInfo),
|
|
C.GstMapFlags(flags),
|
|
)
|
|
if mapInfo == C.NULL {
|
|
return nil
|
|
}
|
|
m.mapInfo = wrapMapInfo((*C.GstMapInfo)(mapInfo))
|
|
return m.mapInfo
|
|
}
|
|
|
|
// Unmap will unmap the data inside this memory. Use this after calling Map on the Memory.
|
|
func (m *Memory) Unmap() {
|
|
if m.mapInfo == nil {
|
|
return
|
|
}
|
|
C.gst_memory_unmap(m.Instance(), (*C.GstMapInfo)(m.mapInfo.Instance()))
|
|
C.free(unsafe.Pointer(m.mapInfo.Instance()))
|
|
}
|
|
|
|
// Bytes will return a byte slice of the data inside this memory if it is readable.
|
|
func (m *Memory) Bytes() []byte {
|
|
mapInfo := m.Map(MapRead)
|
|
if mapInfo == nil {
|
|
return nil
|
|
}
|
|
defer m.Unmap()
|
|
return mapInfo.Bytes()
|
|
}
|