jPSXdec is a cross-platform PlayStation 1 media decoder/converter.
Get the latest version here.

Saturday, April 11, 2009

Through the Digital Looking Glass

While exhaustively reverse-engineering the Serial Experiments Lain game, always in the back of my mind was an article I read years ago. It describes some curious connections between Lain, and another game called Alice In Cyber Land.
http://www.cjas.org/~leng/alice.htm

So naturally, once the Lain game hacking was thoroughly complete, my attention quickly turned to finding the secrets Alice held.

The work to discover the unique ways the game stored its videos really paid off. The Alice videos were all well animated, and suggested a game that could be a lot of fun. But for now I must be content with its raw Japanese clips, all of which can now be viewed on Youtube.

The Alice In Cyber Land franchise didn't stop with the game. It also included a soundtrack, and short OVA. It seems at least episode 1 was fansubbed by a group called "Boot To Da Head" back in 1997. The first episode is now watchable in very low quality, raw Japanese.

While the connections between Lain and Alice are intriguing, you might be interested to know that they don't end there. Tucked away in a corner of the internet is a little account by one of the game's creators that extends the connections to one more series: Digimon Tamers.
http://www.konaka.com/alice6/tamers/characters/juri-e.html

Monday, April 6, 2009

CD-i

I was pleasantly surprised when I found someone concocted a clever way of using jPSXdec to decode CD-i audio.

As explained in Jonathan Atkins's CDXA documentation, the Sony Playstation 1 and the Phillips CD-i both used the same audio format on their CDs. It never occurred to me that the CD-i likely has a retro community still following it, much like the Playstation 1 does.

This video describes a working solution to extracting CD-i audio with jPSXdec that will work with any game. However, after the extraction, you have to manually break up the audio clips and possibly adjust the speed of some.

Alternatively, you could do the job that jPSXdec can't yet do so the extracted audio clips don't need any extra editing.

If you let jPSXdec do its best to index the CD (or raw music file), it will find all the audio sectors, but fails to concatenate most of the contiguous streams. You're left with several thousand audio clips with a duration of 1 sector. It wouldn't be too difficult to write a script that checks the audio properties (channel, frequency, etc) and finds what sectors should be combined into a single audio clip. It even sounds like someone has already managed to make some headway with this.

Adding better CD-i audio handling to jPSXdec is quite easy, and will be included in the next release (whenever I can get this redesign finished). As for CD-i video, I can't say I have much motivation (or time) to figure it out. But if anyone wants to get their hands dirty and write some decoding code of their own, I'd be happy to support them however I can.

Tuesday, January 27, 2009

Java real-time video playback

Much of the easy changes have already been made to jPSXdec. The biggest and hardest change left is implementing real-time playback. To do this in pure Java is tricky. I've spent a month looking at every kind of Java video player out there.

I want to keep jPSXdec as cross-platform and simple-to-use as possible (Just Work™). So while the JMF has Java-only implementations for playback, it needs a separate installation, has far more functionality that I need, and being closed source doesn't help. It's curious that even though the JMF has plenty of documented bugs, and hasn't been updated in years, it's still the de facto Java media standard. Meanwhile, the FMJ library is open source, but it's even bigger than JMF, and uses JNI to wield each platform's native playing capabilities. I've examined various other small libraries, but nothing met my needs: a simple synchronized audio and video player. So I'm stuck trying to figure out how to do it myself.

Initially I thought to duplicate the general design of JMF/FMJ since it seems to work for them. It would also help someone with greater familiarity with those libs to take the next step and properly integrate PSX decoding into them. However, after several days of tearing apart those massive libraries, and seeing I'd only scratched the surface, I dropped that idea.

Finally went back and took a closer look at SurePlayer. It plays mpeg1 movies great with very little processor use. It's fully cross-platform, and is a much more digestible library, so I'll be using that as a guide for implementation. With this clear direction, I can push forward with more jPSXdec development. Maybe in several years when Java 7 is ubiquitous, jPSXdec can be changed to utilize the new JMC.

Also during my searchings I serendipitously ran across a Java library to handle cross-platform raw CD reading! It's not quite as clean as I would like, but it's a pretty good foundation to build upon.

In other news, we've had a couple translators pop out of the woodwork recently. Will they be the salvation this project so desperately needs?

A man can dream.

Wednesday, September 24, 2008

How to encode quality PlayStation 1 video

Recently I've run across a couple of groups trying to replace the video of a Playstation 1 game. As we have to do the same thing with S.E. Lain, I thought I would share some insight as to how it might be done with the highest quality output.

Since there are many things that go into encoding mpeg video, that step is best left to programs that know how to juggle those options, such as ffmpeg. It also allows you to tweak those options, and use its advanced features to get the best results.

So here is how you do it, broken down into 6 ridiculously complicated steps.

  1. Convert your video into 4:2:0 yuv4mpeg2, but using the PSX specific rgb->yuv conversion.
  2. Feed the yuv4mpeg2 video into ffmpeg at an allowed fps and create a mpeg1 movie with only I-frames (-intra). This should be done at a variety of different quality levels (-qscale from 1 to n).
  3. Parse the I-frames out of the movie and parse their macro-blocks
  4. Convert the mpeg1 VLCs to PSX VLCs
  5. Do this for every mpeg1 quality and pick the one that fits best within the amount of space available to the frame
  6. Multiplex the frames and construct all the sectors

If the new video is mostly just the old video with some changes (e.g. subtitles) then quality can improved tremendously with this variation.

  1. Use some method to determine which macro blocks to replace (manually picking them, or performing a diff on lossless video data, or a fuzzy diff on lossy video data)
  2. Only replace those macro blocks with new ones of the same qscale
  3. If the replaced data makes the frame too big, then either replace the entire frame with an ffmpeg created frame that will fit (qscale will probably be bigger), or remove some quality in the frame to make it smaller
  4. Multiplex the frames and construct all the sectors

