mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-19 16:33:50 +00:00
VIDEO: Begin splitting video-specific QuickTime sample description code
This commit is contained in:
parent
82a417b40c
commit
b71d2038ae
@ -186,7 +186,7 @@ void QuickTimeDecoder::seekToFrame(uint32 frame) {
|
|||||||
_audioStartOffset = curVideoTime;
|
_audioStartOffset = curVideoTime;
|
||||||
|
|
||||||
// Re-create the audio stream
|
// Re-create the audio stream
|
||||||
STSDEntry *entry = &_streams[_audioStreamIndex]->stsdEntries[0];
|
AudioSampleDesc *entry = (AudioSampleDesc *)_streams[_audioStreamIndex]->sampleDescs[0];
|
||||||
_audStream = Audio::makeQueuingAudioStream(entry->sampleRate, entry->channels == 2);
|
_audStream = Audio::makeQueuingAudioStream(entry->sampleRate, entry->channels == 2);
|
||||||
|
|
||||||
// First, we need to track down what audio sample we need
|
// First, we need to track down what audio sample we need
|
||||||
@ -318,10 +318,10 @@ void QuickTimeDecoder::pauseVideoIntern(bool pause) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Codec *QuickTimeDecoder::findDefaultVideoCodec() const {
|
Codec *QuickTimeDecoder::findDefaultVideoCodec() const {
|
||||||
if (_videoStreamIndex < 0 || !_streams[_videoStreamIndex]->stsdEntryCount)
|
if (_videoStreamIndex < 0 || _streams[_videoStreamIndex]->sampleDescs.empty())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return _streams[_videoStreamIndex]->stsdEntries[0].videoCodec;
|
return ((VideoSampleDesc *)_streams[_videoStreamIndex]->sampleDescs[0])->videoCodec;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Graphics::Surface *QuickTimeDecoder::decodeNextFrame() {
|
const Graphics::Surface *QuickTimeDecoder::decodeNextFrame() {
|
||||||
@ -341,11 +341,11 @@ const Graphics::Surface *QuickTimeDecoder::decodeNextFrame() {
|
|||||||
uint32 descId;
|
uint32 descId;
|
||||||
Common::SeekableReadStream *frameData = getNextFramePacket(descId);
|
Common::SeekableReadStream *frameData = getNextFramePacket(descId);
|
||||||
|
|
||||||
if (!frameData || !descId || descId > _streams[_videoStreamIndex]->stsdEntryCount)
|
if (!frameData || !descId || descId > _streams[_videoStreamIndex]->sampleDescs.size())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// Find which video description entry we want
|
// Find which video description entry we want
|
||||||
STSDEntry *entry = &_streams[_videoStreamIndex]->stsdEntries[descId - 1];
|
VideoSampleDesc *entry = (VideoSampleDesc *)_streams[_videoStreamIndex]->sampleDescs[descId - 1];
|
||||||
|
|
||||||
if (!entry->videoCodec)
|
if (!entry->videoCodec)
|
||||||
return 0;
|
return 0;
|
||||||
@ -500,7 +500,7 @@ void QuickTimeDecoder::init() {
|
|||||||
|
|
||||||
// Initialize audio, if present
|
// Initialize audio, if present
|
||||||
if (_audioStreamIndex >= 0) {
|
if (_audioStreamIndex >= 0) {
|
||||||
STSDEntry *entry = &_streams[_audioStreamIndex]->stsdEntries[0];
|
AudioSampleDesc *entry = (AudioSampleDesc *)_streams[_audioStreamIndex]->sampleDescs[0];
|
||||||
|
|
||||||
if (checkAudioCodecSupport(entry->codecTag)) {
|
if (checkAudioCodecSupport(entry->codecTag)) {
|
||||||
_audStream = Audio::makeQueuingAudioStream(entry->sampleRate, entry->channels == 2);
|
_audStream = Audio::makeQueuingAudioStream(entry->sampleRate, entry->channels == 2);
|
||||||
@ -518,8 +518,8 @@ void QuickTimeDecoder::init() {
|
|||||||
|
|
||||||
// Initialize video, if present
|
// Initialize video, if present
|
||||||
if (_videoStreamIndex >= 0) {
|
if (_videoStreamIndex >= 0) {
|
||||||
for (uint32 i = 0; i < _streams[_videoStreamIndex]->stsdEntryCount; i++) {
|
for (uint32 i = 0; i < _streams[_videoStreamIndex]->sampleDescs.size(); i++) {
|
||||||
STSDEntry *entry = &_streams[_videoStreamIndex]->stsdEntries[i];
|
VideoSampleDesc *entry = (VideoSampleDesc *)_streams[_videoStreamIndex]->sampleDescs[i];
|
||||||
entry->videoCodec = createCodec(entry->codecTag, entry->bitsPerSample & 0x1F);
|
entry->videoCodec = createCodec(entry->codecTag, entry->bitsPerSample & 0x1F);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -916,12 +916,10 @@ int QuickTimeDecoder::readSTSD(MOVatom atom) {
|
|||||||
_fd->readByte(); // version
|
_fd->readByte(); // version
|
||||||
_fd->readByte(); _fd->readByte(); _fd->readByte(); // flags
|
_fd->readByte(); _fd->readByte(); _fd->readByte(); // flags
|
||||||
|
|
||||||
st->stsdEntryCount = _fd->readUint32BE();
|
uint32 entryCount = _fd->readUint32BE();
|
||||||
st->stsdEntries = new STSDEntry[st->stsdEntryCount];
|
st->sampleDescs.resize(entryCount);
|
||||||
|
|
||||||
for (uint32 i = 0; i < st->stsdEntryCount; i++) { // Parsing Sample description table
|
|
||||||
STSDEntry *entry = &st->stsdEntries[i];
|
|
||||||
|
|
||||||
|
for (uint32 i = 0; i < entryCount; i++) { // Parsing Sample description table
|
||||||
MOVatom a = { 0, 0, 0 };
|
MOVatom a = { 0, 0, 0 };
|
||||||
uint32 start_pos = _fd->pos();
|
uint32 start_pos = _fd->pos();
|
||||||
int size = _fd->readUint32BE(); // size
|
int size = _fd->readUint32BE(); // size
|
||||||
@ -933,11 +931,14 @@ int QuickTimeDecoder::readSTSD(MOVatom atom) {
|
|||||||
|
|
||||||
debug(0, "size=%d 4CC= %s codec_type=%d", size, tag2str(format), st->codec_type);
|
debug(0, "size=%d 4CC= %s codec_type=%d", size, tag2str(format), st->codec_type);
|
||||||
|
|
||||||
entry->codecTag = format;
|
|
||||||
|
|
||||||
if (st->codec_type == CODEC_TYPE_VIDEO) {
|
if (st->codec_type == CODEC_TYPE_VIDEO) {
|
||||||
debug(0, "Video Codec FourCC: \'%s\'", tag2str(format));
|
debug(0, "Video Codec FourCC: \'%s\'", tag2str(format));
|
||||||
|
|
||||||
|
VideoSampleDesc *entry = new VideoSampleDesc();
|
||||||
|
st->sampleDescs[i] = entry;
|
||||||
|
|
||||||
|
entry->codecTag = format;
|
||||||
|
|
||||||
_fd->readUint16BE(); // version
|
_fd->readUint16BE(); // version
|
||||||
_fd->readUint16BE(); // revision level
|
_fd->readUint16BE(); // revision level
|
||||||
_fd->readUint32BE(); // vendor
|
_fd->readUint32BE(); // vendor
|
||||||
@ -1025,6 +1026,11 @@ int QuickTimeDecoder::readSTSD(MOVatom atom) {
|
|||||||
} else if (st->codec_type == CODEC_TYPE_AUDIO) {
|
} else if (st->codec_type == CODEC_TYPE_AUDIO) {
|
||||||
debug(0, "Audio Codec FourCC: \'%s\'", tag2str(format));
|
debug(0, "Audio Codec FourCC: \'%s\'", tag2str(format));
|
||||||
|
|
||||||
|
AudioSampleDesc *entry = new AudioSampleDesc();
|
||||||
|
st->sampleDescs[i] = entry;
|
||||||
|
|
||||||
|
entry->codecTag = format;
|
||||||
|
|
||||||
uint16 stsdVersion = _fd->readUint16BE();
|
uint16 stsdVersion = _fd->readUint16BE();
|
||||||
_fd->readUint16BE(); // revision level
|
_fd->readUint16BE(); // revision level
|
||||||
_fd->readUint32BE(); // vendor
|
_fd->readUint32BE(); // vendor
|
||||||
@ -1229,7 +1235,7 @@ int QuickTimeDecoder::readWAVE(MOVatom atom) {
|
|||||||
if (atom.size > (1 << 30))
|
if (atom.size > (1 << 30))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (st->stsdEntries[0].codecTag == MKID_BE('QDM2')) // Read extradata for QDM2
|
if (st->sampleDescs[0]->codecTag == MKID_BE('QDM2')) // Read extradata for QDM2
|
||||||
st->extradata = _fd->readStream(atom.size - 8);
|
st->extradata = _fd->readStream(atom.size - 8);
|
||||||
else if (atom.size > 8)
|
else if (atom.size > 8)
|
||||||
return readDefault(atom);
|
return readDefault(atom);
|
||||||
@ -1336,7 +1342,7 @@ Audio::AudioStream *QuickTimeDecoder::createAudioStream(Common::SeekableReadStre
|
|||||||
if (!stream || _audioStreamIndex < 0)
|
if (!stream || _audioStreamIndex < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
STSDEntry *entry = &_streams[_audioStreamIndex]->stsdEntries[0];
|
AudioSampleDesc *entry = (AudioSampleDesc *)_streams[_audioStreamIndex]->sampleDescs[0];
|
||||||
|
|
||||||
if (entry->codecTag == MKID_BE('twos') || entry->codecTag == MKID_BE('raw ')) {
|
if (entry->codecTag == MKID_BE('twos') || entry->codecTag == MKID_BE('raw ')) {
|
||||||
// Fortunately, most of the audio used in Myst videos is raw...
|
// Fortunately, most of the audio used in Myst videos is raw...
|
||||||
@ -1381,7 +1387,7 @@ uint32 QuickTimeDecoder::getAudioChunkSampleCount(uint chunk) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void QuickTimeDecoder::readNextAudioChunk() {
|
void QuickTimeDecoder::readNextAudioChunk() {
|
||||||
STSDEntry *entry = &_streams[_audioStreamIndex]->stsdEntries[0];
|
AudioSampleDesc *entry = (AudioSampleDesc *)_streams[_audioStreamIndex]->sampleDescs[0];
|
||||||
Common::MemoryWriteStreamDynamic *wStream = new Common::MemoryWriteStreamDynamic();
|
Common::MemoryWriteStreamDynamic *wStream = new Common::MemoryWriteStreamDynamic();
|
||||||
|
|
||||||
_fd->seek(_streams[_audioStreamIndex]->chunk_offsets[_curAudioChunk]);
|
_fd->seek(_streams[_audioStreamIndex]->chunk_offsets[_curAudioChunk]);
|
||||||
@ -1430,7 +1436,7 @@ void QuickTimeDecoder::updateAudioBuffer() {
|
|||||||
// If we're on the last frame, make sure all audio remaining is buffered
|
// If we're on the last frame, make sure all audio remaining is buffered
|
||||||
numberOfChunksNeeded = _streams[_audioStreamIndex]->chunk_count;
|
numberOfChunksNeeded = _streams[_audioStreamIndex]->chunk_count;
|
||||||
} else {
|
} else {
|
||||||
STSDEntry *entry = &_streams[_audioStreamIndex]->stsdEntries[0];
|
AudioSampleDesc *entry = (AudioSampleDesc *)_streams[_audioStreamIndex]->sampleDescs[0];
|
||||||
|
|
||||||
// Calculate the amount of chunks we need in memory until the next frame
|
// Calculate the amount of chunks we need in memory until the next frame
|
||||||
uint32 timeToNextFrame = getTimeToNextFrame();
|
uint32 timeToNextFrame = getTimeToNextFrame();
|
||||||
@ -1453,24 +1459,30 @@ void QuickTimeDecoder::updateAudioBuffer() {
|
|||||||
readNextAudioChunk();
|
readNextAudioChunk();
|
||||||
}
|
}
|
||||||
|
|
||||||
QuickTimeDecoder::STSDEntry::STSDEntry() {
|
QuickTimeDecoder::SampleDesc::SampleDesc() {
|
||||||
codecTag = 0;
|
codecTag = 0;
|
||||||
bitsPerSample = 0;
|
bitsPerSample = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QuickTimeDecoder::VideoSampleDesc::VideoSampleDesc() : SampleDesc() {
|
||||||
memset(codecName, 0, 32);
|
memset(codecName, 0, 32);
|
||||||
colorTableId = 0;
|
colorTableId = 0;
|
||||||
palette = 0;
|
palette = 0;
|
||||||
videoCodec = 0;
|
videoCodec = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QuickTimeDecoder::VideoSampleDesc::~VideoSampleDesc() {
|
||||||
|
delete[] palette;
|
||||||
|
delete videoCodec;
|
||||||
|
}
|
||||||
|
|
||||||
|
QuickTimeDecoder::AudioSampleDesc::AudioSampleDesc() : SampleDesc() {
|
||||||
channels = 0;
|
channels = 0;
|
||||||
sampleRate = 0;
|
sampleRate = 0;
|
||||||
samplesPerFrame = 0;
|
samplesPerFrame = 0;
|
||||||
bytesPerFrame = 0;
|
bytesPerFrame = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
QuickTimeDecoder::STSDEntry::~STSDEntry() {
|
|
||||||
delete[] palette;
|
|
||||||
delete videoCodec;
|
|
||||||
}
|
|
||||||
|
|
||||||
QuickTimeDecoder::MOVStreamContext::MOVStreamContext() {
|
QuickTimeDecoder::MOVStreamContext::MOVStreamContext() {
|
||||||
chunk_count = 0;
|
chunk_count = 0;
|
||||||
chunk_offsets = 0;
|
chunk_offsets = 0;
|
||||||
@ -1488,8 +1500,6 @@ QuickTimeDecoder::MOVStreamContext::MOVStreamContext() {
|
|||||||
width = 0;
|
width = 0;
|
||||||
height = 0;
|
height = 0;
|
||||||
codec_type = CODEC_TYPE_MOV_OTHER;
|
codec_type = CODEC_TYPE_MOV_OTHER;
|
||||||
stsdEntryCount = 0;
|
|
||||||
stsdEntries = 0;
|
|
||||||
editCount = 0;
|
editCount = 0;
|
||||||
editList = 0;
|
editList = 0;
|
||||||
extradata = 0;
|
extradata = 0;
|
||||||
@ -1504,9 +1514,11 @@ QuickTimeDecoder::MOVStreamContext::~MOVStreamContext() {
|
|||||||
delete[] sample_to_chunk;
|
delete[] sample_to_chunk;
|
||||||
delete[] sample_sizes;
|
delete[] sample_sizes;
|
||||||
delete[] keyframes;
|
delete[] keyframes;
|
||||||
delete[] stsdEntries;
|
|
||||||
delete[] editList;
|
delete[] editList;
|
||||||
delete extradata;
|
delete extradata;
|
||||||
|
|
||||||
|
for (uint32 i = 0; i < sampleDescs.size(); i++)
|
||||||
|
delete sampleDescs[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
} // End of namespace Video
|
} // End of namespace Video
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#ifndef VIDEO_QT_DECODER_H
|
#ifndef VIDEO_QT_DECODER_H
|
||||||
#define VIDEO_QT_DECODER_H
|
#define VIDEO_QT_DECODER_H
|
||||||
|
|
||||||
|
#include "common/array.h"
|
||||||
#include "common/scummsys.h"
|
#include "common/scummsys.h"
|
||||||
#include "common/queue.h"
|
#include "common/queue.h"
|
||||||
#include "common/rational.h"
|
#include "common/rational.h"
|
||||||
@ -156,20 +157,27 @@ private:
|
|||||||
Common::Rational mediaRate;
|
Common::Rational mediaRate;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct STSDEntry {
|
struct SampleDesc {
|
||||||
STSDEntry();
|
SampleDesc();
|
||||||
~STSDEntry();
|
virtual ~SampleDesc() {}
|
||||||
|
|
||||||
uint32 codecTag;
|
uint32 codecTag;
|
||||||
uint16 bitsPerSample;
|
uint16 bitsPerSample;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VideoSampleDesc : public SampleDesc {
|
||||||
|
VideoSampleDesc();
|
||||||
|
~VideoSampleDesc();
|
||||||
|
|
||||||
// Video
|
|
||||||
char codecName[32];
|
char codecName[32];
|
||||||
uint16 colorTableId;
|
uint16 colorTableId;
|
||||||
byte *palette;
|
byte *palette;
|
||||||
Codec *videoCodec;
|
Codec *videoCodec;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AudioSampleDesc : public SampleDesc {
|
||||||
|
AudioSampleDesc();
|
||||||
|
|
||||||
// Audio
|
|
||||||
uint16 channels;
|
uint16 channels;
|
||||||
uint32 sampleRate;
|
uint32 sampleRate;
|
||||||
uint32 samplesPerFrame;
|
uint32 samplesPerFrame;
|
||||||
@ -204,8 +212,7 @@ private:
|
|||||||
uint16 height;
|
uint16 height;
|
||||||
CodecType codec_type;
|
CodecType codec_type;
|
||||||
|
|
||||||
uint32 stsdEntryCount;
|
Common::Array<SampleDesc *> sampleDescs;
|
||||||
STSDEntry *stsdEntries;
|
|
||||||
|
|
||||||
uint32 editCount;
|
uint32 editCount;
|
||||||
EditListEntry *editList;
|
EditListEntry *editList;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user