Skip to content

Commit bf1214a

Browse files
mthrokfacebook-github-bot
authored andcommitted
Set "experimental" automatically when using native opus/vorbis encoder (#3192)
Summary: OPUS encoder and VORBIS encoders require "strict=experimental" flags. This commit enables it automatically. The rational behind of it is typically we care if we can encode these formats at all and not how they are encoded. (This might be concern when these encoder becomes more mature on FFmpeg side and providing flags would result in weird behavior) Also when writing high-level functions that uses StreamWriter, if we do not set these flags, then these high-level functions have to add new options that should be passed down to StreamWriter, which turned out to be very painful in #3163 Pull Request resolved: #3192 Reviewed By: nateanl Differential Revision: D44275089 Pulled By: mthrok fbshipit-source-id: 74a757b4b7fc8467c8c88ffcb54fbaf89d6e4384
1 parent aa590a1 commit bf1214a

File tree

2 files changed

+45
-9
lines changed

2 files changed

+45
-9
lines changed

test/torchaudio_unittest/io/stream_writer_test.py

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -155,21 +155,26 @@ def test_valid_audio_muxer_and_codecs_wav(self, src_fmt, sample_rate, num_channe
155155

156156
@parameterized.expand(
157157
[
158-
("mp3", 8000, 1, "s32p", None),
159-
("mp3", 16000, 2, "fltp", None),
160-
("mp3", 44100, 1, "s16p", {"abr": "true"}),
161-
("flac", 8000, 1, "s16", None),
162-
("flac", 16000, 2, "s32", None),
163-
("opus", 48000, 2, None, {"strict": "experimental"}),
164-
("adts", 8000, 1, "fltp", None), # AAC format
158+
("mp3", 8000, 1, None, "s32p", None),
159+
("mp3", 16000, 2, None, "fltp", None),
160+
("mp3", 44100, 1, None, "s16p", {"abr": "true"}),
161+
("flac", 8000, 1, None, "s16", None),
162+
("flac", 16000, 2, None, "s32", None),
163+
("opus", 48000, 2, "opus", None, None),
164+
("ogg", 48000, 2, "vorbis", None, None),
165+
("adts", 8000, 1, None, "fltp", None), # AAC format
165166
]
166167
)
167-
def test_valid_audio_muxer_and_codecs(self, ext, sample_rate, num_channels, encoder_format, encoder_option):
168+
def test_valid_audio_muxer_and_codecs(
169+
self, ext, sample_rate, num_channels, encoder, encoder_format, encoder_option
170+
):
168171
"""Tensor of various dtypes can be saved as given format."""
169172
path = self.get_dst(f"test.{ext}")
170173
s = StreamWriter(path, format=ext)
171174
s.set_metadata(metadata={"artist": "torchaudio", "title": self.id()})
172-
s.add_audio_stream(sample_rate, num_channels, encoder_option=encoder_option, encoder_format=encoder_format)
175+
s.add_audio_stream(
176+
sample_rate, num_channels, encoder=encoder, encoder_option=encoder_option, encoder_format=encoder_format
177+
)
173178

174179
chunk = get_audio_chunk("flt", sample_rate, num_channels)
175180
with s.open():

torchaudio/csrc/ffmpeg/stream_writer/encode_process.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,37 @@ void open_codec(
178178
AVCodecContextPtr& codec_ctx,
179179
const c10::optional<OptionDict>& option) {
180180
AVDictionary* opt = get_option_dict(option);
181+
182+
// Enable experimental feature if required
183+
// Note:
184+
// "vorbis" refers to FFmpeg's native encoder,
185+
// https://ffmpeg.org/doxygen/4.1/vorbisenc_8c.html#a8c2e524b0f125f045fef39c747561450
186+
// while "libvorbis" refers to the one depends on libvorbis,
187+
// which is not experimental
188+
// https://ffmpeg.org/doxygen/4.1/libvorbisenc_8c.html#a5dd5fc671e2df9c5b1f97b2ee53d4025
189+
// similarly, "opus" refers to FFmpeg's native encoder
190+
// https://ffmpeg.org/doxygen/4.1/opusenc_8c.html#a05b203d4a9a231cc1fd5a7ddeb68cebc
191+
// while "libopus" refers to the one depends on libopusenc
192+
// https://ffmpeg.org/doxygen/4.1/libopusenc_8c.html#aa1d649e48cd2ec00cfe181cf9d0f3251
193+
if (std::strcmp(codec_ctx->codec->name, "vorbis") == 0) {
194+
if (!av_dict_get(opt, "strict", nullptr, 0)) {
195+
TORCH_WARN_ONCE(
196+
"\"vorbis\" encoder is selected. Enabling '-strict experimental'. ",
197+
"If this is not desired, please provide \"strict\" encoder option ",
198+
"with desired value.");
199+
av_dict_set(&opt, "strict", "experimental", 0);
200+
}
201+
}
202+
if (std::strcmp(codec_ctx->codec->name, "opus") == 0) {
203+
if (!av_dict_get(opt, "strict", nullptr, 0)) {
204+
TORCH_WARN_ONCE(
205+
"\"opus\" encoder is selected. Enabling '-strict experimental'. ",
206+
"If this is not desired, please provide \"strict\" encoder option ",
207+
"with desired value.");
208+
av_dict_set(&opt, "strict", "experimental", 0);
209+
}
210+
}
211+
181212
int ret = avcodec_open2(codec_ctx, codec_ctx->codec, &opt);
182213
clean_up_dict(opt);
183214
TORCH_CHECK(ret >= 0, "Failed to open codec: (", av_err2string(ret), ")");

0 commit comments

Comments
 (0)