import datetime
import struct
__all__ = (
'read_element_id',
'read_element_size',
'read_unsigned_integer',
'read_signed_integer',
'read_float',
'read_string',
'read_unicode_string',
'read_date',
'encode_element_id',
'encode_element_size',
'encode_unsigned_integer',
'encode_signed_integer',
'encode_float',
'encode_string',
'encode_unicode_string',
'encode_date',
)
MAXIMUM_ELEMENT_ID_LENGTH = 4
MAXIMUM_ELEMENT_SIZE_LENGTH = 8
MAXIMUM_UNSIGNED_INTEGER_LENGTH = 8
MAXIMUM_SIGNED_INTEGER_LENGTH = 8
def maximum_element_size_for_length(length):
"""
Returns the maximum element size representable in a given number of bytes.
:arg length: the limit on the length of the encoded representation in bytes
:type length: int
:returns: the maximum element size representable
:rtype: int
"""
return (2**(7*length)) - 2
def decode_vint_length(byte, mask=True):
length = None
value_mask = None
for n in xrange(1, 9):
if byte & (2**8 - (2**(8 - n))) == 2**(8 - n):
length = n
value_mask = (2**(8 - n)) - 1
break
if length is None:
raise IOError('Cannot decode invalid varible-length integer.')
if mask:
byte = byte & value_mask
return length, byte
def read_element_id(stream):
"""
Reads an element ID from a file-like object.
:arg stream: the file-like object
:returns: the decoded element ID and its length in bytes
:rtype: tuple
"""
byte = ord(stream.read(1))
length, id_ = decode_vint_length(byte, False)
if length > 4:
raise IOError('Cannot decode element ID with length > 8.')
for i in xrange(0, length - 1):
byte = ord(stream.read(1))
id_ = (id_ * 2**8) + byte
return id_, length
def read_element_size(stream):
"""
Reads an element size from a file-like object.
:arg stream: the file-like object
:returns: the decoded size (or None if unknown) and the length of the descriptor in bytes
:rtype: tuple
"""
byte = ord(stream.read(1))
length, size = decode_vint_length(byte)
for i in xrange(0, length - 1):
byte = ord(stream.read(1))
size = (size * 2**8) + byte
if size == maximum_element_size_for_length(length) + 1:
size = None
return size, length
def read_unsigned_integer(stream, size):
"""
Reads an encoded unsigned integer value from a file-like object.
:arg stream: the file-like object
:arg size: the number of bytes to read and decode
:type size: int
:returns: the decoded unsigned integer value
:rtype: int
"""
value = 0
for i in xrange(0, size):
byte = ord(stream.read(1))
value = (value << 8) | byte
return value
def read_signed_integer(stream, size):
"""
Reads an encoded signed integer value from a file-like object.
:arg stream: the file-like object
:arg size: the number of bytes to read and decode
:type size: int
:returns: the decoded signed integer value
:rtype: int
"""
value = 0
if size > 0:
first_byte = ord(stream.read(1))
value = first_byte
for i in xrange(1, size):
byte = ord(stream.read(1))
value = (value << 8) | byte
if (first_byte & 0b10000000) == 0b10000000:
value = -(2**(size*8) - value)
return value
def read_float(stream, size):
"""
Reads an encoded floating point value from a file-like object.
:arg stream: the file-like object
:arg size: the number of bytes to read and decode (must be 0, 4, or 8)
:type size: int
:returns: the decoded floating point value
:rtype: float
"""
if size not in (0, 4, 8):
raise IOError('Cannot read floating point values with lengths other than 0, 4, or 8 bytes.')
value = 0.0
if size in (4, 8):
data = stream.read(size)
value = struct.unpack({
4: '>f',
8: '>d'
}[size], data)[0]
return value
def read_string(stream, size):
"""
Reads an encoded ASCII string value from a file-like object.
:arg stream: the file-like object
:arg size: the number of bytes to read and decode
:type size: int
:returns: the decoded ASCII string value
:rtype: str
"""
value = ''
if size > 0:
value = stream.read(size)
value = value.partition(chr(0))[0]
return value
def read_unicode_string(stream, size):
"""
Reads an encoded unicode string value from a file-like object.
:arg stream: the file-like object
:arg size: the number of bytes to read and decode
:type size: int
:returns: the decoded unicode string value
:rtype: unicode
"""
value = u''
if size > 0:
data = stream.read(size)
data = data.partition(chr(0))[0]
value = unicode(data, 'utf_8')
return value
def read_date(stream, size):
"""
Reads an encoded date (and time) value from a file-like object.
:arg stream: the file-like object
:arg size: the number of bytes to read and decode (must be 8)
:type size: int
:returns: the decoded date (and time) value
:rtype: datetime
"""
if size != 8:
raise IOError('Cannot read date values with lengths other than 8 bytes.')
data = stream.read(size)
nanoseconds = struct.unpack('>q', data)[0]
delta = datetime.timedelta(microseconds=(nanoseconds // 1000))
return datetime.datetime(2001, 1, 1, tzinfo=None) + delta
def octet(n):
"""
Limits an integer or byte to 8 bits.
"""
return n & 0b11111111
def vint_mask_for_length(length):
"""
Returns the bitmask for the first byte of a variable-length integer (used for element ID and size descriptors).
:arg length: the length of the variable-length integer
:type length: int
:returns: the bitmask for the first byte of the variable-length integer
:rtype: int
"""
return 0b10000000 >> (length - 1)
def encode_element_id(element_id):
"""
Encodes an element ID.
:arg element_id: an element ID
:type element_id: int
:returns: the encoded representation bytes
:rtype: bytearray
"""
length = MAXIMUM_ELEMENT_ID_LENGTH
while length and not (element_id & (vint_mask_for_length(length) << ((length - 1) * 8))):
length -= 1
if not length:
raise ValueError('Cannot encode invalid element ID %s.' % hex(element_id))
data = bytearray(length)
for index in reversed(xrange(length)):
data[index] = octet(element_id)
element_id >>= 8
return data
def encode_element_size(element_size, length=None):
"""
Encodes an element size. If element_size is None, the size will be encoded as unknown. If length is not None, the size will be encoded in that many bytes; otherwise, the size will be encoded in the minimum number of bytes required, or in 8 bytes if the size is unknown (element_size is None).
:arg element_size: the element size, or None if unknown
:type element_size: int or None
:arg length: the length of the encoded representation, or None for the minimum length required (defaults to None)
:type length: int or None
:returns: the encoded representation bytes
:rtype: bytearray
"""
if length is not None and (length < 1 or length > MAXIMUM_ELEMENT_SIZE_LENGTH):
raise ValueError('Cannot encode element sizes into representations shorter than one byte long or longer than %i bytes long.' % MAXIMUM_ELEMENT_SIZE_LENGTH)
if element_size is not None:
if element_size > maximum_element_size_for_length(MAXIMUM_ELEMENT_SIZE_LENGTH if length is None else length):
raise ValueError('Cannot encode element size %i as it would have an encoded representation longer than %i bytes.' % (element_size, (MAXIMUM_ELEMENT_SIZE_LENGTH if length is None else length)))
req_length = 1
while (element_size >> ((req_length - 1) * 8)) >= (vint_mask_for_length(req_length) - 1) and req_length < MAXIMUM_ELEMENT_SIZE_LENGTH:
req_length += 1
if length is None:
length = req_length
else:
if length is None:
length = 8 # other libraries do this, so unless another length is specified for the unknown size descriptor, do as they do to avoid compatibility issues.
element_size = maximum_element_size_for_length(length) + 1
data = bytearray(length)
for index in reversed(xrange(length)):
data[index] = octet(element_size)
element_size >>= 8
if not index:
data[index] = data[index] | vint_mask_for_length(length)
return data
def encode_unsig
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
DASH-JS-master.zip (52个子文件)
DASH-JS-master
bigbuckbunny_mp.mpd 18KB
dashtest.html 2KB
.DS_Store 6KB
origmpds
ibmff
bunny_ibmff_720.mpd 93KB
bunny_ibmff_1080.mpd 107KB
bunny_ibmff_360.mpd 160KB
bunny_ibmff_240.mpd 69KB
dashtest-bunny1080p.html 2KB
webm
bunny.mpd 22KB
bigbuckbunny_1080p.mpd 89KB
sintel_multi_rep.mpd 13KB
bigbuckbunny.mpd 155KB
sintel_test_rep.mpd 2KB
dashtest-ibmff.html 2KB
dashtest-bunny.html 2KB
dash-js
dash.js 2KB
mediaSourceAPIAdaptation.js 2KB
adaptationlogic.js 5KB
timeBuffer.js 3KB
basebuffer.js 5KB
dashPlayerVars.js 208B
.DS_Store 6KB
mpdParser.js 14KB
rate_measurement.js 2KB
eventHandlers.js 2KB
buffer.js 1KB
mediaSourceBuffer.js 5KB
DASHttp.js 5KB
bandwidth.js 2KB
fplot.js 8KB
create_mpd_segment_info.py 3KB
ebml
core.py 14KB
__init__.pyc 203B
schema
ebml.py 2KB
__init__.pyc 303B
ebml.pyc 6KB
__init__.py 89B
matroska.py 260B
specs.py 3KB
specs.pyc 4KB
base.pyc 9KB
matroska.xml 48KB
matroska.pyc 512B
base.py 6KB
tests
__init__.py 0B
test_core.py 5KB
__init__.py 41B
test.webm 1.79MB
create_playlist.py 2KB
core.pyc 16KB
utils
dump_structure.py 2KB
__init__.py 0B
共 52 条
- 1
资源评论
程序小学生
- 粉丝: 143
- 资源: 8
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功