Planet Compsoc

February 13, 2010

Mulletron

Welcome

I’ve decided to move away from Warwick Blogs, on the grounds that I’ll soon be finishing my time at Warwick. Consequently True Contradictions has reached the end of the line. A new blog demands a new name, but I’m sticking with my theme of referencing Para Consistent Logic. Thats Marketing! Its worth linking directly back to my first blog post on True Contradictions.

Quite a lot has happened since then – I’ve graduated, Started a PhD, nearly finished a PhD, Friends have gotten married … but one thing remains the same. My commitment to intermittently writing overly long blog posts and about things that only I care about. I’d buy that for a dollar!

by admin at February 13, 2010 01:26 PM

Bucko

Adventures with DVDs

So I did some analysis on my evil MVM (UK) anime DVDs. I've worked out that they're basically unrepairable. They're run up to 25FPS from 24FPS without just speeding up the content (which is apparently usual), by interpolating fields. The idea is to make 25 ticks per 24 frames, and on tick n add n/25 of the "next" frame to 1-n/25 of the current one. In fact, this is done on fields, though the bottom field is on the opposite phase to the top field. The formula doesn't appear to be exactly linear in this way, but the principle is the same at least. The idea is presumably that on CRT TVs, you won't notice the preghost and postghost artefacts which are quickly covered up by the real content.

The overall result is that on average there's a 1/4 visible ghost on each field, and about 2/25 or more frames look heavily interlaced. Unlike the 3:2 telecine process used on US (NTSC/R1) DVDs, this process is not reversible (not strictly true; a perfect field of frame n can be subtracted from the field in frame n+1 in the correct ratio, then the resulting field multiplied -- but since it's encoded, any artefacts will end up getting added on, then multiplied up and used to derive the next frame). However, you can at least make it appear something other than awful.

Solution (for playback): Use a bob deinterlacer. With mplayer, this is -vf yadif=1 or -vf yadif=3.

Solution (for encoding): Either encode interlaced using -x264encopts interlaced (have fun with your increased bitrate), encode with a bob deinterlacer as above (have fun with your doubled framerate and increased bitrate), or use some other deinterlacer and suffer the drop in quality.

