Thursday, February 28, 2008

libtool 1.5 bug?

I was trying to compile gtk+-2.6.10 using Fink, on Mac OS X 10.5.2 with a new MacBook Pro. It stopped at the following error (I broke the lines to make it fit in 80 columns):
/bin/sh ../libtool --mode=link gcc  -O3 -funroll-loops -fstrict-aliasing -pipe -
Wall   -o libgdk-x11-2.0.la  -version-info 600:10:600 -export-dynamic -rpath /sw
/lib  -export-symbols-regex "^[^_].*" gdk.lo gdkcolor.lo gdkcursor.lo gdkdisplay
.lo gdkdnd.lo gdkdraw.lo gdkevents.lo gdkfont.lo gdkgc.lo gdkglobals.lo gdkkeys.
lo gdkkeyuni.lo gdkimage.lo gdkdisplaymanager.lo gdkpango.lo gdkpixbuf-drawable.
lo gdkpixbuf-render.lo gdkpixmap.lo gdkpolyreg-generic.lo gdkrgb.lo gdkrectangle
.lo gdkregion-generic.lo gdkscreen.lo gdkselection.lo gdkvisual.lo gdkwindow.lo
gdkenumtypes.lo x11/libgdk-x11.la -L/usr/X11/lib -lXrandr -lXrender -lXinerama -
lXext  -L/usr/X11/lib -lXfixes   -L/usr/X11/lib -lXcursor    -Wl,-framework,Core
Services,-framework,ApplicationServices -L/sw/lib -L/usr/X11/lib -lpangoxft-1.0
-lXft -lXrender -lpangoft2-1.0 -lfontconfig -lfreetype -lz -lpangox-1.0 -lX11 -l
pango-1.0 -lm -lgobject-2.0 -lgmodule-2.0 -lglib-2.0 -lintl -liconv    -lm ../gd
k-pixbuf/libgdk_pixbuf-2.0.la -lintl
libtool: link: warning: `/sw/lib//libintl.la' seems to be moved
rm -fr  .libs/libgdk-x11-2.0.exp .libs/libgdk-x11-2.0.lax
generating symbol list for `libgdk-x11-2.0.la'
/usr/bin/nm -p  .libs/gdk.o .libs/gdkcolor.o .libs/gdkcursor.o .libs/gdkdisplay.
o .libs/gdkdnd.o .libs/gdkdraw.o .libs/gdkevents.o .libs/gdkfont.o .libs/gdkgc.o
.libs/gdkglobals.o .libs/gdkkeys.o .libs/gdkkeyuni.o .libs/gdkimage.o .libs/gdk
displaymanager.o .libs/gdkpango.o .libs/gdkpixbuf-drawable.o .libs/gdkpixbuf-ren
der.o .libs/gdkpixmap.o .libs/gdkpolyreg-generic.o .libs/gdkrgb.o .libs/gdkrecta
ngle.o .libs/gdkregion-generic.o .libs/gdkscreen.o .libs/gdkselection.o .libs/gd
kvisual.o .libs/gdkwindow.o .libs/gdkenumtypes.o  x11/.libs/libgdk-x11.a | sed -
n -e 's/^.*[  ]\([BCDEGRST][BCDEGRST]*\)[  ][  ]*_\([_A-Za-z][_A-Za-z0-
9]*\)$/\1 _\2 \2/p' | /usr/bin/sed 's/.* //' | sort | uniq > .libs/libgdk-x11-2.
0.exp
grep -E -e "^[^_].*" ".libs/libgdk-x11-2.0.exp" > ".libs/libgdk-x11-2.0.expT"
mv -f ".libs/libgdk-x11-2.0.expT" ".libs/libgdk-x11-2.0.exp"
rm -fr .libs/libgdk-x11-2.0.lax
mkdir .libs/libgdk-x11-2.0.lax
rm -fr .libs/libgdk-x11-2.0.lax/libgdk-x11.a
mkdir .libs/libgdk-x11-2.0.lax/libgdk-x11.a
Extracting /sw/src/fink.build/gtk+2-2.6.10-1004/gtk+-2.6.10/gdk/x11/.libs/libgdk
-x11.a
(cd .libs/libgdk-x11-2.0.lax/libgdk-x11.a && ar x /sw/src/fink.build/gtk+2-2.6.1
0-1004/gtk+-2.6.10/gdk/x11/.libs/libgdk-x11.a)
sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < .libs/libgdk-x11-2.0.exp >
.libs/libgdk-x11-2.0-symbols.expsym
gcc -dynamiclib ${wl}-undefined ${wl}dynamic_lookup -o .libs/libgdk-x11-2.0.0.60
0.10.dylib  .libs/gdk.o .libs/gdkcolor.o .libs/gdkcursor.o .libs/gdkdisplay.o .l
ibs/gdkdnd.o .libs/gdkdraw.o .libs/gdkevents.o .libs/gdkfont.o .libs/gdkgc.o .li
bs/gdkglobals.o .libs/gdkkeys.o .libs/gdkkeyuni.o .libs/gdkimage.o .libs/gdkdisp
laymanager.o .libs/gdkpango.o .libs/gdkpixbuf-drawable.o .libs/gdkpixbuf-render.
o .libs/gdkpixmap.o .libs/gdkpolyreg-generic.o .libs/gdkrgb.o .libs/gdkrectangle
.o .libs/gdkregion-generic.o .libs/gdkscreen.o .libs/gdkselection.o .libs/gdkvis
ual.o .libs/gdkwindow.o .libs/gdkenumtypes.o  .libs/libgdk-x11-2.0.lax/libgdk-x1
1.a/gdkasync.o .libs/libgdk-x11-2.0.lax/libgdk-x11.a/gdkcolor-x11.o .libs/libgdk
-x11-2.0.lax/libgdk-x11.a/gdkcursor-x11.o .libs/libgdk-x11-2.0.lax/libgdk-x11.a/
gdkdisplay-x11.o .libs/libgdk-x11-2.0.lax/libgdk-x11.a/gdkdnd-x11.o .libs/libgdk
-x11-2.0.lax/libgdk-x11.a/gdkdrawable-x11.o .libs/libgdk-x11-2.0.lax/libgdk-x11.
a/gdkevents-x11.o .libs/libgdk-x11-2.0.lax/libgdk-x11.a/gdkfont-x11.o .libs/libg
dk-x11-2.0.lax/libgdk-x11.a/gdkgc-x11.o .libs/libgdk-x11-2.0.lax/libgdk-x11.a/gd
kgeometry-x11.o .libs/libgdk-x11-2.0.lax/libgdk-x11.a/gdkglobals-x11.o .libs/lib
gdk-x11-2.0.lax/libgdk-x11.a/gdkim-x11.o .libs/libgdk-x11-2.0.lax/libgdk-x11.a/g
dkimage-x11.o .libs/libgdk-x11-2.0.lax/libgdk-x11.a/gdkinput-none.o .libs/libgdk
-x11-2.0.lax/libgdk-x11.a/gdkinput.o .libs/libgdk-x11-2.0.lax/libgdk-x11.a/gdkke
ys-x11.o .libs/libgdk-x11-2.0.lax/libgdk-x11.a/gdkmain-x11.o .libs/libgdk-x11-2.
0.lax/libgdk-x11.a/gdkpango-x11.o .libs/libgdk-x11-2.0.lax/libgdk-x11.a/gdkpixma
p-x11.o .libs/libgdk-x11-2.0.lax/libgdk-x11.a/gdkproperty-x11.o .libs/libgdk-x11
-2.0.lax/libgdk-x11.a/gdkscreen-x11.o .libs/libgdk-x11-2.0.lax/libgdk-x11.a/gdks
election-x11.o .libs/libgdk-x11-2.0.lax/libgdk-x11.a/gdkspawn-x11.o .libs/libgdk
-x11-2.0.lax/libgdk-x11.a/gdkvisual-x11.o .libs/libgdk-x11-2.0.lax/libgdk-x11.a/
gdkwindow-x11.o .libs/libgdk-x11-2.0.lax/libgdk-x11.a/gdkxid.o .libs/libgdk-x11-
2.0.lax/libgdk-x11.a/xsettings-client.o .libs/libgdk-x11-2.0.lax/libgdk-x11.a/xs
ettings-common.o   -L/sw/lib -lc -L/usr/X11/lib /usr/X11/lib/libXrandr.2.0.0.dyl
ib /usr/X11/lib/libXau.6.0.0.dylib /usr/X11/lib/libXdmcp.6.0.0.dylib /usr/X11/li
b/libXinerama.1.0.0.dylib /usr/X11/lib/libXext.6.4.0.dylib /usr/X11/lib/libXfixe
s.3.1.0.dylib /usr/X11/lib/libXcursor.1.0.2.dylib /sw/lib/libpangoxft-1.0.dylib
-L/usr/X11R6/lib /usr/lib/libexpat.dylib /usr/lib/libz.dylib /usr/lib/libc.dylib
/usr/X11/lib/libXft.2.1.2.dylib /usr/X11/lib/libXrender.1.3.0.dylib /sw/lib/lib
pangoft2-1.0.dylib /usr/lib/libm.dylib /usr/X11/lib/libfontconfig.dylib /usr/X11
/lib/libfreetype.dylib -lz /sw/lib/libpangox-1.0.dylib /usr/X11/lib/libX11.6.2.0
.dylib /sw/lib/libpango-1.0.dylib /sw/lib/libgobject-2.0.dylib /sw/lib/libgmodul
e-2.0.dylib /sw/lib/libglib-2.0.dylib /sw/lib/libiconv.dylib -lm ../gdk-pixbuf/.
libs/libgdk_pixbuf-2.0.dylib /sw/lib//libintl.dylib /sw/lib/libintl.dylib  -Wl,-
framework -Wl,CoreServices -Wl,-framework -Wl,ApplicationServices -install_name
/sw/lib/libgdk-x11-2.0.0.dylib -Wl,-compatibility_version -Wl,601 -Wl,-current_
version -Wl,601.10
i686-apple-darwin9-gcc-4.0.1: /usr/X11/lib/libXrandr.2.0.0.dylib: No such file o
r directory
It appears the culprit is that libtool assumes all minor version numbers of dynamic libraries to be zero. But it is not so.
$ ls -l /usr/X11/lib/libXrandr.*
lrwxr-xr-x 1 root wheel     17 2008-02-14 09:48 /usr/X11/lib/libXrandr.2.1.0.dylib -> libXrandr.2.dylib
-rwxr-xr-x 1 root wheel 164144 2008-01-14 00:35 /usr/X11/lib/libXrandr.2.dylib
lrwxr-xr-x 1 root wheel     17 2008-02-14 09:48 /usr/X11/lib/libXrandr.dylib -> libXrandr.2.dylib
-rwxr-xr-x 1 root wheel    955 2007-09-09 01:34 /usr/X11/lib/libXrandr.la
This is the version of libtool I'm using:
$ dpkg -l libtool*
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Installed/Config-files/Unpacked/Failed-config/Half-installed
|/ Err?=(none)/Hold/Reinst-required/X=both-problems (Status,Err: uppercase=bad)
||/ Name           Version        Description
+++-==============-==============-============================================
un  libtool                 (no description available)
ii  libtool14      1.5.26-1       Shared library build helper, v1.5
ii  libtool14-shli 1.5.26-1       Shared libraries for libtool, v1.5
$
A workaround is to create the symbolic link:
$ cd /usr/X11/lib
$ sudo ln -s libXrandr.2.dylib libXrandr.2.0.0.dylib
Password:
$
And this hack should satisfy libtool for now. This is not a bug in the build script of gtk+-2.6.10 in fink, nor the Makefile though. The failed gcc command was generated automatically by libtool.

