Welcome, guest | Sign In | My Account | Store | Cart
import ctypes

def XVID_MAKE_VERSION(a,b,c): return ((((a)&0xff)<<16) | (((b)&0xff)<<8) | ((c)&0xff))
XVID_VERSION
=XVID_MAKE_VERSION(1,3,3)

XVID_GBL_INIT
=0
XVID_GBL_INFO
=1

XVID_DEC_CREATE
=0
XVID_DEC_DESTROY
=1
XVID_DEC_DECODE
=2

XVID_CSP_RGB
=(1<<16)

XVID_TYPE_VOL
=-1

BUFFER_SIZE
=2*1024*1024
BPP
=3
XDIM
=0
YDIM
=0

class xvid_dec_create_t(ctypes.Structure):
 _fields_
=[
 
('version', ctypes.c_int),
 
('width', ctypes.c_int),
 
('height', ctypes.c_int),
 
 
('handle', ctypes.c_void_p),
 
 
('fourcc', ctypes.c_int),
 
('num_threads', ctypes.c_int),
 
]

class xvid_gbl_init_t(ctypes.Structure):
 _fields_
=[
 
('version',ctypes.c_int),
 
('cpu_flags',ctypes.c_uint),
 
('debug',ctypes.c_int),
 
]

class xvid_gbl_info_t(ctypes.Structure):
 _fields_
=[
 
('version',ctypes.c_int),
 
('actual_version',ctypes.c_int),
 
('build',ctypes.c_char_p),
 
('cpu_flags',ctypes.c_uint),
 
('num_threads',ctypes.c_int),
 
]



class xvid_dec_stats_t__data__vol(ctypes.Structure):
 _fields_
=[
 
('general',ctypes.c_int),
 
('width',ctypes.c_int),
 
('height',ctypes.c_int),
 
('par',ctypes.c_int),
 
('par_width',ctypes.c_int),
 
('par_height',ctypes.c_int),
 
]

class xvid_dec_stats_t__data__vop(ctypes.Structure):
 _fields_
=[
 
('general',ctypes.c_int),
 
('time_base',ctypes.c_int),
 
('time_increment',ctypes.c_int),
 
('qscale',ctypes.POINTER(ctypes.c_int)),
 
('qscale_stride',ctypes.c_int),
 
]

class xvid_dec_stats_t__data(ctypes.Union):
 _fields_
=[
 
('vop',xvid_dec_stats_t__data__vop),
 
('vol',xvid_dec_stats_t__data__vol),
 
]

class xvid_dec_stats_t(ctypes.Structure):
 _fields_
=[
 
('version',ctypes.c_int),
 
('type',ctypes.c_int),
 
('data',xvid_dec_stats_t__data),
 
]



class xvid_image_t(ctypes.Structure):
 _fields_
=[
 
('csp',ctypes.c_int),
 
('plane',ctypes.c_void_p*4),
 
('stride',ctypes.c_int*4),
 
]

class xvid_dec_frame_t(ctypes.Structure):
 _fields_
=[
 
('version',ctypes.c_int),
 
('general',ctypes.c_int),
 
('bitstream',ctypes.c_void_p),
 
('length',ctypes.c_int),
 
('output',xvid_image_t),
 
('brightness',ctypes.c_int),
 
]



xvid_dec_create
=None

def xvid_init():
 
global xvid_dec_create

 xvid_gbl_info
=xvid_gbl_info_t()
 xvid_gbl_info
.version=XVID_VERSION
 ctypes
.cdll.xvidcore.xvid_global(None,XVID_GBL_INFO,ctypes.byref(xvid_gbl_info),None)
 xvid_gbl_info
.actual_version

 xvid_gbl_init
=xvid_gbl_init_t()
 xvid_gbl_init
.version=XVID_VERSION
 xvid_gbl_init
.cpu_flags=0
 ctypes
.cdll.xvidcore.xvid_global(None,XVID_GBL_INIT,ctypes.byref(xvid_gbl_init),None)

 xvid_dec_create
=xvid_dec_create_t()
 xvid_dec_create
.version=XVID_VERSION
 xvid_dec_create
.num_threads=xvid_gbl_info.num_threads
 
return ctypes.cdll.xvidcore.xvid_decore(None,XVID_DEC_CREATE,ctypes.byref(xvid_dec_create),None)

def xvid_quit():
 
global xvid_dec_create
 xvid_close
()
 result
