mirror of
https://github.com/asticode/go-astiav.git
synced 2025-10-07 17:10:58 +08:00
Now removing from classers after the free method
This commit is contained in:
@@ -60,8 +60,15 @@ func (bsfc *BitStreamFilterContext) ReceivePacket(p *Packet) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (bsfc *BitStreamFilterContext) Free() {
|
func (bsfc *BitStreamFilterContext) Free() {
|
||||||
classers.del(bsfc)
|
if bsfc.c != nil {
|
||||||
|
// Make sure to clone the classer before freeing the object since
|
||||||
|
// the C free method resets the pointer
|
||||||
|
c := newClonedClasser(bsfc)
|
||||||
C.av_bsf_free(&bsfc.c)
|
C.av_bsf_free(&bsfc.c)
|
||||||
|
// Make sure to remove from classers after freeing the object since
|
||||||
|
// the C free method may use methods needing the classer
|
||||||
|
classers.del(c)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (bsfc *BitStreamFilterContext) InputTimeBase() Rational {
|
func (bsfc *BitStreamFilterContext) InputTimeBase() Rational {
|
||||||
|
20
class.go
20
class.go
@@ -52,6 +52,8 @@ type Classer interface {
|
|||||||
Class() *Class
|
Class() *Class
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _ Classer = (*UnknownClasser)(nil)
|
||||||
|
|
||||||
type UnknownClasser struct {
|
type UnknownClasser struct {
|
||||||
c *Class
|
c *Class
|
||||||
}
|
}
|
||||||
@@ -64,6 +66,24 @@ func (c *UnknownClasser) Class() *Class {
|
|||||||
return c.c
|
return c.c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _ Classer = (*ClonedClasser)(nil)
|
||||||
|
|
||||||
|
type ClonedClasser struct {
|
||||||
|
c *Class
|
||||||
|
}
|
||||||
|
|
||||||
|
func newClonedClasser(c Classer) *ClonedClasser {
|
||||||
|
cl := c.Class()
|
||||||
|
if cl == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return &ClonedClasser{c: newClassFromC(cl.ptr)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *ClonedClasser) Class() *Class {
|
||||||
|
return c.c
|
||||||
|
}
|
||||||
|
|
||||||
var classers = newClasserPool()
|
var classers = newClasserPool()
|
||||||
|
|
||||||
type classerPool struct {
|
type classerPool struct {
|
||||||
|
@@ -31,6 +31,10 @@ func TestClassers(t *testing.T) {
|
|||||||
f := AllocFilterGraph()
|
f := AllocFilterGraph()
|
||||||
c := FindDecoder(CodecIDMjpeg)
|
c := FindDecoder(CodecIDMjpeg)
|
||||||
require.NotNil(t, c)
|
require.NotNil(t, c)
|
||||||
|
bf := FindBitStreamFilterByName("null")
|
||||||
|
require.NotNil(t, bf)
|
||||||
|
bfc, err := AllocBitStreamFilterContext(bf)
|
||||||
|
require.NoError(t, err)
|
||||||
cc := AllocCodecContext(c)
|
cc := AllocCodecContext(c)
|
||||||
require.NotNil(t, cc)
|
require.NotNil(t, cc)
|
||||||
bufferSink := FindFilterByName("buffersink")
|
bufferSink := FindFilterByName("buffersink")
|
||||||
@@ -41,23 +45,27 @@ func TestClassers(t *testing.T) {
|
|||||||
fmc2 := AllocFormatContext()
|
fmc2 := AllocFormatContext()
|
||||||
require.NoError(t, fmc2.OpenInput("testdata/video.mp4", nil, nil))
|
require.NoError(t, fmc2.OpenInput("testdata/video.mp4", nil, nil))
|
||||||
path := filepath.Join(t.TempDir(), "iocontext.txt")
|
path := filepath.Join(t.TempDir(), "iocontext.txt")
|
||||||
ic, err := OpenIOContext(path, NewIOContextFlags(IOContextFlagWrite))
|
ic1, err := OpenIOContext(path, NewIOContextFlags(IOContextFlagWrite))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer os.RemoveAll(path)
|
defer os.RemoveAll(path)
|
||||||
|
ic2, err := AllocIOContext(1, true, nil, nil, nil)
|
||||||
|
require.NoError(t, err)
|
||||||
ssc, err := CreateSoftwareScaleContext(1, 1, PixelFormatRgba, 2, 2, PixelFormatRgba, NewSoftwareScaleContextFlags())
|
ssc, err := CreateSoftwareScaleContext(1, 1, PixelFormatRgba, 2, 2, PixelFormatRgba, NewSoftwareScaleContextFlags())
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
require.Equal(t, cl+8, len(classers.p))
|
require.Equal(t, cl+10, len(classers.p))
|
||||||
v, ok := classers.get(unsafe.Pointer(f.c))
|
v, ok := classers.get(unsafe.Pointer(f.c))
|
||||||
require.True(t, ok)
|
require.True(t, ok)
|
||||||
require.Equal(t, f, v)
|
require.Equal(t, f, v)
|
||||||
|
|
||||||
|
bfc.Free()
|
||||||
cc.Free()
|
cc.Free()
|
||||||
fc.Free()
|
fc.Free()
|
||||||
f.Free()
|
f.Free()
|
||||||
fmc1.Free()
|
fmc1.Free()
|
||||||
fmc2.CloseInput()
|
fmc2.CloseInput()
|
||||||
require.NoError(t, ic.Close())
|
require.NoError(t, ic1.Close())
|
||||||
|
ic2.Free()
|
||||||
ssc.Free()
|
ssc.Free()
|
||||||
require.Equal(t, cl, len(classers.p))
|
require.Equal(t, cl, len(classers.p))
|
||||||
}
|
}
|
||||||
|
@@ -38,8 +38,15 @@ func (cc *CodecContext) Free() {
|
|||||||
C.av_buffer_unref(&cc.hdc.c)
|
C.av_buffer_unref(&cc.hdc.c)
|
||||||
cc.hdc = nil
|
cc.hdc = nil
|
||||||
}
|
}
|
||||||
classers.del(cc)
|
if cc.c != nil {
|
||||||
|
// Make sure to clone the classer before freeing the object since
|
||||||
|
// the C free method resets the pointer
|
||||||
|
c := newClonedClasser(cc)
|
||||||
C.avcodec_free_context(&cc.c)
|
C.avcodec_free_context(&cc.c)
|
||||||
|
// Make sure to remove from classers after freeing the object since
|
||||||
|
// the C free method may use methods needing the classer
|
||||||
|
classers.del(c)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cc *CodecContext) String() string {
|
func (cc *CodecContext) String() string {
|
||||||
|
@@ -27,8 +27,10 @@ func newFilterContext(c *C.AVFilterContext) *FilterContext {
|
|||||||
var _ Classer = (*FilterContext)(nil)
|
var _ Classer = (*FilterContext)(nil)
|
||||||
|
|
||||||
func (fc *FilterContext) Free() {
|
func (fc *FilterContext) Free() {
|
||||||
classers.del(fc)
|
|
||||||
C.avfilter_free(fc.c)
|
C.avfilter_free(fc.c)
|
||||||
|
// Make sure to remove from classers after freeing the object since
|
||||||
|
// the C free method may use methods needing the classer
|
||||||
|
classers.del(fc)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fc *FilterContext) BuffersrcAddFrame(f *Frame, fs BuffersrcFlags) error {
|
func (fc *FilterContext) BuffersrcAddFrame(f *Frame, fs BuffersrcFlags) error {
|
||||||
|
@@ -28,9 +28,14 @@ func AllocFilterGraph() *FilterGraph {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (g *FilterGraph) Free() {
|
func (g *FilterGraph) Free() {
|
||||||
classers.del(g)
|
|
||||||
if g.c != nil {
|
if g.c != nil {
|
||||||
|
// Make sure to clone the classer before freeing the object since
|
||||||
|
// the C free method resets the pointer
|
||||||
|
c := newClonedClasser(g)
|
||||||
C.avfilter_graph_free(&g.c)
|
C.avfilter_graph_free(&g.c)
|
||||||
|
// Make sure to remove from classers after freeing the object since
|
||||||
|
// the C free method may use methods needing the classer
|
||||||
|
classers.del(c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -51,8 +51,10 @@ func AllocOutputFormatContext(of *OutputFormat, formatName, filename string) (*F
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (fc *FormatContext) Free() {
|
func (fc *FormatContext) Free() {
|
||||||
classers.del(fc)
|
|
||||||
C.avformat_free_context(fc.c)
|
C.avformat_free_context(fc.c)
|
||||||
|
// Make sure to remove from classers after freeing the object since
|
||||||
|
// the C free method may use methods needing the classer
|
||||||
|
classers.del(fc)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fc *FormatContext) BitRate() int64 {
|
func (fc *FormatContext) BitRate() int64 {
|
||||||
@@ -192,12 +194,18 @@ func (fc *FormatContext) OpenInput(url string, fmt *InputFormat, d *Dictionary)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (fc *FormatContext) CloseInput() {
|
func (fc *FormatContext) CloseInput() {
|
||||||
if pb := fc.Pb(); pb != nil {
|
pb := fc.Pb()
|
||||||
|
if fc.c != nil {
|
||||||
|
// Make sure to clone the classer before freeing the object since
|
||||||
|
// the C free method resets the pointer
|
||||||
|
c := newClonedClasser(fc)
|
||||||
|
C.avformat_close_input(&fc.c)
|
||||||
|
// Make sure to remove from classers after freeing the object since
|
||||||
|
// the C free method may use methods needing the classer
|
||||||
|
if pb != nil {
|
||||||
classers.del(pb)
|
classers.del(pb)
|
||||||
}
|
}
|
||||||
classers.del(fc)
|
classers.del(c)
|
||||||
if fc.c != nil {
|
|
||||||
C.avformat_close_input(&fc.c)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -122,15 +122,21 @@ func (ic *IOContext) Class() *Class {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ic *IOContext) Close() error {
|
func (ic *IOContext) Close() error {
|
||||||
classers.del(ic)
|
|
||||||
if ic.c != nil {
|
if ic.c != nil {
|
||||||
return newError(C.avio_closep(&ic.c))
|
// Make sure to clone the classer before freeing the object since
|
||||||
|
// the C free method resets the pointer
|
||||||
|
c := newClonedClasser(ic)
|
||||||
|
if err := newError(C.avio_closep(&ic.c)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Make sure to remove from classers after freeing the object since
|
||||||
|
// the C free method may use methods needing the classer
|
||||||
|
classers.del(c)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ic *IOContext) Free() {
|
func (ic *IOContext) Free() {
|
||||||
classers.del(ic)
|
|
||||||
if ic.c != nil {
|
if ic.c != nil {
|
||||||
if ic.c.buffer != nil {
|
if ic.c.buffer != nil {
|
||||||
C.av_freep(unsafe.Pointer(&ic.c.buffer))
|
C.av_freep(unsafe.Pointer(&ic.c.buffer))
|
||||||
@@ -139,7 +145,13 @@ func (ic *IOContext) Free() {
|
|||||||
C.free(ic.handlerID)
|
C.free(ic.handlerID)
|
||||||
ic.handlerID = nil
|
ic.handlerID = nil
|
||||||
}
|
}
|
||||||
|
// Make sure to clone the classer before freeing the object since
|
||||||
|
// the C free method resets the pointer
|
||||||
|
c := newClonedClasser(ic)
|
||||||
C.avio_context_free(&ic.c)
|
C.avio_context_free(&ic.c)
|
||||||
|
// Make sure to remove from classers after freeing the object since
|
||||||
|
// the C free method may use methods needing the classer
|
||||||
|
classers.del(c)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@@ -60,8 +60,13 @@ func CreateSoftwareScaleContext(srcW, srcH int, srcFormat PixelFormat, dstW, dst
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ssc *SoftwareScaleContext) Free() {
|
func (ssc *SoftwareScaleContext) Free() {
|
||||||
classers.del(ssc)
|
// Make sure to clone the classer before freeing the object since
|
||||||
|
// the C free method may reset the pointer
|
||||||
|
c := newClonedClasser(ssc)
|
||||||
C.sws_freeContext(ssc.c)
|
C.sws_freeContext(ssc.c)
|
||||||
|
// Make sure to remove from classers after freeing the object since
|
||||||
|
// the C free method may use methods needing the classer
|
||||||
|
classers.del(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ Classer = (*SoftwareScaleContext)(nil)
|
var _ Classer = (*SoftwareScaleContext)(nil)
|
||||||
|
Reference in New Issue
Block a user