Tuesday, February 26, 2008

Studying s211nup1.bin

Using a hex editor to look at the firmware after extracting it from the downloaded zip file, the first 0x60 (96) bytes contain some sort of firmware header. The rest of the firmware is a binary that runs on something that looks like a 32-bit RISC machine. Further examination reveals that it runs on a little Endian ARM processor because of the prevalence of the 0xe??????? instructions. It is a unique feature of the ARM: each instruction codes the condition to execute in the 4 highest bits that can make the code really compact. The condition e? means "always."

There is another unique feature about ARM. Since each instruction is exactly 32-bit wide, there is no one instruction that loads a whole 32-bit constant. Compiler often loads constant from memory relative to the program counter, and then leaps over the constant pool later (which is non-sensible instruction). This behavior is observed from the firmware as well.

The firmware initializes sp to 0x44000000. If the code is loaded at 0x40000000 like standard practice, then it means the hardware expects 64MB of ram. There also seems to be a memory mapped I/O block in the upper memory area around 0xffff????.

The next step is to look at the strings literals in the firmware and see which code references a given string. Since string literals are intertwined with code, this could help establishing the memory mapping for where the code should be loaded.

Sunday, February 24, 2008

Review of Sanyo VPC-HD1000

I own the Sanyo VPC-HD1000 camcorder since November 2007. Having made about 32GB, or 6 hours of videos, I think I can say a little bit about this camcorder. I'll start by saying that all the reviews you read online are still true, most of the pros and cons. I'm not going to repeat what they said. I'm just going to nitpick a bit more. All these remarks apply to the latest firmware update in 11/21/07 as well as factory firmware.

