<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>Bluish Coder: mozilla</title>
 <link href="http://bluishcoder.co.nz/tag/mozilla/atom.xml" rel="self"/>
 <link href="http://bluishcoder.co.nz/"/>
 <updated>2010-09-01T15:17:43+12:00</updated>
 <id>http://bluishcoder.co.nz/</id>
 <author>
   <name>Chris Double</name>
   <email>chris.double@double.co.nz</email>
 </author>

 
 <entry>
   <title>Experimental Playback Statistics for HTML Video and Audio</title>
   <link href="http://bluishcoder.co.nz/2010/08/24/experimental-playback-statistics-for-html-video-audio.html"/>
   <updated>2010-08-24T17:30:00+12:00</updated>
   <id>http://bluishcoder.co.nz/2010/08/24/experimental-playback-statistics-for-html-video-audio</id>
   <content type="html">&lt;p&gt;Now that HTML video is getting more usage there have been requests for statistics during playback so performance can be measured from JavaScript. This has come up a few times on &lt;a href='http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2010-May/026523.html'&gt;the WHATWG mailing list&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I raised &lt;a href='https://bugzilla.mozilla.org/show_bug.cgi?id=580531'&gt;bug 580531&lt;/a&gt; to add some additional data to media and video DOM elements to provide this information. The patch in that bug adds two attributes to the DOM HTMLVideoElement object, both prefixed by &amp;#8216;moz&amp;#8217; to prevent name clashes as they are experimental:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;interface nsIDOMHTMLVideoElement : nsIDOMHTMLMediaElement
{
   ...
   // A count of the number of frames that have been decoded and ready
   // to be displayed. This can be used for computing the decoding framerate
   readonly attribute unsigned long mozDecodedFrames;
 
   // A count of the number of frames that have been dropped for performance
   // reasons during playback.
   readonly attribute unsigned long mozDroppedFrames;
};&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;mozDecodedFrames is an incrementing count each time a frame is decoded and ready to be displayed. mozDroppedFrames is incremented each to a frame is dropped to keep playback going at the correct frame rate. These can be used to compute the current framerate that the video is being decoded at, and the framerate that it should be decoding at by combining the two counts. This will give client JavaScript code an indication if the hardware is able to play the video.&lt;/p&gt;

&lt;p&gt;Another requested feature is information on the download rate. Currently the Firefox implementation of HTML video and audio uses a non-standard extension to &amp;#8216;progress&amp;#8217; events. We provide information attached to the event that gives the current byte position in the media file as it downloads, and the total bytes available. This was actually required by the &lt;a href='http://www.whatwg.org/specs/web-apps/current-work/multipage/#video'&gt;WHATWG spec&lt;/a&gt; at one point but it changed a while back and I don&amp;#8217;t think any other browser implements it.&lt;/p&gt;

&lt;p&gt;This has been used in experimental pages to compute things like download rate and we use it in our own controls implementation to display a progress bar as we didn&amp;#8217;t implement the &amp;#8216;buffered&amp;#8217; attribute. &lt;a href='https://bugzilla.mozilla.org/show_bug.cgi?id=462957'&gt;Support for &amp;#8216;buffered&amp;#8217; has now landed&lt;/a&gt; so we want to &lt;a href='https://bugzilla.mozilla.org/show_bug.cgi?id=584615'&gt;remove the non-standard &amp;#8216;progress&amp;#8217; information&lt;/a&gt; to be spec compliant.&lt;/p&gt;

&lt;p&gt;To address the needs of those using the progress data for bandwidth calculation I&amp;#8217;ve added two attributes to HTMLMediaElement:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;interface nsIDOMHTMLMediaElement : nsIDOMHTMLElement
{
   ...
   // The approximate rate at which the media resource is being downloaded in
   // bytes per second. If the rate is not available (possibly due
   // to not having downloaded enough data to compute a consistent value)
   // this will be NaN.
   readonly attribute float mozDownloadRate;
 
   // The approximate rate at which the media resource is being decoded in
   // bytes per second. If the rate is not available this will be
   // NaN.
   readonly attribute float mozDecodeRate;
};&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;mozDownloadRate is an estimate, in bytes per second, of the current download rate of the media. If not enough information has been downloaded for a reliable estimate this will be NaN. mozDecodeRate provides the rate at which decoding is occurring. In the patch this is the length of the video divided by the duration and remains constant.&lt;/p&gt;

