blob: 5431d1e3e89c3609049d6eb27bb764d0eb88171f [file] [log] [blame]
Jack Jansenab98ae92001-08-19 22:13:00 +00001# Parsers/generators for QuickTime media descriptions
2import struct
3
4Error = 'MediaDescr.Error'
5
6class _MediaDescriptionCodec:
Tim Peters182b5ac2004-07-18 06:16:08 +00007 def __init__(self, trunc, size, names, fmt):
8 self.trunc = trunc
9 self.size = size
10 self.names = names
11 self.fmt = fmt
Raymond Hettingerff41c482003-04-06 09:01:11 +000012
Tim Peters182b5ac2004-07-18 06:16:08 +000013 def decode(self, data):
14 if self.trunc:
15 data = data[:self.size]
16 values = struct.unpack(self.fmt, data)
17 if len(values) != len(self.names):
Georg Brandl1f6176e2010-02-06 23:54:43 +000018 raise Error, ('Format length does not match number of names')
Tim Peters182b5ac2004-07-18 06:16:08 +000019 rv = {}
20 for i in range(len(values)):
21 name = self.names[i]
22 value = values[i]
23 if type(name) == type(()):
24 name, cod, dec = name
25 value = dec(value)
26 rv[name] = value
27 return rv
Raymond Hettingerff41c482003-04-06 09:01:11 +000028
Georg Brandl1f6176e2010-02-06 23:54:43 +000029 def encode(self, dict):
Tim Peters182b5ac2004-07-18 06:16:08 +000030 list = [self.fmt]
31 for name in self.names:
32 if type(name) == type(()):
33 name, cod, dec = name
34 else:
35 cod = dec = None
36 value = dict[name]
37 if cod:
38 value = cod(value)
39 list.append(value)
40 rv = struct.pack(*list)
41 return rv
Raymond Hettingerff41c482003-04-06 09:01:11 +000042
Jack Jansenab98ae92001-08-19 22:13:00 +000043# Helper functions
44def _tofixed(float):
Tim Peters182b5ac2004-07-18 06:16:08 +000045 hi = int(float)
46 lo = int(float*0x10000) & 0xffff
47 return (hi<<16)|lo
Raymond Hettingerff41c482003-04-06 09:01:11 +000048
Jack Jansenab98ae92001-08-19 22:13:00 +000049def _fromfixed(fixed):
Tim Peters182b5ac2004-07-18 06:16:08 +000050 hi = (fixed >> 16) & 0xffff
51 lo = (fixed & 0xffff)
52 return hi + (lo / float(0x10000))
Raymond Hettingerff41c482003-04-06 09:01:11 +000053
Jack Jansenab98ae92001-08-19 22:13:00 +000054def _tostr31(str):
Tim Peters182b5ac2004-07-18 06:16:08 +000055 return chr(len(str)) + str + '\0'*(31-len(str))
Raymond Hettingerff41c482003-04-06 09:01:11 +000056
Jack Jansenab98ae92001-08-19 22:13:00 +000057def _fromstr31(str31):
Tim Peters182b5ac2004-07-18 06:16:08 +000058 return str31[1:1+ord(str31[0])]
Jack Jansenab98ae92001-08-19 22:13:00 +000059
60SampleDescription = _MediaDescriptionCodec(
Raymond Hettingerff41c482003-04-06 09:01:11 +000061 1, # May be longer, truncate
62 16, # size
63 ('descSize', 'dataFormat', 'resvd1', 'resvd2', 'dataRefIndex'), # Attributes
64 "l4slhh" # Format
Jack Jansenab98ae92001-08-19 22:13:00 +000065)
66
67SoundDescription = _MediaDescriptionCodec(
Raymond Hettingerff41c482003-04-06 09:01:11 +000068 1,
69 36,
70 ('descSize', 'dataFormat', 'resvd1', 'resvd2', 'dataRefIndex',
71 'version', 'revlevel', 'vendor', 'numChannels', 'sampleSize',
72 'compressionID', 'packetSize', ('sampleRate', _tofixed, _fromfixed)),
73 "l4slhhhh4shhhhl" # Format
Jack Jansenab98ae92001-08-19 22:13:00 +000074)
75
76SoundDescriptionV1 = _MediaDescriptionCodec(
Raymond Hettingerff41c482003-04-06 09:01:11 +000077 1,
78 52,
79 ('descSize', 'dataFormat', 'resvd1', 'resvd2', 'dataRefIndex',
80 'version', 'revlevel', 'vendor', 'numChannels', 'sampleSize',
81 'compressionID', 'packetSize', ('sampleRate', _tofixed, _fromfixed), 'samplesPerPacket',
82 'bytesPerPacket', 'bytesPerFrame', 'bytesPerSample'),
83 "l4slhhhh4shhhhlllll" # Format
Jack Jansenab98ae92001-08-19 22:13:00 +000084)
85
86ImageDescription = _MediaDescriptionCodec(
Raymond Hettingerff41c482003-04-06 09:01:11 +000087 1, # May be longer, truncate
88 86, # size
89 ('idSize', 'cType', 'resvd1', 'resvd2', 'dataRefIndex', 'version',
90 'revisionLevel', 'vendor', 'temporalQuality', 'spatialQuality',
91 'width', 'height', ('hRes', _tofixed, _fromfixed), ('vRes', _tofixed, _fromfixed),
92 'dataSize', 'frameCount', ('name', _tostr31, _fromstr31),
93 'depth', 'clutID'),
94 'l4slhhhh4sllhhlllh32shh',
Jack Jansenab98ae92001-08-19 22:13:00 +000095)
96
97# XXXX Others, like TextDescription and such, remain to be done.