[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
parent
4828b7f1c1
commit
af0a2436fc
|
@ -35,6 +35,11 @@
|
|||
AVFrame *lastDecodedFrame;
|
||||
AVPacket *lastReadPacket;
|
||||
|
||||
BOOL metadataUpdated;
|
||||
|
||||
int prebufferedAudio;
|
||||
uint8_t *prebufferedAudioData;
|
||||
|
||||
BOOL rawDSD;
|
||||
BOOL rawDSDReverseBits;
|
||||
BOOL rawDSDPlanar;
|
||||
|
|
|
@ -462,8 +462,23 @@ static uint8_t reverse_bits[0x100];
|
|||
replayGainTrackPeak = 0.0;
|
||||
albumArt = [NSData data];
|
||||
id3Metadata = @{};
|
||||
metadataUpdated = NO;
|
||||
[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;
|
||||
}
|
||||
|
||||
|
@ -608,6 +623,8 @@ static uint8_t reverse_bits[0x100];
|
|||
if(![source seekable]) {
|
||||
[self willChangeValueForKey:@"metadata"];
|
||||
[self didChangeValueForKey:@"metadata"];
|
||||
} else {
|
||||
metadataUpdated = YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -632,19 +649,35 @@ static uint8_t reverse_bits[0x100];
|
|||
if(![source seekable]) {
|
||||
[self willChangeValueForKey:@"metadata"];
|
||||
[self didChangeValueForKey:@"metadata"];
|
||||
} else {
|
||||
metadataUpdated = YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (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)
|
||||
return 0;
|
||||
|
||||
int frameSize = rawDSD ? channels : channels * (bitsPerSample / 8);
|
||||
int dataSize = 0;
|
||||
|
||||
int bytesToRead = frames * frameSize;
|
||||
int bytesRead = 0;
|
||||
int seekBytesSkip = 0;
|
||||
|
||||
int errcode;
|
||||
|
@ -852,6 +885,8 @@ static uint8_t reverse_bits[0x100];
|
|||
if(!totalFrames)
|
||||
return -1;
|
||||
|
||||
prebufferedAudio = 0;
|
||||
|
||||
if(frame >= totalFrames) {
|
||||
framesRead = totalFrames;
|
||||
endOfStream = YES;
|
||||
|
|
Loading…
Reference in New Issue