&lt;p&gt;Whether this gets landed is yet to be determined but I think the information is useful and I&amp;#8217;d be interested in any feedback on the data I&amp;#8217;ve decided to include. There is some feedback in the bug from the patch review already and there&amp;#8217;s plenty of time between now and when the Firefox 4 rush is over to look over ideas of what could be included, removed or changed. I &lt;a href='http://lists.whatwg.org/htdig.cgi/whatwg-whatwg.org/2010-August/027929.html'&gt;posted about the proposed additions&lt;/a&gt; in the WHATWG mailing list and there are some responses in that thread.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Safer C Code Using ATS</title>
   <link href="http://bluishcoder.co.nz/2010/06/02/safer-c-code-using-ats.html"/>
   <updated>2010-06-02T18:00:00+12:00</updated>
   <id>http://bluishcoder.co.nz/2010/06/02/safer-c-code-using-ats</id>
   <content type="html">&lt;p&gt;When developing the &lt;a href='/2008/07/theora-video-backend-for-firefox-landed.html'&gt;original Ogg backend for Firefox&lt;/a&gt; we had to integrate and use a number of C libraries. Over the months after landing a number of bugs were raised for various issues in the backend. A fair number of these were the result of common coding errors. Things like not checking return values of the C API calls and not releasing resources correctly. This was internal to the third party libraries we used as well as in our own code. This has made me interested in looking at programming languges that make these sorts of errors easier to find.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;ve &lt;a href='/tags/ats/'&gt;previously written&lt;/a&gt; about &lt;a href='http://ats-lang.org'&gt;ATS&lt;/a&gt;, a programming language with dependent and linear types. With ATS you can use C code directly and annotate the code with types to make some usage errors detectable at compile time. Some papers that cover this usage of ATS are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://portal.acm.org/citation.cfm?id=1707793&amp;amp;dl=ACM'&gt;Operating System Development with ATS&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://portal.acm.org/citation.cfm?id=1292597.1292605'&gt;Implementing Reliable Linux Device Drivers with ATS&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://www.ats-lang.org/PAPER/SPPSV-padl05.pdf'&gt;Safe Programming with Pointers through Stateful Views&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this post I look at ways of using a C library from &lt;a href='http://ats-lang.org'&gt;ATS&lt;/a&gt; that shows dealing with static checking of return values and resource releasing. I start from a simple wrapper and then explore how I can use ATS to make usage of the API safer from common programmer errors. The library I&amp;#8217;m using to do this is &lt;a href='http://curl.haxx.se/libcurl/'&gt;libcurl&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A simple usage of libcurl to retrieve the HTML from a URL and print it to stdout is (&lt;a href='/ats/curl/simple.c'&gt;simple.c&lt;/a&gt;):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#include &amp;lt;curl/curl.h&amp;gt;

int main(void)
{
  CURL *curl;
  CURLcode res;

  curl = curl_easy_init();
  curl_easy_setopt(curl, CURLOPT_URL, &amp;quot;bluishcoder.co.nz&amp;quot;);
  res = curl_easy_perform(curl);
  curl_easy_cleanup(curl);
  return 0;
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This can be compiled and run with:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ gcc -o simple simple.c `curl-config --libs`
$ ./simple
...&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id='ensuring_release_of_resources'&gt;Ensuring release of resources&lt;/h2&gt;

&lt;p&gt;My first attempt at translating this into ATS is in &lt;a href='/ats/curl/simple1.dats'&gt;simple1.dats&lt;/a&gt; (&lt;a href='/ats/curl/simple1.html'&gt;pretty-printed version&lt;/a&gt;):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;%{^
#include &amp;lt;curl/curl.h&amp;gt;
%}

absviewtype CURLptr (l:addr) // CURL*

abst@ype CURLoption = $extype &amp;quot;CURLoption&amp;quot;
macdef CURLOPT_URL = $extval(CURLoption, &amp;quot;CURLOPT_URL&amp;quot;)

extern fun curl_easy_init {l:addr}
  ()
  : CURLptr l = &amp;quot;#curl_easy_init&amp;quot;
extern fun curl_easy_setopt {l:addr} {p:type}
  (handle: !CURLptr l, option: CURLoption, parameter: p)
  : int = &amp;quot;#curl_easy_setopt&amp;quot;
extern fun curl_easy_perform {l:addr}
  (handle: !CURLptr l)
  : int = &amp;quot;#curl_easy_perform&amp;quot;
extern fun curl_easy_cleanup {l:addr}
  (handle: CURLptr l)
  : void = &amp;quot;#curl_easy_cleanup&amp;quot;

implement main() = let
  val curl  = curl_easy_init();
  val res = curl_easy_setopt(curl, CURLOPT_URL, &amp;quot;www.bluishcoder.co.nz&amp;quot;);
  val res = curl_easy_perform(curl);
  val () = curl_easy_cleanup(curl);
in
  ()
end;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &amp;#8216;main&amp;#8217; function looks very much like the C code. The definitions before that make the libcurl C functions, types and enums available to ATS. To compile and run this code:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ atscc -o simple1 simple1.dats `curl-config --libs`
$ ./simple1
..&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The libcurl type CURLoption is a C enum. To wrap this in ATS I use $extype to refer to the C name directly:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;abst@ype CURLoption = $extype &amp;quot;CURLoption&amp;quot;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I only reference one value of these types. That is CURLOPT_URL and again I reference the C value directly. Since this is a value rather than a type I use $extval:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;macdef CURLOPT_URL = $extval(CURLoption, &amp;quot;CURLOPT_URL&amp;quot;)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The CURL type is an abstract type in C - we don&amp;#8217;t care what it is actually composed of. A CURL object is always refered to via a pointer. This is modeled in ATS with:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;absviewtype CURLptr (l:addr) // CURL*&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Think of &amp;#8216;CURLptr&amp;#8217; as being &amp;#8216;a reference to a CURL object&amp;#8217;. It&amp;#8217;s basically a C &amp;#8216;CURL*&amp;#8217;. The definition above states that a CURLptr is an object of type &amp;#8216;CURLptr&amp;#8217; located at a memory address &amp;#8216;l&amp;#8217;.&lt;/p&gt;

&lt;p&gt;The C definition of curl_easy_init looks like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;CURL *curl_easy_init(void);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The ATS definition is:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;extern fun curl_easy_init {l:addr} () : CURLptr l = &amp;quot;#curl_easy_init&amp;quot; &lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &amp;#8216;extern&amp;#8217; at the beginning and the &amp;#8216;#curl_easy_init&amp;#8217; at the end means that the implementation of this function is a C function called &amp;#8216;curl_easy_init&amp;#8217; in an external library. The &amp;#8216;{l:addr}&amp;#8217; following the function name gives the type of the &amp;#8216;l&amp;#8217; used in the return type - that being a pointer. The return type is &amp;#8216;CURLptr l&amp;#8217; which I described previously. The function returns a CURLptr object located at pointer address &amp;#8216;l&amp;#8217;.&lt;/p&gt;

&lt;p&gt;The C definition of curl_easy_setopt looks like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...);&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It is a C function that takes a variable number of arguments. For this example I&amp;#8217;m only using one additional parameter so I cheat and declare it in ATS as accepting one. I&amp;#8217;ll cover how to do variable argument functions later. The ATS definition is:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;extern fun curl_easy_setopt {l:addr} {p:type}
  (handle: !CURLptr l, option: CURLoption, parameter: p)
  : int = &amp;quot;#curl_easy_setopt&amp;quot;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The function takes three arguments and returns one. The arguments it takes are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a &amp;#8216;!CURLptr l&amp;#8217;. As described before this is a CURLptr object located at address &amp;#8216;l&amp;#8217;. The &amp;#8217;!&amp;#8217; means curl_easy_setopt does not consume the object - we can continue to use it later. The &amp;#8216;l&amp;#8217; is declared to be of type &amp;#8216;addr&amp;#8217; earlier in the definition using {l:addr}.&lt;/li&gt;

