From 24052ed1b36e0ce81fb863830a93f8282285f30d Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 6 Sep 2025 17:15:46 +0200 Subject: Fix incorrectly-clipped audio on export (possibly #2865). --- src/lib/ffmpeg_file_encoder.cc | 5 +++-- test/data | 2 +- test/ffmpeg_encoder_test.cc | 24 ++++++++++++++++++++++++ 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/lib/ffmpeg_file_encoder.cc b/src/lib/ffmpeg_file_encoder.cc index e63d92d5b..9f391df5d 100644 --- a/src/lib/ffmpeg_file_encoder.cc +++ b/src/lib/ffmpeg_file_encoder.cc @@ -26,6 +26,7 @@ #include "image.h" #include "job.h" #include "log.h" +#include "maths_util.h" #include "player.h" #include "player_video.h" extern "C" { @@ -151,7 +152,7 @@ public: int16_t* q = reinterpret_cast(samples); for (int i = 0; i < size; ++i) { for (int j = 0; j < channels; ++j) { - *q++ = data[j + channel_offset][i] * 32767; + *q++ = clamp(std::lround(data[j + channel_offset][i] * 32767), -32768L, 32767L); } } break; @@ -161,7 +162,7 @@ public: int32_t* q = reinterpret_cast(samples); for (int i = 0; i < size; ++i) { for (int j = 0; j < channels; ++j) { - *q++ = data[j + channel_offset][i] * 2147483647; + *q++ = clamp(std::llround(data[j + channel_offset][i] * 2147483647.0), -2147483648LL, 2147483647LL); } } break; diff --git a/test/data b/test/data index 0e08d3157..349501404 160000 --- a/test/data +++ b/test/data @@ -1 +1 @@ -Subproject commit 0e08d315725cb18acd04880eb6c7f463f003873c +Subproject commit 349501404a251e7250094937c418b78027243925 diff --git a/test/ffmpeg_encoder_test.cc b/test/ffmpeg_encoder_test.cc index cb4f3cfea..051832b2f 100644 --- a/test/ffmpeg_encoder_test.cc +++ b/test/ffmpeg_encoder_test.cc @@ -538,3 +538,27 @@ BOOST_AUTO_TEST_CASE(ffmpeg_encoder_missing_frame_at_end) BOOST_CHECK_EQUAL(nb_read_frames, 26); } + +BOOST_AUTO_TEST_CASE(test_ffmpeg_encoder_with_clipping_dcp_audio) +{ + string const name = "test_ffmpeg_encoder_with_clipping_dcp_audio"; + auto content = content_factory("test/data/sine_16_48_440_10.wav"); + auto film = new_test_film(name + "_in", content); + content[0]->audio->set_gain(0.5); + + make_and_verify_dcp( + film, + { dcp::VerificationNote::Code::MISSING_CPL_METADATA } + ); + + auto dcp = make_shared(film->dir(film->dcp_name())); + auto film2 = new_test_film(name + "_out", { dcp }); + + auto job = make_shared(film, TranscodeJob::ChangedBehaviour::IGNORE); + auto const out = boost::filesystem::path("build/test") / (name + "_out.mov"); + FFmpegFilmEncoder encoder(film, job, out, ExportFormat::PRORES_HQ, false, true, false, 23); + encoder.go(); + + check_ffmpeg(out, boost::filesystem::path("test/data") / (name + ".mov"), 0); +} + -- cgit v1.2.3