mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-16 10:04:28 +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:
78
src/video.h
78
src/video.h
@@ -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(§or, 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) {
|
||||||
|
vFrameIndex = (vFrameIndex + 1) % VIDEO_MAX_FRAMES;
|
||||||
if (sector->chunkIndex == 0) {
|
vFrame = vFrames + vFrameIndex;
|
||||||
vFrameIndex = (vFrameIndex + 1) % VIDEO_MAX_FRAMES;
|
vFrame->size = 0;
|
||||||
vFrame = vFrames + vFrameIndex;
|
vFrame->width = sector.width;
|
||||||
vFrame->size = 0;
|
vFrame->height = sector.height;
|
||||||
vFrame->width = sector->width;
|
vFrame->qscale = sector.qscale;
|
||||||
vFrame->height = sector->height;
|
|
||||||
vFrame->qscale = sector->qscale;
|
|
||||||
}
|
|
||||||
|
|
||||||
ASSERT(vFrame->size + VIDEO_CHUNK_SIZE < sizeof(vFrame->data));
|
|
||||||
memcpy(vFrame->data + vFrame->size, data + sizeof(SyncHeader) + sizeof(Sector), VIDEO_CHUNK_SIZE);
|
|
||||||
vFrame->size += VIDEO_CHUNK_SIZE;
|
|
||||||
|
|
||||||
if (sector->chunkIndex == sector->chunksCount - 1) {
|
|
||||||
//LOG("frame %d: %dx%d %d\n", sector->frameIndex, frame->width, frame->height, frame->size);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (syncHeader->submode.isAudio) {
|
ASSERT(vFrame->size + VIDEO_CHUNK_SIZE < sizeof(vFrame->data));
|
||||||
channels = syncHeader->coding.stereo ? 2 : 1;
|
stream->raw(vFrame->data + vFrame->size, VIDEO_CHUNK_SIZE);
|
||||||
freq = syncHeader->coding.rate ? 37800 : 18900;
|
vFrame->size += VIDEO_CHUNK_SIZE;
|
||||||
|
|
||||||
|
if (hasSyncHeader)
|
||||||
|
stream->seek(280);
|
||||||
|
|
||||||
|
if (sector.chunkIndex == sector.chunksCount - 1)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
} 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;
|
||||||
|
Reference in New Issue
Block a user