From 8f7b26cb5dec57aa75e44ac1a19927a76a340e01 Mon Sep 17 00:00:00 2001 From: Christopher Snowhill Date: Thu, 21 Jul 2022 04:03:21 -0700 Subject: [PATCH] [FFmpeg Input] Buffer up to 5ms each read call Buffer up to 5 milliseconds of audio, or at minimum 1024 samples, each call. Also pre-allocate the buffer, rather than using a stack buffer. Signed-off-by: Christopher Snowhill --- Plugins/FFMPEG/FFMPEGDecoder.h | 3 +++ Plugins/FFMPEG/FFMPEGDecoder.m | 22 ++++++++++++++++------ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/Plugins/FFMPEG/FFMPEGDecoder.h b/Plugins/FFMPEG/FFMPEGDecoder.h index c1662cb76..8bd814d37 100644 --- a/Plugins/FFMPEG/FFMPEGDecoder.h +++ b/Plugins/FFMPEG/FFMPEGDecoder.h @@ -43,6 +43,9 @@ int64_t ffmpeg_seek(void *opaque, int64_t offset, int whence); AVFrame *lastDecodedFrame; AVPacket *lastReadPacket; + int sampleBufferSize; + uint8_t *sampleBuffer; + int metadataUpdateInterval; int metadataUpdateCount; diff --git a/Plugins/FFMPEG/FFMPEGDecoder.m b/Plugins/FFMPEG/FFMPEGDecoder.m index 73fd7c032..31709efdc 100644 --- a/Plugins/FFMPEG/FFMPEGDecoder.m +++ b/Plugins/FFMPEG/FFMPEGDecoder.m @@ -435,6 +435,14 @@ static uint8_t reverse_bits[0x100]; endOfStream = NO; endOfAudio = NO; + sampleBufferSize = MAX(codecCtx->sample_rate / 200, 1024); // Minimum 1024 samples, or maximum 5 milliseconds + sampleBufferSize *= rawDSD ? channels : channels * (bitsPerSample / 8); + sampleBuffer = av_malloc(sampleBufferSize); + if(!sampleBuffer) { + ALog(@"Out of memory!"); + return NO; + } + metadataUpdateInterval = codecCtx->sample_rate; metadataUpdateCount = 0; @@ -512,6 +520,11 @@ static uint8_t reverse_bits[0x100]; ioCtx = NULL; } + if(sampleBuffer) { + av_free(sampleBuffer); + sampleBuffer = NULL; + } + if(buffer) { av_free(buffer); buffer = NULL; @@ -696,14 +709,11 @@ static void setDictionary(NSMutableDictionary *dict, NSString *tag, NSString *va if(totalFrames && framesRead >= totalFrames) return nil; - int frames = 1024; - int frameSize = rawDSD ? channels : channels * (bitsPerSample / 8); - int bytesToRead = frames * frameSize; + int bytesToRead = sampleBufferSize; int bytesRead = 0; - uint8_t buffer[bytesToRead]; - void *buf = (void *)buffer; + void *buf = (void *)sampleBuffer; int dataSize = 0; @@ -914,7 +924,7 @@ static void setDictionary(NSMutableDictionary *dict, NSString *tag, NSString *va id audioChunkClass = NSClassFromString(@"AudioChunk"); AudioChunk *chunk = [[audioChunkClass alloc] initWithProperties:[self properties]]; - [chunk assignSamples:buffer frameCount:framesReadNow]; + [chunk assignSamples:sampleBuffer frameCount:framesReadNow]; return chunk; }