I'll start with things that I like:
  • EIS (electronic image stablization) does not reduce field of view, contrary to what some other website claims. The image area on the CMOS used for video recording is about 80% width of the image area used for taking still photos (I realize that EIS is available for still photos, and that does not reduce field of view either). This leaves plenty of image area for EIS and does not reduce either field of view or image quality. In fact, EIS improves image quality quite a bit because the H.264 codec does not have to deal with all that shaking. See below about H.264 motion artifact.

    I find that I simply can't do without EIS. It is pretty much a requirement if you want a steady shot. I tried mounting the camcorder on a folded tripod, which helped stablizing the image but with limited success. Maybe one of these DIY steadicam can help, but I haven't tried.
  • The resolution is very good, good enough to introduce aliasing when scaling the video by half, i.e. from 1920x1080 to 960x540. From casual eyeballing, I'd say 720 lines is about the native resolution of this camcorder, so you get the most out of the HDHR mode, or 1280x720 at 60p. Note: both 1080i and 720p modes have the same field of view.

    I imagine if you want 1080@60i, you get the best result by upsampling 720@60p in post-production. I haven't tried it though.
  • Very good low light performance. ISO 400 is good enough to shoot all well-lit city streets at night without additional lighting (to a point that the street lights raise my concern about possible light pollution problem). Some people aren't happy with the low light performance because they expect a small lightbulb can illuminate a scene like daylight. This is not going to happen for any camera. This is why professional filmmakers use ridiculous lighting equipment.
