libcle266mpegdec libcle266mpegdec
Status: Beta
Brought to you by:
rofafor
libcle266mpegdec ================ This is a library which performs decoding of an MPEG-2 video elementary stream using the hardware MPEG-2 decoder found in the VIA CLE266 chipset on various motherboards including some of the VIA Epia series. The library is based on the Andreas Robinson's mtest-0.1.1, that's propably based on the work of Ivor Hewitt who reverse-engineered libddmpeg released by VIA. The code looks quite similar to the XVMC portion of the Openchrome driver for Xorg. Prerequisites ------------- This library accesses the CLE266 video hardware by memory maping the framebuffer device. Only the linux-viafb driver from DirectFB CVS has been tested. The DirectFB and DFB++ libraries should be patched with GetFBOffset and GetFBOffsetDFB++ patches to enable the framebuffer offsets to be retrieved for the surfaces used as buffers, recompiled and installed. NOTE: The both patches have been merged into DirectFB CVS since 2006-10-08! Installation ------------ Building and installing is straightforward. Simply run: ./configure make make install License ------- The license in source code headers has been changed from MIT to LGPL as Andreas Robinson states in his email on DirectFB-dev mailing list: "Hi, I just realized I have completely forgotten to mention the hardware decoder test program on this mailinglist. Doh! So, look here: http://cle266dfb.sourceforge.net/mtest-0.1.1.tar.gz It is not really finished yet, and the license headers are wrong (should be LGPL, but are not.) but it works. Regards, Andreas" Internals --------- The structure of library is fairly simple. The API calls decoder.c which in turn calls parser.c which calls scanner.c. Scanner.c reads the mpeg file, locates block start codes and unpacks header blocks into C structures. Parser.c implements the mpeg2 state machine described in the standard. Decoder.c takes data from the scanner and parser and gives it to the hardware interface in hwdec.c. The application code must set up 4 buffers for the decoder to work with and tell to the library where these buffers are. After that the MPEG-2 data can be send to the library. When a frame has been decoded, it will be in one of the four buffers, and it can then be copied back from there for display. There is no A-V synchronization or display capability in this library, so feed it a video elementary stream and get back frames! Library HOWTO ------------- Here's an example code to show howto interface the library. See cle266mpegdec.h for function prototypes. This example uses DirectFB for creating the buffers as DirectFB surfaces with a YV12 pixel format. No DirectFB initialisation code or error checking is included: *** Setting up buffers *** #include <directfb.h> IDirectFB *dfb; IDirectFBSurface *mpegfb[4]; DFBSurfaceDescription dsc; int *mpegfb_ptr[4]; int mpegfb_ofs[4]; int mpegfb_stride; uint8_t *buf; int i; /* The first step is to call CLE266MPEGInitialise() * which mmaps /dev/fb0 and initialises the decoder */ fprintf(stderr, "Initialising CLE266 decoder:"); if (!CLE266MPEGInitialise("/dev/fb0")) { fprintf(stderr, "failed!\n"); return false; } else { fprintf(stderr, "success!\n"); } dsc.flags = (DFBSurfaceDescriptionFlags)(DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS); dsc.caps = DSCAPS_VIDEOONLY; dsc.pixelformat = DSPF_YV12; /* Set width and height as appropriate! e.g. 720 x 576 */ dsc.width = width; dsc.height = height; /* Create the MPEG buffers */ for ( i = 0; i < 4; i++) { dfb->CreateSurface(dfb, &dsc, &mpegfb[i]); mpegfb[i]->Clear(mpegfb[i], 0, 0, 0, 0); mpegfb[i]->Lock(mpegfb[i], DSLF_WRITE, (void**) &buf, &mpegfb_stride); /* This is the step which requires the DirectFB / DFB++ patches */ mpegfb[i]->GetFramebufferOffset(mpegfb[i], &mpegfb_ofs[i]); mpegfb_ptr[i] = buf; } /* Inform the decoder of the line length and locations of the buffers: */ CLE266MPEGSetStride(mpegfb_stride, mpegfb_stride >> 1); for (i = 0; i < 4; i++) { int y_offset = mpegfb_ofs[i]; int u_offset = y_offset + (mpegfb_stride * height); int v_offset = u_offset + (mpegfb_stride >> 1) * (height >> 1); CLE266MPEGSetFrameBuffer(i, y_offset, u_offset, v_offset); } *** Sending data to the decoder *** Now that the decoder is initialised, we can start sending data to it, that should be an MPEG-2 video elementary stream. The MPEG-2 data is in the buffer 'data' and has length 'len'. The function returns the number of bytes decoded in 'len' and the index of the framebuffer containing any decoded frame or -1 if no frame has yet been decoded. This will need to be in a loop with the buffer being incremented for each call. /* repeat while cle266FB is -1 */ cle266FB = CLE266MPEGDecodeData(data, &len, &pts); On successful decoding, the decoded frame will be in the buffer "mpegfb[i]" from where it can be blitted to another surface for display or copied elsewhere as needed. *** Clearing up *** The application code should call CLE266MPEGClose() on exit. References ---------- This library is based on the Andreas Robinson's mtest-0.1.1: http://www.directfb.org/mailinglists/directfb-dev/2004/01-2004/msg00131.html http://cle266dfb.sourceforge.net/mtest-0.1.1.tar.gz Colin Paton's libsoftmpeg-cle266 that's based on mentioned mtest: http://www.linuxtv.org/mailinglists/linuxtv-softmpeg/2004/03-2004/msg00031.html http://crp.pwp.blueyonder.co.uk/MPEG/libsoftmpeg-cle266-0.01.tgz Laurence Abbott's libcle266decode-0.1 that's based on mentioned libsoftmpeg-cle266: http://lists.berlios.de/pipermail/softdevice-devel/2006q2/001943.html http://vdr.club-burniston.co.uk/softdevice_cle266.diff http://vdr.club-burniston.co.uk/libcle266decode-0.1.tar.gz