Skip to content

Commit 60e56f3

Browse files
authored
Merge pull request #36 from mutablelogic/ffmpeg61
Fixed bug with resampling
2 parents df83a43 + 6d2f60d commit 60e56f3

File tree

5 files changed

+51
-11
lines changed

5 files changed

+51
-11
lines changed

etc/test/jfk.wav

344 KB
Binary file not shown.

pkg/ffmpeg/decoder.go

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -111,15 +111,17 @@ func (d *Decoder) Close() error {
111111
// Decode a packet into a set of frames to pass back to the
112112
// DecoderFrameFn. If the packet is nil, then the decoder will
113113
// flush any remaining frames.
114-
// TODO: Optionally use the user defined packet function
115-
// if they want to use AVParser
116-
// TODO: The frame sent to DecoderFrameFn needs to have the
117-
// correct timebase, etc set
114+
// TODO: Optionally use the user defined packet function if they want to use AVParser
118115
func (d *Decoder) decode(packet *ff.AVPacket, fn DecoderFrameFn) error {
119116
if fn == nil {
120117
return ErrBadParameter.With("DecoderFrameFn is nil")
121118
}
122119

120+
// Set the timebase for the packet
121+
if packet != nil {
122+
packet.SetTimeBase(d.timeBase)
123+
}
124+
123125
// Submit the packet to the decoder (nil packet will flush the decoder)
124126
if err := ff.AVCodec_send_packet(d.codec, packet); err != nil {
125127
return ErrInternalAppError.With("AVCodec_send_packet:", err)
@@ -142,6 +144,9 @@ func (d *Decoder) decode(packet *ff.AVPacket, fn DecoderFrameFn) error {
142144
return ErrInternalAppError.With("AVCodec_receive_frame:", err)
143145
}
144146

147+
// Set the timebase for the frame
148+
d.frame.SetTimeBase(packet.TimeBase())
149+
145150
// Obtain the output frame. If a new frame is returned, it is
146151
// managed by the rescaler/resizer and no need to unreference it
147152
// later.
@@ -161,12 +166,6 @@ func (d *Decoder) decode(packet *ff.AVPacket, fn DecoderFrameFn) error {
161166
continue
162167
}
163168

164-
// Copy across the timebase and pts
165-
// TODO
166-
// fmt.Println("pts=", d.frame.Pts())
167-
// (*ff.AVFrame)(dest).SetPts(d.frame.Pts())
168-
// (*ff.AVFrame)(dest).SetTimeBase(d.timeBase)
169-
170169
// Pass back to the caller
171170
if err := fn(d.stream, dest); errors.Is(err, io.EOF) {
172171
// End early, return EOF

pkg/ffmpeg/reader_test.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,3 +168,38 @@ func Test_reader_005(t *testing.T) {
168168
t.FailNow()
169169
}
170170
}
171+
172+
func Test_reader_006(t *testing.T) {
173+
assert := assert.New(t)
174+
175+
// Read a file
176+
r, err := os.Open("../../etc/test/jfk.wav")
177+
if !assert.NoError(err) {
178+
t.FailNow()
179+
}
180+
defer r.Close()
181+
182+
input, err := ffmpeg.NewReader(r)
183+
if !assert.NoError(err) {
184+
t.FailNow()
185+
}
186+
defer input.Close()
187+
188+
// Map function - only audio streams
189+
mapfn := func(stream int, par *ffmpeg.Par) (*ffmpeg.Par, error) {
190+
if par.Type() == media.AUDIO {
191+
t.Logf("Stream %v[%d] => %v", par.Type(), stream, par)
192+
return par, nil
193+
}
194+
return nil, nil
195+
}
196+
197+
framefn := func(stream int, frame *ffmpeg.Frame) error {
198+
t.Log("Got frame", frame)
199+
return nil
200+
}
201+
202+
if err := input.Decode(context.Background(), mapfn, framefn); !assert.NoError(err) {
203+
t.FailNow()
204+
}
205+
}

pkg/ffmpeg/resampler.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ func (r *resampler) Frame(src *Frame) (*Frame, error) {
107107
}
108108

109109
// Check buffer
110-
// TODO UGLY CODE ALERT
110+
// TODO: UGLY CODE ALERT
111111
if r.dest.NumSamples() < num_samples {
112112
sample_fmt := r.dest.SampleFormat()
113113
sample_rate := r.dest.SampleRate()

sys/ffmpeg61/swresample_convert.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,12 @@ func SWResample_get_out_samples(ctx *SWRContext, in_samples int) (int, error) {
6868

6969
// Convert the samples in the input AVFrame and write them to the output AVFrame.
7070
func SWResample_convert_frame(ctx *SWRContext, src, dest *AVFrame) error {
71+
// TODO: This is likely a terrible idea but the only thing I can get to work
72+
// at the moment. Later find out why swr_convert_frame isn't working.
73+
// Ref: https://stackoverflow.com/questions/77502983/libswresample-why-does-swr-init-change-in-ch-layout-order-so-it-no-longer-m
74+
if err := SWResample_config_frame(ctx, src, dest); err != nil {
75+
return err
76+
}
7177
if err := AVError(C.swr_convert_frame((*C.struct_SwrContext)(ctx), (*C.struct_AVFrame)(dest), (*C.struct_AVFrame)(src))); err != 0 {
7278
return err
7379
} else {

0 commit comments

Comments
 (0)