Devdualcpu
Additional notes may be shown below. Please discuss this message on the article's Talk Page.
Contents |
Introduction
The /dev/dualcpu character device is the official way of interacting with the 940t. It only provides video decoding functions. It is not a general purpose interface. At present it seems only MPEG4 decoding functions are provided, with provision for H263, MJPEG and MPEG2 decoding, as well as MPEG4 encoding.
Communication is achieved through a serials of ioctl calls to the device. Reading from the device gives it's status as a single byte.
Documentation
The only current documentation is in the form of the source release from November, 2005.
The relevent files are:
drivers/char/dualcpu.h drivers/char/dualcpu.c drivers/char/vpp.h drivers/char/vpp.c
You can view them in the cvs repository by going to http://cvs.sourceforge.net/viewcvs.py/open2x/linux-mmsp2/drivers/char/#dirlist
Call Sequence
This information is derived from the strace below.
open /dev/dualcpu as dualcpu ioctl dualcpu IOCTL_DUALCPU_MP4D_INIT ioctl dualcpu IOCTL_DUALCPU_MP4D_INIT_BUF times 6
while playing video: ioctl dualcpu IOCTL_DUALCPU_MP4D_RUN read status if status == 21: draw frame end if end while
strace
The following seems to be the call sequence that mplayer in firmware 1.1 makes to /dev/dualcpu
fd 13 is /dev/dualcpu fd 14 is /dev/vpp - video post processor
Intialization
open("/dev/dualcpu", O_RDWR) = 13 open("/dev/vpp", O_RDWR) = 14 ioctl(14, 0x7630, 0) = 0 --- this one appears to be undocumented ioctl(13, IOCTL_DUALCPU_MP4D_INIT, 0x157bf4) = 1 read(13, "\5", 32) = 1 ioctl(13, IOCTL_DUALCPU_MP4D_INIT_BUF, 0x157c14) = 1 read(13, "\5", 32) = 1 ioctl(13, IOCTL_DUALCPU_MP4D_INIT_BUF, 0x157c14) = 1 read(13, "\5", 32) = 1 ioctl(13, IOCTL_DUALCPU_MP4D_INIT_BUF, 0x157c14) = 1 read(13, "\5", 32) = 1 ioctl(13, IOCTL_DUALCPU_MP4D_INIT_BUF, 0x157c14) = 1 read(13, "\5", 32) = 1 ioctl(13, IOCTL_DUALCPU_MP4D_INIT_BUF, 0x157c14) = 1 read(13, "\5", 32) = 1 ioctl(13, IOCTL_DUALCPU_MP4D_INIT_BUF, 0x157c14) = 1 read(13, "\5", 32) = 1 --- how does it know when to stop buffering ? ioctl(14, OCTL_MMSP2_SET_FDC, 0x157c58) = 0 ioctl(14, IOCTL_MMSP2_SET_SC, 0x157ca0) = 0 ioctl(14, IOCTL_MMSP2_SET_YUVA, 0x157c74) = 0 ioctl(14, IOCTL_MMSP2_YUVA_OFF, 0) = 0 ioctl(14, IOCTL_MMSP2_YUVB_OFF, 0) = 0
Video Decoding
ioctl(13, IOCTL_DUALCPU_MP4D_RUN, 0x157c20) = 1 read(13, "\2", 32) = 1 ioctl(13, IOCTL_DUALCPU_MP4D_RUN, 0x157c20) = 1 read(13, "\2", 32) = 1 ioctl(13, IOCTL_DUALCPU_MP4D_RUN, 0x157c20) = 1 read(13, "\2", 32) = 1 ioctl(13, IOCTL_DUALCPU_MP4D_RUN, 0x157c20) = 1 read(13, "\21", 32) = 1 ioctl(13, IOCTL_DUALCPU_MP4D_RUN, 0x157c20) = 1 read(13, "\2", 32) = 1 ioctl(13, IOCTL_DUALCPU_MP4D_RUN, 0x157c20) = 1 read(13, "\2", 32) = 1 ioctl(13, IOCTL_DUALCPU_MP4D_RUN, 0x157c20) = 1 read(13, "\2", 32) = 1 ioctl(13, IOCTL_DUALCPU_MP4D_RUN, 0x157c20) = 1 read(13, "\21", 32) = 1 ioctl(14, IOCTL_MMSP2_START_FDC, 0x15b308) = 0 ioctl(14, IOCTL_MMSP2_START_SC, 0x2) = 0 ioctl(14, IOCTL_MMSP2_SC_BUSY, 0) = 0 ioctl(13, IOCTL_DUALCPU_MP4D_RUN, 0x157c20) = 1 read(13, "\2", 32) = 1 ioctl(13, IOCTL_DUALCPU_MP4D_RUN, 0x157c20) = 1 read(13, "\2", 32) = 1 ioctl(13, IOCTL_DUALCPU_MP4D_RUN, 0x157c20) = 1 read(13, "\2", 32) = 1 ioctl(13, IOCTL_DUALCPU_MP4D_RUN, 0x157c20) = 1 read(13, "\2", 32) = 1 ioctl(13, IOCTL_DUALCPU_MP4D_RUN, 0x157c20) = 1 read(13, "\2", 32) = 1 ioctl(13, IOCTL_DUALCPU_MP4D_RUN, 0x157c20) = 1 read(13, "\21", 32) = 1 ioctl(14, IOCTL_MMSP2_START_FDC, 0x15b308) = 0 ioctl(14, IOCTL_MMSP2_START_SC, 0x2) = 0 ioctl(14, IOCTL_MMSP2_SC_BUSY, 0) = 0 ioctl(13, IOCTL_DUALCPU_MP4D_RUN, 0x157c20) = 1 read(13, "\2", 32) = 1 ioctl(13, IOCTL_DUALCPU_MP4D_RUN, 0x157c20) = 1 read(13, "\2", 32) = 1 ioctl(13, IOCTL_DUALCPU_MP4D_RUN, 0x157c20) = 1 read(13, "\21", 32) = 1 ioctl(14, IOCTL_MMSP2_START_FDC, 0x15b308) = 0 ioctl(14, IOCTL_MMSP2_START_SC, 0x2) = 0 ioctl(14, IOCTL_MMSP2_SC_BUSY, 0) = 0 ioctl(14, VIDIOCSYNC, 0) = 0 ioctl(13, IOCTL_DUALCPU_MP4D_RUN, 0x157c20) = 1 read(13, "\2", 32) = 1 ioctl(13, IOCTL_DUALCPU_MP4D_RUN, 0x157c20) = 1 read(13, "\2", 32) = 1 ioctl(13, IOCTL_DUALCPU_MP4D_RUN, 0x157c20) = 1 read(13, "\21", 32) = 1 ioctl(14, IOCTL_MMSP2_START_FDC, 0x15b308) = 0 ioctl(14, IOCTL_MMSP2_START_SC, 0x2) = 0 ioctl(14, IOCTL_MMSP2_SC_BUSY, 0) = 0 ioctl(13, IOCTL_DUALCPU_MP4D_RUN, 0x157c20) = 1 read(13, "\21", 32) = 1 ioctl(14, IOCTL_MMSP2_START_FDC, 0x15b308) = 0 ioctl(14, IOCTL_MMSP2_START_SC, 0x2) = 0 ioctl(14, IOCTL_MMSP2_SC_BUSY, 0) = 0 ioctl(13, IOCTL_DUALCPU_MP4D_RUN, 0x157c20) = 1 read(13, "\2", 32) = 1 ioctl(13, IOCTL_DUALCPU_MP4D_RUN, 0x157c20) = 1 read(13, "\2", 32) = 1 ioctl(13, IOCTL_DUALCPU_MP4D_RUN, 0x157c20) = 1 read(13, "\2", 32) = 1 ioctl(13, IOCTL_DUALCPU_MP4D_RUN, 0x157c20) = 1 read(13, "\21", 32) = 1 ioctl(14, IOCTL_MMSP2_START_FDC, 0x15b308) = 0 ioctl(14, IOCTL_MMSP2_START_SC, 0x2) = 0 ioctl(14, IOCTL_MMSP2_SC_BUSY, 0) = 0 ioctl(13, IOCTL_DUALCPU_MP4D_RUN, 0x157c20) = 1 read(13, "\21", 32) = 1 ioctl(14, IOCTL_MMSP2_START_FDC, 0x15b308) = 0 ioctl(14, IOCTL_MMSP2_START_SC, 0x2) = 0 ioctl(14, IOCTL_MMSP2_SC_BUSY, 0) = 0 ioctl(13, IOCTL_DUALCPU_MP4D_RUN, 0x157c20) = 1 read(13, "\2", 32) = 1