This is simple library for playing avi video clips. Videos must be SOUNDLESS (and maybe Xvid encoded wont hurt), to work it properly. I am using it to play intro. It suites good to this purpose, since it can play one clip at a time only.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 | 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
|
Notes
You need Xvid installed .. or xvidcore.dll in application folder.
Xvid is released under GPL, and this code links to it, so it inherits GPL too.
XVID_VERSION is hardcoded to 1.3.3, this should work with any 1.x.x dll
Tkinter example:
from Tkinter import Tk,Canvas
import Image,ImageTk# PIL needed
import xvid# this here is our library
frame=None# to save object reference
def upd():
global tk,can,img, frame
data=xvid.xvid_decode_frame()
if data is False:
tk.destroy()
return
image=Image.fromstring('RGB',(xvid.XDIM,xvid.YDIM),data,'raw','RGB',xvid.XDIM*xvid.BPP,1)# decode frame data by this way
frame=ImageTk.PhotoImage(image)
can.itemconfigure(img,image=frame)
tk.after(1,upd)
xvid.xvid_open('./mini3HGJ-KingOfTheHill/src/intro.avi')# set to location of your SOUNDLESS Xvid avi
xvid.xvid_decode_frame()# to get XDIM and YDIM set
W=xvid.XDIM
H=xvid.YDIM
tk=Tk()
x=(tk.winfo_screenwidth()/2)-(W/2)
y=(tk.winfo_screenheight()/2)-(H/2)
tk.geometry('%dx%d+%d+%d'%(W,H,x,y))
can=Canvas(tk,background='black',width=W,height=H)
img=can.create_image(0,0,anchor='nw')
can.grid(sticky='SWEN')
tk.after(100,upd)
tk.mainloop()
xvid.xvid_quit()
pygame example:
import pygame as pg
import xvid# this here is our library
import Image# PIL meeded
xvid.xvid_open('./mini3HGJ-KingOfTheHill/src/intro.avi')# set to location of your SOUNDLESS Xvid avi
xvid.xvid_decode_frame()# to get XDIM and YDIM set
W=xvid.XDIM
H=xvid.YDIM
pg.init()
sc=pg.display.set_mode((W,H))
run=True
while run:
for e in pg.event.get():
if e.type==pg.QUIT: run=False
data=xvid.xvid_decode_frame()
image=Image.fromstring('RGB',(xvid.XDIM,xvid.YDIM),data,'raw','RGB',xvid.XDIM*xvid.BPP,1)# data ti PIL image
frame=pg.image.fromstring(image.tostring(),(xvid.XDIM,xvid.YDIM),'RGB')# PIL image to pygame surface
sc.blit(frame,(0,0))
pg.display.update()
pg.quit()
xvid.xvid_quit()