Search This Blog

Loading...

Saturday, 13 April 2013

The Ultimate (and free) DVD / Blu-ray ripping Guide!

I've seen a few guides around on ripping DVDs, but fewer for Blu-rays, and many miss what I believe are important steps (such as ensuring the correct foreign language subtitles are preserved!) While ripping your entire DVD collection would have seemed insane due to storage requirements even a few years ago, these days it can make perfect sense.

This guide doesn't show you a one click approach that does all the work for you, it's much more of a manual process. But the benefits of putting a bit more effort in really do pay off - you get to use entirely free tools with no demo versions, it's reliable and works with all discs I've tried it with (bar one that was heavily scratched!), you get much more control over the quality / file size ratio and quality / encode time ratio, you can ensure any forced subtitles are correctly transferred across - the list goes on. You can also be sure that you get a high quality, completely DRM-free rip that you can do with as you choose without fear that some built in time bomb is going to stop the file from ever playing again if you transfer it to another computer.

Usual yada yada disclaimer that this isn't necessarily legal in your country, so check first and proceed with caution - I present this as a technical guide on the process only. If you are going to do it, just make a single personal copy.

Tools

I'll detail the tools used as we go, but it may make sense to install them ahead of time so you can follow the article more easily.

MakeMKV - We'll be using this to rip the raw files from the disc, this works with both Blu-rays and DVDs. If MakeMKV complains about not having a license key, grab the latest one from here.
Handbrake - We'll be using this to compress the file that MKV generates down to a more reasonable size.
VLC - We'll be using this to play / check the MKV files. Any media player that can play them will do, but if you're not sure grab this since it definitely does.

MKVExtract - We'll be using this to extract subtitle streams.
DVDs onlySubresync - We'll be using this to convert subtitles into a better format. Note: The download points to VobSub, of which Subresync is a part.
Blu-rays onlySuprip - As above, but for Blu-rays.


The Initial Rip

Put your disc in the drive and load up MakeMKV (get rip of any auto-playing DVD players that might pop up.) You should be presented with something like the following:



Select the correct optical drive from the list if you have more than one (unlikely these days) and then hit the big button. MakeMKV will then proceed to analyse your disc, which may well take a while - when it's done it'll show you the titles, like so:


