1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-08-17 18:36:43 +02:00

#129 fix for FMVs copied without sync headers, but audio will has "clicks" because most of tools copy only 2048 bytes from 2352 bytes of sector data :(

This commit is contained in:
XProger
2018-09-27 05:51:06 +03:00
parent 50339b874c
commit ad90010d6b

View File

@@ -832,6 +832,8 @@ struct Video {
int curAudioPos; int curAudioPos;
int curAudioFrame; int curAudioFrame;
bool hasSyncHeader;
STR(Stream *stream) : Decoder(stream), vFrameIndex(-1), aFrameIndex(-1), audioDecoder(NULL) { STR(Stream *stream) : Decoder(stream), vFrameIndex(-1), aFrameIndex(-1), audioDecoder(NULL) {
curAudioFrame = 0; curAudioFrame = 0;
@@ -850,6 +852,13 @@ struct Video {
buildLUT(AC_LUT_9, 62, 110, 9); buildLUT(AC_LUT_9, 62, 110, 9);
int pos = stream->pos; int pos = stream->pos;
uint32 syncMagic[3];
stream->raw(syncMagic, sizeof(syncMagic));
stream->seek(-12);
hasSyncHeader = syncMagic[0] == 0xFFFFFF00 && syncMagic[1] == 0xFFFFFFFF && syncMagic[2] == 0x00FFFFFF;
nextFrame(); nextFrame();
VideoFrame &frame = vFrames[vFrameIndex]; VideoFrame &frame = vFrames[vFrameIndex];
@@ -886,54 +895,49 @@ struct Video {
bool nextFrame() { bool nextFrame() {
OS_LOCK(Sound::lock); OS_LOCK(Sound::lock);
uint8 data[SECTOR_SIZE];
VideoFrame *vFrame = vFrames + vFrameIndex; VideoFrame *vFrame = vFrames + vFrameIndex;
while (stream->pos < stream->size) { while (stream->pos < stream->size) {
if (stream->raw(data, sizeof(data)) != sizeof(data)) {
ASSERT(false);
return false;
}
SyncHeader *syncHeader = (SyncHeader*)data; if (hasSyncHeader)
stream->seek(24);
if (syncHeader->sync[0] != 0xFFFFFF00 || syncHeader->sync[1] != 0xFFFFFFFF || syncHeader->sync[2] != 0x00FFFFFF) { Sector sector;
ASSERT(false); stream->raw(&sector, sizeof(Sector));
return false;
}
if (syncHeader->submode.isVideo || syncHeader->submode.isData) { if (sector.magic == MAGIC_STR) {
Sector *sector = (Sector*)(data + sizeof(SyncHeader));
if (sector->magic == MAGIC_STR) { if (sector.chunkIndex == 0) {
if (sector->chunkIndex == 0) {
vFrameIndex = (vFrameIndex + 1) % VIDEO_MAX_FRAMES; vFrameIndex = (vFrameIndex + 1) % VIDEO_MAX_FRAMES;
vFrame = vFrames + vFrameIndex; vFrame = vFrames + vFrameIndex;
vFrame->size = 0; vFrame->size = 0;
vFrame->width = sector->width; vFrame->width = sector.width;
vFrame->height = sector->height; vFrame->height = sector.height;
vFrame->qscale = sector->qscale; vFrame->qscale = sector.qscale;
} }
ASSERT(vFrame->size + VIDEO_CHUNK_SIZE < sizeof(vFrame->data)); ASSERT(vFrame->size + VIDEO_CHUNK_SIZE < sizeof(vFrame->data));
memcpy(vFrame->data + vFrame->size, data + sizeof(SyncHeader) + sizeof(Sector), VIDEO_CHUNK_SIZE); stream->raw(vFrame->data + vFrame->size, VIDEO_CHUNK_SIZE);
vFrame->size += VIDEO_CHUNK_SIZE; vFrame->size += VIDEO_CHUNK_SIZE;
if (sector->chunkIndex == sector->chunksCount - 1) { if (hasSyncHeader)
//LOG("frame %d: %dx%d %d\n", sector->frameIndex, frame->width, frame->height, frame->size); stream->seek(280);
return true;
}
}
} else if (syncHeader->submode.isAudio) { if (sector.chunkIndex == sector.chunksCount - 1)
channels = syncHeader->coding.stereo ? 2 : 1; return true;
freq = syncHeader->coding.rate ? 37800 : 18900;
} else {
channels = 2;
freq = 37800;
aFrameIndex = (aFrameIndex + 1) % AUDIO_MAX_FRAMES; aFrameIndex = (aFrameIndex + 1) % AUDIO_MAX_FRAMES;
AudioFrame *aFrame = aFrames + aFrameIndex; AudioFrame *aFrame = aFrames + aFrameIndex;
aFrame->pos = stream->pos - sizeof(data); aFrame->pos = stream->pos - sizeof(sector);
aFrame->size = AUDIO_CHUNK_SIZE; aFrame->size = AUDIO_CHUNK_SIZE; // !!! MUST BE 2304 !!! most of CD image tools copy only 2048 per sector, so "clicks" will be there
stream->seek(2048 - sizeof(sector));
if (hasSyncHeader)
stream->seek(280);
}; };
} }
return false; return false;