&lt;li&gt;a &amp;#8216;CURLoption&amp;#8217;&lt;/li&gt;

&lt;li&gt;a parameter value of type &amp;#8216;p&amp;#8217;. This is of type &amp;#8216;type&amp;#8217; (from the {p:type} earlier in the definition). This is the type of all ATS objects that fit in a machine word (pointers, integers, etc).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The remaining two CURL functions used in the example are variants of these. The main difference is in the ATS definition of &amp;#8216;curl_easy_cleanup&amp;#8217;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;extern fun curl_easy_cleanup {l:addr}
  (handle: CURLptr l)
  : void = &amp;quot;#curl_easy_cleanup&amp;quot;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Here the &amp;#8216;handle&amp;#8217; parameter is a &amp;#8216;CURLptr l&amp;#8217;. There is no &amp;#8217;!&amp;#8217; before it. This means the function consumes the argument and it cannot be used after this call. The type &amp;#8216;CURLptr l&amp;#8217; is a linear type. It must be destroyed at some point in the program and once destroyed it cannot be re-used.&lt;/p&gt;

&lt;p&gt;By defining &amp;#8216;curl_easy_cleanup&amp;#8217; in this way we enforce a contract which states that the programmer must call this function if they have a live &amp;#8216;CURLptr l&amp;#8217; object. You can see this in practice if you remove the cleanup call and try to compile. A compile error will result. A compile error will also occur if you try to use the curl handle after the cleanup call.&lt;/p&gt;

&lt;p&gt;Because of the usage of the linear type we&amp;#8217;re already safe from one class of common programmer error. That of not calling cleanup functions for allocated objects.&lt;/p&gt;

&lt;h2 id='handling_null_pointers'&gt;Handling NULL pointers&lt;/h2&gt;

&lt;p&gt;There is a bug lurking in this version (and the C program). &amp;#8217;&lt;a href='http://curl.haxx.se/libcurl/c/curl_easy_init.html'&gt;curl_easy_init&lt;/a&gt;&amp;#8217; can return NULL and if it does you should not call any other curl functions. Using ATS we can define things in such a way that it is a requirement to check for NULL to successfully compile.&lt;/p&gt;

