mirror of
https://github.com/taglib/taglib.git
synced 2025-07-21 06:24:19 -04:00
Ignore fake MPEG frame headers when seeking them.
This commit is contained in:
@ -346,55 +346,52 @@ void MPEG::File::setID3v2FrameFactory(const ID3v2::FrameFactory *factory)
|
||||
|
||||
long MPEG::File::nextFrameOffset(long position)
|
||||
{
|
||||
bool foundLastSyncPattern = false;
|
||||
|
||||
ByteVector buffer;
|
||||
char frameSyncBytes[2] = {};
|
||||
|
||||
while(true) {
|
||||
seek(position);
|
||||
buffer = readBlock(bufferSize());
|
||||
|
||||
if(buffer.size() <= 0)
|
||||
const ByteVector buffer = readBlock(bufferSize());
|
||||
if(buffer.size() == 0)
|
||||
return -1;
|
||||
|
||||
if(foundLastSyncPattern && secondSynchByte(buffer[0]))
|
||||
return position - 1;
|
||||
|
||||
for(unsigned int i = 0; i < buffer.size() - 1; i++) {
|
||||
if(firstSyncByte(buffer[i]) && secondSynchByte(buffer[i + 1]))
|
||||
return position + i;
|
||||
for(unsigned int i = 0; i < buffer.size(); ++i) {
|
||||
frameSyncBytes[0] = frameSyncBytes[1];
|
||||
frameSyncBytes[1] = buffer[i];
|
||||
if(firstSyncByte(frameSyncBytes[0]) && secondSynchByte(frameSyncBytes[1])) {
|
||||
Header header(this, position + i - 1, true);
|
||||
if(header.isValid())
|
||||
return position + i - 1;
|
||||
}
|
||||
}
|
||||
|
||||
foundLastSyncPattern = firstSyncByte(buffer[buffer.size() - 1]);
|
||||
position += buffer.size();
|
||||
position += bufferSize();
|
||||
}
|
||||
}
|
||||
|
||||
long MPEG::File::previousFrameOffset(long position)
|
||||
{
|
||||
bool foundFirstSyncPattern = false;
|
||||
ByteVector buffer;
|
||||
char frameSyncBytes[2] = {};
|
||||
|
||||
while (position > 0) {
|
||||
long size = std::min<long>(position, bufferSize());
|
||||
while(position > 0) {
|
||||
const long size = std::min<long>(position, bufferSize());
|
||||
position -= size;
|
||||
|
||||
seek(position);
|
||||
buffer = readBlock(size);
|
||||
const ByteVector buffer = readBlock(bufferSize());
|
||||
if(buffer.size() == 0)
|
||||
return -1;
|
||||
|
||||
if(buffer.size() <= 0)
|
||||
break;
|
||||
|
||||
if(foundFirstSyncPattern && firstSyncByte(buffer[buffer.size() - 1]))
|
||||
return position + buffer.size() - 1;
|
||||
|
||||
for(int i = buffer.size() - 2; i >= 0; i--) {
|
||||
if(firstSyncByte(buffer[i]) && secondSynchByte(buffer[i + 1]))
|
||||
return position + i;
|
||||
for(int i = buffer.size() - 1; i >= 0; i--) {
|
||||
frameSyncBytes[1] = frameSyncBytes[0];
|
||||
frameSyncBytes[0] = buffer[i];
|
||||
if(firstSyncByte(frameSyncBytes[0]) && secondSynchByte(frameSyncBytes[1])) {
|
||||
Header header(this, position + i, true);
|
||||
if(header.isValid())
|
||||
return position + i + header.frameLength();
|
||||
}
|
||||
}
|
||||
|
||||
foundFirstSyncPattern = secondSynchByte(buffer[0]);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -157,23 +157,13 @@ void MPEG::Properties::read(File *file)
|
||||
{
|
||||
// Only the first valid frame is required if we have a VBR header.
|
||||
|
||||
long firstFrameOffset = file->firstFrameOffset();
|
||||
const long firstFrameOffset = file->firstFrameOffset();
|
||||
if(firstFrameOffset < 0) {
|
||||
debug("MPEG::Properties::read() -- Could not find an MPEG frame in the stream.");
|
||||
return;
|
||||
}
|
||||
|
||||
Header firstHeader(file, firstFrameOffset);
|
||||
|
||||
while(!firstHeader.isValid()) {
|
||||
firstFrameOffset = file->nextFrameOffset(firstFrameOffset + 1);
|
||||
if(firstFrameOffset < 0) {
|
||||
debug("MPEG::Properties::read() -- Could not find a valid first MPEG frame in the stream.");
|
||||
return;
|
||||
}
|
||||
|
||||
firstHeader = Header(file, firstFrameOffset);
|
||||
}
|
||||
const Header firstHeader(file, firstFrameOffset, false);
|
||||
|
||||
// Check for a VBR header that will help us in gathering information about a
|
||||
// VBR stream.
|
||||
@ -207,24 +197,13 @@ void MPEG::Properties::read(File *file)
|
||||
|
||||
// Look for the last MPEG audio frame to calculate the stream length.
|
||||
|
||||
long lastFrameOffset = file->lastFrameOffset();
|
||||
const long lastFrameOffset = file->lastFrameOffset();
|
||||
if(lastFrameOffset < 0) {
|
||||
debug("MPEG::Properties::read() -- Could not find an MPEG frame in the stream.");
|
||||
return;
|
||||
}
|
||||
|
||||
Header lastHeader(file, lastFrameOffset, false);
|
||||
|
||||
while(!lastHeader.isValid()) {
|
||||
lastFrameOffset = file->previousFrameOffset(lastFrameOffset);
|
||||
if(lastFrameOffset < 0) {
|
||||
debug("MPEG::Properties::read() -- Could not find a valid last MPEG frame in the stream.");
|
||||
return;
|
||||
}
|
||||
|
||||
lastHeader = Header(file, lastFrameOffset, false);
|
||||
}
|
||||
|
||||
const Header lastHeader(file, lastFrameOffset, false);
|
||||
const long streamLength = lastFrameOffset - firstFrameOffset + lastHeader.frameLength();
|
||||
if(streamLength > 0)
|
||||
d->length = static_cast<int>(streamLength * 8.0 / d->bitrate + 0.5);
|
||||
|
Reference in New Issue
Block a user