diff --git a/Frameworks/vgmstream/vgmstream/src/coding/ffmpeg_decoder.c b/Frameworks/vgmstream/vgmstream/src/coding/ffmpeg_decoder.c index 1e5f6b44f..ccfd93609 100644 --- a/Frameworks/vgmstream/vgmstream/src/coding/ffmpeg_decoder.c +++ b/Frameworks/vgmstream/vgmstream/src/coding/ffmpeg_decoder.c @@ -178,6 +178,21 @@ void decode_ffmpeg(VGMSTREAM *vgmstream, toConsume = FFMIN((dataSize - bytesConsumedFromDecodedFrame), (bytesToRead - bytesRead)); + if (data->samplesToDiscard) { + int bytesPerFrame = ((data->bitsPerSample / 8) * channels); + int samplesToConsume = toConsume / bytesPerFrame; + if (data->samplesToDiscard >= samplesToConsume) { + data->samplesToDiscard -= samplesToConsume; + bytesConsumedFromDecodedFrame = dataSize; + continue; + } + else { + bytesConsumedFromDecodedFrame += data->samplesToDiscard * bytesPerFrame; + toConsume -= data->samplesToDiscard * bytesPerFrame; + data->samplesToDiscard = 0; + } + } + if (!planar || channels == 1) { memmove(targetBuf + bytesRead, (lastDecodedFrame->data[0] + bytesConsumedFromDecodedFrame), toConsume); } diff --git a/Frameworks/vgmstream/vgmstream/src/vgmstream.c b/Frameworks/vgmstream/vgmstream/src/vgmstream.c index 7cd4bfdbe..af9fe6e50 100644 --- a/Frameworks/vgmstream/vgmstream/src/vgmstream.c +++ b/Frameworks/vgmstream/vgmstream/src/vgmstream.c @@ -520,6 +520,7 @@ void reset_vgmstream(VGMSTREAM * vgmstream) { data->framesRead = 0; data->endOfStream = 0; data->endOfAudio = 0; + data->samplesToDiscard = 0; } #endif @@ -1782,7 +1783,16 @@ int vgmstream_do_loop(VGMSTREAM * vgmstream) { if (vgmstream->coding_type==coding_FFmpeg) { ffmpeg_codec_data *data = (ffmpeg_codec_data *)(vgmstream->codec_data); int64_t ts; - data->framesRead = vgmstream->loop_start_sample; + ts = vgmstream->loop_start_sample; + if (ts >= data->sampleRate * 2) { + data->samplesToDiscard = data->sampleRate * 2; + ts -= data->samplesToDiscard; + } + else { + data->samplesToDiscard = (int)ts; + ts = 0; + } + data->framesRead = (int)ts; ts = data->framesRead * (data->formatCtx->duration) / data->totalFrames; avformat_seek_file(data->formatCtx, -1, ts - 1000, ts, ts, AVSEEK_FLAG_ANY); avcodec_flush_buffers(data->codecCtx); diff --git a/Frameworks/vgmstream/vgmstream/src/vgmstream.h b/Frameworks/vgmstream/vgmstream/src/vgmstream.h index 0742b9f0f..70f1d2209 100644 --- a/Frameworks/vgmstream/vgmstream/src/vgmstream.h +++ b/Frameworks/vgmstream/vgmstream/src/vgmstream.h @@ -897,6 +897,9 @@ typedef struct { int readNextPacket; int endOfStream; int endOfAudio; + + // Seeking is not ideal, so rollback is necessary + int samplesToDiscard; } ffmpeg_codec_data; #endif