[FFMPEG Input] Support reading more metadata

Now read all metadata and signal it, and also support pre-buffering
a small block of sample frames if there is embedded artwork, since the
embedded artwork must be handled by the sample decode function.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
swiftingly
Christopher Snowhill 2022-06-11 06:39:00 -07:00
parent 4828b7f1c1
commit af0a2436fc
2 changed files with 43 additions and 3 deletions

View File

@ -35,6 +35,11 @@
AVFrame *lastDecodedFrame; AVFrame *lastDecodedFrame;
AVPacket *lastReadPacket; AVPacket *lastReadPacket;
BOOL metadataUpdated;
int prebufferedAudio;
uint8_t *prebufferedAudioData;
BOOL rawDSD; BOOL rawDSD;
BOOL rawDSDReverseBits; BOOL rawDSDReverseBits;
BOOL rawDSDPlanar; BOOL rawDSDPlanar;

View File

@ -462,8 +462,23 @@ static uint8_t reverse_bits[0x100];
replayGainTrackPeak = 0.0; replayGainTrackPeak = 0.0;
albumArt = [NSData data]; albumArt = [NSData data];
id3Metadata = @{}; id3Metadata = @{};
metadataUpdated = NO;
[self updateMetadata]; [self updateMetadata];
prebufferedAudio = 0;
prebufferedAudioData = NULL;
if(attachedPicIndex >= 0) {
int frameSize = rawDSD ? channels : channels * (bitsPerSample / 8);
prebufferedAudioData = malloc(1024 * frameSize);
[self readAudio:prebufferedAudioData frames:1024];
}
if(metadataUpdated) {
[self willChangeValueForKey:@"metadata"];
[self didChangeValueForKey:@"metadata"];
}
return YES; return YES;
} }
@ -608,6 +623,8 @@ static uint8_t reverse_bits[0x100];
if(![source seekable]) { if(![source seekable]) {
[self willChangeValueForKey:@"metadata"]; [self willChangeValueForKey:@"metadata"];
[self didChangeValueForKey:@"metadata"]; [self didChangeValueForKey:@"metadata"];
} else {
metadataUpdated = YES;
} }
} }
} }
@ -632,19 +649,35 @@ static uint8_t reverse_bits[0x100];
if(![source seekable]) { if(![source seekable]) {
[self willChangeValueForKey:@"metadata"]; [self willChangeValueForKey:@"metadata"];
[self didChangeValueForKey:@"metadata"]; [self didChangeValueForKey:@"metadata"];
} else {
metadataUpdated = YES;
} }
} }
} }
- (int)readAudio:(void *)buf frames:(UInt32)frames { - (int)readAudio:(void *)buf frames:(UInt32)frames {
int frameSize = rawDSD ? channels : channels * (bitsPerSample / 8);
int bytesToRead = frames * frameSize;
int bytesRead = 0;
if(prebufferedAudio) {
// A bit of ignored read-ahead to support embedded artwork
int bytesBuffered = prebufferedAudio * frameSize;
int bytesToCopy = (bytesBuffered > bytesToRead) ? bytesToRead : bytesBuffered;
memcpy(buf, prebufferedAudioData, bytesToCopy);
memmove(prebufferedAudioData, prebufferedAudioData + bytesToCopy, bytesBuffered - bytesToCopy);
prebufferedAudio -= bytesToCopy / frameSize;
bytesRead = bytesToCopy;
int framesReadNow = bytesRead / frameSize;
framesRead -= framesReadNow;
}
if(totalFrames && framesRead >= totalFrames) if(totalFrames && framesRead >= totalFrames)
return 0; return 0;
int frameSize = rawDSD ? channels : channels * (bitsPerSample / 8);
int dataSize = 0; int dataSize = 0;
int bytesToRead = frames * frameSize;
int bytesRead = 0;
int seekBytesSkip = 0; int seekBytesSkip = 0;
int errcode; int errcode;
@ -852,6 +885,8 @@ static uint8_t reverse_bits[0x100];
if(!totalFrames) if(!totalFrames)
return -1; return -1;
prebufferedAudio = 0;
if(frame >= totalFrames) { if(frame >= totalFrames) {
framesRead = totalFrames; framesRead = totalFrames;
endOfStream = YES; endOfStream = YES;