[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;
|
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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue