CedarX/Reverse Engineering

= Initial information = On June 15 2012 Iain Bullard started reverse engineering the proprietary libraries.

Unfortunately driver are proxy that maps HW Regs to Userspace using mmap all stuff constain in libvecore.so


 * open_cdxalloc as an free reimplementation of Allwinner's libcederxalloc.a.
 * CedarXWrapper as a LD_PRELOADed wrapper to help understanding the proprietary libraries.
 * CedarXPlayerTest as a basic player to use when testing.

= Object file observations = While android and linux are different beasts from the userspace sense, It could be that the code was written in such way, that it could compile to both targets. Meaning that object files could be similar enough.

From android
The android-linux libvecore.a (md5sum 1c347a9ad3072ce3288bd6dba625b2a4) static lib contains the following files: android functions

From linux-armhf
The linux-armhf libvecore.so (md5sum a026d27307e5204db191878651cc6394) shared object contains the following functions: linux-armhf functions

Lilky both
To generate this list, libvecore.a was used, as it separates things quite nicely and appears to be identical to libvecore.so. That said, this obviously does not have to be true. There is one major difference, libvecore.so also has crtstuff.c functions combined from. While investigating nothing indicated that crtstuff.c from gcc was used directly, it is still likly some functions where used from there.

sunxi-bsp/cedarx-libs/libcedarv/android/libvecore $ arm-pc-linux-gnueabi-ar t libvecore.a | sort

The rest of the bits are all open source, see the linux-sunxi github. The exception is libcedarxalloc.a, but as mentioned above, we have open_cdxalloc.

Function references
So far the following references can easily be observed with readelf -W -s. This is just an indication of some functions, by far complete as it would take way to long and is not really needed.

FFmpeg huffman tree builder: ff_huff_build_tree http://ffmpeg.org/doxygen/trunk/huffman_8c.html

libjpeg: get_soi http://sourceforge.net/p/libjpeg-turbo/code/HEAD/tree/trunk/jdmarker.c

libvp62: VP62_InitCoeffScaleFactors http://en.verysource.com/code/5378534_1/libvp62.h.html

H264/AVC Reference encoder/decoder: remove_frame_from_dpb http://iphome.hhi.de/suehring/tml/doc/lenc/html/mbuffer_8c.html#901bd781eb9aef8b79e98b8e10fbc2aa

VC1 Reference decoder: vc1_eResult vc1DECPIC_UnpackInterlaceMVModeParams http://wiki.multimedia.cx/index.php?title=Understanding_VC-1#vc1DECPIC_UnpackInterlaceMVModeParams

MPEG2: There seems to have happened some function renaming etc, the one that google found though was: ParseQuantMatrixExtension http://sources.team-mediaportal.com/svn/public/tags/Release%201.0.2/DirectShowFilters/TsReader/source/MpegPesParser.cpp = HW Registers guide = REGS_BASE = 0x01C00000 A10  IO register base addr

MACC_REGS_BASE = (REGS_BASE + 0x0E000) media accelerate VE IO space(4 kb)

Reset/Clock reg
MACC_REGS_BASE + 0x00

On some cases reset logic not same with Cedar revisions

generaly possible cases

0x0000

0x0001

0x0010

0x0011

VE Revision register
MACC_REGS_BASE + 0xF2

CedarX(or allwinner chip) version

cases

0x1625 - a13

0x1623 - a10

0x1620

0x1619

MPEG Engine
Base address

MPEG_REGS_BASE = (MACC_REGS_BASE + 0x100)

Interupt enable reg = MPEG_REGS_BASE + 0x14

H264 Engine
Base address

H264_REGS_BASE = (MACC_REGS_BASE + 0x200)

Interupt enable reg = H264_REGS_BASE + 0x20

bitmask 0x0111 enable/disable IRQs from H264 decoder

VC1 Engine
Base address

VC1_REGS_BASE = (MACC_REGS_BASE + 0x300)

Interupt enable reg = VC1_REGS_BASE + 0x24

RMVB Engine
Base address

RMVB_REGS_BASE = (MACC_REGS_BASE + 0x400)

Interupt enable reg = RMVB_REGS_BASE + 0x14

ISP ??
Base address

ISP_REGS_BASE = (MACC_REGS_BASE + 0xa00)

Interupt enable reg = ISP_REGS_BASE + 0x8

AVC Encoder engine
Base address

ISP_REGS_BASE = (MACC_REGS_BASE + 0xb00 )

Interupt enable reg = ISP_REGS_BASE + 0x8

Blob exported funtions description
libv_open do clock setup and initial configuration and init selected engine doing selected *_open

MJPEG Engine API
mjpeg_setup_anaglagh_transform

mjpeg_set_vbv -Video buffering verifier config (CBR/VBR select) call calbacks vbv_get_base_addr and vbv_get_size that we have in source and save infor to internal structure.

mjpeg_set_parent - save pointer to internal structure

mjpeg_set_minor_vbv - STUD

mjpeg_reset - do reset using ve_reset_hardware and internal reset function that touches clock/reset register

mjpeg_release - call callback fbm_release and ve_reset_hardware that we have in sources

mjpeg_open - init mjpeg decoder called by libve_open

mjpeg_io_control -

mjpeg_get_stream_info - use callback for memcopy

mjpeg_get_minor_fbm STUD

mjpeg_get_fbm_num return 1;

mjpeg_get_fbm - return int valure

mjpeg_flush - STUD

mjpeg_decode - general big decoding function

mjpeg_close_anaglagh_transform

mjpeg_close - do callbacks ve_reset_hardware and fbm_release that we have in source

Other findings

 * Old and new kernel drivers both offer a way to directly access registers. It looks like for quite some functions, this approach was chosen. Probably to hide the gory details in the library.