Skip to content

Commit 8b30ed0

Browse files
committed
Adding param checking for encoder
1 parent 200f3bc commit 8b30ed0

File tree

2 files changed

+76
-8
lines changed

2 files changed

+76
-8
lines changed

encoder.go

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -69,24 +69,47 @@ func newEncoder(ctx *ff.AVFormatContext, stream_id int, param Parameters) (*enco
6969
switch codec.Type() {
7070
case ff.AVMEDIA_TYPE_AUDIO:
7171
encoder.t = AUDIO
72-
// TODO: Check codec supports this configuration
7372

74-
// Set codec parameters
75-
if err := codecctx.SetChannelLayout(par.audiopar.Ch); err != nil {
73+
// Choose sample format
74+
if sampleformat, err := ff.AVCodec_supported_sampleformat(codec, par.audiopar.SampleFormat); err != nil {
75+
ff.AVCodec_free_context(codecctx)
76+
return nil, err
77+
} else {
78+
codecctx.SetSampleFormat(sampleformat)
79+
}
80+
81+
// Choose sample rate
82+
if samplerate, err := ff.AVCodec_supported_samplerate(codec, par.audiopar.Samplerate); err != nil {
83+
ff.AVCodec_free_context(codecctx)
84+
return nil, err
85+
} else {
86+
codecctx.SetSampleRate(samplerate)
87+
}
88+
89+
// Choose channel layout
90+
if channellayout, err := ff.AVCodec_supported_channellayout(codec, par.audiopar.Ch); err != nil {
91+
ff.AVCodec_free_context(codecctx)
92+
return nil, err
93+
} else if err := codecctx.SetChannelLayout(channellayout); err != nil {
7694
ff.AVCodec_free_context(codecctx)
7795
return nil, err
7896
}
79-
codecctx.SetSampleFormat(par.audiopar.SampleFormat)
80-
codecctx.SetSampleRate(par.audiopar.Samplerate)
8197

8298
// Set stream parameters
8399
encoder.stream.SetTimeBase(ff.AVUtil_rational(1, par.audiopar.Samplerate))
100+
84101
case ff.AVMEDIA_TYPE_VIDEO:
85102
encoder.t = VIDEO
86-
// TODO: Check codec supports this configuration
103+
104+
// Choose pixel format
105+
if pixelformat, err := ff.AVCodec_supported_pixelformat(codec, par.videopar.PixelFormat); err != nil {
106+
ff.AVCodec_free_context(codecctx)
107+
return nil, err
108+
} else {
109+
codecctx.SetPixFmt(pixelformat)
110+
}
87111

88112
// Set codec parameters
89-
codecctx.SetPixFmt(par.videopar.PixelFormat)
90113
codecctx.SetWidth(par.videopar.Width)
91114
codecctx.SetHeight(par.videopar.Height)
92115

sys/ffmpeg61/avcodec_core.go

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package ffmpeg
22

3-
import "unsafe"
3+
import (
4+
"fmt"
5+
"unsafe"
6+
)
47

58
////////////////////////////////////////////////////////////////////////////////
69
// CGO
@@ -99,3 +102,45 @@ func AVCodec_is_encoder(codec *AVCodec) bool {
99102
func AVCodec_is_decoder(codec *AVCodec) bool {
100103
return C.av_codec_is_decoder((*C.struct_AVCodec)(codec)) != 0
101104
}
105+
106+
// Return a supported sample format that is closest to the given sample format.
107+
func AVCodec_supported_sampleformat(codec *AVCodec, samplefmt AVSampleFormat) (AVSampleFormat, error) {
108+
for _, fmt := range codec.SampleFormats() {
109+
if fmt == samplefmt {
110+
return samplefmt, nil
111+
}
112+
}
113+
return AVSampleFormat(AV_SAMPLE_FMT_NONE), fmt.Errorf("sample format %v is not supported by codec %q", samplefmt, codec.Name())
114+
}
115+
116+
// Return a supported sample rate that is closest to the given sample rate.
117+
func AVCodec_supported_samplerate(codec *AVCodec, samplerate int) (int, error) {
118+
max := 0
119+
for _, rate := range codec.SupportedSamplerates() {
120+
if rate == samplerate {
121+
return samplerate, nil
122+
}
123+
if rate > max {
124+
max = rate
125+
}
126+
}
127+
if max > 0 {
128+
return max, nil
129+
} else {
130+
return 0, fmt.Errorf("sample rate %v is not supported by codec %q", samplerate, codec.Name())
131+
}
132+
}
133+
134+
// Return a supported channel layout that is closest to the given channel layout.
135+
func AVCodec_supported_channellayout(codec *AVCodec, channellayout AVChannelLayout) (AVChannelLayout, error) {
136+
for _, layout := range codec.ChannelLayouts() {
137+
if C.av_channel_layout_compare(&layout, &channellayout) == 0 {
138+
return channellayout, nil
139+
}
140+
}
141+
}
142+
143+
// Return a supported pixel format that is closest to the given pixel format.
144+
func AVCodec_supported_pixelformat(AVCodec *codec, AVPixelFormat pixelformat) (AVPixelFormat, error) {
145+
146+
}

0 commit comments

Comments
 (0)