mirror of
https://github.com/asticode/go-astiav.git
synced 2026-04-22 15:57:03 +08:00
IOInterrupted now has a pointer to the callback + added tests for dictionary and iointerrupter for openiocontext
This commit is contained in:
@@ -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
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -1,4 +1,4 @@
|
||||
#include <libavformat/avio.h>
|
||||
|
||||
int astiavInterruptCallback(void *ret);
|
||||
AVIOInterruptCB astiavNewInterruptCallback(int *ret);
|
||||
AVIOInterruptCB* astiavNewInterruptCallback(int *ret);
|
||||
@@ -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())
|
||||
|
||||
Reference in New Issue
Block a user