Bluish Coder

Programming Languages, Martials Arts and Computers. The Weblog of Chris Double.


2010-02-22

HTML 5 Video Element for Internet Explorer

Cristian Adam has been working on a plugin for Internet Explorer that implements the HTML 5 video element.

He has released a new version of the Xiph Ogg Codecs with a technical preview of the <video> element for IE. A screencast of it working is available at Cristian's website.

Tags: mozilla  video 

2010-02-20

Pure Preforking Echo Server Example

A few months back there were some examples of preforking servers implemented in various languages showing how posix API's could be used in those languages. Some examples were:

I'm learning the Pure programming language and took a stab at doing a Pure implementation. Pure comes with a good FFI for calling C functions and the needed posix calls are provided in the 'posix' library that comes with it.

It doesn't have any socket routines however but there is a library by Mike Maul called pure-lang-extras that provides this. With pure-lang-extras installed the preforking echo server looks like this:

using ffi, system;
using posix, posix::socket;
using namespace posix, posix::socket;

let sockfd = socket AF_INET SOCK_STREAM 0;
let yes = {1};
setsockopt sockfd SOL_SOCKET SO_REUSEADDR (int_pointer yes) (sizeof sint_t) 0;
let ai = make_sockaddr AF_INET "*" 5000;
bind_socket sockfd ai;
listen sockfd 10;

fork_child f = if pid == 0 then f pid $$ exit 0 else pid when pid = fork end;

child pid  =  fprintf file "Child %d echo> " getpid $$
              fflush file $$
              fprintf file "%s\n" (fgets file) $$
              fclose file $$
              child pid 
              when
                client = accept_socket sockfd ai;
                file = fdopen client "r+";
              end;

let children = [fork_child child|x=0..2];
do (printf "Forked: %d\n") children;
do (\n->(waitpid n NULL 0)) children;

