IOInterrupted now has a pointer to the callback + added tests for dictionary and iointerrupter for openiocontext

This commit is contained in:
Quentin Renard
2024-12-13 11:23:45 +01:00
parent f8f8f0e7ee
commit 7dedb3f330
9 changed files with 51 additions and 18 deletions
+4
View File
@@ -1,3 +1,7 @@
# v0.27.0
- make sure to call the `IOInterrupter`.`Free` method after using `NewIOInterrupter`
# v0.25.0
- `CodecParameters`.`CodecType` and `CodecParameters`.`SetCodecType` have been removed, use `CodecParameters`.`MediaType` and `CodecParameters`.`SetMediaType` instead
+1 -1
View File
@@ -106,7 +106,7 @@ func (fc *FormatContext) SetIOInterrupter(i *IOInterrupter) {
if i == nil {
fc.c.interrupt_callback = C.AVIOInterruptCB{}
} else {
fc.c.interrupt_callback = i.c
fc.c.interrupt_callback = *i.c
}
}
+2
View File
@@ -90,6 +90,7 @@ func TestFormatContext(t *testing.T) {
require.NotNil(t, fc4)
defer fc4.Free()
ii1 := NewIOInterrupter()
defer ii1.Free()
fc4.SetIOInterrupter(ii1)
ii1.Interrupt()
require.ErrorIs(t, fc4.OpenInput("testdata/video.mp4", nil, nil), ErrExit)
@@ -98,6 +99,7 @@ func TestFormatContext(t *testing.T) {
require.NotNil(t, fc9)
defer fc9.Free()
ii2 := NewIOInterrupter()
defer ii2.Free()
fc9.SetIOInterrupter(ii2)
fc9.SetIOInterrupter(nil)
require.NoError(t, fc4.OpenInput("testdata/video.mp4", nil, nil))
+6 -5
View File
@@ -118,7 +118,7 @@ func OpenIOContext(filename string, flags IOContextFlags, ii *IOInterrupter, d *
}
var cii *C.AVIOInterruptCB = nil
if ii != nil {
cii = &ii.c
cii = ii.c
}
var c *C.AVIOContext
if err := newError(C.avio_open2(&c, cfi, C.int(flags), cii, dc)); err != nil {
@@ -137,14 +137,15 @@ func (ic *IOContext) Close() error {
// Make sure to clone the classer before freeing the object since
// the C free method may reset the pointer
c := newClonedClasser(ic)
if err := newError(C.avio_closep(&ic.c)); err != nil {
return err
}
// Error is returned when closing the url but pointer has been freed at this point
// therefore we must make sure classers are cleaned up properly even on error
err := newError(C.avio_closep(&ic.c))
// Make sure to remove from classers after freeing the object since
// the C free method may use methods needing the classer
if c != nil {
if c != nil && ic.c == nil {
classers.del(c)
}
return err
}
return nil
}
+24 -8
View File
@@ -56,17 +56,33 @@ func TestIOContext(t *testing.T) {
func TestOpenIOContext(t *testing.T) {
path := filepath.Join(t.TempDir(), "iocontext.txt")
c, err := OpenIOContext(path, NewIOContextFlags(IOContextFlagWrite), nil, nil)
c1, err := OpenIOContext(path, NewIOContextFlags(IOContextFlagWrite), nil, nil)
require.NoError(t, err)
cl := c.Class()
defer os.RemoveAll(path)
cl := c1.Class()
require.NotNil(t, cl)
require.Equal(t, "AVIOContext", cl.Name())
c.Write(nil)
c.Write([]byte("test"))
require.NoError(t, c.Close())
b, err := os.ReadFile(path)
c1.Write(nil)
c1.Write([]byte("test"))
require.NoError(t, c1.Close())
b1, err := os.ReadFile(path)
require.NoError(t, err)
require.Equal(t, "test", string(b))
err = os.Remove(path)
require.Equal(t, "test", string(b1))
ii := NewIOInterrupter()
defer ii.Free()
c2, err := OpenIOContext(path, NewIOContextFlags(IOContextFlagRead), ii, nil)
require.NoError(t, err)
b2 := make([]byte, 10)
_, err = c2.Read(b2)
require.NoError(t, err)
ii.Interrupt()
_, err = c2.Read(b2)
require.ErrorIs(t, err, ErrExit)
require.ErrorIs(t, c2.Close(), ErrExit)
d := NewDictionary()
require.NoError(t, d.Set("protocol_whitelist", "rtp", NewDictionaryFlags()))
_, err = OpenIOContext(path, NewIOContextFlags(IOContextFlagWrite), nil, d)
require.Error(t, err)
}
+5 -2
View File
@@ -1,12 +1,15 @@
#include <libavformat/avio.h>
#include <stdlib.h>
int astiavInterruptCallback(void *ret)
{
return *((int*)ret);
}
AVIOInterruptCB astiavNewInterruptCallback(int *ret)
AVIOInterruptCB* astiavNewInterruptCallback(int *ret)
{
AVIOInterruptCB c = { astiavInterruptCallback, ret };
AVIOInterruptCB* c = malloc(sizeof(AVIOInterruptCB));
c->callback = astiavInterruptCallback;
c->opaque = ret;
return c;
}
+7 -1
View File
@@ -1,10 +1,12 @@
package astiav
//#include "io_interrupter.h"
//#include <stdlib.h>
import "C"
import "unsafe"
type IOInterrupter struct {
c C.AVIOInterruptCB
c *C.AVIOInterruptCB
i C.int
}
@@ -14,6 +16,10 @@ func NewIOInterrupter() *IOInterrupter {
return i
}
func (i *IOInterrupter) Free() {
C.free(unsafe.Pointer(i.c))
}
func (i *IOInterrupter) Interrupt() {
i.i = 1
}
+1 -1
View File
@@ -1,4 +1,4 @@
#include <libavformat/avio.h>
int astiavInterruptCallback(void *ret);
AVIOInterruptCB astiavNewInterruptCallback(int *ret);
AVIOInterruptCB* astiavNewInterruptCallback(int *ret);
+1
View File
@@ -8,6 +8,7 @@ import (
func TestIOInterrupter(t *testing.T) {
ii := NewIOInterrupter()
defer ii.Free()
require.False(t, ii.Interrupted())
ii.Interrupt()
require.True(t, ii.Interrupted())