diff --git a/src/core/video_format.h b/src/core/video_format.h index b29b095e82..edb554d416 100644 --- a/src/core/video_format.h +++ b/src/core/video_format.h @@ -95,7 +95,7 @@ struct video_format_desc final std::size_t size; // frame size in bytes std::wstring name; // name of output format - int audio_channels = 8; + int audio_channels = 16; int audio_sample_rate; std::vector audio_cadence; // rotating optimal number of samples per frame diff --git a/src/modules/ffmpeg/producer/av_producer.cpp b/src/modules/ffmpeg/producer/av_producer.cpp index b28ed4f307..1d063847be 100644 --- a/src/modules/ffmpeg/producer/av_producer.cpp +++ b/src/modules/ffmpeg/producer/av_producer.cpp @@ -523,7 +523,8 @@ struct Filter const AVSampleFormat sample_fmts[] = {AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_NONE}; FF(av_opt_set_int_list(sink, "sample_fmts", sample_fmts, -1, AV_OPT_SEARCH_CHILDREN)); - // TODO Always output 8 channels and remove hack in make_frame. + const int channel_counts[] = {16, -1}; + FF(av_opt_set_int_list(sink, "channel_counts", channel_counts, -1, AV_OPT_SEARCH_CHILDREN)); const int sample_rates[] = {format_desc.audio_sample_rate, -1}; FF(av_opt_set_int_list(sink, "sample_rates", sample_rates, -1, AV_OPT_SEARCH_CHILDREN)); diff --git a/src/modules/ffmpeg/util/av_util.cpp b/src/modules/ffmpeg/util/av_util.cpp index 6fd3743b98..fa6a2e4736 100644 --- a/src/modules/ffmpeg/util/av_util.cpp +++ b/src/modules/ffmpeg/util/av_util.cpp @@ -69,13 +69,22 @@ core::mutable_frame make_frame(void* tag, }, [&]() { if (audio) { - // TODO This is a bit of a hack - frame.audio_data() = std::vector(audio->nb_samples * 8, 0); - auto dst = frame.audio_data().data(); - auto src = reinterpret_cast(audio->data[0]); - for (auto i = 0; i < audio->nb_samples; i++) { - for (auto j = 0; j < std::min(8, audio->channels); ++j) { - dst[i * 8 + j] = src[i * audio->channels + j]; + const int channel_count = 16; + frame.audio_data() = std::vector(audio->nb_samples * channel_count, 0); + + if (audio->channels == channel_count) { + std::memcpy(frame.audio_data().data(), + reinterpret_cast(audio->data[0]), + sizeof(int32_t) * channel_count * audio->nb_samples); + } else { + // This isn't pretty, but some callers may not provide 16 channels + + auto dst = frame.audio_data().data(); + auto src = reinterpret_cast(audio->data[0]); + for (auto i = 0; i < audio->nb_samples; i++) { + for (auto j = 0; j < std::min(channel_count, audio->channels); ++j) { + dst[i * channel_count + j] = src[i * audio->channels + j]; + } } } }