@@ -92,15 +92,16 @@ AudioEncoder::AudioEncoder(
9292 validateSampleRate (*avCodec, sampleRate);
9393 avCodecContext_->sample_rate = sampleRate;
9494
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+
97103 // 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).
104105
105106 int numChannels = static_cast <int >(wf_.sizes ()[0 ]);
106107 TORCH_CHECK (
@@ -135,6 +136,27 @@ AudioEncoder::AudioEncoder(
135136 streamIndex_ = avStream->index ;
136137}
137138
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+
138160void AudioEncoder::encode () {
139161 UniqueAVFrame avFrame (av_frame_alloc ());
140162 TORCH_CHECK (avFrame != nullptr , " Couldn't allocate AVFrame." );
0 commit comments