From 59d54f319019b47127545133f8bbf4f757678052 Mon Sep 17 00:00:00 2001 From: Christopher Snowhill Date: Thu, 21 Jul 2022 03:50:39 -0700 Subject: [PATCH] [Inputs] Severely reduce metadata update intervals The Vorbis, Opus, MAD MPEG, and especially the FFmpeg inputs needed to have their metadata update intervals severely reduced, to reduce CPU usage, especially on files with lots of tags. Interval reduced to only once per second. Signed-off-by: Christopher Snowhill --- Plugins/FFMPEG/FFMPEGDecoder.h | 3 +++ Plugins/FFMPEG/FFMPEGDecoder.m | 11 +++++++++-- Plugins/MAD/MADDecoder.h | 3 +++ Plugins/MAD/MADDecoder.m | 14 +++++++++++++- Plugins/Opus/Opus/OpusDecoder.h | 3 +++ Plugins/Opus/Opus/OpusDecoder.m | 9 ++++++++- Plugins/Vorbis/VorbisDecoder.h | 3 +++ Plugins/Vorbis/VorbisDecoder.m | 12 +++++++++++- 8 files changed, 53 insertions(+), 5 deletions(-) diff --git a/Plugins/FFMPEG/FFMPEGDecoder.h b/Plugins/FFMPEG/FFMPEGDecoder.h index 2d62c0e7e..c1662cb76 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 metadataUpdateInterval; + int metadataUpdateCount; + BOOL metadataUpdated; AudioChunk *prebufferedChunk; diff --git a/Plugins/FFMPEG/FFMPEGDecoder.m b/Plugins/FFMPEG/FFMPEGDecoder.m index 20557dd58..7c84125b1 100644 --- a/Plugins/FFMPEG/FFMPEGDecoder.m +++ b/Plugins/FFMPEG/FFMPEGDecoder.m @@ -435,6 +435,9 @@ static uint8_t reverse_bits[0x100]; endOfStream = NO; endOfAudio = NO; + metadataUpdateInterval = codecCtx->sample_rate; + metadataUpdateCount = 0; + if(rawDSD) { totalFrames *= 8; } @@ -899,14 +902,18 @@ static void setDictionary(NSMutableDictionary *dict, NSString *tag, NSString *va } } - [self updateMetadata]; - int framesReadNow = bytesRead / frameSize; if(totalFrames && (framesRead + framesReadNow > totalFrames)) framesReadNow = (int)(totalFrames - framesRead); framesRead += framesReadNow; + metadataUpdateCount += framesReadNow; + if(metadataUpdateCount >= metadataUpdateInterval) { + metadataUpdateCount -= metadataUpdateInterval; + [self updateMetadata]; + } + id audioChunkClass = NSClassFromString(@"AudioChunk"); AudioChunk *chunk = [[audioChunkClass alloc] initWithProperties:[self properties]]; [chunk assignSamples:buffer frameCount:framesReadNow]; diff --git a/Plugins/MAD/MADDecoder.h b/Plugins/MAD/MADDecoder.h index e10a8fa04..d2ce8a595 100644 --- a/Plugins/MAD/MADDecoder.h +++ b/Plugins/MAD/MADDecoder.h @@ -49,6 +49,9 @@ long framesToSkip; int layer; + int metadataUpdateInterval; + int metadataUpdateCount; + NSString *genre; NSString *album; NSString *artist; diff --git a/Plugins/MAD/MADDecoder.m b/Plugins/MAD/MADDecoder.m index 90d0ba53f..6e5b7e69d 100644 --- a/Plugins/MAD/MADDecoder.m +++ b/Plugins/MAD/MADDecoder.m @@ -461,6 +461,11 @@ DLog(@"Decoding first frame: %i", r); } while(r == 0); + if(r != -1) { + metadataUpdateInterval = sampleRate; + metadataUpdateCount = 0; + } + return (r == -1 ? NO : YES); } @@ -472,6 +477,9 @@ framesToSkip = _startPadding; } + metadataUpdateInterval = sampleRate; + metadataUpdateCount = 0; + return ret; } @@ -730,7 +738,11 @@ [self syncFormat]; } - [self updateMetadata]; + metadataUpdateCount += chunk ? [chunk frameCount] : 0; + if(metadataUpdateCount >= metadataUpdateInterval) { + metadataUpdateCount -= metadataUpdateInterval; + [self updateMetadata]; + } // DLog(@"Read: %i/%i", bytesRead, size); return chunk; diff --git a/Plugins/Opus/Opus/OpusDecoder.h b/Plugins/Opus/Opus/OpusDecoder.h index a74b29657..fb69ee19d 100644 --- a/Plugins/Opus/Opus/OpusDecoder.h +++ b/Plugins/Opus/Opus/OpusDecoder.h @@ -23,6 +23,9 @@ int channels; long totalFrames; + int metadataUpdateInterval; + int metadataUpdateCount; + NSDictionary *metaDict; NSDictionary *icyMetaDict; diff --git a/Plugins/Opus/Opus/OpusDecoder.m b/Plugins/Opus/Opus/OpusDecoder.m index ea83f38e0..8e4fb37df 100644 --- a/Plugins/Opus/Opus/OpusDecoder.m +++ b/Plugins/Opus/Opus/OpusDecoder.m @@ -129,6 +129,9 @@ opus_int64 sourceTell(void *_stream) { [self updateMetadata]; + metadataUpdateInterval = 48000; + metadataUpdateCount = 0; + return YES; } @@ -269,7 +272,11 @@ static void setDictionary(NSMutableDictionary *dict, NSString *tag, NSString *va } while(total != size && numread != 0); - [self updateIcyMetadata]; + metadataUpdateCount += total / channels; + if(metadataUpdateCount >= metadataUpdateInterval) { + metadataUpdateCount -= metadataUpdateInterval; + [self updateIcyMetadata]; + } id audioChunkClass = NSClassFromString(@"AudioChunk"); AudioChunk *chunk = [[audioChunkClass alloc] initWithProperties:[self properties]]; diff --git a/Plugins/Vorbis/VorbisDecoder.h b/Plugins/Vorbis/VorbisDecoder.h index 61c271ea0..fef512f31 100644 --- a/Plugins/Vorbis/VorbisDecoder.h +++ b/Plugins/Vorbis/VorbisDecoder.h @@ -32,6 +32,9 @@ float frequency; long totalFrames; + int metadataUpdateInterval; + int metadataUpdateCount; + NSDictionary *metaDict; NSDictionary *icyMetaDict; diff --git a/Plugins/Vorbis/VorbisDecoder.m b/Plugins/Vorbis/VorbisDecoder.m index c73c53e31..f68d9f5d5 100644 --- a/Plugins/Vorbis/VorbisDecoder.m +++ b/Plugins/Vorbis/VorbisDecoder.m @@ -109,6 +109,9 @@ long sourceTell(void *datasource) { [self updateMetadata]; + metadataUpdateInterval = frequency; + metadataUpdateCount = 0; + return YES; } @@ -215,6 +218,9 @@ static void setDictionary(NSMutableDictionary *dict, NSString *tag, NSString *va channels = vi->channels; frequency = vi->rate; + metadataUpdateInterval = frequency; + metadataUpdateCount = 0; + [self willChangeValueForKey:@"properties"]; [self didChangeValueForKey:@"properties"]; @@ -254,7 +260,11 @@ static void setDictionary(NSMutableDictionary *dict, NSString *tag, NSString *va } while(total != frames && numread != 0); - [self updateIcyMetadata]; + metadataUpdateCount += total; + if(metadataUpdateCount >= metadataUpdateInterval) { + metadataUpdateCount -= metadataUpdateInterval; + [self updateIcyMetadata]; + } [chunk assignSamples:buffer frameCount:total];