Fix #121719: Sound does not play when playback starts outside of strip

The issue was caused by an integer overflow in the `FFMPEGReader::seek`, which
lead to different results depending on an exact compiler version and platform.

The overflow happened in the equation which calculates `m_position`, in its
`packet.pts - st_time` part, which is effectively `int64_t - uint64_t` which is
expected to result in `uint64_t` due to the way how upcasting works in C++.

With the values `packet.pts=0` and `st_time=353600` from the test file the
calculation resulted in a negative value, which then wrapped around due to the
unsigned nature of the type, resulting in very big value on arm64. The value
was wrong, but it did not manifest itself as an error, since the seek code
believed it found the place.

However, when built on x86 platform, the result value was very large negative
value. It is possible that the type upcasting went different, due to the
multiplication with a double value later in the formula. And this large negative
value lead to the seeking code to read the entire file, trying to make it so
the `m_position` is not less than the requested position.

Fortunately, the `AVStream::start_time` is `int64_t`, which leads to a simple
fix which avoids signed/unsigned cast, making the seeking code to properly
calculate `m_position` on both arm64 and x64 platforms, regardless of the
compiler.

Pull Request: https://projects.blender.org/blender/blender/pulls/122149
This commit is contained in:
Sergey Sharybin 2024-05-23 21:25:04 +02:00 committed by Sergey Sharybin
parent f46e3d1067
commit 68a76c3c77

@ -409,7 +409,7 @@ void FFMPEGReader::seek(int position)
{
double pts_time_base = av_q2d(m_formatCtx->streams[m_stream]->time_base);
uint64_t st_time = m_formatCtx->streams[m_stream]->start_time;
int64_t st_time = m_formatCtx->streams[m_stream]->start_time;
uint64_t seek_pos = (uint64_t)(position / (pts_time_base * m_specs.rate));
if(st_time != AV_NOPTS_VALUE)