From 09efdfd00e97f3c22bdf6eb155a53b049337687b Mon Sep 17 00:00:00 2001 From: Diallo Han Date: Thu, 5 Sep 2024 17:37:27 +0900 Subject: [PATCH 1/3] add audiofifo --- audio_fifo.go | 46 ++++++++++++++++++++++++++++++++++++++++++++++ audio_fifo_test.go | 36 ++++++++++++++++++++++++++++++++++++ frame.go | 4 ++++ 3 files changed, 86 insertions(+) create mode 100644 audio_fifo.go create mode 100644 audio_fifo_test.go diff --git a/audio_fifo.go b/audio_fifo.go new file mode 100644 index 0000000..42068b0 --- /dev/null +++ b/audio_fifo.go @@ -0,0 +1,46 @@ +package astiav + +//#cgo pkg-config: libavutil +//#include +//#include +import "C" +import "unsafe" + +type AudioFifo struct { + c *C.struct_AVAudioFifo +} + +func newAudioFifoFromC(c *C.struct_AVAudioFifo) *AudioFifo { + if c == nil { + return nil + } + return &AudioFifo{c: c} +} + +func AllocAudioFifo(sampleFmt SampleFormat, channels int, nbSamples int) *AudioFifo { + return newAudioFifoFromC(C.av_audio_fifo_alloc(C.enum_AVSampleFormat(sampleFmt), C.int(channels), C.int(nbSamples))) +} + +func (a *AudioFifo) AudioFifoRealloc(nbSamples int) int { + return int(C.av_audio_fifo_realloc((*C.struct_AVAudioFifo)(a.c), C.int(nbSamples))) +} + +func (a *AudioFifo) AudioFifoSize() int { + return int(C.av_audio_fifo_size((*C.struct_AVAudioFifo)(a.c))) +} + +func (a *AudioFifo) AudioFifoSpace() int { + return int(C.av_audio_fifo_space((*C.struct_AVAudioFifo)(a.c))) +} + +func (a *AudioFifo) AudioFifoWrite(data **uint8, nbSamples int) int { + return int(C.av_audio_fifo_write((*C.struct_AVAudioFifo)(a.c), (*unsafe.Pointer)(unsafe.Pointer(data)), C.int(nbSamples))) +} + +func (a *AudioFifo) AudioFifoRead(data **uint8, nbSamples int) int { + return int(C.av_audio_fifo_read((*C.struct_AVAudioFifo)(a.c), (*unsafe.Pointer)(unsafe.Pointer(data)), C.int(nbSamples))) +} + +func (a *AudioFifo) AudioFifoFree() { + C.av_audio_fifo_free((*C.struct_AVAudioFifo)(a.c)) +} diff --git a/audio_fifo_test.go b/audio_fifo_test.go new file mode 100644 index 0000000..6b7e29d --- /dev/null +++ b/audio_fifo_test.go @@ -0,0 +1,36 @@ +package astiav + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestAudioFIFO(t *testing.T) { + audioFifo := AllocAudioFifo( + SampleFormatFltp, + 2, + 960) + + writeSamples := 1024 + readSamples := 120 + writeFrame := AllocFrame() + writeFrame.SetNbSamples(writeSamples) + writeFrame.SetChannelLayout(ChannelLayoutStereo) + writeFrame.SetSampleFormat(SampleFormatFltp) + writeFrame.SetSampleRate(48000) + writeFrame.AllocBuffer(0) + + readFrame := AllocFrame() + readFrame.SetNbSamples(readSamples) + readFrame.SetChannelLayout(ChannelLayoutStereo) + readFrame.SetSampleFormat(SampleFormatFltp) + readFrame.SetSampleRate(48000) + readFrame.AllocBuffer(0) + + written := audioFifo.AudioFifoWrite(writeFrame.DataPtr(), writeFrame.NbSamples()) + require.Equal(t, writeSamples, written) + read := audioFifo.AudioFifoRead(readFrame.DataPtr(), readFrame.NbSamples()) + require.Equal(t, readSamples, read) + require.Equal(t, audioFifo.AudioFifoSize(), writeSamples-readSamples) +} diff --git a/frame.go b/frame.go index 685f79f..b13942f 100644 --- a/frame.go +++ b/frame.go @@ -217,3 +217,7 @@ func (f *Frame) MoveRef(src *Frame) { func (f *Frame) UnsafePointer() unsafe.Pointer { return unsafe.Pointer(f.c) } + +func (f *Frame) DataPtr() **uint8 { + return (**uint8)(unsafe.Pointer(&f.c.data[0])) +} From ae170424de5741074e17a5c716d6b7333fea5eb4 Mon Sep 17 00:00:00 2001 From: Diallo Han Date: Thu, 5 Sep 2024 20:24:34 +0900 Subject: [PATCH 2/3] applied review --- audio_fifo.go | 34 ++++++++++++++++++++-------------- audio_fifo_test.go | 18 +++++++++++++----- 2 files changed, 33 insertions(+), 19 deletions(-) diff --git a/audio_fifo.go b/audio_fifo.go index 42068b0..a184116 100644 --- a/audio_fifo.go +++ b/audio_fifo.go @@ -1,13 +1,13 @@ package astiav -//#cgo pkg-config: libavutil //#include //#include import "C" import "unsafe" +// https://github.com/FFmpeg/FFmpeg/blob/n7.0/libavutil/audio_fifo.c#L37 type AudioFifo struct { - c *C.struct_AVAudioFifo + c *C.AVAudioFifo } func newAudioFifoFromC(c *C.struct_AVAudioFifo) *AudioFifo { @@ -21,26 +21,32 @@ func AllocAudioFifo(sampleFmt SampleFormat, channels int, nbSamples int) *AudioF return newAudioFifoFromC(C.av_audio_fifo_alloc(C.enum_AVSampleFormat(sampleFmt), C.int(channels), C.int(nbSamples))) } -func (a *AudioFifo) AudioFifoRealloc(nbSamples int) int { - return int(C.av_audio_fifo_realloc((*C.struct_AVAudioFifo)(a.c), C.int(nbSamples))) +func (a *AudioFifo) Realloc(nbSamples int) error { + return newError(C.av_audio_fifo_realloc(a.c, C.int(nbSamples))) } -func (a *AudioFifo) AudioFifoSize() int { - return int(C.av_audio_fifo_size((*C.struct_AVAudioFifo)(a.c))) +func (a *AudioFifo) Size() int { + return int(C.av_audio_fifo_size(a.c)) } -func (a *AudioFifo) AudioFifoSpace() int { - return int(C.av_audio_fifo_space((*C.struct_AVAudioFifo)(a.c))) +func (a *AudioFifo) Space() int { + return int(C.av_audio_fifo_space(a.c)) } -func (a *AudioFifo) AudioFifoWrite(data **uint8, nbSamples int) int { - return int(C.av_audio_fifo_write((*C.struct_AVAudioFifo)(a.c), (*unsafe.Pointer)(unsafe.Pointer(data)), C.int(nbSamples))) +func (a *AudioFifo) Write(f *Frame) (int, error) { + frameRawData := (**uint8)(unsafe.Pointer(&f.c.data[0])) + ret := int(C.av_audio_fifo_write(a.c, (*unsafe.Pointer)(unsafe.Pointer(frameRawData)), C.int(f.NbSamples()))) + if ret < 0 { + return ret, newError(C.int(ret)) + } + return ret, nil } -func (a *AudioFifo) AudioFifoRead(data **uint8, nbSamples int) int { - return int(C.av_audio_fifo_read((*C.struct_AVAudioFifo)(a.c), (*unsafe.Pointer)(unsafe.Pointer(data)), C.int(nbSamples))) +func (a *AudioFifo) Read(f *Frame) int { + frameRawData := (**uint8)(unsafe.Pointer(&f.c.data[0])) + return int(C.av_audio_fifo_read(a.c, (*unsafe.Pointer)(unsafe.Pointer(frameRawData)), C.int(f.NbSamples()))) } -func (a *AudioFifo) AudioFifoFree() { - C.av_audio_fifo_free((*C.struct_AVAudioFifo)(a.c)) +func (a *AudioFifo) Free() { + C.av_audio_fifo_free(a.c) } diff --git a/audio_fifo_test.go b/audio_fifo_test.go index 6b7e29d..4ed1e1a 100644 --- a/audio_fifo_test.go +++ b/audio_fifo_test.go @@ -7,11 +7,11 @@ import ( ) func TestAudioFIFO(t *testing.T) { - audioFifo := AllocAudioFifo( + af := AllocAudioFifo( SampleFormatFltp, 2, 960) - + defer af.Free() writeSamples := 1024 readSamples := 120 writeFrame := AllocFrame() @@ -28,9 +28,17 @@ func TestAudioFIFO(t *testing.T) { readFrame.SetSampleRate(48000) readFrame.AllocBuffer(0) - written := audioFifo.AudioFifoWrite(writeFrame.DataPtr(), writeFrame.NbSamples()) + written, err := af.Write(writeFrame) + require.Equal(t, err, nil) require.Equal(t, writeSamples, written) - read := audioFifo.AudioFifoRead(readFrame.DataPtr(), readFrame.NbSamples()) + read := af.Read(readFrame) require.Equal(t, readSamples, read) - require.Equal(t, audioFifo.AudioFifoSize(), writeSamples-readSamples) + require.Equal(t, af.Size(), writeSamples-readSamples) + reallocSamples := 3000 + err = af.Realloc(reallocSamples) + require.Equal(t, err, nil) + expectedAfSize := writeSamples - readSamples + require.Equal(t, af.Space(), reallocSamples-expectedAfSize) + // It still has the same amount of data + require.Equal(t, af.Size(), expectedAfSize) } From e4288156d62556106158d97fb29cfe4b4e954696 Mon Sep 17 00:00:00 2001 From: Diallo Han Date: Thu, 5 Sep 2024 20:46:28 +0900 Subject: [PATCH 3/3] apply review --- audio_fifo.go | 12 +++++++----- audio_fifo_test.go | 7 ++++--- frame.go | 4 ---- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/audio_fifo.go b/audio_fifo.go index a184116..43cd712 100644 --- a/audio_fifo.go +++ b/audio_fifo.go @@ -34,17 +34,19 @@ func (a *AudioFifo) Space() int { } func (a *AudioFifo) Write(f *Frame) (int, error) { - frameRawData := (**uint8)(unsafe.Pointer(&f.c.data[0])) - ret := int(C.av_audio_fifo_write(a.c, (*unsafe.Pointer)(unsafe.Pointer(frameRawData)), C.int(f.NbSamples()))) + ret := int(C.av_audio_fifo_write(a.c, (*unsafe.Pointer)(unsafe.Pointer(&f.c.data[0])), C.int(f.NbSamples()))) if ret < 0 { return ret, newError(C.int(ret)) } return ret, nil } -func (a *AudioFifo) Read(f *Frame) int { - frameRawData := (**uint8)(unsafe.Pointer(&f.c.data[0])) - return int(C.av_audio_fifo_read(a.c, (*unsafe.Pointer)(unsafe.Pointer(frameRawData)), C.int(f.NbSamples()))) +func (a *AudioFifo) Read(f *Frame) (int, error) { + ret := int(C.av_audio_fifo_read(a.c, (*unsafe.Pointer)(unsafe.Pointer(&f.c.data[0])), C.int(f.NbSamples()))) + if ret < 0 { + return ret, newError(C.int(ret)) + } + return ret, nil } func (a *AudioFifo) Free() { diff --git a/audio_fifo_test.go b/audio_fifo_test.go index 4ed1e1a..91a3156 100644 --- a/audio_fifo_test.go +++ b/audio_fifo_test.go @@ -29,14 +29,15 @@ func TestAudioFIFO(t *testing.T) { readFrame.AllocBuffer(0) written, err := af.Write(writeFrame) - require.Equal(t, err, nil) + require.NoError(t, err) require.Equal(t, writeSamples, written) - read := af.Read(readFrame) + read, err := af.Read(readFrame) + require.NoError(t, err) require.Equal(t, readSamples, read) require.Equal(t, af.Size(), writeSamples-readSamples) reallocSamples := 3000 err = af.Realloc(reallocSamples) - require.Equal(t, err, nil) + require.NoError(t, err) expectedAfSize := writeSamples - readSamples require.Equal(t, af.Space(), reallocSamples-expectedAfSize) // It still has the same amount of data diff --git a/frame.go b/frame.go index b13942f..685f79f 100644 --- a/frame.go +++ b/frame.go @@ -217,7 +217,3 @@ func (f *Frame) MoveRef(src *Frame) { func (f *Frame) UnsafePointer() unsafe.Pointer { return unsafe.Pointer(f.c) } - -func (f *Frame) DataPtr() **uint8 { - return (**uint8)(unsafe.Pointer(&f.c.data[0])) -}