mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-03 09:23:37 +00:00
VIDEO: Handle STRN chunks in AVI file streams to set stream name
This commit is contained in:
parent
8a6bba0fec
commit
bb2d290dca
@ -101,6 +101,7 @@ void AVIDecoder::initCommon() {
|
||||
_movieListEnd = 0;
|
||||
_fileStream = 0;
|
||||
_videoTrackCounter = _audioTrackCounter = 0;
|
||||
_lastAddedTrack = nullptr;
|
||||
memset(&_header, 0, sizeof(_header));
|
||||
}
|
||||
|
||||
@ -147,10 +148,12 @@ bool AVIDecoder::parseNextChunk() {
|
||||
case ID_JUNQ: // Same as JUNK, safe to ignore
|
||||
case ID_ISFT: // Metadata, safe to ignore
|
||||
case ID_DISP: // Metadata, should be safe to ignore
|
||||
case ID_STRN: // Metadata, safe to ignore
|
||||
case ID_DMLH: // OpenDML extension, contains an extra total frames field, safe to ignore
|
||||
skipChunk(size);
|
||||
break;
|
||||
case ID_STRN: // Metadata, safe to ignore
|
||||
readStreamName(size);
|
||||
break;
|
||||
case ID_IDX1:
|
||||
readOldIndex(size);
|
||||
break;
|
||||
@ -265,8 +268,7 @@ void AVIDecoder::handleStreamHeader(uint32 size) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!_selectTrackFn || _selectTrackFn(true, _videoTrackCounter++))
|
||||
addTrack(new AVIVideoTrack(_header.totalFrames, sHeader, bmInfo, initialPalette));
|
||||
addTrack(new AVIVideoTrack(_header.totalFrames, sHeader, bmInfo, initialPalette));
|
||||
} else if (sHeader.streamType == ID_AUDS) {
|
||||
PCMWaveFormat wvInfo;
|
||||
wvInfo.tag = _fileStream->readUint16LE();
|
||||
@ -281,17 +283,48 @@ void AVIDecoder::handleStreamHeader(uint32 size) {
|
||||
if (wvInfo.channels == 2)
|
||||
sHeader.sampleSize /= 2;
|
||||
|
||||
if (!_selectTrackFn || _selectTrackFn(false, _audioTrackCounter++)) {
|
||||
AVIAudioTrack *track = createAudioTrack(sHeader, wvInfo);
|
||||
track->createAudioStream();
|
||||
addTrack(track);
|
||||
}
|
||||
AVIAudioTrack *track = createAudioTrack(sHeader, wvInfo);
|
||||
track->createAudioStream();
|
||||
addTrack(track);
|
||||
}
|
||||
|
||||
// Ensure that we're at the end of the chunk
|
||||
_fileStream->seek(startPos + strfSize);
|
||||
}
|
||||
|
||||
void AVIDecoder::addTrack(Track *track, bool isExternal) {
|
||||
if (!_selectTrackFn ||
|
||||
(dynamic_cast<AVIVideoTrack *>(track) && _selectTrackFn(true, _videoTrackCounter++)) ||
|
||||
(dynamic_cast<AVIAudioTrack *>(track) && _selectTrackFn(false, _audioTrackCounter++))) {
|
||||
VideoDecoder::addTrack(track, isExternal);
|
||||
_lastAddedTrack = track;
|
||||
} else {
|
||||
_lastAddedTrack = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void AVIDecoder::readStreamName(uint32 size) {
|
||||
if (!_lastAddedTrack) {
|
||||
skipChunk(size);
|
||||
} else {
|
||||
// Get in the name
|
||||
assert(size > 0 && size < 64);
|
||||
char buffer[64];
|
||||
_fileStream->read(buffer, size);
|
||||
if (size & 1)
|
||||
_fileStream->skip(1);
|
||||
|
||||
// Apply it to the most recently read stream
|
||||
assert(_lastAddedTrack);
|
||||
AVIVideoTrack *vidTrack = dynamic_cast<AVIVideoTrack *>(_lastAddedTrack);
|
||||
AVIAudioTrack *audTrack = dynamic_cast<AVIAudioTrack *>(_lastAddedTrack);
|
||||
if (vidTrack)
|
||||
vidTrack->getName() = Common::String(buffer);
|
||||
else if (audTrack)
|
||||
audTrack->getName() = Common::String(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
bool AVIDecoder::loadStream(Common::SeekableReadStream *stream) {
|
||||
close();
|
||||
|
||||
@ -301,7 +334,7 @@ bool AVIDecoder::loadStream(Common::SeekableReadStream *stream) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 fileSize = stream->readUint32LE();
|
||||
int32 fileSize = stream->readUint32LE();
|
||||
uint32 riffType = stream->readUint32BE();
|
||||
|
||||
if (riffType != ID_AVI) {
|
||||
|
@ -83,6 +83,16 @@ protected:
|
||||
bool supportsAudioTrackSwitching() const { return true; }
|
||||
AudioTrack *getAudioTrack(int index);
|
||||
|
||||
/**
|
||||
* Define a track to be used by this class.
|
||||
*
|
||||
* The pointer is then owned by this base class.
|
||||
*
|
||||
* @param track The track to add
|
||||
* @param isExternal Is this an external track not found by loadStream()?
|
||||
*/
|
||||
void addTrack(Track *track, bool isExternal = false);
|
||||
|
||||
struct BitmapInfoHeader {
|
||||
uint32 size;
|
||||
uint32 width;
|
||||
@ -166,6 +176,7 @@ protected:
|
||||
uint32 quality;
|
||||
uint32 sampleSize;
|
||||
Common::Rect frame;
|
||||
Common::String name;
|
||||
};
|
||||
|
||||
class AVIVideoTrack : public FixedRateVideoTrack {
|
||||
@ -181,6 +192,7 @@ protected:
|
||||
Graphics::PixelFormat getPixelFormat() const;
|
||||
int getCurFrame() const { return _curFrame; }
|
||||
int getFrameCount() const { return _frameCount; }
|
||||
Common::String &getName() { return _vidsHeader.name; }
|
||||
const Graphics::Surface *decodeNextFrame() { return _lastFrame; }
|
||||
|
||||
const byte *getPalette() const;
|
||||
@ -224,6 +236,7 @@ protected:
|
||||
void skipAudio(const Audio::Timestamp &time, const Audio::Timestamp &frameTime);
|
||||
virtual void resetStream();
|
||||
uint32 getCurChunk() const { return _curChunk; }
|
||||
Common::String &getName() { return _audsHeader.name; }
|
||||
void setCurChunk(uint32 chunk) { _curChunk = chunk; }
|
||||
|
||||
bool isRewindable() const { return true; }
|
||||
@ -272,6 +285,7 @@ protected:
|
||||
Common::Rational _frameRateOverride;
|
||||
|
||||
int _videoTrackCounter, _audioTrackCounter;
|
||||
Track *_lastAddedTrack;
|
||||
SelectTrackFn _selectTrackFn;
|
||||
|
||||
void initCommon();
|
||||
@ -280,6 +294,7 @@ protected:
|
||||
void skipChunk(uint32 size);
|
||||
void handleList(uint32 listSize);
|
||||
void handleStreamHeader(uint32 size);
|
||||
void readStreamName(uint32 size);
|
||||
uint16 getStreamType(uint32 tag) const { return tag & 0xFFFF; }
|
||||
byte getStreamIndex(uint32 tag) const;
|
||||
void checkTruemotion1();
|
||||
|
Loading…
x
Reference in New Issue
Block a user