=ctypes.cdll.xvidcore.xvid_decore(xvid_dec_create.handle,XVID_DEC_DESTROY,None,None)
 xvid_dec_create
=None
 
return result



_xvid_input_file
=None
_xvid_input_file_eof
=False
_xvid_mp4_buffer
=None
_xvid_mp4_buffer_position
=0
_xvid_mp4_ptr
=None
_xvid_out_buffer
=None

def xvid_open(fn):
 
global _xvid_input_file,_xvid_mp4_buffer,_xvid_mp4_ptr,_xvid_mp4_buffer_position,_xvid_input_file_eof,xvid_dec_create
 
if xvid_dec_create is None: xvid_init()
 xvid_close
()
 _xvid_input_file
=open(fn,'rb')
 _xvid_mp4_buffer
=ctypes.create_string_buffer(BUFFER_SIZE)
 _xvid_mp4_buffer
.value=_xvid_input_file.read(BUFFER_SIZE)
 _xvid_mp4_ptr
=ctypes.pointer(_xvid_mp4_buffer)
 _xvid_mp4_buffer_position
=0
 _xvid_input_file_eof
=False

def xvid_close():
 
global _xvid_input_file,_xvid_mp4_buffer_position
 
if _xvid_input_file is None: return
 _xvid_input_file
.close()
 _xvid_input_file
=None
 _xvid_mp4_buffer_position
=0

def xvid_decode_frame():
 
global xvid_dec_create,_xvid_mp4_buffer,_xvid_mp4_buffer_position,_xvid_out_buffer,_xvid_mp4_ptr,_xvid_input_file,XDIM,YDIM,_xvid_input_file_eof

 
if _xvid_mp4_buffer_position>BUFFER_SIZE-40: return False# shortest frames have around 38,39 bytes, at the end there could remain some (3 in my test vid) unusable bytes in buffer
 
if xvid_dec_create is None: return False
 
 
#input buffer check
 
if _xvid_mp4_buffer_position>BUFFER_SIZE/2 and not _xvid_input_file_eof:
  chunksize
=BUFFER_SIZE-_xvid_mp4_buffer_position
  chunk
=_xvid_input_file.read(chunksize)
 
if len(chunk)<chunksize: _xvid_input_file_eof=True
  _xvid_mp4_buffer
.value=(_xvid_mp4_buffer.raw+chunk)[-BUFFER_SIZE:]
  _xvid_mp4_buffer_position
=chunksize-len(chunk)
  _xvid_mp4_ptr
=ctypes.pointer(_xvid_mp4_buffer)
 
 
 xvid_dec_stats
=xvid_dec_stats_t()
 xvid_dec_stats
.version=XVID_VERSION

 xvid_dec_frame
=xvid_dec_frame_t()
 xvid_dec_frame
.version=XVID_VERSION
 xvid_dec_frame
.general=0
 xvid_dec_frame
.bitstream=ctypes.cast(_xvid_mp4_ptr,ctypes.c_void_p)
 xvid_dec_frame
.length=len(_xvid_mp4_buffer)-_xvid_mp4_buffer_position
 xvid_dec_frame
.output.plane[0]=ctypes.cast(_xvid_out_buffer,ctypes.c_void_p)
 xvid_dec_frame
.output.stride[0]=XDIM*BPP
 xvid_dec_frame
.output.csp=XVID_CSP_RGB
 
 used
=ctypes.cdll.xvidcore.xvid_decore(xvid_dec_create.handle,XVID_DEC_DECODE,ctypes.byref(xvid_dec_frame),ctypes.byref(xvid_dec_stats))
 _xvid_mp4_buffer_position
+=used
 
if used==0: print _xvid_mp4_buffer_position,BUFFER_SIZE,BUFFER_SIZE-_xvid_mp4_buffer_position
 _xvid_mp4_ptr
=ctypes.cast(ctypes.cast(_xvid_mp4_buffer,ctypes.c_void_p).value+_xvid_mp4_buffer_position,ctypes.c_char_p)

 
if xvid_dec_stats.type==XVID_TYPE_VOL:
 
if XDIM*YDIM<xvid_dec_stats.data.vol.width*xvid_dec_stats.data.vol.height:
   XDIM
=xvid_dec_stats.data.vol.width
   YDIM
=xvid_dec_stats.data.vol.height
   _xvid_out_buffer
=ctypes.create_string_buffer(XDIM*YDIM*4)
 
return xvid_decode_frame()
 
 
return _xvid_out_buffer.raw

History