aboutsummaryrefslogtreecommitdiff
path: root/graphics/video
diff options
context:
space:
mode:
authorMatthew Hoops2010-05-23 23:26:28 +0000
committerMatthew Hoops2010-05-23 23:26:28 +0000
commit8f14c15b1afc51a860d7fae28a59cbcd4d7d4d04 (patch)
tree0cbd344af6dbce6450bfba1a9d061558c4348853 /graphics/video
parentb3bd797e019c20de1d4bfdac131e6e3e2c45860a (diff)
downloadscummvm-rg350-8f14c15b1afc51a860d7fae28a59cbcd4d7d4d04.tar.gz
scummvm-rg350-8f14c15b1afc51a860d7fae28a59cbcd4d7d4d04.tar.bz2
scummvm-rg350-8f14c15b1afc51a860d7fae28a59cbcd4d7d4d04.zip
Add support for loading the QuickTime 'moov' atom from the file's resource fork, needed for SCI Mac.
svn-id: r49172
Diffstat (limited to 'graphics/video')
-rw-r--r--graphics/video/qt_decoder.cpp68
-rw-r--r--graphics/video/qt_decoder.h10
2 files changed, 64 insertions, 14 deletions
diff --git a/graphics/video/qt_decoder.cpp b/graphics/video/qt_decoder.cpp
index 4a9be0b0fd..5e50772024 100644
--- a/graphics/video/qt_decoder.cpp
+++ b/graphics/video/qt_decoder.cpp
@@ -35,6 +35,7 @@
#include "common/debug.h"
#include "common/endian.h"
+#include "common/macresman.h"
#include "common/util.h"
#include "common/zlib.h"
@@ -67,10 +68,14 @@ QuickTimeDecoder::QuickTimeDecoder() : VideoDecoder() {
_fd = 0;
_scaledSurface = 0;
_dirtyPalette = false;
+ _resFork = new Common::MacResManager();
+
+ initParseTable();
}
QuickTimeDecoder::~QuickTimeDecoder() {
close();
+ delete _resFork;
}
uint16 QuickTimeDecoder::getWidth() const {
@@ -256,7 +261,7 @@ uint32 QuickTimeDecoder::getTimeToNextFrame() const {
if (endOfVideo() || _curFrame < 0)
return 0;
- // Convert from the Sega FILM base to 1000
+ // Convert from the QuickTime rate base to 1000
uint32 nextFrameStartTime = _nextFrameStartTime * 1000 / _streams[_videoStreamIndex]->time_scale;
uint32 elapsedTime = getElapsedTime();
@@ -266,6 +271,41 @@ uint32 QuickTimeDecoder::getTimeToNextFrame() const {
return nextFrameStartTime - elapsedTime;
}
+bool QuickTimeDecoder::loadFile(const Common::String &filename) {
+ if (!_resFork->open(filename) || !_resFork->hasDataFork())
+ return false;
+
+ _foundMOOV = _foundMDAT = false;
+ _numStreams = 0;
+ _partial = 0;
+ _videoStreamIndex = _audioStreamIndex = -1;
+ _startTime = 0;
+
+ MOVatom atom = { 0, 0, 0xffffffff };
+
+ if (_resFork->hasResFork()) {
+ _fd = _resFork->getResource(MKID_BE('moov'), 0x80);
+ if (_fd) {
+ atom.size = _fd->size();
+ if (readDefault(atom) < 0 || !_foundMOOV)
+ return false;
+ }
+ delete _fd;
+
+ atom.type = 0;
+ atom.offset = 0;
+ atom.size = 0xffffffff;
+ }
+
+ _fd = _resFork->getDataFork();
+
+ if (readDefault(atom) < 0 || !_foundMOOV || !_foundMDAT)
+ return false;
+
+ init();
+ return true;
+}
+
bool QuickTimeDecoder::load(Common::SeekableReadStream &stream) {
_fd = &stream;
_foundMOOV = _foundMDAT = false;
@@ -274,21 +314,22 @@ bool QuickTimeDecoder::load(Common::SeekableReadStream &stream) {
_videoStreamIndex = _audioStreamIndex = -1;
_startTime = 0;
- initParseTable();
-
MOVatom atom = { 0, 0, 0xffffffff };
- if (readDefault(atom) < 0 || (!_foundMOOV && !_foundMDAT))
+ if (readDefault(atom) < 0 || !_foundMOOV || !_foundMDAT) {
+ _fd = 0;
return false;
+ }
- debug(0, "on_parse_exit_offset=%d", _fd->pos());
+ init();
+ return true;
+}
+void QuickTimeDecoder::init() {
// some cleanup : make sure we are on the mdat atom
if((uint32)_fd->pos() != _mdatOffset)
_fd->seek(_mdatOffset, SEEK_SET);
- _next_chunk_offset = _mdatOffset; // initialise reading
-
for (uint32 i = 0; i < _numStreams;) {
if (_streams[i]->codec_type == CODEC_TYPE_MOV_OTHER) {// not audio, not video, delete
delete _streams[i];
@@ -302,14 +343,12 @@ bool QuickTimeDecoder::load(Common::SeekableReadStream &stream) {
for (uint32 i = 0; i < _numStreams; i++) {
MOVStreamContext *sc = _streams[i];
- if(!sc->time_rate)
+ if (!sc->time_rate)
sc->time_rate = 1;
- if(!sc->time_scale)
+ if (!sc->time_scale)
sc->time_scale = _timeScale;
- //av_set_pts_info(s->streams[i], 64, sc->time_rate, sc->time_scale);
-
sc->duration /= sc->time_rate;
sc->ffindex = i;
@@ -341,8 +380,6 @@ bool QuickTimeDecoder::load(Common::SeekableReadStream &stream) {
_scaledSurface->create(getWidth(), getHeight(), getPixelFormat().bytesPerPixel);
}
}
-
- return true;
}
void QuickTimeDecoder::initParseTable() {
@@ -392,6 +429,11 @@ int QuickTimeDecoder::readDefault(MOVatom atom) {
if (atom.size >= 8) {
a.size = _fd->readUint32BE();
a.type = _fd->readUint32BE();
+
+ // Some QuickTime videos with resource forks have mdat chunks
+ // that are of size 0. Adjust it so it's the correct size.
+ if (a.size == 0)
+ a.size = _fd->size();
}
total_size += 8;
diff --git a/graphics/video/qt_decoder.h b/graphics/video/qt_decoder.h
index dc0557b388..545866f9e5 100644
--- a/graphics/video/qt_decoder.h
+++ b/graphics/video/qt_decoder.h
@@ -45,6 +45,7 @@
namespace Common {
class File;
+ class MacResManager;
}
namespace Graphics {
@@ -79,6 +80,12 @@ public:
uint32 getFrameCount() const;
/**
+ * Load a video file
+ * @param filename the filename to load
+ */
+ bool loadFile(const Common::String &filename);
+
+ /**
* Load a QuickTime video file from a SeekableReadStream
* @param stream the stream to load
*/
@@ -221,7 +228,6 @@ protected:
uint32 _duration;
uint32 _mdatOffset;
uint32 _mdatSize;
- uint32 _next_chunk_offset;
MOVStreamContext *_partial;
uint32 _numStreams;
int _ni;
@@ -230,6 +236,7 @@ protected:
byte _palette[256 * 3];
bool _dirtyPalette;
uint32 _beginOffset;
+ Common::MacResManager *_resFork;
void initParseTable();
Audio::AudioStream *createAudioStream(Common::SeekableReadStream *stream);
@@ -238,6 +245,7 @@ protected:
uint32 getFrameDuration();
uint32 getCodecTag();
byte getBitsPerPixel();
+ void init();
Audio::QueuingAudioStream *_audStream;
void startAudio();