This can be run (assuming it's in a file called 'test.pure') with:

$ pure -x test.pure
Forked: 10433
Forked: 10434
Forked: 10435

It will fork three worker processes all waiting on the same socket provided by the main process. The main process waits until all three worker processes complete or are killed. You can test it out by using telnet to port 5000:

$ telnet localhost 5000
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Child 10433 echo> test test test
test test test
Connection closed by foreign host.

If you do this a few times you'll see it cycle through the worker processes.

The example code mostly does posix calls and thin wrapper's around C functions so it doesn't show off much of the interesting parts of Pure. Pure has automatic currying (or partial evaluation) of functions by missing arguments from the function. For example, this code:

do (printf "Forked: %d\n") children;

printf is like the C printf function. It takes a format string followed by a tuple containing arguments for each format directive in that string. In the example above it has one of these, '%d'. The code (printf "Forked: %d\n") is missing the last argument expected to printf. Thanks to partial evaluation this evaluates to a function that takes one argument. do calls this function for each element in the children list, passing the list element to the function resulting in the printf call. It's equivalent to this more verbose code:

do (\n -> printf "Forked: %d\n" n) children;

Another Pure feature used is the ability to get raw pointers to matrices. The code {1} is a one row matrix containing one element, the interger '1'. A later line gets a raw pointer to this, converting it to a array of integers if it isn't already in that format: int_pointer yes.

To fork the child processes I use a list comprehension:

let children = [fork_child child|x=0..2];

0..2 is a short hand syntax to create a list of numbers from 0 to 2. The [...|....] is a list comprehension. The left hand side is called for each element of the right hand side and the result accumulated in a list. For example, at the Pure REPL:

> [x*2|x=0..5];
[0,2,4,6,8,10]

For more on Pure there is quite a bit of documentation:

Tags: pure 

2010-02-19

Comparing Colour Space Conversion Libraries

The libtheora api gives YCbCr data as the result of a decoded frame. The current method of displaying data through Firefox requires it to be converted to RGBA. The conversion of YCbCr to RGBA turns out to be a bottleneck.

In current Firefox builds we use the conversion routines provided by liboggplay. The Ogg backend is being modified to reduce the third party library usage (Started by me and continued now by Chris Pearce) 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.

I tested the following colour space conversion routines:

  • Using integer math and lookup tables.
  • A basic C version using floating point math.
  • liboggplay. BSD license.
  • FrameWave (also known as the AMD Performance Library). Apache License 2.0.
  • [Intel Integrated Performance Primitives] (http://software.intel.com/en-us/intel-ipp/). Commercial license.
  • Moonlight's colour space conversion routines. I tested the C and MMX implementation from Moonlight. LGPL2 license.
  • The conversion routines from Chromium. BSD license.
  • libswscale. LGPL license.

For testing I modified plogg 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:

Implementation Total Time Frame Time Relative
FrameWave 1.00752 0.00033584 0.65|
Chromium 1.02053 0.00034017 0.66|
Intel IPP (optimized) 1.32477 0.00044159 0.85|
Moonlight MMX 1.35934 0.00045311 0.87|
liboggplay 1.55765 0.00051921 1.00|
libswscale 2.68307 0.00089435 1.72|
Intel IPP (default) 4.21107 0.00140369 2.70|
Integer C 4.81204 0.00160401 3.09|
Moonlight C 6.80419 0.00226806 4.37|
Floating Point C 11.16770 0.00372257 7.17|

The 'Total Time' is the time spent in the conversion code for every frame in the file (3,000 frames). 'Frame Time' is the average time per frame. 'Relative' 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.

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's smaller and easier to integrate if we were to choose to use it. The 'default' Intel IPP version uses the non-processor specific implementation whereas the 'optimized' uses routines optimized for the particular processor on the machine I used for testing.

I'm interested in any comments on the libraries listed and recommendations for other libraries that I could try. I'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.

Tags: mozilla  video 

2010-02-18

On2 Stockholders Approve Google Merger

Last year Google announced that they were going to acquire On2 Technologies. This is the company that produced (and open sourced) the VP3 video codec that Theora is based on. Google wrote on their blog:

Although we'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' team and technology will help us further that goal.

The deal has been delayed awaiting approval of the majority of the On2 stockholders to agree on the acquisition. According to the On2 website this happened today:

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.

On2 stockholders holding in excess of a majority of the outstanding shares of On2 Common Stock voted in favor of the merger proposal.

It'll be interesting to see what comes from this. On2 have other video codecs. (VP6 used in Flash on some video sites, VP7 and their latest codec VP8.

Tags: mozilla  video 

2010-02-14

Dealing with my archived Blogger posts

I've stopped using Blogger for the weblog and have moved to using Jekyll.

I've set things up so I can edit the posts on my local push, push to my server using git and it publishes the new post.

Blogger provides a way to export all existing posts and comments as an XML file. I used this to manually import a few posts to test out Jekyll but then decided this was way to much work to convert everything. Instead I opted to create posts that link to my original Blogger ones so at least the archives and tags list in Jekyll will allow listing the posts and titles.

To import the existing archived blogger posts I wrote a program to read from the Blogger export file, extract the title, post tags/categories and existing URL and create Jekyll equivalents. It seems to have worked ok and I'll manually fix up any problems if I find them.

I wrote the importer in the Pure Programming Language to have a play with that language. I dabbled with it when it first came out but this was my first time using it in anger. It worked out pretty well. The core of the code to write out the posts looks like:

write_tag_header fd [] = ();
write_tag_header fd (x:xs) = fprintf fd "tags:\n" ();

write_tags fd (x:xs) = fprintf fd "  - %s\n" x $$ 
                       write_tags_fd xs;
write_tags fd [] = ();

create_post post = fprintf fd "---\n" () $$
                   fprintf fd "layout: post\n" () $$
                   fprintf fd "title: %s\n" title $$
                   write_tag_header fd tags $$
                   write_tags fd tags $$
                   fprintf fd "---\n" () $$
                   fprintf fd "Original Post [%s](%s)\n" (title,href) $$
                   fclose fd
                   when
                       filename = post_filename post;
                       fd = fopen filename "w";
                       title = article_title post;
                       href = article_url post;
                       tags = article_tags post;
                  end;

Basically I used the Pure XML library to get a list of posts (I use an XPATH expression to get the relevant parts of the post from the Blogger XML). For each post I then call create_post on it:

map create_post all_posts

I didn't go crazy and convert the actual HTML content into the markdown format I'm using fo the Jekyll posts and convert everything completely - maybe a task for another day.

Tags: misc  pure 


This site is accessable over tor as hidden service 6vp5u25g4izec5c37wv52skvecikld6kysvsivnl6sdg6q7wy25lixad.onion, or Freenet using key:
USK@1ORdIvjL2H1bZblJcP8hu2LjjKtVB-rVzp8mLty~5N4,8hL85otZBbq0geDsSKkBK4sKESL2SrNVecFZz9NxGVQ,AQACAAE/bluishcoder/-61/


Tags

Archives
Links