def decode(self, file_strm): if file_strm is None: print "file_strm is None" return file_strm file_strm = FullBox.decode(self, file_strm) if self.version == 1: self.creation_time = file_strm.ReadUInt64() self.creation_time -= UTC_MP4_INTERVAL self.offset += UInt64ByteLen if self.creation_time > 0: self.creation_time_fmt = Util.datetime_format( self.creation_time) self.modification_time = file_strm.ReadUInt64() self.modification_time -= UTC_MP4_INTERVAL self.offset += UInt64ByteLen if self.modification_time > 0: self.modification_time_fmt = Util.datetime_format( self.modification_time) self.timescale = file_strm.read_uint32() self.offset += UInt32ByteLen self.duration = file_strm.ReadUInt64() self.offset += UInt64ByteLen else: self.creation_time = file_strm.read_uint32() self.creation_time -= UTC_MP4_INTERVAL self.offset += UInt32ByteLen if self.creation_time > 0: self.creation_time_fmt = Util.datetime_format( self.creation_time) self.modification_time = file_strm.read_uint32() self.modification_time -= UTC_MP4_INTERVAL self.offset += UInt32ByteLen if self.modification_time > 0: self.modification_time_fmt = Util.datetime_format( self.modification_time) self.timescale = file_strm.read_uint32() self.offset += UInt32ByteLen self.duration = file_strm.read_uint32() self.offset += UInt32ByteLen """ ISO Language Codes Because the language codes specified by ISO 639-2/T are three characters long, they must be packed to fit into a 16-bit field. The packing algorithm must map each of the three characters, which are always lowercase, into a 5-bit integer and then concatenate these integers into the least significant 15 bits of a 16-bit integer, leaving the 16-bit integer’s most significant bit set to zero. One algorithm for performing this packing is to treat each ISO character as a 16-bit integer. Subtract 0x60 from the first character and multiply by 2^10 (0x400), subtract 0x60 from the second character and multiply by 2^5 (0x20), subtract 0x60 from the third character, and add the three 16-bit values. This will result in a single 16-bit value with the three codes correctly packed into the 15 least significant bits and the most significant bit set to zero. Example: The ISO language code 'jpn' consists of the three hexadecimal values 0x6A, 0x70, 0x6E. Subtracting 0x60 from each value yields the values 0xA, 0x10, 0xE, as shown in Table 5-2. Table 5-2 5-bit values of UTF-8 characters Character UTF-8 code 5-bit value Shifted value j 0x6A 0xA (01010) 0x2800 (01010..........) p 0x70 0x10 (10000) 0x200 (.....10000.....) n 0x6E 0xE (01110) 0xE (..........01110) The first value is shifted 10 bits to the left (multiplied by 0x400) and the second value is shifted 5 bits to the left (multiplied by 0x20). This yields the values 0x2800, 0x200, 0xE. When added, this results in the 16-bit packed language code value of 0x2A0E """ self.language_code = file_strm.read_uint16() self.offset += UInt16ByteLen self.pad = self.language_code >> 15 & 0x01 for i in range(len(self.language)): lang_ = ((self.language_code >> ((2 - i) * 5)) & 0x1F) + 0x60 self.language[i] = chr(lang_) self.pre_defined = file_strm.read_uint16() self.offset += UInt16ByteLen tmp_size = self.offset - self.box_offset if tmp_size != self.Size(): file_strm.seek(self.Size() - tmp_size, os.SEEK_CUR) return file_strm
def decode(self, file_strm): if file_strm is None: print "file_strm is None" return file_strm file_strm = FullBox.decode(self, file_strm) if self.version == 1: self.creation_time = file_strm.read_uint64() self.creation_time -= UTC_MP4_INTERVAL self.offset += UInt64ByteLen if self.creation_time > 0: self.creation_time_fmt = Util.datetime_format( self.creation_time) self.modification_time = file_strm.read_uint64() self.modification_time -= UTC_MP4_INTERVAL self.offset += UInt64ByteLen if self.modification_time > 0: self.modification_time_fmt = Util.datetime_format( self.modification_time) self.timescale = file_strm.read_uint32() self.offset += UInt32ByteLen self.duration = file_strm.read_uint64() self.offset += UInt64ByteLen else: self.creation_time = file_strm.read_uint32() self.creation_time -= UTC_MP4_INTERVAL self.offset += UInt32ByteLen if self.creation_time > 0: self.creation_time_fmt = Util.datetime_format( self.creation_time) self.modification_time = file_strm.read_uint32() self.modification_time -= UTC_MP4_INTERVAL self.offset += UInt32ByteLen if self.modification_time > 0: self.modification_time_fmt = Util.datetime_format( self.modification_time) self.timescale = file_strm.read_uint32() self.offset += UInt32ByteLen self.duration = file_strm.read_uint32() self.offset += UInt32ByteLen self.rate = file_strm.read_uint32() self.offset += UInt32ByteLen self.rate_fmt = "%d.%d" % (self.rate >> 16, self.rate & 0x0000FFFF) self.volume = file_strm.read_uint16() self.offset += UInt16ByteLen self.volume_fmt = "%d.%d" % (self.volume >> 8, self.volume & 0x00FF) self.reserved = file_strm.read_uint16() self.offset += UInt16ByteLen for idx in range(len(self.reserved1)): reserved1_ = file_strm.read_uint32() self.offset += UInt32ByteLen self.reserved1[idx] = reserved1_ for idx in range(len(self.matrix)): matrix_ = file_strm.read_uint32() self.offset += UInt32ByteLen self.matrix[idx] = matrix_ for idx in range(len(self.pre_defined)): pre_defined_ = file_strm.read_uint32() self.offset += UInt32ByteLen self.pre_defined[idx] = pre_defined_ self.next_track_ID = file_strm.read_uint32() self.offset += UInt32ByteLen tmp_size = self.offset - self.box_offset if tmp_size != self.Size(): file_strm.seek(self.Size() - tmp_size, os.SEEK_CUR) return file_strm