obs-ffmpeg: Allow specifying audio sample format

This commit is contained in:
derrod 2023-04-03 22:48:55 +02:00 committed by Rodney
parent d2902c1316
commit c2e66942d0

View file

@ -210,7 +210,8 @@ static void init_sizes(struct enc_encoder *enc, audio_t *audio)
#endif
static void *enc_create(obs_data_t *settings, obs_encoder_t *encoder,
const char *type, const char *alt)
const char *type, const char *alt,
enum AVSampleFormat sample_format)
{
struct enc_encoder *enc;
int bitrate = (int)obs_data_get_int(settings, "bitrate");
@ -283,9 +284,27 @@ static void *enc_create(obs_data_t *settings, obs_encoder_t *encoder,
#endif
enc->context->sample_rate = audio_output_get_sample_rate(audio);
enc->context->sample_fmt = enc->codec->sample_fmts
? enc->codec->sample_fmts[0]
: AV_SAMPLE_FMT_FLTP;
if (enc->codec->sample_fmts) {
/* Check if the requested format is actually available for the specified
* encoder. This may not always be the case due to FFmpeg changes or a
* fallback being used (for example, when libopus is unavailable). */
enum AVSampleFormat fmt = enc->codec->sample_fmts[0];
while (fmt != AV_SAMPLE_FMT_NONE) {
if (fmt == sample_format) {
enc->context->sample_fmt = fmt;
break;
}
fmt++;
}
/* Fall back to default if requested format was not found. */
if (enc->context->sample_fmt == AV_SAMPLE_FMT_NONE)
enc->context->sample_fmt = enc->codec->sample_fmts[0];
} else {
/* Fall back to planar float if codec does not specify formats. */
enc->context->sample_fmt = AV_SAMPLE_FMT_FLTP;
}
/* check to make sure sample rate is supported */
if (enc->codec->supported_samplerates) {
@ -335,37 +354,41 @@ fail:
static void *aac_create(obs_data_t *settings, obs_encoder_t *encoder)
{
return enc_create(settings, encoder, "aac", NULL);
return enc_create(settings, encoder, "aac", NULL, AV_SAMPLE_FMT_NONE);
}
static void *opus_create(obs_data_t *settings, obs_encoder_t *encoder)
{
return enc_create(settings, encoder, "libopus", "opus");
return enc_create(settings, encoder, "libopus", "opus",
AV_SAMPLE_FMT_FLT);
}
static void *pcm_create(obs_data_t *settings, obs_encoder_t *encoder)
{
return enc_create(settings, encoder, "pcm_s16le", NULL);
return enc_create(settings, encoder, "pcm_s16le", NULL,
AV_SAMPLE_FMT_NONE);
}
static void *pcm24_create(obs_data_t *settings, obs_encoder_t *encoder)
{
return enc_create(settings, encoder, "pcm_s24le", NULL);
return enc_create(settings, encoder, "pcm_s24le", NULL,
AV_SAMPLE_FMT_NONE);
}
static void *pcm32_create(obs_data_t *settings, obs_encoder_t *encoder)
{
return enc_create(settings, encoder, "pcm_f32le", NULL);
return enc_create(settings, encoder, "pcm_f32le", NULL,
AV_SAMPLE_FMT_NONE);
}
static void *alac_create(obs_data_t *settings, obs_encoder_t *encoder)
{
return enc_create(settings, encoder, "alac", NULL);
return enc_create(settings, encoder, "alac", NULL, AV_SAMPLE_FMT_S32P);
}
static void *flac_create(obs_data_t *settings, obs_encoder_t *encoder)
{
return enc_create(settings, encoder, "flac", NULL);
return enc_create(settings, encoder, "flac", NULL, AV_SAMPLE_FMT_S16);
}
static bool do_encode(struct enc_encoder *enc, struct encoder_packet *packet,