aboutsummaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorMatthew Hoops2011-04-08 22:46:19 -0400
committerMatthew Hoops2011-04-08 22:46:19 -0400
commit7c5dfaa04c2d02a22b301823bedb2940c3e590aa (patch)
treecb3feb850b2095f1f717ebe9ab99ad7ecd8fa5b6 /common
parentfaee277978c54ccb3dcccfedc75ddb31f44e630f (diff)
downloadscummvm-rg350-7c5dfaa04c2d02a22b301823bedb2940c3e590aa.tar.gz
scummvm-rg350-7c5dfaa04c2d02a22b301823bedb2940c3e590aa.tar.bz2
scummvm-rg350-7c5dfaa04c2d02a22b301823bedb2940c3e590aa.zip
COMMON: Parse the MPEG-4 esds atom
Diffstat (limited to 'common')
-rw-r--r--common/quicktime.cpp67
-rw-r--r--common/quicktime.h3
2 files changed, 70 insertions, 0 deletions
diff --git a/common/quicktime.cpp b/common/quicktime.cpp
index fe48cfdcb1..a28f8180cf 100644
--- a/common/quicktime.cpp
+++ b/common/quicktime.cpp
@@ -170,6 +170,7 @@ void QuickTimeParser::initParseTable() {
{ &QuickTimeParser::readLeaf, MKID_BE('vmhd') },
{ &QuickTimeParser::readCMOV, MKID_BE('cmov') },
{ &QuickTimeParser::readWAVE, MKID_BE('wave') },
+ { &QuickTimeParser::readESDS, MKID_BE('esds') },
{ 0, 0 }
};
@@ -721,6 +722,71 @@ int QuickTimeParser::readWAVE(MOVatom atom) {
return 0;
}
+enum {
+ kMP4IODescTag = 2,
+ kMP4ESDescTag = 3,
+ kMP4DecConfigDescTag = 4,
+ kMP4DecSpecificDescTag = 5
+};
+
+static int readMP4DescLength(Common::SeekableReadStream *stream) {
+ int length = 0;
+ int count = 4;
+
+ while (count--) {
+ byte c = stream->readByte();
+ length = (length << 7) | (c & 0x7f);
+
+ if (!(c & 0x80))
+ break;
+ }
+
+ return length;
+}
+
+static void readMP4Desc(Common::SeekableReadStream *stream, byte &tag, int &length) {
+ tag = stream->readByte();
+ length = readMP4DescLength(stream);
+}
+
+int QuickTimeParser::readESDS(MOVatom atom) {
+ if (_numStreams < 1)
+ return 0;
+
+ MOVStreamContext *st = _streams[_numStreams - 1];
+
+ _fd->readUint32BE(); // version + flags
+
+ byte tag;
+ int length;
+
+ readMP4Desc(_fd, tag, length);
+ _fd->readUint16BE(); // id
+ if (tag == kMP4ESDescTag)
+ _fd->readByte(); // priority
+
+ // Check if we've got the Config MPEG-4 header
+ readMP4Desc(_fd, tag, length);
+ if (tag != kMP4DecConfigDescTag)
+ return 0;
+
+ st->objectTypeMP4 = _fd->readByte();
+ _fd->readByte(); // stream type
+ _fd->readUint16BE(); _fd->readByte(); // buffer size
+ _fd->readUint32BE(); // max bitrate
+ _fd->readUint32BE(); // avg bitrate
+
+ // Check if we've got the Specific MPEG-4 header
+ readMP4Desc(_fd, tag, length);
+ if (tag != kMP4DecSpecificDescTag)
+ return 0;
+
+ st->extradata = _fd->readStream(length);
+
+ debug(0, "MPEG-4 object type = %02x", st->objectTypeMP4);
+ return 0;
+}
+
void QuickTimeParser::close() {
for (uint32 i = 0; i < _numStreams; i++)
delete _streams[i];
@@ -761,6 +827,7 @@ QuickTimeParser::MOVStreamContext::MOVStreamContext() {
nb_frames = 0;
duration = 0;
start_time = 0;
+ objectTypeMP4 = 0;
}
QuickTimeParser::MOVStreamContext::~MOVStreamContext() {
diff --git a/common/quicktime.h b/common/quicktime.h
index 42b48bbb94..8e6b0ec64c 100644
--- a/common/quicktime.h
+++ b/common/quicktime.h
@@ -163,6 +163,8 @@ protected:
uint32 start_time;
Common::Rational scaleFactorX;
Common::Rational scaleFactorY;
+
+ byte objectTypeMP4;
};
virtual SampleDesc *readSampleDesc(MOVStreamContext *st, uint32 format) = 0;
@@ -198,6 +200,7 @@ protected:
int readSTTS(MOVatom atom);
int readCMOV(MOVatom atom);
int readWAVE(MOVatom atom);
+ int readESDS(MOVatom atom);
};
} // End of namespace Common