[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 <kode54@gmail.com>
main
Christopher Snowhill 2022-07-21 03:50:39 -07:00
parent 0b8a850086
commit 59d54f3190
8 changed files with 53 additions and 5 deletions

View File

@ -43,6 +43,9 @@ int64_t ffmpeg_seek(void *opaque, int64_t offset, int whence);
AVFrame *lastDecodedFrame; AVFrame *lastDecodedFrame;
AVPacket *lastReadPacket; AVPacket *lastReadPacket;
int metadataUpdateInterval;
int metadataUpdateCount;
BOOL metadataUpdated; BOOL metadataUpdated;
AudioChunk *prebufferedChunk; AudioChunk *prebufferedChunk;

View File

@ -435,6 +435,9 @@ static uint8_t reverse_bits[0x100];
endOfStream = NO; endOfStream = NO;
endOfAudio = NO; endOfAudio = NO;
metadataUpdateInterval = codecCtx->sample_rate;
metadataUpdateCount = 0;
if(rawDSD) { if(rawDSD) {
totalFrames *= 8; totalFrames *= 8;
} }
@ -899,14 +902,18 @@ static void setDictionary(NSMutableDictionary *dict, NSString *tag, NSString *va
} }
} }
[self updateMetadata];
int framesReadNow = bytesRead / frameSize; int framesReadNow = bytesRead / frameSize;
if(totalFrames && (framesRead + framesReadNow > totalFrames)) if(totalFrames && (framesRead + framesReadNow > totalFrames))
framesReadNow = (int)(totalFrames - framesRead); framesReadNow = (int)(totalFrames - framesRead);
framesRead += framesReadNow; framesRead += framesReadNow;
metadataUpdateCount += framesReadNow;
if(metadataUpdateCount >= metadataUpdateInterval) {
metadataUpdateCount -= metadataUpdateInterval;
[self updateMetadata];
}
id audioChunkClass = NSClassFromString(@"AudioChunk"); id audioChunkClass = NSClassFromString(@"AudioChunk");
AudioChunk *chunk = [[audioChunkClass alloc] initWithProperties:[self properties]]; AudioChunk *chunk = [[audioChunkClass alloc] initWithProperties:[self properties]];
[chunk assignSamples:buffer frameCount:framesReadNow]; [chunk assignSamples:buffer frameCount:framesReadNow];

View File

@ -49,6 +49,9 @@
long framesToSkip; long framesToSkip;
int layer; int layer;
int metadataUpdateInterval;
int metadataUpdateCount;
NSString *genre; NSString *genre;
NSString *album; NSString *album;
NSString *artist; NSString *artist;

View File

@ -461,6 +461,11 @@
DLog(@"Decoding first frame: %i", r); DLog(@"Decoding first frame: %i", r);
} while(r == 0); } while(r == 0);
if(r != -1) {
metadataUpdateInterval = sampleRate;
metadataUpdateCount = 0;
}
return (r == -1 ? NO : YES); return (r == -1 ? NO : YES);
} }
@ -472,6 +477,9 @@
framesToSkip = _startPadding; framesToSkip = _startPadding;
} }
metadataUpdateInterval = sampleRate;
metadataUpdateCount = 0;
return ret; return ret;
} }
@ -730,7 +738,11 @@
[self syncFormat]; [self syncFormat];
} }
[self updateMetadata]; metadataUpdateCount += chunk ? [chunk frameCount] : 0;
if(metadataUpdateCount >= metadataUpdateInterval) {
metadataUpdateCount -= metadataUpdateInterval;
[self updateMetadata];
}
// DLog(@"Read: %i/%i", bytesRead, size); // DLog(@"Read: %i/%i", bytesRead, size);
return chunk; return chunk;

View File

@ -23,6 +23,9 @@
int channels; int channels;
long totalFrames; long totalFrames;
int metadataUpdateInterval;
int metadataUpdateCount;
NSDictionary *metaDict; NSDictionary *metaDict;
NSDictionary *icyMetaDict; NSDictionary *icyMetaDict;

View File

@ -129,6 +129,9 @@ opus_int64 sourceTell(void *_stream) {
[self updateMetadata]; [self updateMetadata];
metadataUpdateInterval = 48000;
metadataUpdateCount = 0;
return YES; return YES;
} }
@ -269,7 +272,11 @@ static void setDictionary(NSMutableDictionary *dict, NSString *tag, NSString *va
} while(total != size && numread != 0); } while(total != size && numread != 0);
[self updateIcyMetadata]; metadataUpdateCount += total / channels;
if(metadataUpdateCount >= metadataUpdateInterval) {
metadataUpdateCount -= metadataUpdateInterval;
[self updateIcyMetadata];
}
id audioChunkClass = NSClassFromString(@"AudioChunk"); id audioChunkClass = NSClassFromString(@"AudioChunk");
AudioChunk *chunk = [[audioChunkClass alloc] initWithProperties:[self properties]]; AudioChunk *chunk = [[audioChunkClass alloc] initWithProperties:[self properties]];

View File

@ -32,6 +32,9 @@
float frequency; float frequency;
long totalFrames; long totalFrames;
int metadataUpdateInterval;
int metadataUpdateCount;
NSDictionary *metaDict; NSDictionary *metaDict;
NSDictionary *icyMetaDict; NSDictionary *icyMetaDict;

View File

@ -109,6 +109,9 @@ long sourceTell(void *datasource) {
[self updateMetadata]; [self updateMetadata];
metadataUpdateInterval = frequency;
metadataUpdateCount = 0;
return YES; return YES;
} }
@ -215,6 +218,9 @@ static void setDictionary(NSMutableDictionary *dict, NSString *tag, NSString *va
channels = vi->channels; channels = vi->channels;
frequency = vi->rate; frequency = vi->rate;
metadataUpdateInterval = frequency;
metadataUpdateCount = 0;
[self willChangeValueForKey:@"properties"]; [self willChangeValueForKey:@"properties"];
[self didChangeValueForKey:@"properties"]; [self didChangeValueForKey:@"properties"];
@ -254,7 +260,11 @@ static void setDictionary(NSMutableDictionary *dict, NSString *tag, NSString *va
} while(total != frames && numread != 0); } while(total != frames && numread != 0);
[self updateIcyMetadata]; metadataUpdateCount += total;
if(metadataUpdateCount >= metadataUpdateInterval) {
metadataUpdateCount -= metadataUpdateInterval;
[self updateIcyMetadata];
}
[chunk assignSamples:buffer frameCount:total]; [chunk assignSamples:buffer frameCount:total];