%PDF- %PDF-
Direktori : /home/waritko/build/Bento4/Source/Python/bento4/ |
Current File : //home/waritko/build/Bento4/Source/Python/bento4/streams.py |
from ctypes import c_int, c_double, c_char_p, byref, \ CFUNCTYPE, POINTER, string_at from bento4 import * from bento4.errors import check_result, SUCCESS, ERROR_READ_FAILED, FAILURE, \ ERROR_WRITE_FAILED, ERROR_EOS, ERROR_OUT_OF_RANGE, \ ERROR_NOT_SUPPORTED class ByteStream(object): """abstract ByteStream class""" def __init__(self, bt4stream): self.bt4stream = bt4stream super(ByteStream, self).__init__() def __del__(self): lb4.AP4_ByteStream_Release(self.bt4stream) @property def size(self): v = Ap4LargeSize() f = lb4.AP4_ByteStream_GetSize f.restype = check_result f(self.bt4stream, byref(v)) return v.value def read_partial(self, bytes_to_read): bytes_read = Ap4Size() p = create_string_buffer(bytes_to_read) f = lb4.AP4_ByteStream_ReadPartial f.restype = check_result f(self.bt4stream, p, Ap4Size(bytes_to_read), byref(bytes_read)) return (p.raw, bytes_read.value) def read(self, bytes_to_read): p = create_string_buffer(bytes_to_read) f = lb4.AP4_ByteStream_Read f.restype = check_result f(self.bt4stream, p, Ap4Size(bytes_to_read)) return p.raw def read_double(self): v = c_double() f = lb4.AP4_ByteStream_ReadDouble f.restype = check_result f(self.bt4stream, byref(v)) return v.value def read_ui64(self): v = Ap4UI64() f = lb4.AP4_ByteStream_ReadUI64 f.restype = check_result f(self.bt4stream, byref(v)) return v.value def read_ui32(self): v = Ap4UI32() f = lb4.AP4_ByteStream_ReadUI32 f.restype = check_result f(self.bt4stream, byref(v)) return v.value def read_ui24(self): v = Ap4UI32() f = lb4.AP4_ByteStream_ReadUI24 f.restype = check_result f(self.bt4stream, byref(v)) return v.value def read_ui16(self): v = Ap4UI16() f = lb4.AP4_ByteStream_ReadUI16 f.restype = check_result f(self.bt4stream, byref(v)) return v.value def read_ui08(self): v = Ap4UI08() f = lb4.AP4_ByteStream_ReadUI08 f.restype = check_result f(self.straem, byref(v)) return v.value def read_string(self, length): p = create_string_buffer(length+1) f = lb4.AP4_ByteStream_ReadString f.restype = check_result f(self.bt4stream, p, Ap4Size(length+1)) return p.value def write_partial(self, buffer): bytes_written = Ap4Size() f = lb4.AP4_ByteStream_WritePartial f.restype = check_result f(self.bt4stream, c_char_p(buffer), Ap4Size(len(buffer)),byref(bytes_written)) return bytes_written def write(self, buffer): f = lb4.AP4_ByteStream_Write f.restype = check_result f(self.bt4stream, c_char_p(buffer), Ap4Size(len(buffer))) def write_double(self, value): f = lb4.AP4_ByteStream_WriteDouble f.restype = check_result f(self.bt4stream, c_double(value)) def write_ui64(self, value): f = lb4.AP4_ByteStream_WriteUI64 f.restype = check_result f(self.bt4stream, Ap4UI64(value)) def write_ui32(self, value): f = lb4.AP4_ByteStream_WriteUI32 f.restype = check_result f(self.bt4stream, Ap4UI32(value)) def write_ui24(self, value): f = lb4.AP4_ByteStream_WriteUI24 f.restype = check_result f(self.bt4stream, Ap4UI32(value)) def write_ui16(self, value): f = lb4.AP4_ByteStream_WriteUI16 f.restype = check_result f(self.bt4stream, Ap4UI16(value)) def write_ui08(self, value): f = lb4.AP4_ByteStream_WriteUI08 f.restype = check_result f(self.bt4stream, Ap4UI08(value)) def write_string(self, value): f = lb4.AP4_ByteStream_Write f.restype = check_result f(self.bt4stream, c_char_p(buffer)) def copy_to(self, receiver, size): f = lb4.AP4_ByteStream_CopyTo f.restype = check_result f(self.bt4stream, receiver.stream, AP4_Size(size)) def seek(self, position): f = lb4.AP4_ByteStream_Seek f.restype = check_result f(self.bt4stream, Ap4Position(position)) def flush(self): f = lb4.AP4_ByteStream_Flush f.restype = check_result f(self.bt4stream) def tell(self): pos = Ap4Position() f = lb4.AP4_ByteStream_Tell f.restype = check_result f(self.bt4stream, byref(pos)) return pos.value class MemoryByteStream(ByteStream): @staticmethod def from_buffer(buffer): """Factory method""" buffer_size = Ap4Size(len(buffer)) bt4stream = lb4.AP4_MemoryByteStream_FromBuffer(c_char_p(buffer), buffer_size) return MemoryByteStream(bt4stream=bt4stream) def __init__(self, size=0, bt4stream=None): if bt4stream is None: bt4stream = lb4.AP4_MemoryByteStream_Create(Ap4Size(size)) super(MemoryByteStream, self).__init__(bt4stream) class FileByteStream(ByteStream): MODE_READ = 0 MODE_WRITE = 1 MODE_READ_WRITE = 2 def __init__(self, name, mode): result = Ap4Result(0) f = lb4.AP4_FileByteStream_Create bt4stream = f(c_char_p(name), c_int(mode), byref(result)) check_result(result) super(FileByteStream, self).__init__(bt4stream) class ByteStreamDelegate(Structure): pass read_partial_proto = CFUNCTYPE(Ap4Result, POINTER(ByteStreamDelegate), POINTER(Ap4Byte), Ap4Size, POINTER(Ap4Size)) write_partial_proto = CFUNCTYPE(Ap4Result, POINTER(ByteStreamDelegate), c_void_p, Ap4Size, POINTER(Ap4Size)) seek_proto = CFUNCTYPE(Ap4Result, POINTER(ByteStreamDelegate), Ap4Position) tell_proto = CFUNCTYPE(Ap4Result, POINTER(ByteStreamDelegate), POINTER(Ap4Position)) get_size_proto = CFUNCTYPE(Ap4Result, POINTER(ByteStreamDelegate), POINTER(Ap4LargeSize)) flush_proto = CFUNCTYPE(Ap4Result, POINTER(ByteStreamDelegate)) ByteStreamDelegate._fields_ = [("read_partial", read_partial_proto), ("write_partial", write_partial_proto), ("seek", seek_proto), ("tell", tell_proto), ("get_size", get_size_proto), ("flush", flush_proto), ("destroy", c_void_p), # must be set to None ("oid", c_int)] # object id # dict where we are going to store the pybytestream instances by id PYSTREAM_OBJECTS = {} def delegate_read_partial(pdelegate, buffer, bytes_to_read, bytes_read): pystream = PYSTREAM_OBJECTS[pdelegate[0].oid] return pystream.c_read_partial(buffer, bytes_to_read, bytes_read) def delegate_read_partial(pdelegate, buffer, bytes_to_write, bytes_written): pystream = PYSTREAM_OBJECTS[pdelegate[0].oid] return pystream.c_write_partial(buffer, bytes_to_write, bytes_written) def delegate_seek(pdelegate, position): pystream = PYSTREAM_OBJECTS[pdelegate[0].oid] return pystream.c_seek(position) def delegate_tell(pdelegate, position): pystream = PYSTREAM_OBJECTS[pdelegate[0].oid] return pystream.c_tell(position) def delegate_get_size(pdelegate, size): pystream = PYSTREAM_OBJECTS[pdelegate[0].oid] return pystream.c_get_size(size) def delegate_flush(pdelegate, size): pystream = PYSTREAM_OBJECTS[pdelegate[0].oid] return pystream.c_flush() class PyByteStream(ByteStream): def __init__(self, pystream): self.delegate = ByteStreamDelegate( read_partial=read_partial_proto(delegate_read_partial), write_partial=write_partial_proto(delegate_write_partial), seek=seek_proto(delegate_seek), tell=tell_proto(delegate_tell), get_size=get_size_proto(delegate_get_size), flush=flush_proto(delegate_flush), destroy=None, oid=id(stream)) PYSTREAM_OBJECTS[id(pystream)] = pystream # store the stream bt4stream = lb4.AP4_ByteStream_FromDelegate(byref(self.delegate)) super(PyByteStream, self).__init__(bt4stream) def c_read_partial(self, buffer, bytes_to_read, bytes_read): return ERROR_NOT_SUPPORTED def c_write_partial(self, buffer, bytes_to_write, bytes_written): return ERROR_NOT_SUPPORTED def c_seek(self, position): return ERROR_NOT_SUPPORTED def c_tell(self, position): return ERROR_NOT_SUPPORTED def c_get_size(self, size): return ERROR_NOT_SUPPORTED def c_flush(self): return ERROR_NOT_SUPPORTED class PyFileByteStream(PyByteStream): def __init__(self, file, size=0): self.file = file self.size = size super(PyFileByteStream, self).__init__(self) def c_read_partial(self, buffer, bytes_to_read, bytes_read): try: s = self.file.read(bytes_to_read) bytes_read[0] = len(s) buffer[:bytes_to_read] = s[:bytes_to_read] # copy the buffer except EOFError: return ERROR_EOS except IOError: return READ_FAILED return SUCCESS def c_write_partial(self, buffer, bytes_to_write, bytes_written): try: self.file.write(string_at(buffer, bytes_to_write)) bytes_written[0] = bytes_to_write except IOError: return WRITE_FAILED return SUCCESS def c_seek(self, position): try: self.file.seek(position) except Exception: return ERROR_OUT_OF_RANGE return SUCCESS def c_tell(self, position): try: position[0] = self.file.tell() except Exception: return FAILURE return SUCCESS def c_get_size(self, size): if self.size: size[0] = self.size return SUCCESS else: return ERROR_NOT_SUPPORTED def c_flush(self): try: self.file.flush() except Exception: return FAILURE return SUCCESS