はじめに
FFmpegではAACのsample_fmtがデフォルトでfltpになっています。
ソースコードやメーリングリストを調べてみました。
ffmpeg-3.0.3
ffmpeg-3.0.3のソースコードを見てみます。
libavcodec/aacdec.c
AVCodec ff_aac_decoder = {
.name = "aac",
.long_name = NULL_IF_CONFIG_SMALL("AAC (Advanced Audio Coding)"),
.type = AVMEDIA_TYPE_AUDIO,
.id = AV_CODEC_ID_AAC,
.priv_data_size = sizeof(AACContext),
.init = aac_decode_init,
.close = aac_decode_close,
.decode = aac_decode_frame,
.sample_fmts = (const enum AVSampleFormat[]) {
AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE
},
.capabilities = AV_CODEC_CAP_CHANNEL_CONF | AV_CODEC_CAP_DR1,
.caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
.channel_layouts = aac_channel_layout,
.flush = flush,
.priv_class = &aac_decoder_class,
.profiles = NULL_IF_CONFIG_SMALL(ff_aac_profiles),
};
以下の通り、AV_SAMPLE_FMT_FLTPしか受け付けられなくなっていました。
.sample_fmts = (const enum AVSampleFormat[]) {
AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE
},
aacdec_template.c
デコード初期化aac_decode_initはaacdec_template.cにあります。
static av_cold int aac_decode_init(AVCodecContext *avctx)
{
AACContext *ac = avctx->priv_data;
int ret;
ret = ff_thread_once(&aac_table_init, &aac_static_table_init);
if (ret != 0)
return AVERROR_UNKNOWN;
ac->avctx = avctx;
ac->oc[1].m4ac.sample_rate = avctx->sample_rate;
aacdec_init(ac);
#if USE_FIXED
avctx->sample_fmt = AV_SAMPLE_FMT_S32P;
#else
avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
#endif /* USE_FIXED */
以下の通り、USE_FIXEDがdefineされていなければ固定でAV_SAMPLE_FMT_FLTPになります。
#if USE_FIXED
avctx->sample_fmt = AV_SAMPLE_FMT_S32P;
#else
avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
#endif /* USE_FIXED */
オプション指定でs16にできないものかと思っていましたがソースコード上で固定でfltpになっていることが分かりました。
git上の修正
fltp固定に変更したときの修正は以下です。
aacdec: use float planar sample format for output
https://github.com/FFmpeg/FFmpeg/commit/3d3cf6745e2a5dc9c377244454c3186d75b177fa
変更した理由
[FFmpeg-user] what is "fltp" for audio when using ffmpeg
メーリングリストの記載によるとfltpにした目的は以下とのこと。
The main target is to eliminate extra processing in audio decoders and move
out it to dedicated re-sampling library.