<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Hardwarebug</title>
	<atom:link href="http://hardwarebug.org/feed/" rel="self" type="application/rss+xml" />
	<link>http://hardwarebug.org</link>
	<description>Everything is broken</description>
	<lastBuildDate>Tue, 17 Aug 2010 14:47:17 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Countryside</title>
		<link>http://hardwarebug.org/2010/08/17/countryside/</link>
		<comments>http://hardwarebug.org/2010/08/17/countryside/#comments</comments>
		<pubDate>Tue, 17 Aug 2010 14:47:17 +0000</pubDate>
		<dc:creator>Mans</dc:creator>
				<category><![CDATA[Photos]]></category>

		<guid isPermaLink="false">http://hardwarebug.org/?p=541</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p><a href="http://hardwarebug.org/wp-content/uploads/2010/08/img_3331.jpg"><img src="http://hardwarebug.org/wp-content/uploads/2010/08/img_3331-300x200.jpg" alt="" title="img_3331" width="300" height="200" class="aligncenter size-medium wp-image-544" /></a><br />
<span id="more-541"></span><br />
<a href="http://hardwarebug.org/wp-content/uploads/2010/08/img_3360.jpg"><img src="http://hardwarebug.org/wp-content/uploads/2010/08/img_3360-300x200.jpg" alt="" title="img_3360" width="300" height="200" class="aligncenter size-medium wp-image-549" /></a><br />
<a href="http://hardwarebug.org/wp-content/uploads/2010/08/img_3363-e1282054082843.jpg"><img src="http://hardwarebug.org/wp-content/uploads/2010/08/img_3363-e1282054082843-200x300.jpg" alt="" title="img_3363" width="200" height="300" class="aligncenter size-medium wp-image-550" /></a><br />
<a href="http://hardwarebug.org/wp-content/uploads/2010/08/img_3405.jpg"><img src="http://hardwarebug.org/wp-content/uploads/2010/08/img_3405-300x200.jpg" alt="" title="img_3405" width="300" height="200" class="aligncenter size-medium wp-image-564" /></a><br />
<a href="http://hardwarebug.org/wp-content/uploads/2010/08/img_3342.jpg"><img src="http://hardwarebug.org/wp-content/uploads/2010/08/img_3342-300x200.jpg" alt="" title="img_3342" width="300" height="200" class="aligncenter size-medium wp-image-560" /></a><br />
<a href="http://hardwarebug.org/wp-content/uploads/2010/08/img_3339.jpg"><img src="http://hardwarebug.org/wp-content/uploads/2010/08/img_3339-300x200.jpg" alt="" title="img_3339" width="300" height="200" class="aligncenter size-medium wp-image-546" /></a><br />
<a href="http://hardwarebug.org/wp-content/uploads/2010/08/img_3379.jpg"><img src="http://hardwarebug.org/wp-content/uploads/2010/08/img_3379-300x200.jpg" alt="" title="img_3379" width="300" height="200" class="aligncenter size-medium wp-image-551" /></a><br />
<a href="http://hardwarebug.org/wp-content/uploads/2010/08/img_3337.jpg"><img src="http://hardwarebug.org/wp-content/uploads/2010/08/img_3337-300x200.jpg" alt="" title="img_3337" width="300" height="200" class="aligncenter size-medium wp-image-545" /></a><br />
<a href="http://hardwarebug.org/wp-content/uploads/2010/08/img_3290.jpg"><img src="http://hardwarebug.org/wp-content/uploads/2010/08/img_3290-300x200.jpg" alt="" title="img_3290" width="300" height="200" class="aligncenter size-medium wp-image-542" /></a><br />
<a href="http://hardwarebug.org/wp-content/uploads/2010/08/img_3308.jpg"><img src="http://hardwarebug.org/wp-content/uploads/2010/08/img_3308-300x200.jpg" alt="" title="img_3308" width="300" height="200" class="aligncenter size-medium wp-image-562" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://hardwarebug.org/2010/08/17/countryside/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>ARM inline asm secrets</title>
		<link>http://hardwarebug.org/2010/07/06/arm-inline-asm-secrets/</link>
		<comments>http://hardwarebug.org/2010/07/06/arm-inline-asm-secrets/#comments</comments>
		<pubDate>Tue, 06 Jul 2010 20:52:43 +0000</pubDate>
		<dc:creator>Mans</dc:creator>
				<category><![CDATA[ARM]]></category>
		<category><![CDATA[Compilers]]></category>

		<guid isPermaLink="false">http://hardwarebug.org/?p=493</guid>
		<description><![CDATA[Although I generally recommend against using GCC inline assembler, preferring instead pure assembler code in separate files, there are occasions where inline is the appropriate solution. Should one, at a time like this, turn to the GCC documentation for guidance, one must be prepared for a degree of disappointment. As it happens, much of the [...]]]></description>
			<content:encoded><![CDATA[<p>Although I generally recommend against using GCC inline assembler, preferring instead pure assembler code in separate files, there are occasions where inline is the appropriate solution. Should one, at a time like this, turn to the GCC documentation for guidance, one must be prepared for a degree of disappointment. As it happens, much of the inline asm syntax is left entirely undocumented. This article attempts to fill in some of the blanks for the ARM target.<br />
<span id="more-493"></span></p>
<style>
.asm { border-collapse: collapse; }
.asm td { padding: 0.5em; }
.asm td:first-child { font-family: monospace; font-weight: bold; vertical-align: top }
</style>
<h3>Constraints</h3>
<p>Each operand of an inline asm block is described by a constraint string encoding the valid representations of the operand in the generated assembler. For example the &#8220;r&#8221; code denotes a general-purpose register. In addition to the standard constraints, ARM allows a number of special codes, only some of which are documented. The full list, including a brief description, is available in the <code>constraints.md</code> file in the GCC source tree.  The following table is an extract from this file consisting of the codes which are meaningful in an inline asm block (a few are only useful in the machine description itself).</p>
<table class="asm">
<tr>
<td>f</td>
<td>Legacy FPA registers <code>f0-f7</code>.</td>
</tr>
<tr>
<td>t</td>
<td>The VFP registers <code>s0-s31</code>.</td>
</tr>
<tr>
<td>v</td>
<td>The Cirrus Maverick co-processor registers.</td>
</tr>
<tr>
<td>w</td>
<td>The VFP registers <code>d0-d15</code>, or <code>d0-d31</code> for VFPv3.</td>
</tr>
<tr>
<td>x</td>
<td>The VFP registers <code>d0-d7</code>.</td>
</tr>
<tr>
<td>y</td>
<td>The Intel iWMMX co-processor registers.</td>
</tr>
<tr>
<td>z</td>
<td>The Intel iWMMX GR registers.</td>
</tr>
<tr>
<td>l</td>
<td>In Thumb state the core registers <code>r0-r7</code>.</td>
</tr>
<tr>
<td>h</td>
<td>In Thumb state the core registers <code>r8-r15</code>.</td>
</tr>
<tr>
<td>j</td>
<td>A constant suitable for a MOVW instruction. (ARM/Thumb-2)</td>
</tr>
<tr>
<td>b</td>
<td>Thumb only.  The union of the low registers and the stack register.</td>
</tr>
<tr>
<td>I</td>
<td>In ARM/Thumb-2 state a constant that can be used as an immediate value in a Data Processing instruction.  In Thumb-1 state a constant in the range 0 to 255.</td>
</tr>
<tr>
<td>J</td>
<td>In ARM/Thumb-2 state a constant in the range -4095 to 4095.  In Thumb-1 state a constant in the range -255 to -1.</td>
</tr>
<tr>
<td>K</td>
<td>In ARM/Thumb-2 state a constant that satisfies the <code>I</code> constraint if inverted.  In Thumb-1 state a constant that satisfies the <code>I</code> constraint multiplied by any power of 2.</td>
</tr>
<tr>
<td>L</td>
<td>In ARM/Thumb-2 state a constant that satisfies the <code>I</code> constraint if negated.  In Thumb-1 state a constant in the range -7 to 7.</td>
</tr>
<tr>
<td>M</td>
<td>In Thumb-1 state a constant that is a multiple of 4 in the range 0 to 1020.</td>
</tr>
<tr>
<td>N</td>
<td>Thumb-1 state a constant in the range 0 to 31.</td>
</tr>
<tr>
<td>O</td>
<td>In Thumb-1 state a constant that is a multiple of 4 in the range -508 to 508.</td>
</tr>
<tr>
<td>Pa</td>
<td>In Thumb-1 state a constant in the range -510 to +510</td>
</tr>
<tr>
<td>Pb</td>
<td>In Thumb-1 state a constant in the range -262 to +262</td>
</tr>
<tr>
<td>Ps</td>
<td>In Thumb-2 state a constant in the range -255 to +255</td>
</tr>
<tr>
<td>Pt</td>
<td>In Thumb-2 state a constant in the range -7 to +7</td>
</tr>
<tr>
<td>G</td>
<td>In ARM/Thumb-2 state a valid FPA immediate constant.</td>
</tr>
<tr>
<td>H</td>
<td>In ARM/Thumb-2 state a valid FPA immediate constant when negated.</td>
</tr>
<tr>
<td>Da</td>
<td>In ARM/Thumb-2 state a const_int, const_double or const_vector that can be generated with two Data Processing insns.</td>
</tr>
<tr>
<td>Db</td>
<td>In ARM/Thumb-2 state a const_int, const_double or const_vector that can be generated with three Data Processing insns.</td>
</tr>
<tr>
<td>Dc</td>
<td>In ARM/Thumb-2 state a const_int, const_double or const_vector that can be generated with four Data Processing insns.  This pattern is disabled if optimizing for space or when we have load-delay slots to fill.</td>
</tr>
<tr>
<td>Dn</td>
<td>In ARM/Thumb-2 state a const_vector which can be loaded with a Neon vmov immediate instruction.</td>
</tr>
<tr>
<td>Dl</td>
<td>In ARM/Thumb-2 state a const_vector which can be used with a Neon vorr or vbic instruction.</td>
</tr>
<tr>
<td>DL</td>
<td>In ARM/Thumb-2 state a const_vector which can be used with a Neon vorn or vand instruction.</td>
</tr>
<tr>
<td>Dv</td>
<td>In ARM/Thumb-2 state a const_double which can be used with a VFP fconsts instruction.</td>
</tr>
<tr>
<td>Dy</td>
<td>In ARM/Thumb-2 state a const_double which can be used with a VFP fconstd instruction.</td>
</tr>
<tr>
<td>Ut</td>
<td>In ARM/Thumb-2 state an address valid for loading/storing opaque structure types wider than TImode.</td>
</tr>
<tr>
<td>Uv</td>
<td>In ARM/Thumb-2 state a valid VFP load/store address.</td>
</tr>
<tr>
<td>Uy</td>
<td>In ARM/Thumb-2 state a valid iWMMX load/store address.</td>
</tr>
<tr>
<td>Un</td>
<td>In ARM/Thumb-2 state a valid address for Neon doubleword vector load/store instructions.</td>
</tr>
<tr>
<td>Um</td>
<td>In ARM/Thumb-2 state a valid address for Neon element and structure load/store instructions.</td>
</tr>
<tr>
<td>Us</td>
<td>In ARM/Thumb-2 state a valid address for non-offset loads/stores of quad-word values in four ARM registers.</td>
</tr>
<tr>
<td>Uq</td>
<td>In ARM state an address valid in ldrsb instructions.</td>
</tr>
<tr>
<td>Q</td>
<td>In ARM/Thumb-2 state an address that is a single base register.</td>
</tr>
</table>
<h3>Operand codes</h3>
<p>Within the text of an inline asm block, operands are referenced as <code>%0</code>, <code>%1</code> etc. Register operands are printed as <code>rN</code>, memory operands as <code>[rN, #offset]</code>, and so forth.  In some situations, for example with operands occupying multiple registers, more detailed control of the output may be required, and once again, an undocumented feature comes to our rescue.</p>
<p>Special code letters inserted between the <code>%</code> and the operand number alter the output from the default for each type of operand.  The table below lists the more useful ones.</p>
<table class="asm">
<tr>
<td>c</td>
<td>An integer or symbol address without a preceding # sign</td>
</tr>
<tr>
<td>B</td>
<td>Bitwise inverse of integer or symbol without a preceding #</td>
</tr>
<tr>
<td>L</td>
<td>The low 16 bits of an immediate constant</td>
</tr>
<tr>
<td>m</td>
<td>The base register of a memory operand</td>
</tr>
<tr>
<td>M</td>
<td>A register range suitable for LDM/STM</td>
</tr>
<tr>
<td>H</td>
<td>The highest-numbered register of a pair</td>
</tr>
<tr>
<td>Q</td>
<td>The least significant register of a pair</td>
</tr>
<tr>
<td>R</td>
<td>The most significant register of a pair</td>
</tr>
<tr>
<td>P</td>
<td>A double-precision VFP register</td>
</tr>
<tr>
<td>p</td>
<td>The high single-precision register of a VFP double-precision register</td>
</tr>
<tr>
<td>q</td>
<td>A NEON quad register</td>
</tr>
<tr>
<td>e</td>
<td>The low doubleword register of a NEON quad register</td>
</tr>
<tr>
<td>f</td>
<td>The high doubleword register of a NEON quad register</td>
</tr>
<tr>
<td>h</td>
<td>A range of VFP/NEON registers suitable for VLD1/VST1</td>
</tr>
<tr>
<td>A</td>
<td>A memory operand for a VLD1/VST1 instruction</td>
</tr>
<tr>
<td>y</td>
<td>S register as indexed D register, e.g. <code>s5</code> becomes <code>d2[1]</code></td>
</tr>
</table>
]]></content:encoded>
			<wfw:commentRss>http://hardwarebug.org/2010/07/06/arm-inline-asm-secrets/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Hacking the Popcorn Hour C-200</title>
		<link>http://hardwarebug.org/2010/05/03/hacking-the-popcorn-hour-c-200/</link>
		<comments>http://hardwarebug.org/2010/05/03/hacking-the-popcorn-hour-c-200/#comments</comments>
		<pubDate>Mon, 03 May 2010 03:14:34 +0000</pubDate>
		<dc:creator>Mans</dc:creator>
				<category><![CDATA[Hardware]]></category>
		<category><![CDATA[MIPS]]></category>

		<guid isPermaLink="false">http://hardwarebug.org/?p=479</guid>
		<description><![CDATA[Update: A new firmware version has been released since the publication of this article. I do not know if the procedure described below will work with the new version. The Popcorn Hour C-200 is a Linux-based media player with impressive specifications. At its heart is a Sigma Designs SMP8643 system on chip with a 667MHz [...]]]></description>
			<content:encoded><![CDATA[<p><b>Update:</b> A new firmware version has been released since the publication of this article. I do not know if the procedure described below will work with the new version.</p>
<p>The <a href="http://www.popcornhour.com/onlinestore/index.php?pluginoption=productspec&#038;item_id=12">Popcorn Hour C-200</a> is a Linux-based media player with impressive specifications.  At its heart is a <a href="http://www.sigmadesigns.com/">Sigma Designs</a> <a href="http://www.sigmadesigns.com/products.php?id=35">SMP8643</a> system on chip with a 667MHz <a href="http://mips.com/products/cores/32-64-bit-cores/mips32-74k/">MIPS 74Kf</a> as main CPU, several co-processors, and 512MB of DRAM attached.  Gigabit Ethernet, SATA, and USB provide connectivity with the world around it.  With a modest $299 on the price tag, the temptation to repurpose the unit as a low-power server or cheap development board is hard to resist.  This article shows how such a conversion can be achieved.<br />
<span id="more-479"></span></p>
<h1>Kernel</h1>
<p>The PCH runs a patched Linux 2.6.22.19 kernel.  A <a href="http://www.networkedmediatank.com/download/firmware/nmt/gpl/linux-2.6.22.19.tar.bz2">source tarball</a> is available from the manufacturer. This contains the sources with Sigma support patches, <a href="http://www.kernel.org/pub/linux/kernel/people/ck/patches/2.6/2.6.22/2.6.22-ck1/">Con Kolivas&#8217; patch set</a> (scheduler tweaks), and assorted unrelated changes. Properly split patches are unfortunately not available.  I have created a reduced patch against vanilla 2.6.22.19 with only Sigma-specific changes, available <a href="http://hardwarebug.org/files/pch_hack/Sigma-Tango2-3-patches.patch.bz2">here</a>.</p>
<p>The installed kernel has a number of features disabled, notably PTY support and oprofile.  We will use <a href="http://linux.die.net/man/8/kexec">kexec</a> to load a more friendly one.</p>
<p>As might be expected, the PCH kernel does not have kexec support enabled.  It does however, by virtue of using closed-source components, support module loading.  This lets us turn kexec into a module and load it.  A patch for this is available <a href="http://hardwarebug.org/files/pch_hack/kexec-as-module-for-PCH-C-200.patch">here</a>.  To build the module, apply the patch to the PCH sources and build using <a href="http://hardwarebug.org/files/pch_hack/kexec_module_config">this configuration</a>.  This will produce two modules, <code>kexec.ko</code> and <code>mips_kexec.ko</code>.  No other products of this build will be needed.</p>
<p>The replacement kernel can be built from the PCH sources or, if one prefers, from vanilla 2.6.22.19 with the Sigma-only <a href="http://hardwarebug.org/files/pch_hack/Sigma-Tango2-3-patches.patch.bz2">patch</a>.  For the latter case, <a href="http://hardwarebug.org/files/pch_hack/kernel_config">this config</a> provides a minimal starting point suitable for NFS-root.</p>
<p>When configuring the kernel, make sure <code>CONFIG_TANGOX_IGNORE_CMDLINE</code> is enabled.  Otherwise the command line will be overridden by a useless one stored in flash.  A good command line can be set with <code>CONFIG_CMDLINE</code> (under &#8220;Kernel hacking&#8221; in <code>menuconfig</code>) or passed from kexec.</p>
<h1>Taking control</h1>
<p>In order to load our kexec module, we must first gain root privileges on the PCH, and here a few features of the system are working to our advantage:</p>
<ol>
<li>The PCH allows mounting any NFS export to access media files stored there.</li>
<li>There is an HTTP server running.  As root.</li>
<li>This HTTP server can be readily instructed to fetch files from an NFS mount.</li>
<li>Files with a name ending in .cgi are executed.  As root.</li>
</ol>
<p>All we need do to profit from this is place the kexec modules, the kexec userspace tools, and a simple script on an NFS export.  Once this is done, and the mount point configured on the PCH, a simple HTTP request will send the old kernel screaming to /dev/null, our shiny new kernel taking its place.</p>
<h1>The rootfs</h1>
<p>A kernel is mostly useless without a root filesystem containing tools and applications.  A number of tools for cross-compiling a full system exist, each with its strengths and weaknesses.  The only thing to look out for is the version of kernel headers used (usually a linux-headers package).  As we will be running an old kernel, chances are the default version is too recent.  Other than this, everything should be by the book.</p>
<h1>Assembling the parts</h1>
<p>Having gathered all the pieces, it is now time to assemble the hack.  The following steps are suitable for an NFS-root system.  Adaptation to a disk-based system is left as an exercise.</p>
<ol>
<li>Build a rootfs for MIPS 74Kf little endian.  Make sure kernel headers used are no more recent than 2.6.22.x.  Include a recent version of the kexec userspace tools.</li>
<li>Fetch and unpack the PCH <a href="http://www.networkedmediatank.com/download/firmware/nmt/gpl/linux-2.6.22.19.tar.bz2">kernel sources</a>.</li>
<li>Apply the modular kexec <a href="http://hardwarebug.org/files/pch_hack/kexec-as-module-for-PCH-C-200.patch">patch</a>.</li>
<li>Using <a href="http://hardwarebug.org/files/pch_hack/kexec_module_config">this config</a>, build the modules and install them as usual to the rootfs.  The version string must be 2.6.22.19-19-4.</li>
<li>From either the same kernel sources or plain 2.6.22.19 with Sigma <a href="http://hardwarebug.org/files/pch_hack/Sigma-Tango2-3-patches.patch.bz2">patches</a>, build a <code>vmlinux</code> and (optionally) modules using <a href="http://hardwarebug.org/files/pch_hack/kernel_config">this</a> config. Modify the compiled-in command line to point to the correct rootfs. Set the version string to something other than in the previous step.
<li>Copy <code>vmlinux</code> to any directory in the rootfs.</li>
<li>Copy <a href="http://hardwarebug.org/files/pch_hack/kexec.sh"><code>kexec.sh</code></a> and <a href="http://hardwarebug.org/files/pch_hack/kexec.cgi"><code>kexec.cgi</code></a> to the same directory as <code>vmlinux</code>.</li>
<li>Export the rootfs over NFS with full read/write permissions for the PCH.</li>
<li>Power on the PCH, and update to latest firmware.</li>
<li>Configure an NFS mount of the rootfs.</li>
<li>Navigate to the rootfs in the PCH UI.  A directory listing of <code>bin</code>, <code>dev</code>, etc. should be displayed.</li>
<li>On the host system, run the <code>kexec.sh</code> script with the target hostname or IP address as argument.</li>
<li>If all goes well, the new kernel will boot and mount the rootfs.</li>
</ol>
<h1>Serial console</h1>
<p>A serial console is indispensable for solving boot problems.  The PCH board has two UART connectors.  We will use the one labeled UART0. The pinout is as follows (not standard PC pinout).</p>
<pre>
        +-----------+
       2| * * * * * |10
       1| * * * * * |9
        \-----------+
          J7 UART0
    /---------------------/ board edge
</pre>
<table>
<tr style="text-align: left">
<th>Pin</th>
<th>Function</th>
</tr>
<tr>
<td>1</td>
<td>+5V</td>
</tr>
<tr>
<td>5</td>
<td>Rx</td>
</tr>
<tr>
<td>6</td>
<td>Tx</td>
</tr>
<tr>
<td>10</td>
<td>GND</td>
</tr>
</table>
<p>The signals are 3.3V so a converter, e.g. MAX202, is required for connecting this to a PC serial port.  The default port settings are 115200 bps 8n1.</p>
]]></content:encoded>
			<wfw:commentRss>http://hardwarebug.org/2010/05/03/hacking-the-popcorn-hour-c-200/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Nexus One</title>
		<link>http://hardwarebug.org/2010/03/19/nexus-one/</link>
		<comments>http://hardwarebug.org/2010/03/19/nexus-one/#comments</comments>
		<pubDate>Fri, 19 Mar 2010 03:41:48 +0000</pubDate>
		<dc:creator>Mans</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://hardwarebug.org/?p=465</guid>
		<description><![CDATA[I have had a Nexus One for about a week (thanks Google), and naturally I have an opinion or two about it. Hardware With the front side dominated by a touch-screen and a lone, round button, the Nexus One appearance is similar to that of most contemporary smartphones. The reverse sports a 5 megapixel camera [...]]]></description>
			<content:encoded><![CDATA[<p>I have had a <a href="http://www.google.com/phone">Nexus One</a> for about a week (thanks Google), and naturally I have an opinion or two about it.<br />
<span id="more-465"></span></p>
<h1>Hardware</h1>
<p>With the front side dominated by a touch-screen and a lone, round button, the Nexus One appearance is similar to that of most contemporary smartphones. The reverse sports a 5 megapixel camera with LED flash, a Google logo, and a smaller HTC logo. Power button, volume control, and headphone and micro-USB sockets are found along the edges. It is with appreciation I note the lack of a front-facing camera; the silly idea of video calls is finally put to rest.</p>
<p>Powering up the phone (I&#8217;m beginning to question the applicability of that word), I am immediately enamoured with the display. At 800&#215;480 pixels, the AMOLED display is crystal-clear and easily viewable even in bright light. In a darker environment, the display automatically dims. The display does have one quirk in that the subpixel pattern doesn&#8217;t actually have a full RGB triplet for each pixel. The close-up photo below shows the pattern seen when displaying a solid white colour.</p>
<p><img src="http://hardwarebug.org/wp-content/uploads/2010/03/img_3147.jpg" alt="Nexus One display close-up" title="Nexus One display close-up" width="214" height="200" class="aligncenter size-full wp-image-477" /></p>
<p>The result of this is that fine vertical lines, particularly red or blue ones, look a bit jagged. Most of the time this is not much of a problem, and I find it an acceptable compromise for the higher effective resolution it provides.</p>
<h1>Basic interaction</h1>
<p>The Android system is by now familiar, and the Nexus offers no surprises in basic usage. All the usual applications come pre-installed: browser, email, calendar, contacts, maps, and even voice calls. Many of the applications integrate with a Google account, which is nice. Calendar entries, map placemarks, etc. are automatically shared between desktop and mobile. Gone is the need for the bug-ridden custom synchronisation software with which mobile phones of the past were plagued.</p>
<p>Launching applications is mostly speedy, and recently used apps are kept loaded as long as memory needs allow. Although this garbage-collection-style of application management, where you are never quite sure whether an app is still running, takes a few moments of acclimatisation, it works reasonably well in day to day use. Most of the applications are well-behaved and save their data before terminating.</p>
<h1>Email</h1>
<p>Two email applications are included out of the box: one generic and one Gmail-only. As I do not use Gmail, I cannot comment on this application. The generic email client supports IMAP, but is rather limited in functionality. Fortunately, a much-enhanced version, <a href="http://code.google.com/p/k9mail/">K-9</a>, is available for download. The main feature I find lacking here is threaded message view.</p>
<p>The features, or lack thereof, in the email applications is not, however, of huge importance, as composing email, or any longer piece of text, is something one rather avoids on a system like this. The on-screen keyboard, while falling among the better of its kind, is still slow to use. Lack of tactile feedback means accidentally tapping the wrong key is easily done, and entering numbers or punctuation is an outright chore.</p>
<h1>Browser</h1>
<p>Whatever the Nexus lacks in email abilities, it makes up for with the browser. Surfing the web on a phone has never been this pleasant. Page rendering is quick, and zooming is fast and simple. Even pages not designed for mobile viewing are easy to read with smart reformatting almost entirely eliminating the sideways scrolling which hampered many a mobile browser of old.</p>
<h1>Calls and messaging</h1>
<p>Being a phone, the Nexus One is obviously able to make and receive calls, and it does so with ease. Entering a number or locating a stored contact are both straight-forward operations. During a call, audio is clear and of adequate loudness, although I have yet to use the phone in really noisy surroundings.</p>
<p>The other traditional task of a mobile phone, messaging, is also well-supported. There isn&#8217;t really much to say about this.</p>
<h1>Multimedia</h1>
<p>Having a bit of an interest in most things multimedia, I obviously tested the capabilities of the Nexus by throwing some assorted samples at it, revealing ample space for improvement. With video limited to H.264 and MPEG4, and the only supported audio codecs being AAC, MP3, Vorbis, and AMR, there are many files which will not play.</p>
<p>To make matters worse, only selected combinations of audio and video will play together. Several video files I tested played without sound, yet when presented with the very same audio data alone, it was correctly decoded. As for container formats, it appears restricted to MP4/MOV, and Ogg (for Vorbis). AVI files are recognised as media files, but I was unable to find an AVI file which would play.</p>
<p>With a device clearly capable of so much more, the poor multimedia support is nothing short of embarrassing.</p>
<h1>The Market</h1>
<p>Much of the hype surrounding Android revolves around the Market, Google&#8217;s virtual marketplace for app authors to sell or give away their creations. The thousands of available applications are broadly categorised, and a search function is available.</p>
<p>The categorised lists are divided into free and paid sections, while search results, disappointingly, are not. To aid the decision, ratings and comments are displayed alongside the summary and screenshots of each application. Overall, the process of finding and installing an application is mostly painless. While it could certainly be improved, it could also have been much worse.</p>
<p>The applications themselves are, as hinted above, beyond numerous. Sadly, quality does not quite match up to quantity. The vast majority of the apps are pointless, though occasionally mildly amusing, gimmicks of no practical value. The really good ones, and they do exist, are very hard to find unless one knows precisely what to look for.</p>
<h1>Battery</h1>
<p>Packing great performance into a pocket-size device comes with a price in battery life. The battery in the Nexus lasts considerably shorter time than that in my older, less feature-packed Nokia phone. To some extent this is probably a result of me actually using it a lot more, yet the end result is the same: more frequent recharging. I should probably get used to the idea of recharging the phone every other night.</p>
<h1>Verdict</h1>
<p>The Nexus One is a capable hardware platform running an OS with plenty of potential. The applications are still somewhat lacking (or very hard to find), although the basic features work reasonably well. Hopefully future Android updates will see more and better core applications integrated, and I imagine that over time, I will find third-party apps to solve my problems in a way I like. I am not putting this phone on the shelf just yet.</p>
]]></content:encoded>
			<wfw:commentRss>http://hardwarebug.org/2010/03/19/nexus-one/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Ogg objections</title>
		<link>http://hardwarebug.org/2010/03/03/ogg-objections/</link>
		<comments>http://hardwarebug.org/2010/03/03/ogg-objections/#comments</comments>
		<pubDate>Wed, 03 Mar 2010 14:17:07 +0000</pubDate>
		<dc:creator>Mans</dc:creator>
				<category><![CDATA[Multimedia]]></category>

		<guid isPermaLink="false">http://hardwarebug.org/?p=374</guid>
		<description><![CDATA[The Ogg container format is being promoted by the Xiph Foundation for use with its Vorbis and Theora codecs. Unfortunately, a number of technical shortcomings in the format render it ill-suited to most, if not all, use cases. This article examines the most severe of these flaws. Overview of Ogg The basic unit in an [...]]]></description>
			<content:encoded><![CDATA[<p>The Ogg container format is being promoted by the Xiph Foundation for use with its Vorbis and Theora codecs. Unfortunately, a number of technical shortcomings in the format render it ill-suited to most, if not all, use cases.  This article examines the most severe of these flaws.<br />
<span id="more-374"></span></p>
<h1>Overview of Ogg</h1>
<p>The basic unit in an Ogg stream is the <em>page</em> consisting of a header followed by one or more packets from a single elementary stream. A page can contain up to 255 packets, and a packet can span any number of pages. The following table describes the page header.</p>
<div class="frame-outer small">
<div style="text-align: left;">
<table>
<tr>
<th>Field</th>
<th>Size (bits)</th>
<th>Description</th>
</tr>
<tr>
<td>capture_pattern</td>
<td>32</td>
<td>magic number &#8220;OggS&#8221;</td>
</tr>
<tr>
<td>version</td>
<td>8</td>
<td>always zero</td>
</tr>
<tr>
<td>flags</td>
<td>8</td>
</tr>
<tr>
<td>granule_position</td>
<td>64</td>
<td>abstract timestamp</td>
</tr>
<tr>
<td>bitstream_serial_number</td>
<td>32</td>
<td>elementary stream number</td>
</tr>
<tr>
<td>page_sequence_number</td>
<td>32</td>
<td>incremented by 1 each page</td>
</tr>
<tr>
<td>checksum</td>
<td>32</td>
<td>CRC of entire page</td>
</tr>
<tr>
<td>page_segments</td>
<td>8</td>
<td>length of segment_table</td>
</tr>
<tr>
<td>segment_table</td>
<td>variable</td>
<td>list of packet sizes</td>
</tr>
</table>
</div>
</div>
<p>Elementary stream types are identified by looking at the payload of the first few pages, which contain any setup data required by the decoders. For full details, see the official <a href="http://xiph.org/ogg/">format specification</a>.</p>
<h1>Generality</h1>
<p>Ogg, legend tells, was designed to be a general-purpose container format. To most multimedia developers, a general-purpose format is one in which encoded data of any type can be encapsulated with a minimum of effort.</p>
<p>The Ogg format defined by the specification does not fit this description. For every format one wishes to use with Ogg, a complex <em>mapping</em> must first be defined. This mapping defines how to identify a codec, how to extract setup data, and even how timestamps are to be interpreted. All this is done differently for every codec. To correctly parse an Ogg stream, every such mapping ever defined must be known.</p>
<p>Under this premise, a centralised repository of codec mappings would seem like a sensible idea, but alas, no such thing exists. It is simply impossible to obtain a exhaustive list of defined mappings, which makes the task of creating a complete implementation somewhat daunting.</p>
<p>One brave soul, Tobias Waldvogel, created a mapping, OGM, capable of storing any Microsoft AVI compatible codec data in Ogg files. This format saw some use in the wild, but was <a href="http://www.xiph.org/container/ogm.html">frowned upon</a> by Xiph, and it was eventually displaced by other formats.</p>
<p>True generality is evidently not to be found with the Ogg format.</p>
<p>A good example of a general-purpose format is <a href="http://matroska.org/">Matroska</a>. This container can trivially accommodate any codec, all it requires is a unique string to identify the codec. For codecs requiring setup data, a standard location for this is provided in the container. Furthermore, an official list of codec identifiers is maintained, meaning all information required to fully support Matroska files is available from one place.</p>
<p>Matroska also has probably the greatest advantage of all: it is in active, wide-spread use. Historically, standards derived from existing practice have proven more successful than those created by a design committee.</p>
<h1>Overhead</h1>
<p>When designing a container format, one important consideration is that of overhead, i.e. the extra space required in addition to the elementary stream data being combined. For any given container, the overhead can be divided into a fixed part, independent of the total file size, and a variable part growing with increasing file size.  The fixed overhead is not of much concern, its relative contribution being negligible for typical file sizes.</p>
<p>The variable overhead in the Ogg format comes from the page headers, mostly from the <code>segment_table</code> field.  This field uses a most peculiar encoding, somewhat reminiscent of Roman numerals. In Roman times, numbers were written as a sequence of symbols, each representing a value, the combined value being the sum of the constituent values.</p>
<p>The <code>segment_table</code> field lists the sizes of all packets in the page. Each value in the list is coded as a number of bytes equal to 255 followed by a final byte with a smaller value. The packet size is simply the sum of all these bytes. Any strictly additive encoding, such as this, has the distinct drawback of coded length being linearly proportional to the encoded value.  A value of 5000, a reasonable packet size for video of moderate bitrate, requires no less than 20 bytes to encode.</p>
<p>On top of this we have the 27-byte page header which, although paling in comparison to the packet size encoding, is still much larger than necessary. Starting at the top of the list:</p>
<ul>
<li>The <code>version</code> field could be disposed of, a single-bit marker being adequate to separate this first version from hypothetical future versions. One of the unused positions in the <code>flags</code> field could be used for this purpose</li>
<li>A 64-bit <code>granule_position</code> is completely overkill. 32 bits would be more than enough for the vast majority of use cases. In extreme cases, a one-bit flag could be used to signal an extended timestamp field.</li>
<li>32-bit elementary stream number? Are they anticipating files with four billion elementary streams? An eight-bit field, if not smaller, would seem more appropriate here.</li>
<li>The 32-bit <code>page_sequence_number</code> is inexplicable. The intent is to allow detection of page loss due to transmission errors. ISO MPEG-TS uses a 4-bit counter per 188-byte packet for this purpose, and that format is used where packet loss actually happens, unlike any use of Ogg to date.</li>
<li>A mandatory 32-bit checksum is nothing but a waste of space when using a reliable storage/transmission medium. Again, a flag could be used to signal the presence of an optional checksum field.</li>
</ul>
<p>With the changes suggested above, the page header would shrink from 27 bytes to 12 bytes in size.</p>
<p>We thus see that in an Ogg file, the packet size fields alone contribute an overhead of 1/255 or approximately 0.4%. This is a hard lower bound on the overhead, not attainable even in theory. In reality the overhead tends to be closer to 1%.</p>
<p>Contrast this with the ISO MP4 file format, which can easily achieve an overhead of less than 0.05% with a 1 Mbps elementary stream.</p>
<h1>Latency</h1>
<p>In many applications end-to-end latency is an important factor. Examples include video conferencing, telephony, live sports events, interactive gaming, etc. With the codec layer contributing as little as <a href="http://x264dev.multimedia.cx/?p=249">10 milliseconds</a> of latency, the amount imposed by the container becomes an important factor.</p>
<p>Latency in an Ogg-based system is introduced at both the sender and the receiver. Since the page header depends on the entire contents of the page (packet sizes and checksum), a full page of packets must be buffered by the sender before a single bit can be transmitted. This sets a lower bound for the sending latency at the duration of a page.</p>
<p>On the receiving side, playback cannot commence until packets from all elementary streams are available. Hence, with two streams (audio and video) interleaved at the page level, playback is delayed by at least one page duration (two if checksums are verified).</p>
<p>Taking both send and receive latencies into account, the minimum end-to-end latency for Ogg is thus twice the duration of a page, triple if strict checksum verification is required. If page durations are variable, the maximum value must be used in order to avoid buffer underflows.</p>
<p>Minimum latency is clearly achieved by minimising the page duration, which in turn implies sending only one packet per page. This is where the size of the page header becomes important. The header for a single-packet page is <code>27 + packet_size/255</code> bytes in size. For a 1 Mbps video stream at 25 fps this gives an overhead of approximately 1%.  With a typical audio packet size of 400 bytes, the overhead becomes a staggering 7%. The average overhead for a multiplex of these two streams is 1.4%.</p>
<p>As it stands, the Ogg format is clearly not a good choice for a low-latency application. The key to low latency is small packets and fine-grained interleaving of streams, and although Ogg can provide both of these, by sending a single packet per page, the price in overhead is simply too high.</p>
<p>ISO MPEG-PS has an overhead of 9 bytes on most packets (a 5-byte timestamp is added a few times per second), and Microsoft&#8217;s ASF has a 12-byte packet header. My suggestions for compacting the Ogg page header would bring it in line with these formats.</p>
<h1>Random access</h1>
<p>Any general-purpose container format needs to allow random access for direct seeking to any given position in the file. Despite this goal being explicitly mentioned in the Ogg specification, the format only allows the most crude of random access methods.</p>
<p>While many container formats include an index allowing a time to be directly translated into an offset into the file, Ogg has nothing of this kind, the stated rationale for the omission being that this would require a two-pass multiplexing, the second pass creating the index. This is obviously not true; the index could simply be written at the end of the file. Those objecting that this index would be unavailable in a streaming scenario are forgetting that seeking is impossible there regardless.</p>
<p>The method for seeking suggested by the Ogg documentation is to perform a binary search on the file, after each file-level seek operation scanning for a page header, extracting the timestamp, and comparing it to the desired position. When the elementary stream encoding allows only certain packets as random access points (video key frames), a second search will have to be performed to locate the entry point closest to the desired time. In a large file (sizes upwards of 10 GB are common), 50 seeks might be required to find the correct position.</p>
<p>A typical hard drive has an average seek time of roughly 10 ms, giving a total time for the seek operation of around 500 ms, an annoyingly long time. On a slow medium, such as an optical disc or files served over a network, the times are orders of magnitude longer.</p>
<p>A factor further complicating the seeking process is the possibility of header emulation within the elementary stream data. To safeguard against this, one has to read the entire page and verify the checksum. If the storage medium cannot provide data much faster than during normal playback, this provides yet another substantial delay towards finishing the seeking operation. This too applies to both network delivery and optical discs.</p>
<p>Although optical disc usage is perhaps in decline today, one should bear in mind that the Ogg format was designed at a time when CDs and DVDs were rapidly gaining ground, and network-based storage is most certainly on the rise.</p>
<p>The final nail in the coffin of seeking is the codec-dependent timestamp format. At each step in the seeking process, the timestamp parsing specified by the codec mapping corresponding the current page must be invoked. If the mapping is not known, the best one can do is skip pages until one with a known mapping is found. This delays the seeking and complicates the implementation, both bad things.</p>
<h1>Timestamps</h1>
<p>A problem old as multimedia itself is that of synchronising multiple elementary streams (e.g. audio and video) during playback; badly synchronised A/V is highly unpleasant to view. By the time Ogg was invented, solutions to this problem were long since explored and well-understood. The key to proper synchronisation lies in tagging elementary stream packets with timestamps, packets carrying the same timestamp intended for simultaneous presentation. The concept is as simple as it seems, so it is astonishing to see the amount of complexity with which the Ogg designers managed to imbue it. So bizarre is it, that I have devoted an <a href="http://hardwarebug.org/2008/11/17/ogg-timestamps-explored/">entire article</a> to the topic, and will not cover it further here.</p>
<h1>Complexity</h1>
<p>Video and audio decoding are time-consuming tasks, so containers should be designed to minimise extra processing required. With the data volumes involved, even an act as simple as copying a packet of compressed data can have a significant impact. Once again, however, Ogg lets us down. Despite the brevity of the specification, the format is remarkably complicated to parse properly.</p>
<p>The unusual and inefficient encoding of the packet sizes limits the page size to somewhat less than 64 kB. To still allow individual packets larger than this limit, it was decided to allow packets spanning multiple pages, a decision with unfortunate implications. A page-spanning packet as it arrives in the Ogg stream will be discontiguous in memory, a situation most decoders are unable to handle, and reassembly, i.e. copying, is required.</p>
<p>The knowledgeable reader may at this point remark that the MPEG-TS format also splits packets into pieces requiring reassembly before decoding. There is, however, a significant difference there. MPEG-TS was designed for hardware demultiplexing feeding directly into hardware decoders. In such an implementation the fragmentation is not a problem. Rather, the fine-grained interleaving is a feature allowing smaller on-chip buffers.</p>
<p>Buffering is also an area in which Ogg suffers. To keep the overhead down, pages must be made as large as practically possible, and page size translates directly into demultiplexer buffer size. Playback of a file with two elementary streams thus requires 128 kB of buffer space. On a modern PC this is perhaps nothing to be concerned about, but in a small embedded system, e.g. a portable media player, it can be relevant.</p>
<p>In addition to the above, a number of other issues, some of them minor, others more severe, make Ogg processing a painful experience. A selection follows:</p>
<ul>
<li>32-bit random elementary stream identifiers mean a simple table-lookup cannot be used. Instead the list of streams must be searched for a match. While trivial to do in software, it is still annoying, and a hardware demultiplexer would be significantly more complicated than with a smaller identifier.</li>
<li>Semantically ambiguous streams are possible. For example, the continuation flag (bit 1) may conflict with continuation (or lack thereof) implied by the segment table on the preceding page. Such invalid files have been spotted in the wild.</li>
<li>Concatenating independent Ogg streams forms a valid stream. While finding a use case for this strange feature is difficult, an implementation must of course be prepared to encounter such streams. Detecting and dealing with these adds pointless complexity.</li>
<li>Unusual terminology: inventing new terms for well-known concepts is confusing for the developer trying to understand the format in relation to others. A few examples:<br />
<table style="text-align: left; width: 100%;">
<tr>
<th>Ogg name</th>
<th>Usual name</th>
</tr>
<tr>
<td>logical bitstream</td>
<td>elementary stream</td>
</tr>
<tr>
<td>grouping</td>
<td>multiplexing</td>
</tr>
<tr>
<td>lacing value</td>
<td>packet size (approximately)</td>
</tr>
<tr>
<td>segment</td>
<td>imaginary element serving no real purpose</td>
</tr>
<tr>
<td>granule position</td>
<td>timestamp</td>
</tr>
</table>
</li>
</ul>
<h1>Final words</h1>
<p>We have found the Ogg format to be a dubious choice in just about every situation. Why then do certain organisations and individuals persist in promoting it with such ferocity?</p>
<p>When challenged, three types of reaction are characteristic of the Ogg campaigners.</p>
<p>On occasion, these people will assume an apologetic tone, explaining how Ogg was only ever designed for simple audio-only streams (ignoring it is as bad for these as for anything), and this is no doubt true. Why then, I ask again, do they continue to tout Ogg as the one-size-fits-all solution they already admitted it is not?</p>
<p>More commonly, the Ogg proponents will respond with hand-waving arguments best summarised as <em id="notbad" onmouseover="document.getElementById('notbad').textContent='Ogg isn\'t dead, it\'s just resting'" onmouseout="document.getElementById('notbad').textContent='Ogg isn\'t bad, it\'s just different'">Ogg isn&#8217;t bad, it&#8217;s just different</em>. My reply to this assertion is twofold:</p>
<ul>
<li>Being too different <em>is</em> bad. We live in a world where multimedia files come in many varieties, and a decent media player will need to handle the majority of them. Fortunately, most multimedia file formats share some basic traits, and they can easily be processed in the same general framework, the specifics being taken care of at the input stage. A format deviating too far from the standard model becomes problematic.</li>
<li>Ogg <em>is</em> bad. When every angle of examination reveals serious flaws, bad is the only fitting description.</li>
</ul>
<p>The third reaction bypasses all technical analysis: <em>Ogg is patent-free</em>, a claim I am not qualified to directly discuss. Assuming it is true, it still does not alter the fact that <u>Ogg is a bad format</u>. Being free from patents does not magically make Ogg a good choice as file format. If all the standard formats are indeed covered by patents, the only proper solution is to design a new, good format which is not, this time hopefully avoiding the old mistakes.</p>
]]></content:encoded>
			<wfw:commentRss>http://hardwarebug.org/2010/03/03/ogg-objections/feed/</wfw:commentRss>
		<slash:comments>91</slash:comments>
		</item>
		<item>
		<title>Cat pictures</title>
		<link>http://hardwarebug.org/2010/02/21/cat-pictures/</link>
		<comments>http://hardwarebug.org/2010/02/21/cat-pictures/#comments</comments>
		<pubDate>Sun, 21 Feb 2010 20:19:07 +0000</pubDate>
		<dc:creator>Mans</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://hardwarebug.org/?p=362</guid>
		<description><![CDATA[It has come to my attention that this blog suffers a complete lack of the single most important thing on the Internet: cat pictures. Here is a feeble attempt to remedy this most shocking of shortfalls.]]></description>
			<content:encoded><![CDATA[<p>It has come to my attention that this blog suffers a complete lack of the single most important thing on the Internet: <b>cat pictures</b>.  Here is a feeble attempt to remedy this most shocking of shortfalls.</p>
<p><a href="http://hardwarebug.org/wp-content/uploads/2010/02/dsc00508.jpg"><img src="http://hardwarebug.org/wp-content/uploads/2010/02/dsc00508-300x184.jpg" alt="" title="Kitten" width="300" height="184" class="aligncenter size-medium wp-image-363" /></a><br />
<span id="more-362"></span><br />
<a href="http://hardwarebug.org/wp-content/uploads/2010/02/img_1195.jpg"><img src="http://hardwarebug.org/wp-content/uploads/2010/02/img_1195-300x200.jpg" alt="" title="Cat" width="300" height="200" class="aligncenter size-medium wp-image-367" /></a></p>
<p><a href="http://hardwarebug.org/wp-content/uploads/2010/02/img_1186.jpg"><img src="http://hardwarebug.org/wp-content/uploads/2010/02/img_1186-300x204.jpg" alt="" title="Another cat" width="300" height="204" class="aligncenter size-medium wp-image-368" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://hardwarebug.org/2010/02/21/cat-pictures/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>1080p video on Beagle</title>
		<link>http://hardwarebug.org/2010/02/10/1080p-video-on-beagle/</link>
		<comments>http://hardwarebug.org/2010/02/10/1080p-video-on-beagle/#comments</comments>
		<pubDate>Wed, 10 Feb 2010 01:22:35 +0000</pubDate>
		<dc:creator>Mans</dc:creator>
				<category><![CDATA[Multimedia]]></category>

		<guid isPermaLink="false">http://hardwarebug.org/?p=299</guid>
		<description><![CDATA[FOSDEM 2010 is over, and I&#8217;d like to call it a success for FFmpeg. The 11-man strong delegation showed the stunned audience a smashing demo featuring a Beagle-powered video wall. It looked like this: The people who pulled this off look like this:]]></description>
			<content:encoded><![CDATA[<p>FOSDEM 2010 is over, and I&#8217;d like to call it a success for <a href="http://ffmpeg.org/">FFmpeg</a>.  The 11-man strong delegation showed the stunned audience a smashing demo featuring a <a href="http://beagleboard.org/">Beagle</a>-powered video wall. It looked like this:</p>
<p><object class="frame-outer  size-full aligncenter" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="384" height="313" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/9pwUdRKllo0&amp;hl=en_US&amp;fs=1" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="384" height="313" src="http://www.youtube.com/v/9pwUdRKllo0&amp;hl=en_US&amp;fs=1" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p>The people who pulled this off look like this:</p>
<p style="text-align: center;"><a href="http://hardwarebug.org/wp-content/uploads/2010/02/img_3133.jpg"><img class="size-full wp-image-321 aligncenter" title="The FFmpeg team at FOSDEM 2010" src="http://hardwarebug.org/wp-content/uploads/2010/02/img_3133_small.jpg" alt="The FFmpeg team" width="384" height="256" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://hardwarebug.org/2010/02/10/1080p-video-on-beagle/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>IJG swings again, and misses</title>
		<link>http://hardwarebug.org/2010/02/01/ijg-swings-again-and-misses/</link>
		<comments>http://hardwarebug.org/2010/02/01/ijg-swings-again-and-misses/#comments</comments>
		<pubDate>Mon, 01 Feb 2010 16:18:24 +0000</pubDate>
		<dc:creator>Mans</dc:creator>
				<category><![CDATA[Multimedia]]></category>

		<guid isPermaLink="false">http://hardwarebug.org/?p=234</guid>
		<description><![CDATA[Earlier this month the IJG unleashed version 8 of its ubiquitous libjpeg library on the world. Eager to try out the &#8220;major breakthrough in image coding technology&#8221; promised in the README file accompanying v7, I downloaded the release. A glance at the README file suggests something major indeed is afoot: Version 8.0 is the first [...]]]></description>
			<content:encoded><![CDATA[<p>Earlier this month the <a href="http://ijg.org/">IJG</a> unleashed version 8 of its ubiquitous libjpeg library on the world. Eager to try out the &#8220;major breakthrough in image coding technology&#8221; <a href="http://hardwarebug.org/2009/08/04/ijg-is-back/">promised</a> in the README file accompanying v7, I downloaded the release. A glance at the README file suggests something major indeed is afoot:</p>
<blockquote><p>Version 8.0 is the first release of a new generation JPEG standard to overcome the limitations of the original JPEG specification.</p></blockquote>
<p>The text also hints at the existence of a <a href="http://jpegclub.org/temp/ITU-T-JPEG-Plus-Proposal_R3.doc">document</a> detailing these marvellous new features, and a Google search later a copy has found its way onto my monitor. As I read, however, my state of mind shifts from an initial excited curiosity, through bewilderment and disbelief, finally arriving at pure merriment.<br />
<span id="more-234"></span><br />
Already on the first page it becomes clear no new JPEG standard in fact exists. All we have is an unsolicited proposal sent to the ITU-T by members of the IJG. Realising that even the most brilliant of inventions must start off as mere proposals, I carry on reading. The summary informs me that I am about to witness the introduction of three extensions to the T.81 JPEG format:</p>
<ol>
<li>An alternative coefficient scan sequence for DCT coefficient serialization</li>
<li>A SmartScale extension in the Start-Of-Scan (SOS) marker segment</li>
<li>A Frame Offset definition in or in addition to the Start-Of-Frame (SOF) marker segment</li>
</ol>
<p>Together these three extensions will, it is promised, &#8220;bring DCT based JPEG back to the forefront of state-of-the-art image coding technologies.&#8221;</p>
<h3>Alternative scan</h3>
<p>The first of the proposed extensions introduces an alternative DCT coefficient scan sequence to be used in place of the zigzag scan employed in most block transform based codecs.</p>
<div id="attachment_239" class="wp-caption aligncenter" style="width: 335px"><img class="size-full wp-image-239" title="jpeg8-alt-scan" src="http://hardwarebug.org/wp-content/uploads/2010/02/jpeg8-alt-scan.png" alt="Alternative scan sequence" width="325" height="256" /><p class="wp-caption-text">Alternative scan sequence</p></div>
<p>The advantage of this scan would be that combined with the existing progressive mode, it simplifies decoding of an initial low-resolution image which is enhanced through subsequent passes. The author of the document calls this scheme  &#8220;image-pyramid/hierarchical multi-resolution coding.&#8221; It is not immediately obvious to me how this constitutes even a small advance in image coding technology.</p>
<p>At this point I am beginning to suspect that our friend from the IJG has been trapped in a half-world between interlaced GIF images transmitted down noisy phone lines and today&#8217;s inferno of SVC, MVC, and other buzzwords.</p>
<h3>(Not so) SmartScale</h3>
<p>Disguised behind this camel-cased moniker we encounter a method which, we are told, will provide better image quality at high compression ratios. The author has combined two well-known (to us) properties in a (to him) clever way.</p>
<p>The first property concerns the perceived impact of different types of distortion in an image. When encoding with JPEG, as the quantiser is increased, the decoded image becomes ever more blocky. At a certain point, a better subjective visual quality can be achieved by down-sampling the image before encoding it, thus allowing a lower quantiser to be used. If the decoded image is scaled back up to the original size, the unpleasant, blocky appearance is replaced with a smooth blur.</p>
<p>The second property belongs to the DCT where, as we all know, the top-left (DC) coefficient is the average of the entire block, its neighbours represent the lowest frequency components etc. A top-left-aligned subset of the coefficient block thus represents a low-resolution version of the full block in the spatial domain.</p>
<p>In his flash of genius, our hero came up with the idea of using the DCT for down-scaling the image. Unfortunately, he appears to possess precious little knowledge of sampling theory and human visual perception. Any block-based resampling will inevitably produce sharp artefacts along the block edges. The human visual system is particularly sensitive to sharp edges, so this is one of the most unwanted types of distortion in an encoded image.</p>
<p>Despite the obvious flaws in this approach, I decided to give it a try. After all, the software is already written, allowing downscaling by factors of 8/8..16.</p>
<p>Using a 1280&#215;720 <a href="http://hardwarebug.org/wp-content/uploads/2010/02/parkrun.png">test image</a>, I encoded it with each of the nine scaling options, from unity to half size, each time adjusting the quality parameter for a final encoded file size of no more than 200000 bytes. The following table presents the encoded file size, the libjpeg quality parameter used, and the <a href="http://en.wikipedia.org/wiki/Structural_similarity">SSIM</a> metric for each of the images.</p>
<table width="50%" align="center">
<tbody>
<tr style="text-align: left">
<th>Scale</th>
<th>Size</th>
<th>Quality</th>
<th>SSIM</th>
</tr>
<tr>
<td>8/8</td>
<td>198462</td>
<td>59</td>
<td>0.940</td>
</tr>
<tr>
<td>8/9</td>
<td>196337</td>
<td>70</td>
<td>0.936</td>
</tr>
<tr>
<td>8/10</td>
<td>196133</td>
<td>79</td>
<td>0.934</td>
</tr>
<tr>
<td>8/11</td>
<td>197179</td>
<td>84</td>
<td>0.927</td>
</tr>
<tr>
<td>8/12</td>
<td>193872</td>
<td>89</td>
<td>0.915</td>
</tr>
<tr>
<td>8/13</td>
<td>197153</td>
<td>92</td>
<td>0.914</td>
</tr>
<tr>
<td>8/14</td>
<td>188334</td>
<td>94</td>
<td>0.899</td>
</tr>
<tr>
<td>8/15</td>
<td>198911</td>
<td>96</td>
<td>0.886</td>
</tr>
<tr>
<td>8/16</td>
<td>197190</td>
<td>97</td>
<td>0.869</td>
</tr>
</tbody>
</table>
<p>Although the smaller images allowed a higher quality setting to be used, the SSIM value drops significantly. Numbers may of course be misleading, but the images below speak for themselves. These are cut-outs from the full image, the original on the left, unscaled JPEG-compressed in the middle, and JPEG with 8/16 scaling to the right.</p>
<div style="text-align: center;"><a href="http://hardwarebug.org/wp-content/uploads/2010/02/parkrun-cut1.png"><img class="alignnone size-full wp-image-246" title="Original" src="http://hardwarebug.org/wp-content/uploads/2010/02/parkrun-cut1.png" alt="" width="128" height="140" /></a><a href="http://hardwarebug.org/wp-content/uploads/2010/02/jpeg8-88-cut1.png"><img class="alignnone size-full wp-image-247" title="No scaling" src="http://hardwarebug.org/wp-content/uploads/2010/02/jpeg8-88-cut1.png" alt="" width="128" height="140" /></a><a href="http://hardwarebug.org/wp-content/uploads/2010/02/jpeg8-816-cut1.png"><img class="alignnone size-full wp-image-244" title="Scale 8/16" src="http://hardwarebug.org/wp-content/uploads/2010/02/jpeg8-816-cut1.png" alt="" width="128" height="140" /></a></div>
<div style="text-align: center;"><a href="http://hardwarebug.org/wp-content/uploads/2010/02/parkrun-cut2.png"><img class="alignnone size-full wp-image-255" title="Original" src="http://hardwarebug.org/wp-content/uploads/2010/02/parkrun-cut2.png" alt="" width="128" height="140" /></a><a href="http://hardwarebug.org/wp-content/uploads/2010/02/jpeg8-88-cut2.png"><img class="alignnone size-full wp-image-256" title="No scaling" src="http://hardwarebug.org/wp-content/uploads/2010/02/jpeg8-88-cut2.png" alt="" width="128" height="140" /></a><a href="http://hardwarebug.org/wp-content/uploads/2010/02/jpeg8-816-cut2.png"><img class="alignnone size-full wp-image-257" title="Scale 8/16" src="http://hardwarebug.org/wp-content/uploads/2010/02/jpeg8-816-cut2.png" alt="" width="128" height="140" /></a></div>
<p>Looking at these images, I do not need to hesitate before picking the JPEG variant I prefer.</p>
<h3>Frame offset</h3>
<p>The third and final extension proposed is quite simple and also quite pointless: a top-left cropping to be applied to the decoded image. The alleged utility of this feature would be to enable lossless cropping of a JPEG image. In a typical image workflow, however, JPEG is only used for the final published version, so the need for this feature appears quite far-fetched.</p>
<h3>The grand finale</h3>
<p>Throughout the text, the author makes references to &#8220;the fundamental DCT property for image representation.&#8221; In his own words:</p>
<blockquote><p>This property was found by the author during implementation of the new DCT scaling features and is after his belief one of the most important discoveries in digital image coding after releasing the JPEG standard in 1992.</p></blockquote>
<p>The secret is to be revealed in an annex to the main text. This annex quotes in full a post by the author to the comp.dsp Usenet group in a thread with the subject <a href="http://groups.google.com/group/comp.dsp/browse_frm/thread/4eb02c1d668daa7d">why DCT</a>. Reading the entire thread proves quite amusing. A few excerpts follow.</p>
<blockquote>
<div class="frame-outer small">
<div style="text-align: left;">The actual reason is much simpler, and therefore apparently very difficult to recognize by complicated-thinking people.<br/><br />
Here is the explanation:<br/><br />
What are people doing when they have a bunch of images and want a quick preview?  They use thumbnails!  What are thumbnails? Thumbnails are small downscaled versions of the original image! If you want more details of the image, you can zoom in stepwise by enlarging (upscaling) the image.</div>
</div>
</blockquote>
<blockquote>
<div class="frame-outer small">
<div style="text-align: left;">So with proper understanding of the fundamental DCT property, the MPEG folks could make their videos more scalable, but, as in the case of JPEG, they are unable to recognize this simple but basic property, unfortunately, and pursue rather inferior approaches in actual developments.</div>
</div>
</blockquote>
<blockquote>
<div class="frame-outer small">
<div style="text-align: left;">These are just phrases, and they don&#8217;t explain anything. But this is typical for the current state in this field: The relevant people ignore and deny the true reasons, and thus they turn in a circle and no progress is being made.</div>
</div>
</blockquote>
<blockquote>
<div class="frame-outer small">
<div style="text-align: left;">However, there are dark forces in action today which ignore and deny any fruitful advances in this field. That is the reason that we didn&#8217;t see any progress in JPEG for more than a decade, and as long as those forces dominate, we will see more confusion and less enlightenment. The truth is always simple, and the DCT *is* simple, but this fact is suppressed by established people who don&#8217;t want to lose their dubious position.</div>
</div>
</blockquote>
<p>I believe a trip to the <a href="http://en.wikipedia.org/wiki/Technology_in_The_Hitchhiker%27s_Guide_to_the_Galaxy#Total_Perspective_Vortex">Total Perspective Vortex</a> may be in order. Perhaps his tin-foil hat will save him.</p>
]]></content:encoded>
			<wfw:commentRss>http://hardwarebug.org/2010/02/01/ijg-swings-again-and-misses/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Bit-field badness</title>
		<link>http://hardwarebug.org/2010/01/30/bit-field-badness/</link>
		<comments>http://hardwarebug.org/2010/01/30/bit-field-badness/#comments</comments>
		<pubDate>Sat, 30 Jan 2010 16:15:05 +0000</pubDate>
		<dc:creator>Mans</dc:creator>
				<category><![CDATA[Compilers]]></category>
		<category><![CDATA[Optimisation]]></category>

		<guid isPermaLink="false">http://hardwarebug.org/?p=230</guid>
		<description><![CDATA[Consider the following C code which is based on an real-world situation. struct bf1_31 { unsigned a:1; unsigned b:31; }; void func(struct bf1_31 *p, int n, int a) { int i = 0; do { if (p[i].a) p[i].b += a; } while (++i &#60; n); } How would we best write this in ARM assembler? [...]]]></description>
			<content:encoded><![CDATA[<p>Consider the following C code which is based on an real-world situation.</p>
<blockquote>
<pre>struct bf1_31 {
    unsigned a:1;
    unsigned b:31;
};

void func(struct bf1_31 *p, int n, int a)
{
    int i = 0;
    do {
        if (p[i].a)
            p[i].b += a;
    } while (++i &lt; n);
}
</pre>
</blockquote>
<p>How would we best write this in ARM assembler? This is how I would do it:<br />
<span id="more-230"></span></p>
<blockquote>
<pre>func:
        ldr     r3,  [r0], #4
        tst     r3,  #1
        add     r3,  r3,  r2,  lsl #1
        strne   r3,  [r0, #-4]
        subs    r1,  r1,  #1
        bgt     func
        bx      lr
</pre>
</blockquote>
<p>The <code>add</code> instruction is unconditional to avoid a dependency on the comparison. Unrolling the loop would mask the latency of the <code>ldr</code> instruction as well, but that is outside the scope of this experiment.</p>
<p>Now compile this code with <code>gcc -march=armv5te -O3</code> and watch in horror:</p>
<blockquote>
<pre>func:
        push    {r4}
        mov     ip, #0
        mov     r4, r2
loop:
        ldrb    r3, [r0]
        add     ip, ip, #1
        tst     r3, #1
        ldrne   r3, [r0]
        andne   r2, r3, #1
        addne   r3, r4, r3, lsr #1
        orrne   r2, r2, r3, lsl #1
        strne   r2, [r0]
        cmp     ip, r1
        add     r0, r0, #4
        blt     loop
        pop     {r4}
        bx      lr
</pre>
</blockquote>
<p>This is nothing short of awful:</p>
<ul>
<li>The same value is loaded from memory twice.</li>
<li>A complicated mask/shift/or operation is used where a simple shifted add would suffice.</li>
<li>Write-back addressing is not used.</li>
<li>The loop control counts up and compares instead of counting down.</li>
<li>Useless <code>mov</code> in the prologue; swapping the roles or <code>r2</code> and <code>r4</code> would avoid this.</li>
<li>Using <code>lr</code> in place of <code>r4</code> would allow the return to be done with <code>pop {pc}</code>, saving one instruction (ignoring for the moment that no callee-saved registers are needed at all).</li>
</ul>
<p>Even for this trivial function the gcc-generated code is more than twice the optimal size and slower by approximately the same factor.</p>
<p>The main issue I wanted to illustrate is the poor handling of bit-fields by gcc. When accessing bitfields from memory, gcc issues a separate load for each field even when they are contained in the same aligned memory word. Although each load after the first will most likely hit L1 cache, this is still bad for several reasons:</p>
<ul>
<li>Loads have typically two or three cycles result latency compared to one cycle for data processing instructions. Any bit-field can be extracted from a register with two shifts, and on ARM the second of these can generally be achieved using a shifted second operand to a following instruction. The ARMv6T2 instruction set also adds the <code>SBFX</code> and <code>UBFX</code> instructions for extracting any signed or unsigned bit-field in one cycle.</li>
<li>Most CPUs have more data processing units than load/store units. It is thus more likely for an ALU instruction than a load/store to issue without delay on a superscalar processor.</li>
<li>Redundant memory accesses can trigger early flushing of store buffers rendering these less efficient.</li>
</ul>
<p>No gcc bashing is complete without a comparison with another compiler, so without further ado, here is the ARM RVCT output (<code>armcc --cpu 5te -O3</code>):</p>
<blockquote>
<pre>func:
        mov     r3, #0
        push    {r4, lr}
loop:
        ldr     ip, [r0, r3, lsl #2]
        tst     ip, #1
        addne   ip, ip, r2, lsl #1
        strne   ip, [r0, r3, lsl #2]
        add     r3, r3, #1
        cmp     r3, r1
        blt     loop
        pop     {r4, pc}
</pre>
</blockquote>
<p>This is much better, the core loop using only one instruction more than my version. The loop control is counting up, but at least this register is reused as offset for the memory accesses. More remarkable is the push/pop of two registers that are never used. I had not expected to see this from RVCT.</p>
<p>Even the best compilers are still no match for a human.</p>
]]></content:encoded>
			<wfw:commentRss>http://hardwarebug.org/2010/01/30/bit-field-badness/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>ARM compiler update</title>
		<link>http://hardwarebug.org/2010/01/15/arm-compiler-update/</link>
		<comments>http://hardwarebug.org/2010/01/15/arm-compiler-update/#comments</comments>
		<pubDate>Fri, 15 Jan 2010 18:48:38 +0000</pubDate>
		<dc:creator>Mans</dc:creator>
				<category><![CDATA[ARM]]></category>
		<category><![CDATA[Compilers]]></category>

		<guid isPermaLink="false">http://hardwarebug.org/?p=228</guid>
		<description><![CDATA[Since my last shootout,  all the tested vendors have updated their compilers. Here is a quick update on each of them. Both the 4.3 and 4.4 branches of FSF GCC have had bugfix releases, bringing them to 4.3.4 and 4.4.2, respectively. Neither update contains anything particularly noteworthy. The CodeSourcery 2009q3 release sees an update to [...]]]></description>
			<content:encoded><![CDATA[<p>Since my <a href="http://hardwarebug.org/2009/08/20/arm-compiler-shoot-out-round-2/">last shootout</a>,  all the tested vendors have updated their compilers. Here is a quick update on each of them.</p>
<p>Both the 4.3 and 4.4 branches of FSF GCC have had bugfix releases, bringing them to <a href="http://gcc.gnu.org/bugzilla/buglist.cgi?bug_status=RESOLVED&amp;resolution=FIXED&amp;target_milestone=4.3.4">4.3.4</a> and <a href="http://gcc.gnu.org/bugzilla/buglist.cgi?bug_status=RESOLVED&amp;resolution=FIXED&amp;target_milestone=4.4.2">4.4.2</a>, respectively. Neither update contains anything particularly noteworthy.</p>
<p>The CodeSourcery 2009q3 release sees an update to a GCC 4.4 base, a significant change from the 4.3 base used in 2009q1. The update is a mixed blessing. In fact, it is mostly a curse and hardly a blessing at all. On the bright side, the floating-point speed regressions in 2009q1 are gone, 2009q3 being a few per cent faster even than 2007q3. Unfortunately, this improvement is completely overshadowed by a major speed regression on integer code, a whopping 24% in one case. This ties in with the slowdown previously observed with FSF GCC 4.4 compared to 4.3.</p>
<p>ARM RVCT 4.0 is now at Build 697. This update fixes some bugs and introduces others. Notably, it no longer builds FFmpeg correctly. The issue has been reported to ARM.</p>
<p>Texas Instruments, finally, have made a formal release, v4.6.1, of their TMS470 compiler incorporating various fixes allowing it to build a moderately patched FFmpeg. The performance remains somewhere between GCC and RVCT on average.</p>
<p>In light of the above, my recommendations remain unchanged:</p>
<ul>
<li>For a free compiler, choose CodeSourcery 2009q1. It beats GCC 4.3.4 by 5-10% in most cases.</li>
<li>GNU purists are best served by GCC 4.3.4, which is up to 20% faster than 4.4.2 and rarely slower.</li>
<li>When price is not a concern, ARM RCVT is a good option, outperforming GCC by up to a factor 2.</li>
<li>In all cases, disable any auto-vectorisation features.</li>
</ul>
<p>Regardless of which compiler is chosen, I cannot overstress the importance of testing. All compilers are crawling with bugs, and even the most innocent-looking code change can trigger one of them. When using a compiler other than GCC, extra caution is advised considering a lot of code is developed using only GCC and may thus fall prey to bugs unique to said other compiler.</p>
]]></content:encoded>
			<wfw:commentRss>http://hardwarebug.org/2010/01/15/arm-compiler-update/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