Alternatively have ffmpeg write an AVI using MJPG codec and parse the JPEG frames and convert the JPEG VLCs to PSX VLCs (I'm not sure how to get ffmpeg to produce quality variations with the MJPG codec).

Monday, July 14, 2008

zOMG psx.lain.pl is down!

And it has been for quite awhile. I thought it was just temporary, but finally learned yesterday that the good fellow that was nice enough to host the page has chosen to close the account. We are grateful for the time we could use the server.

Don't worry, we still have all data and work done so far. Unfortunately we're currently without a host, and the project is still stuck at around 14% completion.

I personally would like to thank everyone that has contributed thus far...

Hikari - Translated dialogs from video sequences to Polish.
phm - Extracted the media with jpsxdec and setup the wiki. Retranslated video sequences dialogs from Polish to English. Advertised for translators, and coordinated with their changes.
MercuryTW - Provided some translations from a translator of his own (Keigo). Edited/corrected translated files.
stalker-kun - Provided hosting for the wiki.
otakufish - Provided some translations.
toruvinn - Provided nice domain.
farhan - Ruthlessly proofread random translations, utilising his qualifications in the field of Applied Pedantry with Grammar Nazism.
fishy - Proofread translations, created the public project page.
arc - Provided some translations.
Jossos - Provided some translations.
utakata - corrected a Japanese transcription.
Najica - Provided some translations.
Quibbage - Created subtitle files for videos.

...and everyone else (sorry if I've missed your name here)--thank you all very much.

jPSXdec development has been pretty quiet as well. I should submit the bug that fails to decode some of the Lain videos, or just commit the fix. The next things to do with jPSXdec require some major changes, and things have been busy (my toon won't hit level 60 by itself ;). I'm still here and interested in the project and related topics. I don't plan on that changing anytime soon.

Sunday, May 4, 2008

Sonic

AVI
Fixed the obvious problems with AVI writing, but still problems persist.
* My Windows Quicktime install must be bad because it crashes from like everything (but Mac Quicktime plays fine)
* My Linux mplayer must be bad because it plays all movies stretched, one way or another
* All programs on my lappy crash from my movies except Windows Media Player
* My Linux Totem still plays it with green garbage

So I think I may be doing MJPG slightly wrong, but I'm not sure what. Plus I finally figured out why I could never find any documentation on the MJPG codec: "there is no document that defines a single exact format that is universally recognized as a complete specification of “Motion JPEG” for use in all contexts" Wikipedia

Native decoder
Got the native decoder working great on Windows, Linux and Mac. CMake has made cross-platform building a breeze :D It's really exciting to see the decoding plow through dozens of frames per second.

Indeed, native decoding is fast...

Java is faster
The heck?? Contrary to what I thought I saw in my initial tests, my swift Java decoding module is significantly faster than using the native decoder. How? Not sure, but I suspect it's due to all the overhead needed when calling a JNI function (such as changing big-endian to little-endian). It already melts through 150 sectors/second like a hot knife through butter--but since it spends half its time with garbage collection, could it be faster with some object pooling?

Tuesday, April 22, 2008

v0.34

I just needed to get something for a public release. It was the re-implementation of the command-line that kept hanging me up (it was boring and I wanted to work on other things ;). I admit in my rush to just get something released, I sorta skimped on the code commenting. :P

Testing

Before releasing, I randomly tested jpsxdec on the dozen or so games that my friends let me borrow. As a result I threw in some last-minute changes to handle a couple new movie types. 'Last minute' means these may not even work right (I look forward to finding a way to save variable frame rate movies ^^).

I ran some quick tests on my Linux Mint machine. Compiz was often rendering the progress window without controls, so there was no way to close the program! And there's an annoying JFileChooser 'All Files' filter bug... :P (just wrote a work-around a moment ago).

My tests on a Mac were a little more promising. Rendering was slick--even looked better than Windows rendering.

After seeing how jpsxdec worked on Linux, I was worried about the quality of jpsxdec--then I saw iTunes for Windows and was feeling pretty good again.

AVI writing is faulty

Seems my AVI writer is getting something wrong because it is crashing or otherwise playing poorly on Linux by VLC ('this avi is broken'), mplayer (plays upside-down, stretched, or just crashes), Totem player (green gunk on the screen). On Windows and Mac, Quicktime is having problems (plays video too slowly or crashes). Real Player also crashes the good crash.

Speed

Since much of the core decoding work for jpsxdec is finished, I started looking for something a little more exciting to work on. So, following MrVacBob's suggestion, I began writing a crazy fast Java decoder. After doing everything I could think of, and examining the work of previous coders, I came to the conclusion that a real-time PSX Java decoder may be possible, but the resulting code would be so ugly, long, and annoying, it just isn't worth it. I hope to complete a faster Java decoder that'll cut the decoding time by maybe half, but also make a small, cross-platform native library will be fast enough for real-time playback.

My friends keep dropping games on me--more than I can keep up with. It takes so long to rip games that I went ahead and threw together raw cd reading on Windows. It's pretty buggy, and I'm sure I'm doing something wrong, but it mostly worked. If ever I can get it more stable, I'll include it. For my Linux coding friends, the JNI Java class is in the source if you feel like writing a Linux version of the lib :)

Licenses

The LGPL of the Swing libraries included with jpsxdec don't require that I distribute the source code of the libraries (I haven't changed them, and I am linking them separately). But since jpsxdec is GPL, does that require me to include the LGPL sources with the distribution? I really didn't want the hassle of it, but just to be safe I included the source with the pre-combiled binaries together in the zip files.