diff --git a/src/sources/soundsourcemp3.cpp b/src/sources/soundsourcemp3.cpp index be8c869aa630..79f35873dcf3 100644 --- a/src/sources/soundsourcemp3.cpp +++ b/src/sources/soundsourcemp3.cpp @@ -234,6 +234,7 @@ SoundSource::OpenResult SoundSourceMp3::tryOpen( // 7000 days of audio duration. quint64 sumBitrateFrames = 0; // nominator quint64 cntBitrateFrames = 0; // denominator + long madFrameLength = 0; mad_header madHeader; mad_header_init(&madHeader); @@ -264,7 +265,7 @@ SoundSource::OpenResult SoundSourceMp3::tryOpen( static_assert(MAD_UNITS_8000_HZ == 8000); const mad_units madUnits = static_cast(madSampleRate); - const long madFrameLength = mad_timer_count(madHeader.duration, madUnits); + madFrameLength = mad_timer_count(madHeader.duration, madUnits); if (0 >= madFrameLength) { kLogger.warning() << "Skipping MP3 frame with invalid length" << madFrameLength @@ -386,7 +387,11 @@ SoundSource::OpenResult SoundSourceMp3::tryOpen( return OpenResult::Failed; } initSampleRateOnce(getSampleRateByIndex(mostCommonSampleRateIndex)); - initFrameIndexRangeOnce(IndexRange::forward(0, m_curFrameIndex)); + + // Because of an off-by-one issue we need to short the file by one frame. + // See comments in restartDecoding() + DEBUG_ASSERT(m_curFrameIndex - madFrameLength == m_seekFrameList.back().frameIndex); + initFrameIndexRangeOnce(IndexRange::forward(0, m_seekFrameList.back().frameIndex)); // Calculate average bitrate values DEBUG_ASSERT(m_seekFrameList.size() > 0); // see above @@ -398,8 +403,10 @@ SoundSource::OpenResult SoundSourceMp3::tryOpen( kLogger.warning() << "Bitrate cannot be calculated from headers"; } - // Terminate m_seekFrameList - addSeekFrame(m_curFrameIndex, nullptr); + // Terminate m_seekFrameList by removing the last frame. + // This is not needed because it would decode data past the last frame + // due to the legacy off-by-one issue + m_seekFrameList.back().pInputData = nullptr; DEBUG_ASSERT(m_seekFrameList.back().frameIndex == frameIndexMax()); // Restart decoding at the beginning of the audio stream