diff --git a/BREAKING_CHANGES.md b/BREAKING_CHANGES.md index 630f024..e9df07d 100644 --- a/BREAKING_CHANGES.md +++ b/BREAKING_CHANGES.md @@ -2,6 +2,7 @@ - `CodecParameters`.`CodecType` and `CodecParameters`.`SetCodecType` have been removed, use `CodecParameters`.`MediaType` and `CodecParameters`.`SetMediaType` instead - `HardwareFrameContext`.`SetPixelFormat` has been replaced with `HardwareFrameContext`.`SetHardwarePixelFormat` +- `FormatContext`.`SetInterruptCallback` has been replaced with `FormatContext`.`SetIOInterrupter` # v0.24.0 diff --git a/format_context.go b/format_context.go index 1c191f9..f128fa2 100644 --- a/format_context.go +++ b/format_context.go @@ -102,10 +102,12 @@ func (fc *FormatContext) SetFlags(f FormatContextFlags) { } // https://ffmpeg.org/doxygen/7.0/structAVFormatContext.html#a5b37acfe4024d92ee510064e80920b40 -func (fc *FormatContext) SetInterruptCallback() IOInterrupter { - i := newDefaultIOInterrupter() - fc.c.interrupt_callback = i.c - return i +func (fc *FormatContext) SetIOInterrupter(i *IOInterrupter) { + if i == nil { + fc.c.interrupt_callback = C.AVIOInterruptCB{} + } else { + fc.c.interrupt_callback = i.c + } } // https://ffmpeg.org/doxygen/7.0/structAVFormatContext.html#a6c01f25ef062e0398b0b55dd337246ed diff --git a/format_context_test.go b/format_context_test.go index 9f8ce6a..444e631 100644 --- a/format_context_test.go +++ b/format_context_test.go @@ -89,9 +89,19 @@ func TestFormatContext(t *testing.T) { fc4 := AllocFormatContext() require.NotNil(t, fc4) defer fc4.Free() - fc4.SetInterruptCallback().Interrupt() + ii1 := NewIOInterrupter() + fc4.SetIOInterrupter(ii1) + ii1.Interrupt() require.ErrorIs(t, fc4.OpenInput("testdata/video.mp4", nil, nil), ErrExit) + fc9 := AllocFormatContext() + require.NotNil(t, fc9) + defer fc9.Free() + ii2 := NewIOInterrupter() + fc9.SetIOInterrupter(ii2) + fc9.SetIOInterrupter(nil) + require.NoError(t, fc4.OpenInput("testdata/video.mp4", nil, nil)) + fc5 := AllocFormatContext() require.NotNil(t, fc5) defer fc5.Free() diff --git a/io_interrupter.go b/io_interrupter.go index 9ede1fe..88a5206 100644 --- a/io_interrupter.go +++ b/io_interrupter.go @@ -3,26 +3,25 @@ package astiav //#include "io_interrupter.h" import "C" -type IOInterrupter interface { - Interrupt() - Resume() -} - -type defaultIOInterrupter struct { +type IOInterrupter struct { c C.AVIOInterruptCB i C.int } -func newDefaultIOInterrupter() *defaultIOInterrupter { - i := &defaultIOInterrupter{} +func NewIOInterrupter() *IOInterrupter { + i := &IOInterrupter{} i.c = C.astiavNewInterruptCallback(&i.i) return i } -func (i *defaultIOInterrupter) Interrupt() { +func (i *IOInterrupter) Interrupt() { i.i = 1 } -func (i *defaultIOInterrupter) Resume() { +func (i *IOInterrupter) Interrupted() bool { + return i.i == 1 +} + +func (i *IOInterrupter) Resume() { i.i = 0 } diff --git a/io_interrupter_test.go b/io_interrupter_test.go index 395688b..88f0bdd 100644 --- a/io_interrupter_test.go +++ b/io_interrupter_test.go @@ -6,11 +6,11 @@ import ( "github.com/stretchr/testify/require" ) -func TestDefaultIOInterrupter(t *testing.T) { - ii := newDefaultIOInterrupter() - require.Equal(t, 0, int(ii.i)) +func TestIOInterrupter(t *testing.T) { + ii := NewIOInterrupter() + require.False(t, ii.Interrupted()) ii.Interrupt() - require.Equal(t, 1, int(ii.i)) + require.True(t, ii.Interrupted()) ii.Resume() - require.Equal(t, 0, int(ii.i)) + require.False(t, ii.Interrupted()) } diff --git a/option.go b/option.go index 4fb21f3..dc0b2aa 100644 --- a/option.go +++ b/option.go @@ -7,6 +7,23 @@ import ( "unsafe" ) +// https://www.ffmpeg.org/doxygen/7.0/structAVOption.html +type Option struct { + c *C.AVOption +} + +func newOptionFromC(c *C.AVOption) *Option { + if c == nil { + return nil + } + return &Option{c: c} +} + +// https://www.ffmpeg.org/doxygen/7.0/structAVOption.html#a87e81c6e58d6a94d97a98ad15a4e507c +func (o *Option) Name() string { + return C.GoString(o.c.name) +} + type Options struct { c unsafe.Pointer } @@ -18,19 +35,15 @@ func newOptionsFromC(c unsafe.Pointer) *Options { return &Options{c: c} } -type Option struct { - Name string -} - // https://www.ffmpeg.org/doxygen/7.0/group__opt__mng.html#gabc75970cd87d1bf47a4ff449470e9225 -func (os *Options) List() (list []Option) { +func (os *Options) List() (list []*Option) { var prev *C.AVOption for { o := C.av_opt_next(os.c, prev) if o == nil { return } - list = append(list, Option{Name: C.GoString(o.name)}) + list = append(list, newOptionFromC(o)) prev = o } } diff --git a/option_test.go b/option_test.go index e5656fc..08c0486 100644 --- a/option_test.go +++ b/option_test.go @@ -13,16 +13,20 @@ func TestOption(t *testing.T) { require.NotNil(t, pd) os := pd.Options() require.NotNil(t, os) - require.Equal(t, []Option{{Name: "brand"}, {Name: "empty_hdlr_name"}, {Name: "encryption_key"}, {Name: "encryption_kid"}, {Name: "encryption_scheme"}, {Name: "frag_duration"}, {Name: "frag_interleave"}, {Name: "frag_size"}, {Name: "fragment_index"}, {Name: "iods_audio_profile"}, {Name: "iods_video_profile"}, {Name: "ism_lookahead"}, {Name: "movflags"}, {Name: "cmaf"}, {Name: "dash"}, {Name: "default_base_moof"}, {Name: "delay_moov"}, {Name: "disable_chpl"}, {Name: "empty_moov"}, {Name: "faststart"}, {Name: "frag_custom"}, {Name: "frag_discont"}, {Name: "frag_every_frame"}, {Name: "frag_keyframe"}, {Name: "global_sidx"}, {Name: "isml"}, {Name: "moov_size"}, {Name: "negative_cts_offsets"}, {Name: "omit_tfhd_offset"}, {Name: "prefer_icc"}, {Name: "rtphint"}, {Name: "separate_moof"}, {Name: "skip_sidx"}, {Name: "skip_trailer"}, {Name: "use_metadata_tags"}, {Name: "write_colr"}, {Name: "write_gama"}, {Name: "min_frag_duration"}, {Name: "mov_gamma"}, {Name: "movie_timescale"}, {Name: "rtpflags"}, {Name: "latm"}, {Name: "rfc2190"}, {Name: "skip_rtcp"}, {Name: "h264_mode0"}, {Name: "send_bye"}, {Name: "skip_iods"}, {Name: "use_editlist"}, {Name: "use_stream_ids_as_track_ids"}, {Name: "video_track_timescale"}, {Name: "write_btrt"}, {Name: "write_prft"}, {Name: "pts"}, {Name: "wallclock"}, {Name: "write_tmcd"}}, os.List()) + l := os.List() + require.Len(t, l, 55) + const name = "brand" + o := l[0] + require.Equal(t, name, o.Name()) _, err = os.Get("invalid", NewOptionSearchFlags()) require.Error(t, err) - v, err := os.Get("brand", NewOptionSearchFlags()) + v, err := os.Get(name, NewOptionSearchFlags()) require.NoError(t, err) require.Equal(t, "", v) require.Error(t, os.Set("invalid", "", NewOptionSearchFlags())) - const brand = "test" - require.NoError(t, os.Set("brand", brand, NewOptionSearchFlags())) - v, err = os.Get("brand", NewOptionSearchFlags()) + const value = "test" + require.NoError(t, os.Set(name, value, NewOptionSearchFlags())) + v, err = os.Get(name, NewOptionSearchFlags()) require.NoError(t, err) - require.Equal(t, brand, v) + require.Equal(t, value, v) }