&lt;p&gt;A modified version of the example with the changes to support this is in &lt;a href='/ats/curl/simple2.dats'&gt;simple2.dats&lt;/a&gt; (&lt;a href='/ats/curl/simple2.html'&gt;pretty-printed version&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;In this version we expand on the type CURLptr by adding two typedefs. One for pointers which can be NULL (CURLptr0) and one for pointers which cannot be NULL (CURLptr1):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;absviewtype CURLptr (l:addr) // CURL*
viewtypedef CURLptr0 = [l:addr | l &amp;gt;= null] CURLptr l
viewtypedef CURLptr1 = [l:addr | l &amp;gt;  null] CURLptr l&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The definitions of the Curl functions that are used are changed to use these types in the appropriate places:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;extern fun curl_easy_init
  ()
  : CURLptr0 = &amp;quot;#curl_easy_init&amp;quot;
extern fun curl_easy_setopt {p:type}
  (handle: !CURLptr1, option: CURLoption, parameter: p)
  : int = &amp;quot;#curl_easy_setopt&amp;quot;
extern fun curl_easy_perform
  ( handle: !CURLptr1)
  : int = &amp;quot;#curl_easy_perform&amp;quot;
extern fun curl_easy_cleanup
  (handle: CURLptr1)
  : void = &amp;quot;#curl_easy_cleanup&amp;quot;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&amp;#8216;curl_easy_init&amp;#8217; is changed to return a CURLptr0 since it can return NULL. The other functions use CURLptr1 to signify they must not be NULL. Now if we keep the &amp;#8216;main&amp;#8217; function as before without checking the result of &amp;#8216;curl_easy_init&amp;#8217; we get a compile time error saying the type of the &amp;#8216;curl&amp;#8217; variable does not match that required by &amp;#8216;curl_easy_opt&amp;#8217;.&lt;/p&gt;

&lt;p&gt;The fix is to add a check for NULL:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;implement main() = let
  val curl = curl_easy_init();
  val () = assert_errmsg(CURLptr_isnot_null curl, &amp;quot;curl_easy_init failed&amp;quot;);
  val res = curl_easy_setopt(curl, CURLOPT_URL, &amp;quot;www.bluishcoder.co.nz&amp;quot;);
  val res = curl_easy_perform(curl);
  val ()  = curl_easy_cleanup(curl);
in
  ()
end;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The compiler knows that after the assert check that &amp;#8216;curl&amp;#8217; must not be NULL. This allows the remaining parts of the program to typecheck.&lt;/p&gt;

&lt;h2 id='enforce_checking_of_return_values'&gt;Enforce checking of return values&lt;/h2&gt;

&lt;p&gt;Another common error is that of not checking the return values of C api calls for errors. This proved to be an issue in the first versions of the Firefox Ogg video backend where return values were not checked in some of the third party libraries we were using. Types can be defined in ATS to give compile time errors if return values are not checked for errors.&lt;/p&gt;

&lt;p&gt;&amp;#8216;curl_easy_setopt&amp;#8217; and &amp;#8216;curl_easy_perform&amp;#8217; both return a value indicating success or failure. A non-zero value indicates an error.&lt;/p&gt;

&lt;p&gt;See &lt;a href='/ats/curl/simple3.dats'&gt;simple3.dats&lt;/a&gt; (&lt;a href='/ats/curl/simple3.html'&gt;pretty-printed version&lt;/a&gt;) for the changes required to enforce checking of the values. The definition of &amp;#8216;curl_easy_setopt&amp;#8217; has changed to:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;extern fun curl_easy_setopt {p:type}
  (handle: !CURLptr1 &amp;gt;&amp;gt; opt(CURLptr1, err == 0),
   option: CURLoption, parameter: p)
  : #[err:int] int err = &amp;quot;#curl_easy_setopt&amp;quot;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The same change was made to &amp;#8216;curl_easy_perform&amp;#8217;. The parameter &amp;#8216;handle&amp;#8217; has changed to have a type of &amp;#8216;!CURLptr1&amp;#160;&amp;#187; opt(CURLptr1, err == 0)&amp;#8217;. The type definition before the &amp;#8217;&amp;#187;&amp;#8217; is what the function accepts as input. After the &amp;#8217;&amp;#187;&amp;#8217; is the type of the parameter after the function returns.&lt;/p&gt;

&lt;p&gt;This says that after the function returns the type of &amp;#8216;handle&amp;#8217; is a &amp;#8216;CURLptr1&amp;#8217; if &amp;#8216;err&amp;#8217; is zero. &amp;#8216;err&amp;#8217; is defined later in the definition as an integer. This forces calling code to check the return value to see if it is zero. That code can then continue to use the CURLptr1 type by extracting it from the &amp;#8216;opt&amp;#8217;. This is the adjusted &amp;#8216;main&amp;#8217; function showing how this works:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;implement main() = let
  val curl = curl_easy_init();
  val () = assert_errmsg(CURLptr_isnot_null curl, &amp;quot;curl_easy_init failed&amp;quot;);
  val res = curl_easy_setopt(curl, CURLOPT_URL, &amp;quot;www.bluishcoder.co.nz&amp;quot;);
  val () = assert_errmsg(res = 0, &amp;quot;curl_easy_setopt failed&amp;quot;);
  prval () = opt_unsome(curl);
  val res = curl_easy_perform(curl);
  val () = assert_errmsg(res = 0, &amp;quot;curl_easy_perform failed&amp;quot;);
  prval () = opt_unsome(curl);
  val ()  = curl_easy_cleanup(curl);
in
 ()
end;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Notice the assertion check for the return value of the functions. This is followed by an &amp;#8216;opt_unsome&amp;#8217; call to &amp;#8216;un-opt&amp;#8217; the type and continue using it as a &amp;#8216;CURLptr1&amp;#8217;. If either the assert check, or the &amp;#8216;opt_unsome&amp;#8217; is commented out the code won&amp;#8217;t compile. If the assert check is done for a value other than zero it won&amp;#8217;t compile. The code could also check the result using an &amp;#8216;if&amp;#8217; statement - I use assert here for brevity.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Building Firefox with WebM support</title>
   <link href="http://bluishcoder.co.nz/2010/05/20/building-firefox-with-webm-support.html"/>
   <updated>2010-05-20T21:20:00+12:00</updated>
   <id>http://bluishcoder.co.nz/2010/05/20/building-firefox-with-webm-support</id>
   <content type="html">&lt;p&gt;All the patches to get Firefox built with &lt;a href='http://www.webmproject.org'&gt;WebM&lt;/a&gt; support have now been attached to their relevant bugs. These patches aren&amp;#8217;t ready for review yet but can be used to get a build that has the functionality of the &lt;a href='http://nightly.mozilla.org/webm'&gt;special Firefox WebM builds&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To build use &lt;a href='http://hg.mozilla.org/mozilla-central'&gt;Mozilla Central&lt;/a&gt; as the base with the patches from the following bugs applied:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='https://bugzilla.mozilla.org/show_bug.cgi?id=566241'&gt;Bug 566241 - Video playback stops intermittently&lt;/a&gt; - This has now landed in mozilla-central.&lt;/li&gt;

&lt;li&gt;&lt;a href='https://bugzilla.mozilla.org/show_bug.cgi?id=566498'&gt;Bug 566498 - Move generic video duration computing into Ogg decoder&lt;/a&gt; - This has now landed in mozilla-central.&lt;/li&gt;

&lt;li&gt;&lt;a href='https://bugzilla.mozilla.org/show_bug.cgi?id=566501'&gt;Bug 566501 - Fix seeks needed only by Ogg backend&lt;/a&gt; - This has now landed in mozilla-central.&lt;/li&gt;

&lt;li&gt;&lt;a href='https://bugzilla.mozilla.org/show_bug.cgi?id=567056'&gt;Bug 567056 - Rename some variables&lt;/a&gt; - This has now landed in mozilla-central.&lt;/li&gt;

&lt;li&gt;&lt;a href='https://bugzilla.mozilla.org/show_bug.cgi?id=566246'&gt;Bug 566246 - nestegg, the webm container parser we use&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='https://bugzilla.mozilla.org/show_bug.cgi?id=566247'&gt;Bug 566247 - libvpx, The VP8 SDK and associated build changes&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='https://bugzilla.mozilla.org/show_bug.cgi?id=566245'&gt;Bug 566245 - nsWebMDecoder implementation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hopefully these will be finished, reviewed and landed in short order.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>VP8, WebM and Firefox</title>
   <link href="http://bluishcoder.co.nz/2010/05/20/vp8-webm-firefox.html"/>
   <updated>2010-05-20T04:40:00+12:00</updated>
   <id>http://bluishcoder.co.nz/2010/05/20/vp8-webm-firefox</id>
   <content type="html">&lt;p&gt;For all the details on the recent announcing of VP8 video code support in Firefox, the WebM container and playing YouTube videos with Firefox, read &lt;a href='http://hacks.mozilla.org/2010/05/firefox-youtube-and-webm/'&gt;Firefox, YouTube and WebM&lt;/a&gt; on &lt;a href='http://hacks.mozilla.org'&gt;hacks.mozilla.org&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;More links:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://www.webmproject.org/'&gt;WebM Project&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://nightly.mozilla.org/webm'&gt;Firefox builds with WebM support&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://www.webmproject.org/users/'&gt;How to Play YouTube videos using WebM&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And don&amp;#8217;t forget the &lt;a href='http://labs.opera.com/news/2010/05/19/'&gt;Opera WebM builds&lt;/a&gt; and &lt;a href='http://build.chromium.org/buildbot/snapshots'&gt;Chromium builds&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To find WebM videos on YouTube:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Search using the YouTube search&lt;/li&gt;

&lt;li&gt;On the URL for the search and &amp;#8220;&amp;amp;webm=1&amp;amp;html5=1&amp;#8221; and visit that URL.&lt;/li&gt;

&lt;li&gt;Click on a video.&lt;/li&gt;

&lt;li&gt;Add to the end of that video URL: &amp;amp;html5=1&lt;/li&gt;

&lt;li&gt;Enjoy WebM goodness.&lt;/li&gt;

&lt;li&gt;Right click in Firefox on the video to get fullscreen.&lt;/li&gt;
&lt;/ol&gt;</content>
 </entry>
 
 <entry>
   <title>Fennec on Android</title>
   <link href="http://bluishcoder.co.nz/2010/04/28/fennec-on-android.html"/>
   <updated>2010-04-28T16:10:00+12:00</updated>
   <id>http://bluishcoder.co.nz/2010/04/28/fennec-on-android</id>
   <content type="html">&lt;p&gt;A pre-alpha build of Fennec, the mobile version of Firefox, is &lt;a href='http://blog.vlad1.com/2010/04/27/fennec-on-android-ground-zero/'&gt;available for Android devices&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Over the last few months, we&amp;#8217;ve made some great progress on bringing Firefox to Android. Michael Wu, Brad Lassey, Alex Pakhotin and I have been focusing on getting a build ready that&amp;#8217;s usable by a broader set of people, and we&amp;#8217;re now ready to get that build out there.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href='http://daringfireball.net/linked/2010/04/27/fennec'&gt;John Gruber comments&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It&amp;#8217;ll be interesting to see if Gecko can be turned into a worthy mobile competitor to WebKit.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Gecko already runs in a released mobile device. The &lt;a href='http://maemo.nokia.com/n900/'&gt;Nokia N900&lt;/a&gt; uses &lt;a href='http://en.wikipedia.org/wiki/MicroB'&gt;MicroB&lt;/a&gt; as its built in browser and that is based on Gecko. The web browser functionality of MicroB matches, if not exeeds, that of many WebKit based browsers on other mobiles which I think shows that Gecko can be a &amp;#8216;worthy competitor&amp;#8217;.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>HTML 5 Video Seeking and Redirects</title>
   <link href="http://bluishcoder.co.nz/2010/04/27/html5-video-seeking-and-redirects.html"/>
   <updated>2010-04-27T14:00:00+12:00</updated>
   <id>http://bluishcoder.co.nz/2010/04/27/html5-video-seeking-and-redirects</id>
   <content type="html">&lt;p&gt;&lt;a href='https://bugzilla.mozilla.org/show_bug.cgi?id=560806'&gt;Bug 560806&lt;/a&gt; has landed on trunk. Seeking and duration works for videos hosted on some servers where it didn&amp;#8217;t before.&lt;/p&gt;

&lt;p&gt;Firefox&amp;#8217;s implementation of HTML 5 video allows seeking in unbuffered portions of the video as long as the server that hosts the video supports byte range requests.&lt;/p&gt;

&lt;p&gt;Firefox needs to know in advance if it can seek the video so it can correctly display the &amp;#8216;progress&amp;#8217; bar. It also needs this information so it can compute the duration (which requires seeking into the video to find the end time).&lt;/p&gt;

&lt;p&gt;Most servers that support byte range requests send an &lt;a href='http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html'&gt;Accept-Ranges&lt;/a&gt; header. If we see this on the initial request we know the server supports seeking.&lt;/p&gt;

&lt;p&gt;Some servers support byte range requests but do not send this header. &lt;a href='http://aws.amazon.com/s3/'&gt;Amazon S3&lt;/a&gt; is an example of a server that does this. To detect if these servers support seeking we make our inital request for the video include a &amp;#8216;Range&amp;#8217; header that askes for the bytes from zero to the end of the file. Servers like S3 that support byte ranges will respond with a &amp;#8216;206&amp;#8217; response code meaning a partial request is returned. This is sent even though the byte range we asked for is actually for the entire file. Once we see the &amp;#8216;206&amp;#8217; we mark the resource as seekable.&lt;/p&gt;

&lt;p&gt;A very few servers don&amp;#8217;t send an Accept-Ranges header and recognize our byte range request as actually being for the entire file and return a &amp;#8216;200&amp;#8217; response code. Unfortunately we don&amp;#8217;t recognize resources hosted on these servers as seekable. This means Ogg media on these servers don&amp;#8217;t have a duration since we can&amp;#8217;t seek to find it.&lt;/p&gt;

&lt;p&gt;Another issue we came across, and exists in Firefox 3.5 and Firefox 3.6, is detecting seeking when the initial request for the media resource results in a &amp;#8216;3XX&amp;#8217; response code. This is a redirect to another URL. Current Firefox versions (and possibly other browsers) do not pass on the value of headers to the redirected URL. This means the &amp;#8216;Range&amp;#8217; header is removed and we don&amp;#8217;t get a &amp;#8216;206&amp;#8217; response code on the redirected request. In servers like Amazon S3 that don&amp;#8217;t send &amp;#8216;Accept-Ranges&amp;#8217; this means we don&amp;#8217;t support seeking.&lt;/p&gt;

&lt;p&gt;This is why videos hosted on Amazon S3 and similar serving platforms that arrive there via a redirect don&amp;#8217;t get a duration, show progress or allow seeking. It&amp;#8217;s a fairly common practice to hide the fact that Amazon S3 is being used by having a redirect from a URL on the web site domain that redirects to the S3 location which results in this problem.&lt;/p&gt;

&lt;p&gt;The following are two URL&amp;#8217;s that show the problem. The first is a direct link to the video. The second redirects to the final URL. In the first you can seek and see a duration of &amp;#8216;1:00&amp;#8217;. In the second you can&amp;#8217;t seek and no duration is shown:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://double.co.nz/video_test/no-redirect.html'&gt;No redirect&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://double.co.nz/video_test/redirect.html'&gt;Redirect&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is &lt;a href='https://bugzilla.mozilla.org/show_bug.cgi?id=560806'&gt;Bug 560806&lt;/a&gt; and has been fixed and is now on Firefox trunk and in the &lt;a href='http://ftp.mozilla.org/pub/mozilla.org/firefox/nightly/latest-trunk/'&gt;nightly builds&lt;/a&gt;. The fix was to explicitly pass the &amp;#8216;Range&amp;#8217; header along to the final URL. This workaround exists in a few other areas in Firefox and &lt;a href='https://bugzilla.mozilla.org/show_bug.cgi?id=311599'&gt;Bug 311599&lt;/a&gt; discusses a similar issue for plugins.&lt;/p&gt;

&lt;p&gt;If your own videos are not seekable or showing a duration then you may be facing a similar issue and it might be worthwhile trying a nightly build and seeing if that fixes it. Other things to look at are the server configuration to make sure that byte range requests are supported and the Accept-Ranges header is being sent. If you use Amazon S3 you might want to try and get them to support Accept-Ranges. &lt;a href='http://developer.amazonwebservices.com/connect/message.jspa?messageID=162333'&gt;This forum post&lt;/a&gt; discusses the issue.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Changes to Firefox YCbCr Color Conversion Code</title>
   <link href="http://bluishcoder.co.nz/2010/03/12/changes-to-firefox-ycbcr-code.html"/>
   <updated>2010-03-12T13:30:00+13:00</updated>
   <id>http://bluishcoder.co.nz/2010/03/12/changes-to-firefox-ycbcr-code</id>
   <content type="html">&lt;p&gt;I posted previously about &lt;a href='/2010/02/19/comparing-colour-space-conversion-libraries.html'&gt;colour conversion libraries&lt;/a&gt;. To replace the &lt;a href='http://wiki.xiph.org/OggPlay'&gt;liboggplay&lt;/a&gt; conversion routines we decided to try the &lt;a href='http://code.google.com/chromium/'&gt;Chromium&lt;/a&gt; libraries.&lt;/p&gt;

&lt;p&gt;&lt;a href='https://bugzilla.mozilla.org/show_bug.cgi?id=551277'&gt;Bug 551277&lt;/a&gt; adds the Chromium code and integrates it with the new &lt;a href='https://bugzilla.mozilla.org/show_bug.cgi?id=538323'&gt;video layer painting code&lt;/a&gt;. The Chromium code uses a C fallback if MMX is not available but this is done at compile time. I modified it do runtime detection using Mozilla&amp;#8217;s &lt;a href='http://mxr.mozilla.org/mozilla-central/source/xpcom/glue/SSE.h'&gt;SSE.h&lt;/a&gt; and moved the generic C routine from the Linux specific implementation to be used on all platforms that don&amp;#8217;t have MMX. Some other minor modifications were done (function name, namspacing).&lt;/p&gt;

&lt;p&gt;I added an &amp;#8216;update.sh&amp;#8217; script that can be used to update against the latest Chromium code. Given the path to the Chromium source it applies a patch for the changes I made.&lt;/p&gt;

&lt;p&gt;&lt;a href='https://bugzilla.mozilla.org/show_bug.cgi?id=551378'&gt;Bug 551378&lt;/a&gt; adds YCbCr 4:4:4 conversion (YV24). The Chromium code supported 4:2:0 and 4:2:2 (YV12 and YV16 respectively). Theora also allows 4:4:4 per spec. There aren&amp;#8217;t many 4:4:4 Theora videos out in the wild and the fix in this bug only adds support in the slower C implementation. I detect if the video is a 4:4:4 video and fallback to the C code.&lt;/p&gt;

&lt;p&gt;At some point optimized MMX routines should be done for this. I&amp;#8217;ve raised &lt;a href='https://bugzilla.mozilla.org/show_bug.cgi?id=551844'&gt;Bug 551844&lt;/a&gt; for this. This would probably make a good first bug for anyone who wants something small and self contained to work on. It would be good to contribute this back to Chromium when done too.&lt;/p&gt;

&lt;p&gt;Xiph has a &lt;a href='http://wiki.xiph.org/TheoraTestsuite'&gt;test suite&lt;/a&gt; with example videos in the different formats.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>HTML 5 Video Element for Internet Explorer</title>
   <link href="http://bluishcoder.co.nz/2010/02/22/html5-video-element-for-internet-explorer.html"/>
   <updated>2010-02-22T13:54:00+13:00</updated>
   <id>http://bluishcoder.co.nz/2010/02/22/html5-video-element-for-internet-explorer</id>
   <content type="html">&lt;p&gt;Cristian Adam has been working on a plugin for Internet Explorer that implements the &lt;a href='http://www.whatwg.org/specs/web-apps/current-work/multipage/video.html'&gt;HTML 5 video element&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;He has &lt;a href='http://cristianadam.blogspot.com/2010/02/ie-tag-take-two.html'&gt;released&lt;/a&gt; a new version of the Xiph Ogg Codecs with a technical preview of the &amp;#60;video&amp;#62; element for IE. A screencast of it working is available &lt;a href='http://cristianadam.blogspot.com/2010/02/ie-tag-take-two.html'&gt;at Cristian&amp;#8217;s website&lt;/a&gt;.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Comparing Colour Space Conversion Libraries</title>
   <link href="http://bluishcoder.co.nz/2010/02/19/comparing-colour-space-conversion-libraries.html"/>
   <updated>2010-02-19T17:00:00+13:00</updated>
   <id>http://bluishcoder.co.nz/2010/02/19/comparing-colour-space-conversion-libraries</id>
   <content type="html">&lt;p&gt;The &lt;a href='/2009/06/25/decoding-theora-files-using-libtheora.html'&gt;libtheora api&lt;/a&gt; gives &lt;a href='http://en.wikipedia.org/wiki/YCbCr'&gt;YCbCr data&lt;/a&gt; as the result of a decoded frame. The current method of displaying data through Firefox requires it to be converted to &lt;a href='http://en.wikipedia.org/wiki/RGBA_color_space'&gt;RGBA&lt;/a&gt;. The conversion of YCbCr to RGBA turns out to be a bottleneck.&lt;/p&gt;

&lt;p&gt;In current Firefox builds we use the conversion routines provided by &lt;a href='http://wiki.xiph.org/OggPlay'&gt;liboggplay&lt;/a&gt;. The Ogg backend is &lt;a href='https://bugzilla.mozilla.org/show_bug.cgi?id=531340'&gt;being modified&lt;/a&gt; to reduce the third party library usage (Started by me and continued now by &lt;a href='http://pearce.org.nz/'&gt;Chris Pearce&lt;/a&gt;) and the liboggplay usage will go away. I looked at some of the colour space conversion routines available to get an indication of their relative performance.&lt;/p&gt;

&lt;p&gt;I tested the following colour space conversion routines:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using integer math and lookup tables.&lt;/li&gt;

&lt;li&gt;A basic C version using floating point math.&lt;/li&gt;

&lt;li&gt;&lt;a href='http://wiki.xiph.org/OggPlay'&gt;liboggplay&lt;/a&gt;. BSD license.&lt;/li&gt;

&lt;li&gt;&lt;a href='http://framewave.sourceforge.net/'&gt;FrameWave&lt;/a&gt; (also known as the AMD Performance Library). Apache License 2.0.&lt;/li&gt;

&lt;li&gt;&lt;a href='http://software.intel.com/en-us/intel-ipp/'&gt;Intel Integrated Performance Primitives&lt;/a&gt;. Commercial license.&lt;/li&gt;

&lt;li&gt;&lt;a href='http://blog.sublimeintervention.com/archive/2008/Mar-21.html'&gt;Moonlight&amp;#8217;s colour space conversion routines&lt;/a&gt;. I tested the C and MMX implementation from Moonlight. LGPL2 license.&lt;/li&gt;

&lt;li&gt;The conversion routines from &lt;a href='http://code.google.com/chromium/'&gt;Chromium&lt;/a&gt;. BSD license.&lt;/li&gt;

&lt;li&gt;&lt;a href='http://git.mplayerhq.hu/?p=libswscale;a=summary'&gt;libswscale&lt;/a&gt;. LGPL license.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For testing I modified &lt;a href='http://github.com/doublec/plogg'&gt;plogg&lt;/a&gt; to decode a theora file and time the colour space conversion portion of the process. I have a series of command line switches to pick the implementation of the colour space conversion. I used a movie trailer Theora file I had handy (480x260) and these were the results:&lt;/p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Implementation&lt;/th&gt;&lt;th&gt;Total Time&lt;/th&gt;&lt;th&gt;Frame Time&lt;/th&gt;&lt;th&gt;Relative&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;FrameWave&lt;/td&gt;&lt;td style='text-align: right;'&gt;1.00752&lt;/td&gt;&lt;td style='text-align: right;'&gt;0.00033584&lt;/td&gt;&lt;td style='text-align: right;'&gt;0.65&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;Chromium&lt;/td&gt;&lt;td style='text-align: right;'&gt;1.02053&lt;/td&gt;&lt;td style='text-align: right;'&gt;0.00034017&lt;/td&gt;&lt;td style='text-align: right;'&gt;0.66&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;Intel IPP (optimized)&lt;/td&gt;&lt;td style='text-align: right;'&gt;1.32477&lt;/td&gt;&lt;td style='text-align: right;'&gt;0.00044159&lt;/td&gt;&lt;td style='text-align: right;'&gt;0.85&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;Moonlight MMX&lt;/td&gt;&lt;td style='text-align: right;'&gt;1.35934&lt;/td&gt;&lt;td style='text-align: right;'&gt;0.00045311&lt;/td&gt;&lt;td style='text-align: right;'&gt;0.87&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;liboggplay&lt;/td&gt;&lt;td style='text-align: right;'&gt;1.55765&lt;/td&gt;&lt;td style='text-align: right;'&gt;0.00051921&lt;/td&gt;&lt;td style='text-align: right;'&gt;1.00&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;libswscale&lt;/td&gt;&lt;td style='text-align: right;'&gt;2.68307&lt;/td&gt;&lt;td style='text-align: right;'&gt;0.00089435&lt;/td&gt;&lt;td style='text-align: right;'&gt;1.72&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;Intel IPP (default)&lt;/td&gt;&lt;td style='text-align: right;'&gt;4.21107&lt;/td&gt;&lt;td style='text-align: right;'&gt;0.00140369&lt;/td&gt;&lt;td style='text-align: right;'&gt;2.70&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;Integer C&lt;/td&gt;&lt;td style='text-align: right;'&gt;4.81204&lt;/td&gt;&lt;td style='text-align: right;'&gt;0.00160401&lt;/td&gt;&lt;td style='text-align: right;'&gt;3.09&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;Moonlight C&lt;/td&gt;&lt;td style='text-align: right;'&gt;6.80419&lt;/td&gt;&lt;td style='text-align: right;'&gt;0.00226806&lt;/td&gt;&lt;td style='text-align: right;'&gt;4.37&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;Floating Point C&lt;/td&gt;&lt;td style='text-align: right;'&gt;11.16770&lt;/td&gt;&lt;td style='text-align: right;'&gt;0.00372257&lt;/td&gt;&lt;td style='text-align: right;'&gt;7.17&lt;/td&gt;
&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;The &amp;#8216;Total Time&amp;#8217; is the time spent in the conversion code for every frame in the file (3,000 frames). &amp;#8216;Frame Time&amp;#8217; is the average time per frame. &amp;#8216;Relative&amp;#8217; is the time taken relative to the liboggplay implementation. Since this is what we are currently using this makes it easy to see what sort of improvement we could get by switching. The testing was done on a 1.83 GHz Core Duo laptop running Linux.&lt;/p&gt;

&lt;p&gt;From the results it seems that FrameWave and Chromium are the fastest and very close in performance. The license for the Chromium colour space conversion code is probably a bit better fit for our usage though and it&amp;#8217;s smaller and easier to integrate if we were to choose to use it. The &amp;#8216;default&amp;#8217; Intel IPP version uses the non-processor specific implementation whereas the &amp;#8216;optimized&amp;#8217; uses routines optimized for the particular processor on the machine I used for testing.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;m interested in any comments on the libraries listed and recommendations for other libraries that I could try. I&amp;#8217;ll put the source for the test program on github shortly and update this post with the link. Results from different machines would be useful.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>On2 Stockholders Approve Google Merger</title>
   <link href="http://bluishcoder.co.nz/2010/02/18/on2-stockholders-approve-google-merger.html"/>
   <updated>2010-02-18T15:00:00+13:00</updated>
   <id>http://bluishcoder.co.nz/2010/02/18/on2-stockholders-approve-google-merger</id>
   <content type="html">&lt;p&gt;Last year &lt;a href='http://googleblog.blogspot.com/2009/08/innovation-in-video-on-web.html'&gt;Google announced&lt;/a&gt; that they were going to acquire &lt;a href='http://www.on2.com'&gt;On2 Technologies&lt;/a&gt;. This is the company that produced (and open sourced) the VP3 video codec that Theora is based on. Google wrote on their blog:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Although we&amp;#8217;re not in a position to discuss specific product plans until after the deal closes, we are committed to innovation in video quality on the web, and we believe that On2 Technologies&amp;#8217; team and technology will help us further that goal.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The deal has been delayed awaiting approval of the majority of the On2 stockholders to agree on the acquisition. According to the On2 website &lt;a href='http://www.on2.com/index.php?id=472&amp;amp;news_id=698'&gt;this happened today&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;On2 Technologies, Inc. (NYSE Amex: ONT) today announced that its stockholders approved the merger of On2 with a wholly owned subsidiary of Google Inc. at its Reconvened Special Meeting held earlier today.&lt;/p&gt;

&lt;p&gt;On2 stockholders holding in excess of a majority of the outstanding shares of On2 Common Stock voted in favor of the merger proposal.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It&amp;#8217;ll be interesting to see what comes from this. On2 have other video codecs. (&lt;a href='http://en.wikipedia.org/wiki/VP6'&gt;VP6&lt;/a&gt; used in Flash on some video sites, &lt;a href='http://en.wikipedia.org/wiki/VP7'&gt;VP7&lt;/a&gt; and their latest codec &lt;a href='http://www.on2.com/index.php?id=439&amp;amp;news_id=641'&gt;VP8&lt;/a&gt;.&lt;/p&gt;</content>
 </entry>
 
 
</feed>
