Skip to content

Commit 872b569

Browse files
committed
Automatically find output sample format
1 parent 9150137 commit 872b569

File tree

2 files changed

+31
-8
lines changed

2 files changed

+31
-8
lines changed

src/torchcodec/_core/Encoder.cpp

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
138160
void AudioEncoder::encode() {
139161
UniqueAVFrame avFrame(av_frame_alloc());
140162
TORCH_CHECK(avFrame != nullptr, "Couldn't allocate AVFrame.");

src/torchcodec/_core/Encoder.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class AudioEncoder {
2828
AutoAVPacket& autoAVPacket,
2929
const UniqueAVFrame& avFrame);
3030
void flushBuffers();
31+
AVSampleFormat findOutputSampleFormat(const AVCodec& avCodec);
3132

3233
UniqueEncodingAVFormatContext avFormatContext_;
3334
UniqueAVCodecContext avCodecContext_;

0 commit comments

Comments
 (0)