And the things I don't like:
  • Cannot change manual focus during recording. Actually, you can't change aperture while recording as well, but not being able to change the focus annoys me the most. You can't change ISO and shutter speed during recording either, but you shouldn't need to do that.

    Solution: try one of the auto-focus settings, and both 1-point and 9-point autofocus to see which one applies best to the scene. I don't find aperture to be a big deal because I almost always fix the shutter speed and ISO setting and let the camcorder figure out the right aperture. Other times I fix the aperture as well for the entire take.

    If you have some money and you like to play around, try one of those 35mm depth of field adapters. You use a manual focus lens with the adapter, and you can achieve some amazing effects even with a consumer camcorder. I haven't tried it myself but I'm eagar to find out if it works with Sanyo VPC-HD1000. The adapter is going to be larger than the camera itself, though.
  • Viewfinder preview during standby is not always accurate if you rely on manual ISO, shutter speed, and aperture settings that would change the overall exposure. It always looks "okay" on the preview, but the scene could be drastically over- or under- exposed by surprise.

    Solution: since I use shutter-priority mode, the lower left corner of the screen tells me which aperture would be used. If it hits F/1.8, then there might be risk for underexposure. If it hits F/8.0, then there is risk for overexposure. You just have to tell by experience.

    Otherwise, just hit record and take a test shoot for a few seconds. That always works.
  • Heavy artifact when the scene has a lot of motion, such as looking into a forest on a train ride. There is also sample of flowing water that causes severe artifact. In particular, I blame that the camcorder only records at 12Mbps video in both FULLHD and HDHR mode.

    Solution: no solution as far as I can tell, but you can plan the scene to have less motion, or upgrade to a more expensive camcorder if you feel your artistic license is violated.
  • Recording time limit. The camcorder formats a SDHC card in FAT32 filesystem, and there is a 4GB file size, or 45 minutes at 12Mbps for FULLHD and HDHR modes. Furthermore, the recording just stops rather than seamlessly roll-over to a new file.

    Solution: no solution as far as I can tell. Using an 8GB SDHC memory wouldn't help. Furthermore, the camcorder can only support up to 8GB cards. With 16GB cards becoming very affordable nowadays, the ability for extended continuous recording time is now limited only by firmware.
  • Noisy microphone preamp. You can hear a lot of white noise by plugging in an external mic but having it turned off. There is very little noise at level 1, but the noise becomes painfully audible as you approach volume level 5.

    Solution: keep the external mic volume at level 1. However, see the next caveat.
  • Rattling sound introduced by AAC codec. When implemented correctly, AAC is usually very good at compressing audio, but the firmware may have a bad implementation. This is audible if you listen intently during a quiet scene. It only becomes a problem if you use a good quality external mic with very low noise floor, since the built-in mic never gives you a quiet scene. I blame this on the low 128kbps bitrate and the firmware's implementation of AAC. Higher bitrate could compensate for a bad implementation. I mean, 128kbps is peanuts compared to the 12Mbps video. I think Sanyo should allow at least 256kbps of audio.

    Solution: raise the external mic volume to introduce artificial white noise. You have to decide which is more annoying: white noise or the rattle.
All in all, the problems I find the most annoying with no viable solution is that the camcorder did not use MPEG-4 H.264/AAC to their full potential. The second most annoying problem is the limit in file size to 4GB (or 45 minutes recording time) and the lack of support for 16GB SDHC cards. These are all firmware problems as far as I can tell.

Wednesday, February 6, 2008

Faux Anti-Aliasing

The idea is to take a piece of scanned text in black and white (after thresholding), convert to greyscale, and draw short anti-aliased lines between two edge pixels to smoothen the appearance of text. Unlike unsharpening, we avoid blurring the horizontal and vertical edges.