There may be as few as one title, or tens of titles depending on the disc. If your DVD contains a film, then you want to select the title with the largest size (in this case that's the first one, 6.2GB.) If it's a TV show you're ripping, you should have selected one title for each episode, and they should all be around the same size (ish.) The other titles are likely extras we don't care about, so we'll deselect those. If there's any titles you're unsure about, just include them anyway - it'll take a bit longer to rip, but that's better than doing the whole disc again! 

Expand the view for your chosen title, and you'll likely see something like this:


Each title contains various tracks, and it's these tracks that you're seeing here - the video track is the one at the top (which you definitely want!) there's audio tracks in different languages, and various subtitle tracks. However, I'm not interested in most of these, so I can deselect them. Presuming you're English go ahead and deselect all apart from the audio track that says "English" and the subtitles tracks that say "English" (do this even if you don't care about subtitles, I'll explain later, honest!) Careful if there's more than one audio track that says English that you select the right one (there may be a couple of others, for instance directors commentaries or audio subtitles. The one you want is usually the first "English" one on the list, and usually the one with the highest quality audio (it's often the only one to have surround sound for instance.)

For Blu-rays the view looks slightly different but essentially the same:

The thing to make sure of here is that you select the "DTS-HD Lossless English" audio as well as the normal "DTS 3/2+1" subitem, to make sure you copy all the uncompressed audio across from the disc. You also have a better option with subtitles, in that you can just tick "English (forced only)" as I have here, rather than checking all the tracks.

Select an output folder for the files (I usually make a temporary folder on the desktop to store them in) then hit the Make MKV button, and wait! It has to pull all the data off the disc, so will take quite a while. On my machine it's usually around 20 minutes for a DVD, up to an hour for a Blu-ray. Yours may be longer though, so be patient!

Test the MKV files

When MakeMKV is finished, open each file in VLC and check it's what you think it is - you can then delete any MKV files from titles you don't want, and if you like rename any MKV files so you know what they are more easily (episode 1, episode 2) for instance.

You should now have a rip of whatever DVD or Blu-ray you chose, congratulations! However, take a look at the file size - it's likely huge (it may be around 6 or 7GB for a DVD, and around 30GB for a Blu-ray.) Rip your whole collection and leave it like that, and unless you have access to a colossal amount of storage, you'll run out of space rather quickly! You may also not want an MKV file, you may want something to play on your ipod or similar. The next steps will involve reducing the file size down to around 1/3 of what it is at the moment with no noticeable loss in quality (there are various tradeoffs in this sense over file size and quality, we'll get to those later.)

Checking the subtitles

This is important! This is the part that most guides miss, but can unknowingly wreck many films if you miss this bit out! What we'll do here is check whether the film has any forced subtitles, and if so translate them into a better format.

Forced subtitles are those that appear even when subtitles are normally disabled, and usually contain captions to translate foreign languages spoken by characters in a film. If you're sure that your chosen film or TV show contains no such captions then you can skip this step, but if you're not sure then follow it anyway to check, otherwise your rip may have large parts you can't understand! This page gives a rough idea of some films that have forced subs, but it's by no means comprehensive.

When MakeMKV is finished, you should have a folder with an MKV file in for each title (for films, this will likely just be one MKV.) Fire up the MKVExtract GUI, and drag the MKV file onto it. You'll get a screen that looks a bit like this:


Select each track that says subtitles, make sure "use source dir for output" is checked and then hit "Extract." (If you hit "English (force only)" and had a Blu-ray disc, and there's no subtitle tracks here, that's fine - it's because there's no forced subtitles and you can skip this step.) When it's done, you should then have a .idx and a .sub file (just a .sup file if you're doing this for a blu-ray) for each subtitle track in the same folder as the mkv file. Examine the size of these files (ignore any idx files for this step.) Take the largest file, which will probably be the full subtitles for the film. Now have a look at the other sub / sup files, is there any one that's significantly less (less than half the size) of the others? If there is, you've likely found your forced subtitle track, and this is the one you'll want to include in your final rip. If not and the files are all around the same size, then you can likely skip the rest of this step and continue.

However, there are times when the forced subtitles are mixed in the same track as the normal subtitles (rare, the only discs I've found that do this thus far are the Game of Thrones DVDs), so if that's the case you'll need to export the entire file and just save the forced subs to the srt file (covered later on.)

This is a typical example that does have a forced subtitle track from an episode of Game of Thrones (Blu-ray):

We can clearly see two sup files, one around 16MB and the other around 44KB. It's the late 44KB one that's the forced track in this case, used when the Dothraki are speaking (Game of Thrones viewers will know what I mean!) This is a particularly extreme example - the forced subtitle track only has two lines, so in many cases it may be larger (but in almost all cases, significantly smaller than the main subtitle track.)

If you used a Blu-ray and clicked the forced only option, you can bypass this check - if there is a sup file there then you have your forced track in front of you.

Of course, I'm assuming here that you don't want the full subtitle track, you may well do, for instance if the film is in a foreign language throughout - in this case, do the following for each subtitle track you want in your final rip.

You could just leave it at that, but here (this is the ultimate guide, after all!) we're going to convert to SRT format. SRT subtitles use text as the format rather than an image, which gives a number of advantages - it takes up much less space than an sub / sup track, you can customise the colour / font / size of the subtitles trivially within the application that's playing them, you can trivially make any corrections if there's spelling mistakes (has been known to happen!) and they will be rendered smoothly on any resolution screen. In the case of DVDs especialy SRT files look much better on any modern monitor or television, since they're rendered in the native resolution rather than displayed in scaled up, blocky 704x576 (we moved beyond that resolution in the 90's!) You'll also need to do this step if you're using Blu-rays, because handbrake doesn't yet (at least not at the time of writing, mid April 2013) support Blu-ray sup files directly.

Load up Subresync if you're ripping a DVD, or Suprip if you're ripping a Blu-ray. I'll be doing this with the sup file above, so will be using Suprip. Subresync works in pretty much the same way. Go ahead and open the file, you should end up with something like this:

The circles are of course my doing. Click on the OCR button (circled) and it will go through and convert the image to text, prompting you where it gets stuck. When it does, it will display the image of the letter (or punctuation mark) it's stuck on in the bottom right. Enter it in the box, hit "OK", then keep going until it has decoded the current frame. Move onto the next frame by clicking the right arrow (circled), hit "OCR" again, and repeat the process until done. It takes no more than a few minutes for most films to do things this way, and the benefits make it easily worth it in my opinion.

When done, hit the "SRT" tab, then the "Save" button. Save your SRT file somewhere (in the screenshot above that shows the files, you can see I jumped ahead a bit and saved it into this folder.) Open the SRT file in notepad if you wish just to double check you haven't made any spelling mistakes (you can modify the text how you wish, just don't change any of the timings.)

Repeat this process for each MKV file you have - in the case of TV shows, this may be a few per disc.

Transcoding / Compressing

 Almost there - just one more step! Open up handbrake and drag your MKV file onto it (ignore any warning that appears about automatically named output files.) If you have a subtitles track, click on the subtitles tab, click import SRT, select your SRT file in the drop down box, make sure the "Default" checkbox is selected then press "Add." You should end up with something like this:


When you've sorted the subtitles out, click the "Browse" button and select your destination location.

Don't click on "Start" just yet. You could, and you'd end up with a perfectly decent MKV or MP4 file on handbrake's default settings, but it may not be what you want.

Are you ripping this specifically for a device? If so, click on the preset on the right hand side and then click Start. These should encode relatively quickly, if you're unhappy with the result then just re-encode with the Video Quality slider set a bit higher - find it on the video tab (set it to something like 18 instead of 20 - yes, a lower number is better quality!)

However, if you're just ripping it to have as part of a media centre (which is what I do) then I'd recommend my process, which is adjusting the settings from Handbrake's default to the following:
  • Head over to the "Video" tab, and set the slider value there to 18. (I notice some blocking especially on fast action films when you leave it at 20. You may wish to experiment.)
  • Head over to the "Audio" tab, and select Auto-passthru:
This is important if you want surround sound - if you leave it at the default option it'll be downmixed to a reduced quality stereo. I only have a stereo setup of speakers at the moment, but I do this because if I did get a surround sound system, re-encoding every single DVD just so I can have surround sound would be a nightmare - better to do it right the first time! I'd suggest you do the same, unless you know you really definitely will never need surround sound in your rips and you want your rips to be as small as possible.
  • Select "MKV file" as the container - it's technically much more flexible and generally better than MP4, and all good media players now support it. A lot of people seem to ask "Where's AVI?!" at this point, and get very upset when they can't find it. Don't bother, it's a horrible antiquated format that can't hold separate tracks, can't support modern codecs and can't support any files larger than 2GB. It may be what you're used to, but these days it's really awful. Don't go looking for it, Handbrake doesn't support it any more!
  • Head over to the advanced tab, and in the textbox at the bottom replace the contents with the following:
ref=16:bframes=8:b-adapt=2:direct=auto:me=umh:merange=24:subq=10:rc-lookahead=60:analyse=all:trellis=2




Then you can hit "Start", and wait for your video to encode!

But hang on - what's that weird last step I told you to do? What's that text doing?

Essentially, that text is adjusting a load of advanced options that specify how the encoding works. I won't go into them here, but it essentially says "take a long time over the encode and do it thoroughly, giving me the best quality possible for the final file size." This means that encodes can take a long time. It's very CPU dependant, but as a guide my not-too-slouchy i5 machine takes about 12 hours per hour of Blu-ray footage to encode this way, and around 3 hours per hour of DVD footage. Now if you can't leave your computer on for this long you may want to omit the last step and you'll still end up with a perfectly decent file, just one that's not quite as efficient for the file size as it could be. Personally though my computer stays on 24/7 if it needs to, so I've no problem just leaving things running (don't forget you can queue up as many jobs as you like through handbrake) if it means I end up with a better file at the end of it. Only need to do the encode once!

How you set up handbrake is very much a personal choice, there's no right answer so don't be afraid to experiment around with the options.

When Handbrake is done, then there you have it - your very own DVD or Blu-ray rip!


Check the subtitles!

Yup, we're back with subtitles again, though this time it's just a precautionary measure - check that any forced subtitles you're expecting to show up, actually do show up. There seems to be a bug in Handbrake with subtitles that means under certain conditions (for me this happens often with Blu-rays but not with DVDs) they won't always get written in properly.

If this happens, then fire up MKVMerge (see "joining MKV files" for a description) and load in your transcoded file, deselect the text stream that's in the file, then click "add" and add in your SRT file. MKVMerge (at least under all conditions I've tested it with) seems to do this correctly every time, unlike Handbrake.



Joining MKV files

Most of the time you won't need this step at all - it only applies to a few films I know of (such as the Lord of the Rings extended editions.) But this is where ripping can really have an advantage, because there's no need to swap discs over half way through, or even MKV files - you can rip the discs separately and then join them together in one continuous file. To do this, you need to rip both discs with *exactly* the same settings all round in Handbrake (so if you follow the above guide to the letter you should be fine) and then use a tool called MKVMerge. (This is a fantastic tool that also lets you add things like extra subtitle and audio streams after you've ripped the file, but here we'll be using it to join two MKV files together.)

MKVMerge is part of the MKVToolnix suite, which you can grab from here. When it's installed, you want to run the "MKVMerge GUI".

Once you've got it running, appending the two files together is simple and doesn't take long at all. Just click the add button, then select the first MKV file, then click append (Note: that's append the second time not add!) and select the second MKV file. You should end up with something that looks like this:



Select the output filename (towards the bottom of the window), then click on "Start muxing" and the program will join the two files seamlessly. If it spits back any errors, it's probably becase the two files weren't encoded with exactly the same settings - so double check and try again.


Wrap-up

This may have seemed like an incredibly long process for ripping a disc, and some will say it's overkill. However, while it might take a while the first time, after ripping a few discs this way the process sped up significantly. When you get used to what to do, it really doesn't take long at all, and the results can be anything from a convenient ipod-playable file to a high quality home media centre setup where you can search through and browse available films using something like XBMC. Setting that up isn't too complicated in itself either - but that's for another post!

Tuesday, 5 March 2013

Annoyingly named methods

There's several annoyances I have with method names in the Java API - some are well documented as being ridiculous early design decisions that, well, couldn't be reverted without breaking backwards compatibility. Boolean.getBoolean() is a classic example for instance that really doesn't do what you'd expect.

However, there's another which is more recent that I haven't really heard complained about anywhere else. It's not a deal breaker by any stretch of the imagination, but it is a bad name, and it is mildly annoying.

I'm talking about the removeAll() method present on collection classes. It takes a collection of items to remove from that particular collection - pretty standard stuff. But to me, that should be called removeEach(),  removeAllOf(), or perhaps even just remove(), overloaded with the standard method that takes one parameter (to me the latter seems like the most logical choice.)

The problem I have with removeAll() is that it sounds like a method that you would call to do just that - remove all items from the collection. Wipe it. Now this isn't too bad, because if you get it wrong and call it with no arguments, it doesn't compile, and you can fix it pretty easily.

With JavaFX however, they've very helpfully added a var-args method with this name, that does the same thing. This may seem like a logical extension, but because it's a var-args method, passing no parameters, which does nothing, is a perfectly valid option. Not just at compile time, but at runtime as well. It all goes fine, apart from the method does absolutely nothing. It fails silently.

Perhaps a better implementation would have been to make it a two argument constructor, a "normal" reference to a parameter of type E, and then a var-arg list afterwards, essentially making it a "one or more" var-arg list. Granted, this would remove the ability to directly pass an array in - but an overloaded method expecting an array of that type could easily be added to get around that issue.

Anyway, rant over. Back to playing around with cubic Beizer curves for me!

Tuesday, 11 December 2012

JavaFX - some later thoughts

I've been using JavaFX for a while now, in a couple of projects - for my PhD work, and on the side for Quelea (whose interface has been migrated entirely from Swing over to JavaFX.) As promised, I thought I'd post a few follow up thoughts - good points / bad points now that I've been using it a while.

So, without further ado, the positives!

  • The API is nice and clean - and not just because it's not stuffed with deprecated methods like Swing is, it's just designed in a fundamentally much more sensible way which makes it easier to follow. The concept of properties on elements, with these properties having a common interface, means I can jump right in with a component and see what properties are available to me without having to dig in the documentation to find out exactly how to add a listener for the width of the bottom half of my split pane (for instance.)
  • Layout is vastly improved - a lot of the swing inconsistencies have gone, and the model is now a specific component is tied to a specific layout (HBox, VBox, GridPane and so on) rather than having a separate content pane which can have a layout applied to it. This again ties in with the first point, making for a much easier, nicer API without having to wonder exactly what, if any parameters I need to shove on the end to get the layout manager which I've selected (and what one was it, anyway?) to behave.
  • You can actually do animations with keyframes without resorting to horrible graphics2d hacks - and it's all GPU accelerated.
  • Multimedia support comes as standard, no need to play around with the buggy as hell Javasound or JMF.
  • UI work on the platform thread is enforced most of the time - a runtime exception is thrown if you don't do this, which makes it much easier to find and solve odd annoying concurrency bugs that would often crop up otherwise.
  • The default cross platform skin doesn't make me want to vomit. On the contrary, it actually does a good job of looking rather nice across a range of platforms. It's visually appealing and nicely animated too.
  • Nice native deployment options - they only work on the current platform (i.e. you can't build a deb package on a windows box) but still, I like the change of thought that users are generally much more comfortable with a custom built package for their OS rather than a generic jar / jnlp file.
Despite the above, it's not flawless:
  • The multimedia support is great - when it works. But it supports in reality a very limited range of formats and file types (no mkv at all for instance, some of my mp4 encoded videos still didn't work either.)
  • There's still a few annoying bugs I've come across, such as this one. Nothing that can't be sorted, but these sorts of things are annoying.
  • Some features just aren't there yet - I wanted a pop up panel similar to the ColorPane, but those components just don't exist yet (or at least aren't part of the public API.)
  • No rich text on controls, at least not yet. This gets really annoying if you want to (for instance) bold part of a label. Can't be done, you have to butt multiple labels together in a HBox to get that effect (which, let's face it, is nasty.)
  • No native skins - you can write your own, but at the moment (as far as I know) none are provided to make it look like the native platform you're working on. Some would argue this is a good thing, but sometimes it's nice to have this option.
  • No damn font metrics in the public API - again, something I have to use an internal class for at present (which is really rather annoying and means code I write at present potentially isn't backwards compatible.)
Overall, I must admit I still like it, and while I've uncovered more things I don't like from my initial positive reaction, most of those things are slated for inclusion in Java 8 (so in a year or so at the time of writing.) I still don't think it's going to take off on the mobile or web front - but as a replacement for Swing on the desktop, it's a very welcome (and arguably long overdue) change.

Thursday, 16 February 2012

Dropbox Java API

As well as being useful as general cloud storage, dropbox also has an API that lets you access its contents programmatically. It's a straightforward REST API with a number of language specific libraries to make the going a bit easier. Java is included on the list of SDKs, but at present only Android is included on the list of tutorials. This can be somewhat frustrating because simple examples using Java are lacking.

Fortunately, the process was described by Josh here. So I've taken it and implemented it in Java, and it seems to work. It's a very basic example that authenticates with dropbox then uploads a file called "testing.txt" containing "hello world."

Of course, more functionality is available than this, but this is the hard part (at least I found working this bit out the hard part.) Once you've got your DropboxAPI object, you can work most things from there using the supplied Javadoc.

/**
 * A very basic dropbox example.
 * @author mjrb5
 */
public class DropboxTest {

    private static final String APP_KEY = "APP KEY";
    private static final String APP_SECRET = "SECRET KEY";
    private static final AccessType ACCESS_TYPE = AccessType.APP_FOLDER;
    private static DropboxAPI<WebAuthSession> mDBApi;

    public static void main(String[] args) throws Exception {
        AppKeyPair appKeys = new AppKeyPair(APP_KEY, APP_SECRET);
        WebAuthSession session = new WebAuthSession(appKeys, ACCESS_TYPE);
        WebAuthInfo authInfo = session.getAuthInfo();

        RequestTokenPair pair = authInfo.requestTokenPair;
        String url = authInfo.url;

        Desktop.getDesktop().browse(new URL(url).toURI());
        JOptionPane.showMessageDialog(null, "Press ok to continue once you have authenticated.");
        session.retrieveWebAccessToken(pair);

        AccessTokenPair tokens = session.getAccessTokenPair();
        System.out.println("Use this token pair in future so you don't have to re-authenticate each time:");
        System.out.println("Key token: " + tokens.key);
        System.out.println("Secret token: " + tokens.secret);

        mDBApi = new DropboxAPI<WebAuthSession>(session);
        System.out.println();
        System.out.print("Uploading file...");
        String fileContents = "Hello World!";
        ByteArrayInputStream inputStream = new ByteArrayInputStream(fileContents.getBytes());
        Entry newEntry = mDBApi.putFile("/testing.txt", inputStream, fileContents.length(), null, null);
        System.out.println("Done. \nRevision of file: " + newEntry.rev);
        
    }
}

To use the token pair in future, instead of doing:
WebAuthSession session = new WebAuthSession(appKeys, ACCESS_TYPE);

You would do:
WebAuthSession session = new WebAuthSession(appKeys, ACCESS_TYPE, new AccessTokenPair(key, secret));

...where key and secret are the ones printed in the example above. You can then skip the rest of the auth code (up until you create the DropboxAPI object.)

Wednesday, 15 February 2012

Sometimes, older is better...

When I first started Quelea, I wanted to use it as a kind of testing ground for features and ideas that hadn't already been incorporated into church presentation software. Both in terms of the UI, features and functionality. A lot of these features have worked really well - the ability to import from survivor songbooks for instance, and the instant search that's further improved in the next release.

On the UI side of things I tried to have a go with the ribbon - it's still got a love/hate relationship with people, but I wondered if it could do any good in Quelea. So I had a go, implemented it and left it as such for a few releases.

Thing is, it just didn't work - and I think this was a 50:50 split between it not being suitable for Quelea and the flamingo implementation.

On the suitable for Quelea side:
  • For something that's often run on laptops with small screens, it took up a huge amount of space it didn't need to.
  • There weren't enough controls to make it viable. It works (ish) for office because it replaced a hugely complex menu system, but Quelea just doesn't have that complex menu system, and it won't for the foreseeable future. So it really just acted like a huge toolbar.
And on the flamingo side:
  • It was pretty unmaintained, which doesn't exactly add to my confidence.
  • It only integrated well with the substance look and feel, which users might not want to use.
  • It only integrated at all well with Windows, and Quelea is targetted at cross platform use.
  • It looked - well, odd. Most bits are there, but odd bits like the tight integration with the Window aren't, and that just makes it feel like something's not quite there with it. Combine this with the first point and it isn't going away any time soon either.
Perhaps there are some things I could've chosen to make it look better - like designing the UI in SWT rather than Swing (which has a much nicer looking ribbon.) But I've now replaced the ribbon with a standard set of toolbars and menus, and personally I think this looks much nicer. We'll see how it pans out in practice, but sometimes the older, traditional way is definitely the better one!

Wednesday, 11 January 2012

Java puzzler

You'll need an understanding of weak references to have a meaningful stab at this one.


public class Test {

public static void main(String[] args) {
List<byte[]> list = new ArrayList<byte[]>();

Object thing = new Object();
WeakReference<Object> ref = new WeakReference<Object>(thing);

while(ref.get()!=null) {
list.add(new byte[10000]);
}
System.out.println("bam");
}

}


Before reading any further give it a stab, see what you come up with. Then run it and see. Oh and yes, it compiles and runs.






...







Well, there's two possible options that you could have sensibly come up with. The first is what most people assume will always happen - the byte array will fill up to cause an OutOfMemoryError and the weak reference will never be garbage collected because there also exists a strong reference (thing) that remains in scope throughout the application and thus doesn't "let go" of the object. And indeed if you run it with early versions of Java, this is exactly what will happen.

However, with the latest version of JDK7 (update 2 at the time of writing) the program doesn't do the above, it prints out "bam" and exits cleanly. This initially seems weird - there's still a strong reference in scope so why on earth is it garbage collected?

It boils down to improvements in the JIT. It realises that the hard reference isn't actually used again, so sets it to null thus making it eligible for garbage collection. Put something like "thing.getClass();" as the last line of the program and it always forces the OutOfMemoryError because if that's the case the JIT can't make this optimisation. It's a behaviour that's actually explicitly covered in the JLS:

Optimizing transformations of a program can be designed that reduce the number of objects that are reachable to be less than those which would naively be considered reachable. For example, a compiler or code generator may choose to set a variable or parameter that will no longer be used to null to cause the storage for such an object to be potentially reclaimable sooner.


http://java.sun.com/docs/books/jls/third_edition/html/execution.html#12.6.1

The lesson? Objects can be garbage collected when the JIT decides they're no longer in use, and this may be earlier when it seems - and this in turn means that finalizers can be called when the object might trivially seem in-scope and thus ineligible for collection.

Saturday, 31 December 2011

Aparapi

The massive scalability of modern GPUs has led to many things, from Bitcoin mining to folding@home, seti@home and various other general purpose tasks that involve huge amounts of number crunching. While not as flexible as CPUs, what modern GPUs do they do incredibly fast and parallel thanks to the massive number of stream processors they contain.

I've long been impressed by the technology, and long known that to implement something using it you can use CUDA and/or OpenCL. For about the same amount of time there have been low level Java wrappers too that mean you can execute OpenCL without resorting to native languages - even if it meant you had to write the OpenCL directly and huge amounts of boilerplate code to interface with it. And a completely separate load of code for it to fall back on if the device didn't support OpenCL.

For about the same amount of time, I've thought that what we really need is a near transparent layer in (insert high level language of your choice here) which manages all the boilerplate / fallback code, OpenCL generation etc. for you. Of course, I could have sat down and looked at implementing it myself but I decided to wait for someone to do the hard work for me, thinking that it was inevitable that they would.

Fortunately I was correct, a bit of digging around today turned up Aparapi. It's an initiative started by AMD that enables to bring GPGPU programming to the average Joe Java developer completely transparent (almost) of any OpenCL calls and boilerplate. All it requires is for you to write your code inside a fabricated closure (anonymous inner class at present) and then call an execute method for the number of times you want it to run, in parallel. You can get the index of your essentially parallelised *loop* from within the kernel and crunch away on the GPU.

When lambdas come out of course there will be less boilerplate still - essentially having compresssed the hundreds of lines previously required to do this sort of thing with no more than a couple. Suddenly we've gone from stupidly hard and not worth doing to about as easy as it can get.

I envision this to be the first, but most important (and arguably hardest, but perhaps that's because I'm not a low level guy) step in providing the sort of transparent GPGPU access to Java that I continually dream of. The next step would be for API designers to take advantage of this technology in turn to produce classes like ParallelBufferedImage for instance. When this comes then ordinary Java folk will be able to utilise hugely parallel operations without so much as lifting a finger. We won't have to do anything different and all such API lifting will be done in the background, creating a huge (in some cases) but near invisible performance boost, just using one class rather than another.

Following on from that, the final step if it really takes on would be for it to be included in the API as standard. Possible? Sure. Likely? Who knows, but if so then it'd truly expose GPGPU to the masses.

Of course, that doesn't prohibit playing around until my completely transparent API-level pipe dream comes into play. Me being me I haven't actually got an OpenCL compatible card to try it out (I tend to live in the past a bit on the gaming front) but am thinking of ordering one just to have a play! And next step (naturally) is to see what we can integrate into Quelea to potentially speed that up with GPU hardware. It might even make my idea of keystone correction in software viable, we shall see! Perhaps 2012 will bring us a few more developments. Watch this space!