Don't manually check framesRead and rely on FFmpeg's EOFs

FFmpeg's duration isn't always reliable (ie. bad headers) and the
decoder detects EOFs already, extra decoding attempts should be ignored.
This way vgmstream can use other values without modifying
ffmpeg_codec_data's state.
This commit is contained in:
bnnm 2016-12-03 11:42:38 +01:00
parent 80c8791288
commit 0faa3286aa
3 changed files with 3 additions and 15 deletions

View File

@ -59,8 +59,7 @@ static void convert_audio(sample *outbuf, const uint8_t *inbuf, int sampleCount,
} }
} }
void decode_ffmpeg(VGMSTREAM *vgmstream, void decode_ffmpeg(VGMSTREAM *vgmstream, sample * outbuf, int32_t samples_to_do, int channels) {
sample * outbuf, int32_t samples_to_do, int channels) {
ffmpeg_codec_data *data = (ffmpeg_codec_data *) vgmstream->codec_data; ffmpeg_codec_data *data = (ffmpeg_codec_data *) vgmstream->codec_data;
int bytesPerSample; int bytesPerSample;
@ -87,7 +86,7 @@ void decode_ffmpeg(VGMSTREAM *vgmstream,
/* ignore decode attempts at EOF */ /* ignore decode attempts at EOF */
if ((data->totalFrames && data->framesRead >= data->totalFrames) || data->endOfStream || data->endOfAudio) { if (data->endOfStream || data->endOfAudio) {
memset(outbuf, 0, samples_to_do * channels * sizeof(sample)); memset(outbuf, 0, samples_to_do * channels * sizeof(sample));
return; return;
} }
@ -231,11 +230,6 @@ void decode_ffmpeg(VGMSTREAM *vgmstream,
end: end:
framesReadNow = bytesRead / frameSize; framesReadNow = bytesRead / frameSize;
if (data->totalFrames && (data->framesRead + framesReadNow > data->totalFrames)) {
framesReadNow = (int)(data->totalFrames - data->framesRead);
}
data->framesRead += framesReadNow;
// Convert the audio // Convert the audio
convert_audio(outbuf, data->sampleBuffer, framesReadNow * channels, data->bitsPerSample, data->floatingPoint); convert_audio(outbuf, data->sampleBuffer, framesReadNow * channels, data->bitsPerSample, data->floatingPoint);
@ -259,7 +253,6 @@ void reset_ffmpeg(VGMSTREAM *vgmstream) {
} }
data->readNextPacket = 1; data->readNextPacket = 1;
data->bytesConsumedFromDecodedFrame = INT_MAX; data->bytesConsumedFromDecodedFrame = INT_MAX;
data->framesRead = 0;
data->endOfStream = 0; data->endOfStream = 0;
data->endOfAudio = 0; data->endOfAudio = 0;
data->samplesToDiscard = 0; data->samplesToDiscard = 0;
@ -286,11 +279,9 @@ void seek_ffmpeg(VGMSTREAM *vgmstream, int32_t num_sample) {
/* todo fix this properly */ /* todo fix this properly */
if (data->totalFrames) { if (data->totalFrames) {
data->framesRead = (int)ts; ts = (int)ts * (data->formatCtx->duration) / data->totalFrames;
ts = data->framesRead * (data->formatCtx->duration) / data->totalFrames;
} else { } else {
data->samplesToDiscard = num_sample; data->samplesToDiscard = num_sample;
data->framesRead = 0;
ts = 0; ts = 0;
} }
@ -303,7 +294,6 @@ void seek_ffmpeg(VGMSTREAM *vgmstream, int32_t num_sample) {
/* We could also seek by offset (AVSEEK_FLAG_BYTE) to the frame closest to the loop then discard /* We could also seek by offset (AVSEEK_FLAG_BYTE) to the frame closest to the loop then discard
* some samples, which is fast but would need calculations per format / when frame size is not constant */ * some samples, which is fast but would need calculations per format / when frame size is not constant */
data->samplesToDiscard = num_sample; data->samplesToDiscard = num_sample;
data->framesRead = 0;
ts = 0; ts = 0;
avformat_seek_file(data->formatCtx, data->streamIndex, ts, ts, ts, AVSEEK_FLAG_ANY); avformat_seek_file(data->formatCtx, data->streamIndex, ts, ts, ts, AVSEEK_FLAG_ANY);

View File

@ -332,7 +332,6 @@ ffmpeg_codec_data * init_ffmpeg_faux_riff(STREAMFILE *streamFile, int64_t fmt_of
} }
data->bitrate = (int)(data->codecCtx->bit_rate); data->bitrate = (int)(data->codecCtx->bit_rate);
data->framesRead = 0;
data->endOfStream = 0; data->endOfStream = 0;
data->endOfAudio = 0; data->endOfAudio = 0;

View File

@ -870,7 +870,6 @@ typedef struct {
int floatingPoint; int floatingPoint;
int sampleRate; int sampleRate;
int64_t totalFrames; // sample count, or 0 if unknown int64_t totalFrames; // sample count, or 0 if unknown
int64_t framesRead;
int bitrate; int bitrate;
// Intermediate buffer // Intermediate buffer