Obtain an image of Webcamera from QEMU and add the Bitmap change display function.
import qemu
import os
from ctypes import cdll
import ctypes
import datetime
class syborg_usbtest(qemu.devclass):
REG_ID = 0
REG_INT_ENABLE = 1
REG_DATA_TYPE = 2
REG_DMA_ADDR = 3
REG_DMA_SIZE = 4
REG_DMA_INFO = 5
REG_DMA_INFOSIZE = 6
REG_DMA_CONNECT = 7
REG_DMA_DISCONNECT = 8
def loaddll(self):
#Load DLL
print "start dll load"
self.path = r'.\webcamapi.dll'
self.webcamdll = cdll.LoadLibrary(self.path)
print "end dll load"
def connect(self):
#Connect to USB Camera
print "Connect to USB Camera"
if self.infobuffer == 0:
self.infobuffer = ctypes.create_string_buffer(self.infosize)
self.DevHandle = self.webcamdll.ConnectDevHandle()
self.bufSize = ctypes.c_int()
self.PinHandle = self.webcamdll.ConnectPinHandle(self.DevHandle, ctypes.byref(self.bufSize), ctypes.byref(self.infobuffer))
infobuf = self.infobuffer
for x in infobuf:
ch = ord(x)
if self.infosize > 0:
self.dma_writeb(self.dataformat, ch)
self.dataformat += 1
self.infosize -= 1
def readframe(self):
#Read frame data
if self.buffer == 0:
self.buffer = ctypes.create_string_buffer(self.bufSize.value)
self.timelog("Read frame data Start")
self.Ret = self.webcamdll.ReadFrameData(self.PinHandle, ctypes.byref(self.buffer), self.bufSize.value)
self.timelog("Read frame data End")
#Write frame data. This is for debug.
#self.Ret = self.webcamdll.WriteFrameData("_frameData.bin", ctypes.byref(self.buffer), self.bufSize.value);
buf = self.buffer
length = len(buf)
count = 0
for x in range(1, length, 2):
if self.dma_size > 0:
self.buf = ord(buf[count+1]) << 8 | ord(buf[count+0])
self.dma_writel(self.dma_addr, self.buf)
self.dma_addr += 2
self.dma_size -= 2
count += 2
self.set_irq_level(0, self.int_enable)
def timelog(self,buf):
date = datetime.datetime.today().isoformat()
print "%(view)s %(time)s" % {"view":buf,"time":date}
def create(self):
self.int_enable = 1
self.dma_addr = 0
self.dma_size = 0
self.cha = 0
self.dataformat = 0
self.infosize = 0
self.buffer = 0
self.infobuffer = 0
def write_reg(self, offset, value):
#This func is called when PDD performed WriteReg func.
offset >>= 2
if offset==self.REG_INT_ENABLE:
self.int_enable=value
if value==1:
if self.data_type==0:
self.readframe()
else:
if self.data_type==0:
self.set_irq_level(0, self.int_enable)
#self.timer_off()
elif self.data_type==1:
self.set_irq_level(0, self.int_enable)
elif offset == self.REG_DATA_TYPE:
self.data_type = value
elif offset == self.REG_DMA_ADDR:
self.dma_addr = value
elif offset == self.REG_DMA_SIZE:
self.dma_size = value
elif offset == self.REG_DMA_INFO:
self.dataformat = value
elif offset == self.REG_DMA_INFOSIZE:
self.infosize = value
elif offset == self.REG_DMA_CONNECT:
self.loaddll()
self.connect()
elif offset == self.REG_DMA_DISCONNECT:
self.Ret = self.webcamdll.DisconnectPinHandle(self.PinHandle)
self.set_irq_level(0, self.int_enable)
def read_reg(self, offset):
#This func is called when PDD performed ReadReg func.
offset >>= 2
if offset == self.REG_ID:
return 0xc600f000
elif offset == self.REG_INT_ENABLE:
return self.int_enable
elif offset == self.REG_DMA_ADDR:
return self.dma_addr
elif offset == self.REG_DMA_SIZE:
return self.dma_size
elif offset == self.REG_DMA_FORMAT:
return self.dataformat
return 0
def save(self, f):
f.put_u32(self.int_enable)
f.put_u32(self.dma_addr)
f.put_u32(self.dma_size)
f.put_u32(self.dataformat)
f.put_u32(self.infosize)
f.put_u32(self.buffer)
f.put_u32(self.infobuffer)
def load(self, f):
self.int_enable = f.get_u32()
self.dma_addr = f.get_u32()
self.dma_size = f.get_u32()
self.dataformat = f.get_u32()
self.infosize = f.get_u32()
self.buffer = f.get_u32()
self.infobuffer = f.get_u32()
# Device class properties
regions = [qemu.ioregion(0x1000, readl=read_reg, writel=write_reg)]
irqs = 1
name = "syborg,usbtest"
properties={"chardev":None}
qemu.register_device(syborg_usbtest)