summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2025-09-06 17:15:46 +0200
committerCarl Hetherington <cth@carlh.net>2025-09-06 17:15:46 +0200
commit24052ed1b36e0ce81fb863830a93f8282285f30d (patch)
treea3544b1b8efeac24ef37776b9b09eb479ee27625
parent307264b52c70ca0a79831240874fcb2278ebac89 (diff)
Fix incorrectly-clipped audio on export (possibly #2865).
-rw-r--r--src/lib/ffmpeg_file_encoder.cc5
m---------test/data0
-rw-r--r--test/ffmpeg_encoder_test.cc24
3 files changed, 27 insertions, 2 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<int16_t*>(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<int32_t*>(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
-Subproject 0e08d315725cb18acd04880eb6c7f463f003873
+Subproject 349501404a251e7250094937c418b7802724392
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<DCPContent>(film->dir(film->dcp_name()));
+ auto film2 = new_test_film(name + "_out", { dcp });
+
+ auto job = make_shared<TranscodeJob>(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);
+}
+