Fix writing of planar audio to export buffers in some cases (#2223).
authorCarl Hetherington <cth@carlh.net>
Wed, 30 Mar 2022 20:59:05 +0000 (22:59 +0200)
committerCarl Hetherington <cth@carlh.net>
Sat, 2 Apr 2022 20:27:11 +0000 (22:27 +0200)
Previously we did not take into account alignment padding that can
exist with FLTP samples; each channel's block of samples can have
a gap between.  This doesn't happen with the normal 1024 sample blocks;
only when flushing at the end, when we write shorter blocks.

Not doing this right meant that we were passing uninitialised memory
to aacenc which sometimes responded by returning an EINVAL due to one
of its internal calculations returning a NaN.

src/lib/ffmpeg_file_encoder.cc

index f9443b256ef79a2b3ccf29cccb45e77d9e4d8fe3..57103abc712ab5523fb4c867c28198ed2dc32dcc 100644 (file)
@@ -134,7 +134,8 @@ public:
                auto frame = av_frame_alloc ();
                DCPOMATIC_ASSERT (frame);
 
-               int const buffer_size = av_samples_get_buffer_size (0, channels, size, _codec_context->sample_fmt, 0);
+               int line_size;
+               int const buffer_size = av_samples_get_buffer_size (&line_size, channels, size, _codec_context->sample_fmt, 0);
                DCPOMATIC_ASSERT (buffer_size >= 0);
 
                auto samples = av_malloc (buffer_size);
@@ -169,10 +170,8 @@ public:
                }
                case AV_SAMPLE_FMT_FLTP:
                {
-                       float* q = reinterpret_cast<float*> (samples);
                        for (int i = 0; i < channels; ++i) {
-                               memcpy (q, data[i + channel_offset], sizeof(float) * size);
-                               q += size;
+                               memcpy (reinterpret_cast<float*>(static_cast<uint8_t*>(samples) + i * line_size), data[i + channel_offset], sizeof(float) * size);
                        }
                        break;
                }