Skip to content

Commit

Permalink
Fix button parser
Browse files Browse the repository at this point in the history
  • Loading branch information
SAPikachu committed Oct 27, 2013
1 parent 92d7c8f commit 733df34
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 51 deletions.
78 changes: 27 additions & 51 deletions igstools/parser.py
Original file line number Diff line number Diff line change
@@ -1,53 +1,24 @@
# References:
# Muxer/Demuxer: http://patches.libav.org/patch/22445/
# Decoder: http://patches.libav.org/patch/22446/
import struct

import io
import logging
import functools

from .utils import (
unpack_from_stream as _unpack_from_stream,
eof_aware_read as _eof_aware_read,
log_dict,
)

PALETTE_SEGMENT = 0x14
PICTURE_SEGMENT = 0x15
BUTTON_SEGMENT = 0x18
BUTTON_SEGMENT = 0x18 # noqa
DISPLAY_SEGMENT = 0x80

log = logging.getLogger("parser")

def _eof_aware_read(stream, length, fail_on_no_data=False):
ret = stream.read(length)
if not ret:
if fail_on_no_data:
raise EOFError()

return None

if len(ret) < length:
raise EOFError()

return ret


def _unpack_from_stream(fmt, stream):
data = _eof_aware_read(stream, struct.calcsize(fmt))
if not data:
return None

return struct.unpack(fmt, data)


def _dump_dict(d):
def _dump_value(v):
if isinstance(v, dict):
return "{{{}}}".format(_dump_dict(v))
elif isinstance(v, (bytes, list)):
return "<Len: {}>".format(len(v))

return str(v)

return ", ".join(["=".join([str(k), _dump_value(v)]) for k, v in d.items()])


def _log_dict(d, prefix=""):
log.debug(prefix + _dump_dict(d))
_log_dict = functools.partial(log_dict, log)


def igs_raw_segments(stream):
Expand Down Expand Up @@ -132,25 +103,30 @@ def parse_picture_segment(stream):


def parse_button_segment(stream):
# [u16 width] [u16 height] [u8 framerate_id] [u16 unkwown] [u8 flags]
# [u32 in_time] [u32 to]
width, height, framerate_id, _, flags, in_time, to = \
_unpack_from_stream(">HHBHBII", stream)
# Reference: http://git.videolan.org/?p=libbluray.git;a=tree;f=src/libbluray/decoders # noqa
# [u16 width] [u16 height] [u8 framerate_id] [u16 composition_number]
# [u8 composition_state] [u8 seq_descriptor] [u24 data_len] [u8 model_flags] # noqa
(width, height, framerate_id, composition_number, composition_state,
seq_descriptor, _, _, _, model_flags) = \
_unpack_from_stream(">HHBHBBBBBB", stream)

if to == 0:
# Ten more byte skipped (output generated by TMpegEnc Authoring 5)
_eof_aware_read(stream, 10)

page_count = ord(stream.read(1))
ret = {
"width": width,
"height": height,
"framerate_id": framerate_id,
"flags": flags,
"in_time": in_time,
"to": to,
"composition_number": composition_number,
"composition_state": composition_state,
"seq_descriptor": seq_descriptor,
"model_flags": model_flags,
"pages": [],
}
if (model_flags & 0x80) == 0:
ret["composition_timeout_pts"] = _eof_aware_read(stream, 5, True)
ret["selection_timeout_pts"] = _eof_aware_read(stream, 5, True)

ret["user_timeout_duration"] = _eof_aware_read(stream, 3, True)

page_count = ord(stream.read(1))
_log_dict(ret, "Button segment, ")
for i in range(page_count):
# [u8 page_id] [u8 ?] [u64 uo]
Expand Down
43 changes: 43 additions & 0 deletions igstools/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import struct


def eof_aware_read(stream, length, fail_on_no_data=False):
if length == 0:
return b""

ret = stream.read(length)
if not ret:
if fail_on_no_data:
raise EOFError()

return None

if len(ret) < length:
raise EOFError()

return ret


def unpack_from_stream(fmt, stream):
data = eof_aware_read(stream, struct.calcsize(fmt))
if not data:
return None

return struct.unpack(fmt, data)


def dump_dict(d):
def _dump_value(v):
if isinstance(v, dict):
return "{{{}}}".format(dump_dict(v))
elif isinstance(v, (bytes, list)):
return "<Len: {}>".format(len(v))

return str(v)

return ", ".join(["=".join([str(k), _dump_value(v)])
for k, v in d.items()])


def log_dict(log, d, prefix=""):
log.debug(prefix + dump_dict(d))

0 comments on commit 733df34

Please sign in to comment.