@@ -92,15 +92,16 @@ AudioEncoder::AudioEncoder(
92
92
validateSampleRate (*avCodec, sampleRate);
93
93
avCodecContext_->sample_rate = sampleRate;
94
94
95
- // Note: This is the format of the **input** waveform. This doesn't determine
96
- // the output.
95
+ // Input waveform is expected to be FLTP. Not all encoders support FLTP, so we
96
+ // may need to convert the wf into a supported output sample format, which is
97
+ // what the `.sample_fmt` defines.
98
+ avCodecContext_->sample_fmt = findOutputSampleFormat (*avCodec);
99
+ printf (
100
+ " Will be using: %s\n " ,
101
+ av_get_sample_fmt_name (avCodecContext_->sample_fmt ));
102
+
97
103
// TODO-ENCODING check contiguity of the input wf to ensure that it is indeed
98
- // planar.
99
- // TODO-ENCODING If the encoder doesn't support FLTP (like flac), FFmpeg will
100
- // raise. We need to handle this, probably converting the format with
101
- // libswresample.
102
- avCodecContext_->sample_fmt = AV_SAMPLE_FMT_FLTP;
103
- // avCodecContext_->sample_fmt = AV_SAMPLE_FMT_S16;
104
+ // planar (fltp).
104
105
105
106
int numChannels = static_cast <int >(wf_.sizes ()[0 ]);
106
107
TORCH_CHECK (
@@ -135,6 +136,27 @@ AudioEncoder::AudioEncoder(
135
136
streamIndex_ = avStream->index ;
136
137
}
137
138
139
+ AVSampleFormat AudioEncoder::findOutputSampleFormat (const AVCodec& avCodec) {
140
+ // Find a sample format that the encoder supports. If FLTP is supported then
141
+ // we use that, since this is the expected format of the input waveform.
142
+ // Otherwise, we'll need to convert the waveform before passing it to the
143
+ // encoder. Right now, the output format we'll choose is just the first format
144
+ // in the `sample_fmts` list that the AVCodec defines. Eventually, we may
145
+ // allow the user to choose.
146
+ if (avCodec.sample_fmts == nullptr ) {
147
+ // Can't really validate anything in this case, best we can do is hope that
148
+ // FLTP is supported by the encoder. If not, FFmpeg will raise.
149
+ return AV_SAMPLE_FMT_FLTP;
150
+ }
151
+
152
+ for (auto i = 0 ; avCodec.sample_fmts [i] != -1 ; ++i) {
153
+ if (avCodec.sample_fmts [i] == AV_SAMPLE_FMT_FLTP) {
154
+ return AV_SAMPLE_FMT_FLTP;
155
+ }
156
+ }
157
+ return avCodec.sample_fmts [0 ];
158
+ }
159
+
138
160
void AudioEncoder::encode () {
139
161
UniqueAVFrame avFrame (av_frame_alloc ());
140
162
TORCH_CHECK (avFrame != nullptr , " Couldn't allocate AVFrame." );
0 commit comments