Reverse engineered libomap3camd header file for N9 and N950


A short introduction about N9 camera stack:
Camera stack for N9 is built on top of V4L2 subdev and media controller interfaces.

A GStreamer source element called subdevsrc (And subdevsrc2 starting from PR 1.2) sits on top of the kernel interfaces.
A closed source component called libomap3camd (OMAP3 camera daemon library) contains all the 3A (Auto exposure, Auto white balance and Auto focus) algorithms in addition
to image capturing. It simply gathers statistics from hardware components such as ISP histpgram (And others) and controls the camera pipeline to adjust image quality.

What do we have?
Nokia was kind enough to provide a compiled binaries subdevsrc and libomap3camd to the MeeGo project. However they have not released the header files for libomap3camd.

This puts us (The community) in an unfavorable situation. We cannot easily manipulate our GStreamer stack, update or fix bugs in subdevsrc (Whose source code is publicly available).

How about the future?
You can obtain the code from its git repository.
Using the reverse engineered libomap3camd header, I managed to rebuild subdevsrc for NEMO
and got meego-handset camera to work and capture an image :-)

The code built is from this commit:

commit effd37efa3ba026221e0f84ef370d06f1a122b6c
Author: Tommi Myöhänen <>
Date:   Thu Mar 17 12:38:40 2011 +0200

    Release gst-nokia-videosrc (0.57.0-1)

I failed to build the latest git master due to the old GStreamer photography interface available in Nemo/Mer.

How did all this happen?
It took a day or a bit more of a weekend.
I started by building subdevsrc and creating various enums and structures needed to get it to build (with dummy values).
I then started poking around using the latest nemo mobile release and ltrace.
GstSubdevSrc used 4 functions out of which, cam_set_feature is the most important one.
This approach didn't really work quite well. It seemed that the number of cam_feature_set calls found by ltrace doesn't match those in the code and it seemed that the code used to build the nemo subdevsrc isn't really available.

Here comes N9 to the picture. Thanks to the "beloved" AEGIS framework, ltrace didn't work.
I tried to mock a libomap3camd shared object and LD_PRELOAD it but that also didn't work.

I sat down and wrote a minimal application that would manipulate subdevsrc properties and observe the value of registers (r0 has the library handle but r1 and r2 are really interesting) when gdb breaks on cam_feature_set and I managed to get some values but that was clearly not enough. Even gdb sometimes doesn't break at all :(

The gem was the discovery of a subdevsrc package along with its debugging symbols:
gstreamer0.10-nokia-videosrc-dbg=0.52.19-1+0m6 and gstreamer0.10-nokia-videosrc=0.52.19-1+0m6.
Download and install them (Use inception) and wow! All data structures can be dumped easily using gdb ptype and all enum values can be printed using gdb print.
The only exception was maker_note_t which needed another hack.

And now?
I guess now we can easily update GStreamer and subdevsrc to the latest and even fix any bugs that we find. I am not sure how crippled our libomap3camd is and whether we can get all subdevsrc working but we are at least in a better position.

Add new comment

The content of this field is kept private and will not be shown publicly.