Solution (for screenshots): There is no solution. Sorry, if you own an MVM anime DVD you will never be able to post a full-resolution screenshot. Your best bet is to pick the field which is purest and obliterate the other one, giving a half-res image. You could also try working out the ratios and subtracting fields from the previous and next frames (example: if your frame is 0.7 * n + 0.3 * n+1, then 0.25 * n+1 + 0.75 * n+2 is next, you can remove 6/5 the next image, then add on some of the next one and so on; eventually you'll hit a full image but by that time I don't think you'll be enjoying the result).


Summary: If faced with a choice, and you want to take screenshots of a DVD, I would advise steering clear of any release encoded in this way. I've no idea how to check, but I'll make a list of all the DVDs I find like this. I imagine it's not just limited to anime.

February 13, 2010 11:34 AM

Faux

Catchlogger

Post seriousness: 70%.

Catchlogger [jar] [git src] checks that exceptions are being logged properly.

It’s entirely fallible, but, if your codebase is prone to catching and ignoring exception, and you use log4j, it’s Very Helpful.

For example:


try {
foo();
} catch (IOException e) {
logger.error("bar: failed to foo", e);
}

This is fine; an error has occurred and it’s full stacktrace will be placed in the log4j configured log.


try {
foo();
} catch (IOException e) {
logger.error(e);
logger.info("oh noes", e);
e.printStackTrace();
}

None of these, however, will do anything useful. The first logs just the toString() to the error log, info is too low-level to log exceptions at, and printStackTrace() doesn’t necessarily go anywhere at all.

For this block, catchlogger will issue:
IOException e unused at (Test.java:15) in public main(String[] args) in path.

The JAR is huge as it pulls in the entire Eclipse compiler to parse the source. BSD/MIT licensed.

by Faux at February 13, 2010 11:06 AM

Sinjo

Google are stealing my privacies!

I had my attention brought to another blog post earlier today (which for the purposes of this post, I shall assume you have read). Initially, my thoughts were that Google had gone and committed a rather large error, but I didn’t look too far into it as it wasn’t going to affect me and really had to set off towards home. When I arrived back I started talking about it to a friend, who immediately put me right. It turns out that Google Buzz is not exposing any new data to anyone without being allowed to. It is in fact aggregating already public data into, in my opinion, a pretty nice format.

What has happened here is a complete misunderstanding. Following the main example from that post (though it’s completely true of other services which Buzz can import from) Google Buzz will only display shared Google Reader items and comments that you publicly share. If these are private, then Google Buzz isn’t going to ruin your day and wave them around publicly.

To top this off, within Buzz there is actually a link (under Connected Sites, select Edit next to the Sharing With column) which takes you straight to the privacy options page, where you can go back and fix your earlier mistake of not correctly choosing your privacy settings. I’d actually say that, far from revealing your private data, Google have done a reasonable job of letting you protect your privacy in this case.

The hype that this has generated is rather saddening, and a reminder that people are all too quick to jump on the bandwagon. The author has posted a follow up, with a bit more explanation and as it turns out, a confirmation from Google of what I have focused on here (though this doesn’t have too much attention brought to it).

by Sinjo at February 13, 2010 01:14 AM

February 08, 2010

Blood God

Personal Projects Versus Work

Since I started work, I’ve found that I’ve done less and less work on any of the personal projects that I’ve picked up over time. As I write this, I can think of at least four different projects that I was going to do some work on when I next got an opportunity (such as today – as I’ve had the day off), but I’ve not touched in weeks at best. Of course, these opportunities don’t really come round all that often, as I don’t often have time after work (at least, not if I want to eat and get some sleep), and I always seem to end up otherwise engaged at weekends.

However, when I do have a day where I don’t really need to do anything and have the time to spare (like today) I inevitably end up wasting it through watching TV/films, playing on the XBox, or writing blogs like this. I’ve convinced myself that the main problem is that I spend 40+ hours a week in the office looking at one project or another there. This might involve writing actual code (as most of last week did), integrating various components to solve problems that way, performing analysis on what we need to do or any number of other activities, most of which are things I’d need to do on the personal projects. Given this, I guess I’ve been subconsciously avoiding doing anything on them as it seems too much like work.

Of course, by being apathetic in regard to these projects, they’re ever growing in number as I come up with an idea for something that I (or others) might find useful, and therefore add it to the list. A prime example is the Choob functionality I mentioned in passing in my previous entry about Code Style last month (which was a lot of hot air, and no real action), but there are also a whole load of other things that I’ve been thinking about for a while and should probably do something about.

So, what do I do about this? Well, I guess it all comes down to forcing myself to sit down and write some code, rather than wandering off and parking myself in front of the TV for an entire day. With this in mind I’m going to try and set aside a couple of hours each week (be it at the weekend, or one evening), where I can get something written. This will mean that I need to actually think about what needs doing, and break it up into suitable chunks – but that’s something that would need doing anyway if the projects are to avoid spiralling out of control.

I guess if I can manage that, then I should also be able to keep this blog a bit more up to date, especially with progress, so I may even start updating this more often. Of course, it could all fail miserably, so I guess we’ll just have to see!

by Chris Hawley at February 08, 2010 08:00 PM

February 04, 2010

Alp

HTML5 Theora Video Codec for Silverlight

I’m glad to announce the first release of our fully managed Theora audio / video decoder implementation for the Silverlight platform! The Highgate media suite will bring installation-free support for HTML5 streaming video to an additional ~40% of web users overnight.

Theora

So, a few drinks will be in order to celebrate the release at the FOSDEM beer event, Friday — drop by! And of course, I’d like to invite anyone excited about making open codecs a first class citizen of the Silverlight / Moonlight ecosystem to visit the Mono dev room over the weekend for source code and some frivolous demos between sessions.

Technology

We’ll be releasing a high-performance decoder for Theora video / Ogg Vorbis audio streams that plugs into the Silverlight 3 streaming media abstraction, as well as a reference front-end player interface and JavaScript bridge layer providing basic compatibility with standard HTML5 media tags, adding support for the standard to Internet Explorer and extending the capabilities of WebKit-based browsers like Safari and Epiphany. A cunning plan, one might say!

by alp at February 04, 2010 11:02 PM

February 03, 2010

Connorhd

WebApp – An Android experiment

After thinking about a JavaScript API to allow alerts on an Android phone in this post, I came up with a method of adding this using the current Java Android app API. The solution involves starting a Webkit instance in a custom app, and intercepting links with a certain prefix. In this example android://alert/description creates an alert with title “alert” and description “description”.

To demonstrate here are some screenshots of a sample page using a sample application (if you have an Android phone you can use that link to download it and try it yourself):

The application when you load it:

When clicking go an alert is created:

Viewing the created alert:

The example page is very simple javascript:

function go() {
	window.location = 'android://'+document.getElementById('title').value
		+'/'+document.getElementById('text').value;
}

The source for the app follows and is also fairly simple, most of the code is the rather complex way alerts are generated on Android:

package uk.co.connorhd.android.webapp;
 
import java.net.URLDecoder;
 
import uk.co.connorhd.android.webapp.R;
import uk.co.connorhd.android.webapp.WebApp;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;
 
public class WebApp extends Activity {
  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    WebView webview = new WebView(this);
 
    // We're testing, clear the cache.
    webview.clearCache(true);
 
    setContentView(webview);
 
    webview.getSettings().setJavaScriptEnabled(true);
 
    final Activity activity = this;
    webview.setWebViewClient(new WebViewClient() {
      int alert = 1;
 
      public void onReceivedError(WebView view, int errorCode,
          String description, String failingUrl) {
        Toast.makeText(activity, "Oh no! " + description,
            Toast.LENGTH_SHORT).show();
      }
 
      public boolean shouldOverrideUrlLoading(WebView view, String url) {
        // Is it a hack?
        if (url.startsWith("android")) {
          String ns = Context.NOTIFICATION_SERVICE;
          NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
          int icon = R.drawable.icon;
          CharSequence tickerText = "WebApp Alert!";
          long when = System.currentTimeMillis();
 
          Notification notification = new Notification(icon,
              tickerText, when);
          notification.flags = Notification.FLAG_AUTO_CANCEL;
          Context context = getApplicationContext();
 
          String[] split = url.split("/");
 
          CharSequence contentTitle = URLDecoder.decode(split[2]);
          CharSequence contentText = URLDecoder.decode(split[3]);
 
          Intent notificationIntent = new Intent(activity,
              WebApp.class);
          PendingIntent contentIntent = PendingIntent.getActivity(
              activity, 0, notificationIntent, 0);
 
          notification.setLatestEventInfo(context, contentTitle,
              contentText, contentIntent);
 
          mNotificationManager.notify(alert++, notification);
        } else {
          view.loadUrl(url);
        }
        return true;
      }
    });
 
    webview.loadUrl("http://connorhd.co.uk/files/WebApp.htm");
  }
}

This could easily be extended (and I may try to do this myself for Ircster) to provide all the standard browser functionality (for example the back button doesn’t currently work) and a more complete API to interface with Android.

by Connorhd at February 03, 2010 11:56 PM