Skip to content

Instantly share code, notes, and snippets.

@mjohnsullivan
Created August 17, 2012 10:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mjohnsullivan/3377918 to your computer and use it in GitHub Desktop.
Save mjohnsullivan/3377918 to your computer and use it in GitHub Desktop.
Determines the essence type of an mxf file for DCI digital cinema content: JPEG2000, MPEG or PCM
import sys
import struct
# MXF Keys
MXF_KEYS = {
'\x06\x0e\x2b\x34\x02\x53\x01\x01\x0d\x01\x01\x01\x01\x01\x51\x00' : 'MPEG2VIDEODESCRIPTOR',
'\x06\x0e\x2b\x34\x02\x53\x01\x01\x0d\x01\x01\x01\x01\x01\x5a\x00' : 'JPEG2000PICTURESUBDESCRIPTOR',
'\x06\x0e\x2b\x34\x02\x53\x01\x01\x0d\x01\x01\x01\x01\x01\x48\x00' : 'WAVEAUDIODESCRIPTOR',
'\x06\x0e\x2b\x34\x02\x53\x01\x01\x0d\x01\x01\x01\x01\x01\x37\x00' : 'SOURCEPACKAGE',
'\x06\x0e\x2b\x34\x01\x02\x01\x01\x0d\x01\x03\x01\x15\x01\x05\x00' : 'MPEG2ESSENCE',
'\x06\x0e\x2b\x34\x01\x02\x01\x01\x0d\x01\x03\x01\x15\x01\x08\x00' : 'JPEG2000ESSENCE',
'\x06\x0e\x2b\x34\x01\x02\x01\x01\x0d\x01\x03\x01\x16\x01\x01\x00' : 'WAVESSENCE'
}
def _as_hex_str(bytes):
"""
Pretty-prints bytes as hex values separated by dots
"""
return '.'.join(map(lambda x: '%02X' % ord(x), bytes))
def _decode_ber_length(reader):
"""
Dynamically works out a BER-encoded length value from a stream.read function.
Returns the decoded length and nr of bytes read
"""
length = struct.unpack('>B', reader(1))[0] # Get the first byte and decode it
bytes_read = 1
if length > 127:
bytes_read += length - 128
length = int(reader(length - 128).encode('hex'), 16) # Read the bytes and convert
return (length, bytes_read)
def klvs(stream):
"""
Generator that iterates through KLVs that are
dynamically read from a stream
"""
klv_key_length = 16
pos = 0
while True:
key = stream.read(klv_key_length)
if not key:
break
(length, len_bytes) = _decode_ber_length(stream.read)
value = stream.read(length)
pos += 4 + len_bytes + length
yield (MXF_KEYS.get(key, _as_hex_str(key)), value)
def print_klv_keys(mxf_filename):
"""
Prints out all klv keys found in an mxf file
"""
with open(mxf_filename, 'rb') as mxf_file:
for klv in klvs(mxf_file):
print klv[0]
def essence_type(mxf_filename):
"""
Returns 'JPEG2000', 'MPEG2' or 'PCM' depending on the
essence type contained within the mxf file
"""
with open(mxf_filename, 'rb') as mxf_file:
for klv in klvs(mxf_file):
if klv[0] == 'JPEG2000PICTURESUBDESCRIPTOR':
return 'JPEG2000'
elif klv[0] == 'MPEG2VIDEODESCRIPTOR':
return 'MPEG2'
elif klv[0] == 'WAVEAUDIODESCRIPTOR':
return 'PCM'
if __name__ == '__main__':
if len(sys.argv) != 2:
print 'USAGE: python mxf.py <mxf file name>'
else:
# print_klv_keys(sys.argv[1])
print essence_type(sys.argv[1])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment