jPSXdec is a cross-platform PlayStation 1 media decoder/converter.
Get the latest version here.
Showing posts with label jPSXdec. Show all posts
Showing posts with label jPSXdec. Show all posts

Saturday, July 30, 2016

PlayStation audio and exceptional video quality

I'm still learning about audio in PlayStation games (Nocash Playstation Specifications is amazing!). The XA ADPCM audio format, frequently seen with STR videos, is what I'm most familiar with. But the PlayStation also has a Sound Processing Unit (SPU) that is used to play all other audio you hear in the game.

XA audio is easy to identify and convert. SPU audio, often referred to as "VAG" ("Very Audio Good"), isn't so easy. The easiest clips to identify are simple sound effects that are played and then end. It gets a little more difficult with audio clips that need to loop. Where it gets impossible to identify is when multiple audio clips are combined to form unique sounds in real-time. I believe this is called "SEQ" and is how a lot of background music is done in games. Each instrument is actually little sound clips being played at different frequencies. This brings up another challenge with all SPU audio: clips can be played at any frequency, and there isn't any way to know what it is.

One case where a game used instrumental audio along with STR video is the Valkyrie Profile opening FMV. jPSXdec can only identify the video clip, but has no way to recreate the music. Thankfully, diligent people have put a lot of effort into extracting these instrumental kinds of audio. These are stored in what's known as PSF files. Lo and behold, someone has taken the time extract the Valkyrie Profile instrumental music into PSF files.

With my growing knowledge around PlayStation audio, I thought it would be fun to create a very high quality conversion of the Valkyrie Profile opening. I assume using a PSF converter could produce better quality audio than what you can get on hardware or emulators. jPSXdec can extract the video with the best possible quality which can be made even better with other tools.

Tools used:

Steps:

  1. Extracted Valkyrie Profile opening video with jPSXdec in avi:jyuv format. This is YUV using the [0-255] component range.
  2. Downloaded Valkyrie Profile psf audio clips.
  3. Used Audio Overload to convert opening video PSF to wav.
  4. Used VirtualDub to mux the video and audio into a single avi, with a 1 second audio delay to sync them up correctly.
  5. Created an Avisynth script to upscale the video to HD quality and convert to RGB. DGMPGDec plugin was used for deblocking and nnedi3 plugin for scaling.

    # VALKYRIE.BIN[0]HD.avs
    
    # For deblocking
    LoadPlugin("DGDecode.dll")
    # For scaling
    LoadPlugin("nnedi3.dll")
    
    AviSource("VALKYRIE.BIN[0]jyuv+audio.avi", pixel_type="YV12")
    
    # Deblocking
    # quant is the strength between 1 and 31
    # The quant=31 removed the maximum blocking issues
    # Didn't seem to blur anything else
    BlindPP(quant=31)
    
    # Scale up by 4x for a final resolution of 1280x900
    # The results of nnedi3 appeared slightly better than Spline64Resize
    nnedi3_rpow2(rfactor=4)
    
    # Avisynth has the unique ability to choose the matrix
    # and ChromaInPlacement when converting to RGB (available since Avisynth 2.6)
    # matrix="pc.601" indicates input is in [0-255] component range
    # ChromaInPlacement="MPEG1" is the chroma placement used by PSX
    ConvertToRGB32(matrix="pc.601", ChromaInPlacement="MPEG1")
    
  6. Used ffmepg and this script to convert to an uncompressed/RGB/DIB AVI (5 GB file!):

    ffmpeg -i VALKYRIE.BIN[0]HD.avs -acodec copy -vcodec rawvideo VALKYRIE.BIN[0]HD.avi
    
  7. That looked good, so then compressed to an almost lossless mp4

    ffmpeg -i VALKYRIE.BIN[0]HD.avi -pix_fmt yuv420p -c:v libx264 -qp 1 -preset veryslow -c:a aac -strict experimental -b:a 192k -ac 2 VALKYRIE.BIN[0]HD.mp4
    

The result turned out pretty good.

Tuesday, March 13, 2012

In The News

It might be a time for celebration because I've finally bumped jPSXdec into 'beta' status. It's pretty much feature complete now. At worst there may be a redesign of a couple modules as I've recently been hit with the infamous Judge Dredd which breaks some assumptions. I also think the GUI leaves much to be desired (thank you user-testing!).

During the life of jPSXdec I've always been really interested in what people were using jPSXdec for.

In recent news, a project to recreate the game Blood Omen: Legacy of Kain looks to be using jPSXdec to help upsample the videos.

I was going to link to a recently posted, and possibly related HD version of the Blood Omen videos, but to my surprise, Boulotaur2024's YouTube account has been terminated. He's been posting HD versions of several game videos, utilizing jPSXdec for most of the PlayStation ones. It was great because he found a few games that jPSXdec had problems with. Guess Media Interactive Inc. and the Record Industry Association of Japan didn't appreciate his work.

The great ScummVM project has made use of my awesome documentation to add a PlayStation video player so it could utilize the PSX videos from Broken Sword 1 and 2. They've written up a few instructions on how to get your videos ready to play in the emulator.

Saturday, August 13, 2011

Replicate

On a whim, I ran one of the unique identifiers in the Lain game through Google which led me to a couple interesting sites.

A very impressive Russian site is trying to recreate most of the game's content for browsing on the web. What impressed me even more is the creator managed to reverse-engineer some of the game's data types before I did. He kindly gave jPSXdec a shout out since it was used heavily to extract nearly everything on the site.

This very old Japanese site I've seen before, but did a good job of documenting the game's content as well.

Monday, September 6, 2010

PlayStation Video Decoders:
The Final Showdown

Updated from the previous comparison with the lastest versions, and three new decoders!

Most importantly, I finally captured what it ACTUALLY looks like on PlayStation hardware (in the dead center).

Those on top get it (more) correct, those on the bottom get it (more) wrong (and ffmpeg and Q-gears are just weird).

Naturally jPSXdec dominates in quality and accuracy. :)

The lineup:See the download for all the jucy (and technical) details.

Thursday, August 19, 2010

Immaculate Decoding

Just writing a straight-forward PlayStation 1 video decoder has been a lot of work. However, for the absolute most impeccable quality, there is so much more that can be considered in the process.

Upsampling

When PlayStation videos are created, the pixels are broken up into luma (brightness) components and chroma (color) components. Like with JPEG and MPEG formats, 3/4 of the chroma information is thrown away because the human eye can't really tell (this is an example of lossy compression).

When decoding, that lost chroma information needs to be recreated somehow to convert the pixels back into RGB. Unfortunately there is no one 'right' way to do it, because there's really no way to get that lost information back. All you can do is 'guess' by filling in the blanks based on the information around the pixels using some kind of interpolation. Some of the most well known kinds of interpolation are: nearest neighbor, bilinear, bicubic, and lanczos. I've read about more advanced chroma upsampling approaches that also take into account the luma component. This works because there is often a lot of correlation between the luma and chroma components--when the luma changes, the chroma probably will also. I'd like to try to find the best one, but I haven't had much luck on finding many good resources about them all.

Now, because this is essentially just scaling of a 2D image, I've been worried about this article that points out a nasty little gremlin called gamma correction. It seems nearly everyone has been doing image scaling wrong since the popularization of the sRGB gamma corrected color space. I'm assuming video isn't immune to the same problem, yet I've never seen anyone mention it.

Deblocking

Assuming we find the upsampling method of choice, there are still ways the image can be improved. Most video codecs break the frames down into 'blocks', then encode each block separately--again losing information along the way. When everything is reconstructed, that lost information can often be seen as visible distortions between blocks. This problem has been addressed in more recent video codecs such as h.264, but is still a problem with the older MPEG2. I believe nearly all DVD players do some deblocking before showing the final frame.

Even though MPEG2 has been around a long time and deblocking is so common, I've had the darndest time trying to find much mention of what deblocking algorithms are in use today. UnBlock, and this page on JPEG Post-Processing are the best I've come by. I think I've read somewhere that some advanced deblockers can even make use of the original MPEG2 data to improve the deblocking.

I still consider myself a multimedia novice, so there are probably more post-processing methods that would really make the output shine. A big bummer among all research in that area is that if you can think it, you can pretty much count on it been patented.


Given how difficult all this stuff is, I really really wish I could just pass that problem off to the big players in the field, such as ffmpeg (i.e. libavcodec). I've even considered writing a PSX video to MPEG2 video translator so the MPEG2 video can be fed into ffmpeg. Unfortunately there are some big reasons why doing this still makes me uneasy.

IDCT

The PlayStation uses its own particular IDCT approach that I've never seen anywhere else. Given how important it is that the DCT used to encode the video matches the IDCT used to decode, there are no existing decoders that can do it (except jPSXdec of course).

Differences in YCbCr

Another worry is that a real good quality MPEG2 decoder will spatially position the chroma components in the proper location (vertically aligned with every other luma component) as opposed to how I believe PSX does it (the MPEG1 way: in-between luma components).

To make things a bit more complicated, MPEG2 uses the proper Rec.601 Y'CbCr color space with [16-235] luma, and [16-240] chroma range. PSX on the other hand, uses the full [0-255] range for color information. Many video converters don't handle that discrepancy very well. Related to that, pretty much all converters store the data as integers, so any fractional information is lost after every conversion. In contrast, jPSXdec maintains all that fractional information until the very end.

In general though, I have not been impressed with ffmpeg's quality, so I can't suggest people use it when looking for good quality.


One advantage that comes when incorporating all these enhancements in jPSXdec is it provides a much nicer user experience. No need to be hopping between multiple tools to get the best results.

So if I were to actually implement all these features, where would I get the information I lack? Perhaps the doom9.org forums could help. If any multimedia gurus happen to pass by this post, please, if you could, toss some wisdom my way.

Sunday, February 7, 2010

Writing a Java-only Video Player

Finally designed and put together a fully working implementation, involving a custom blocking queue and 6 threads. I’ve tested it on Windows XP, OS X, and old Kubuntu Hardy. Windows and Mac both look amazing and run perfectly smooth. Unfortunately on Linux the video playback stutters a lot. At first I thought it was due to the GC. After integrating an impressive object pool design, the cause actually turned out to be the Java audio api.

I use the audio playback position to determine when a frame should be displayed. Running a little test exposes how reliable this timer is.


import javax.sound.sampled.*;

public class AudioPositionTest {
public static void main(String[] args) throws LineUnavailableException {
AudioFormat audFmt = new AudioFormat(18900, 16, 2, true, true);
DataLine.Info info = new DataLine.Info(SourceDataLine.class, audFmt);
SourceDataLine player = (SourceDataLine) AudioSystem.getLine(info);
player.open(audFmt);
player.start();

byte[] abBuf = new byte[2 * 400];

long lngTestLength = 20 * 1000; // 20 seconds
long lngTestStart = System.currentTimeMillis();
long lngTestEnd = lngTestStart + lngTestLength;

System.out.println(System.getProperty("os.name") + "\tJava " +
System.getProperty("java.version"));
StringBuilder sb = new StringBuilder(400);
while (System.currentTimeMillis() < lngTestEnd) {
player.write(abBuf, 0, abBuf.length);
long lngTime = System.currentTimeMillis();
long lngPos = player.getLongFramePosition();
sb.append(lngTime - lngTestStart);
sb.append('\t');
sb.append(lngPos);
System.out.println(sb);
sb.setLength(0);
Thread.yield();
}

player.stop();
player.close();
}
}

Graphing some of the output makes it pretty clear why Linux playback is choppy.



Since that isn’t going to work, my next test will involve registering a listener for start and stop events, and track playback time manually. Though I’m worried my time and the playback time are going to get out of sync.

Saturday, October 24, 2009

PSX Video Converter Deathmatch


UPDATE: This comparison has been superseded by a newer one

I took 8 different video converters and lined them up for the showdown of the decade!
Ok, so it's not really that dramatic. Some points of interest:
  • PCSX shows the most amount of blocky artifacts, which is understandable because its converter was designed for speed over quality.
  • PsxMC, PSmplay, PsxTulz, and PCSX all show very similar coloring. PsxMC and PSmplay are especially similar; however, they are not pixel exact matches.
  • Q-gears seems to have the darkest and warmest colors of them all, while ffmpeg is the brightest.
  • jPSXdec seems to produce softer images than the others, and its colors are quite similar to PSXPlay.
The differences may not seem very apparent side-by-side, but if you align the images on top of each other (like layers) then toggle the top image's visibility, the differences really stand out.

Now which is the most accurate? That depends on your definition of accurate.
  1. Do you want the exact values the PlayStation 1 hardware produces?
  2. Do you want it to match how you see it on the television?
  3. Do you want it to more closely resemble what the original designer created?
  4. Do you want a more mathematically precise conversion?
I don't have modded PlayStation hardware, and I don't have any way to very accurately capture composite video output, so I can't investigate #1 or #2.

You need to have the official Sony PlayStation 1 movie converter tool to investigate #3. If some shifty soul wanted to convert this video to STR and send it to me, I could investigate further. ;)

I made my best effort to ensure jPSXdec is very mathematically accurate, so I can at least recommend jPSXdec if you want #4.

Download all the converted images, along with more details (including some source code) on how I did all the conversions.

25Oct2009: updated download with corrections and included convertible test STR.

23Nov2009: updated download with better PsxTulz screenshot (thanks T_chan!).

Saturday, August 15, 2009

jPSXdec forever


According to Ohloh, jPSXdec is worth at least $150,000, but that is for code from a year ago. It now has now swelled to over 28,000 lines of code in over 170 files, and will probably be past 30k LOC by next version's release.

I really wish I could work on jPSXdec non-stop until it's ready for prime time again. School, work, the economy, a seriously expensive family emergency, and some critical life changes have all conspired to make that impossible. In fact, I don't have much hope in seeing the next release available anytime this year.

Things completed so far:
* The complicated part of media playback (managing 6 simultaneous threads isn't easy)
* Much needed cleanup of the Tim decoder, XA ADPCM decoder, and serialization code
* Reorganized the arrangement of media streams verses more static types of media
* Fixed both bugs on the issue list.
* Fixed the Tim false-positive matching that happens fairly often
* Fixed FF7 frame-rate miscalculation
* Break things up by game (i.e. setup plugin system)
* ISO9660 file detection
* Improved detection of audio (including CD-i) and video media items
* More robust disc image detection

Still to do:
* Re-implement the saving process for the various media types
* Redo frame rate detection

Beyond the next release:
* Automatic error reporting
* Redo the GUI
* Append AVI writer to make it stricter so it can produce cleaner AVI files
* AVI PNG codec
* Yuv4mpeg2 writing and/or AVI YUV codec
* Real-time media playback/preview
* Searching for static demux and MDEC data
* Finding and uncompressing lhz data, often used in PSX games
* Raw direct CD reading from the disc drive (based on java-avm)
* CD-i video formats
* More game handling
* STR and XA re-encoders
* CD track audio handling

When hell freezes over:
A custom hex browser for jPSXdec. Other free and/or open source hex browsers are generally decent, but none do everything I really need. Some desired features:
* Viewing of very large files without loading the whole thing into memory (hundreds of MB)
* Quick viewing and editing values as big/little endian of varying bit sizes/signs/types
More specifically for PSX hacking
* Identifying and browsing by sector (much like CDmage and IsoBuster do)
* Highlighting of the sector headers and footers
* Viewing of continuous demuxed sector payloads
* Identification of known sector types, and the various fields in each
* An overview map of the entire CD, with quick identifying symbols/colors for every sector and its type
The closest thing I've seen to this is VirtualDub's hex viewer.

And the ultimate pièce de résistance:
* Real-time processing of the data as you mouse-over it, and showing how it results in the final output
* Allows you to take each bit of data in the disc and follow it through the entire decoding process, each step of the way
* Allow you to change anything in real-time, and see how it would turn out
I've repeatedly imagined a program like this for even just mpeg1 or 2 streams. Those streams are really complicated, and you never get to see the direct connection between the data and the output. It would be so neat to hover over a block or a macro block and be able to see exactly where it was going to end up on screen, how it will look, and everything around it. The whole motion detection as well. It would be an incredible tool to teach people how those streams work. In the almost impossible case you've seen the official Bluetooth development tools, that's exactly what I had in mind.

All these neat ideas could eventually turn jPSXdec into the ultimate PSX hacking utility.

The time frame for everything? A long...long time. Years probably. Which really makes me wonder: what will become of this project in, say, another decade? Should I start soliciting help?

In the next to impossible case someone would like to join in developing jPSXdec, his skills might hopefully include:
* Very usable knowledge of Java (no need for an expert because I don't think I am)
* Love and value for clear and well documented source code
* Some experience with reverse-engineering just about anything (media formats preferred)
Added bonus:
* General understanding of mpeg/jpeg-type image formats
* Awareness of cross-platform development issues, and/or experience with developing simple programs for multiple platforms (i.e. Windows, Linux, Mac)

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.

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.

Thursday, March 13, 2008

Incoming

Been wanting to get some stats on jpsxdec code for a long time (Google code doesn't have such features), finally ran across StatSVN and took a quick look at the results.


Now running over 20,000 lines of code, and almost 100 files. Compared to Oct 21, 2007's 7,000 lines, that's 13,000 LOC over 144 days, for a measly 90 lines per day.

Anyway, I'm guesstimating next week will be the next jpsxdec release. It will have some exciting features:
  • Saving to AVI, both uncompressed and MJPG compressed your mileage may vary
  • A very nice dialog box providing the many decoding options available it's arrite
  • Final Fantasy 9 finally working properly done!
  • Chrono Cross is also working! mostly done!
  • Cleaned up command-line done!
  • and lots of delicious code documentation :)

Sunday, February 17, 2008

nihongo niban

Much awesomeness has transpired recently. But first, the dull ramblings of jpsxdec status.

Looked up how to encode uncompressed (RGB) AVI files. It's not too complicated--Microsoft and other sites have usable documentation. Even found a Java class to get me started. Of course if we're gonna write AVI files, we need to know the frame-rate. Just a simple 400 lines of code is all that took. Needed to also change the overall code design to a 'push' architecture with listeners. This had the additional bonus of pulling the actual file writing to the top-level interface--right where it belongs.

Overall things are looking pretty good. For the next release I want to add a new popup window showing the many decoding options.

Also in the future I want to allow for piping out uncompressed AVI to a program like ffmpeg or mencoder. For Windows I'll also include the infamous Video for Windows. Still need to add raw cd reading.

But while merrily carrying on with all this, out of nowhere came a fishy fellow with the powers of language transformation! He generously offered to spend some time with the S.E. Lain game. Sooo... efforts on jpsxdec are delayed as the Serial Experiments Lain PSX Game Translation Project commences (SELPGTP?).

But with 5.5 hours of audio, he has his work cut out for him. Do you share the powers of language transformation? We could really use your help.

On the technical side, we are working on adding the eventual translation into the game. And I present to you an actual screen shot based on an earlier idea.

Saturday, February 2, 2008

Amalgamation

Been busy with a bunch of different aspects of jpsxdec. Only the GUI and Code Design will be in the next release (v0.31 today!). The rest will show up in releases after that.

GUI
Even though it's a pretty lame GUI now, I hope it will drop the bar of entry a little.


Code Design
I had difficulty deciding on highest-level interface between the GUI/CLI and the logic. So I set it aside and worked on other things.

PSX YUV->yuv4mpeg2 conversion matrix
This will allow jpsxdec to output more accurate .yuv image sequences.

Frame Rate Calculation
I thought it was a good idea to guess the exact FF7 frame rate algorithm via trial-and-error. 8 hours later I finally saw that FF7 frame lengths do actually follow a pattern, but a ridiculous one. I hoped it would come to a frame rate of exactly 15/100.1% (half the rate of NTSC). That is close, but there was no way I could guess the underlying algorithm of this...


if (iMovieType == WACKED_NTSC1 && iThisFrame == 101)
iThisFrameLength = 11;
if (iMovieType == WACKED_NTSC2 && iThisFrame == 100)
iThisFrameLength = 11;
else if (iThisFrame == 200)
iThisFrameLength = 11;
else if (iThisFrame >= 203 && iThisFrame <= 298) {
if (((iThisFrame - 203) % 4) == 0)
iThisFrameLength = 11;
else if (((iThisFrame - 203) % 4) == 1)
iThisFrameLength = 9;
else
iThisFrameLength = 10;
}
else if (iThisFrame == 299)
iThisFrameLength = 11;
else if (iThisFrame >= 303 && iThisFrame <= 398) {
if (((iThisFrame - 303) % 4) == 0)
iThisFrameLength = 11;
else if (((iThisFrame - 303) % 4) == 1)
iThisFrameLength = 9;
else
iThisFrameLength = 10;
}
else if (iThisFrame == 399)
iThisFrameLength = 11;
else if (iThisFrame >= 402 && iThisFrame < 497) {
if (((iThisFrame - 402) % 4) == 0)
iThisFrameLength = 11;
else if (((iThisFrame - 402) % 4) == 2)
iThisFrameLength = 9;
else
iThisFrameLength = 10;
}
else if (iThisFrame == 498)
iThisFrameLength = 11;
else if (iThisFrame == 501)
iThisFrameLength = 11;
else if (iThisFrame >= 504 && iThisFrame <= 600) {
if (((iThisFrame - 504) % 4) == 0)
iThisFrameLength = 9;
else if (((iThisFrame - 504) % 4) == 2)
iThisFrameLength = 11;
else
iThisFrameLength = 10;
}
else
iThisFrameLength = 10;

Raw CD reading (Windows)
Made a native program to read raw CD sectors via DeviceIoControl. It's a simple interactive prompt that accepts commands to open/close a CD and read sectors. I even setup a Java program to communicate with the native program via stdin/out. Unfortunately it was slow, and was very vulnerable to deadlock while reading from stdin. I also started adding ASPI for raw CD reading, but there seems to be a lot more to using that API.

Encoding via VFW (Video for Windows)
I worked out a little program to convert a series of raw image and audio data into an AVI, using the oh-so-familiar Video for Windows popup. I wonder if it can handle accepting all the audio at once, then all the video at once....


JNI
Even though I said it would be a pain in the butt, I guess it's really not so bad. It's kinda like translating VB6 COM code into C++. This will likely speed up raw CD reading, and save me from communicating via stdin/out.

Code Design
Finally got back to this again. Since no solution was particularly attractive, I went with the simplest one. This will only use one optional callback listener (for progress status).

However, I have begun to think that the 'pull' architecture is not the best approach to begin with. A 'push' architecture is more applicable to this situation: as sectors are read from the disc, they need to be 'pushed' into the appropriate streams. Listeners can be added to collect the streams of interest. If jpsxdec was to ever play media in real time (not likely), this would be the necessary design. In any case, the 'push' approach would make decoding a little faster because there is less seek time.

Sunday, January 6, 2008

HATSUHINODE

Hope all had a pleasant new year. As we enter 2008, it is interesting to note that this year marks the 10th anniversary of the Serial Experiments Lain anime series, along with the Playstation game.

Now that holidays are over, I finally managed to release the latest compiled executable on the download page. No changes to the program interface (same wonderful command-line that you're used to ;), but it has all the latest internal goodness that I hope actually works--most notable is it now [edit] mostly supports FF8 (it would help to fully test it before making such calims :P).

Friday, December 14, 2007

Happy Winter Solstice

This time of year brings, among other things, demands that defy the known laws of time and space. So further updates for jPSXdec and the STR file format will have to wait until after the holidays.

In the works:
  • Full FF8 support done!
  • GUI well, it's something
  • Removing dependence on Java 1.6, down to 1.5 done!
  • FF9 video support video yes, audio no
  • TIM image searching and converting need to include more comprehensive TIM searching
So until then, may you have a pleasant season.

Thursday, November 29, 2007

Games tested with jPSXdec

PLEASE LEAVE A COMMENT ABOUT ANY GAME YOU USED WITH JPSXDEC

Alundra 2 - works
Valkyrie Profile - works
Xenogears - works
Final Fantasy Chronicles - works (video at 30 fps)
Saiyuki: Journey West - works
Intelligent Qube - works
Power Puff Girls - works
Simpsons Wrestling - works
Super Puzzle Fighter 2 Turbo - works
Lethal Enforcers 1 and 2 - works
Battle Arena Toshinden - works
Metal Gear Solid - works
Silent Hill - works
Tekken 3 - works
Xeno Gears - works
Motorhead - works
Oddworld Abes Oddysee - works
Spyro - works
Worms World Party - works
Soul Blade - works
R4 Ridge Racer Type 4 - works

Samples from ffmpeg examples
abc000.str - works (video at 30 fps)
descent_descent-e.str.bz2 - works
finalfantasyVII_movie-gold4.mov.bz2 - works
jumpingflash2_music2.xai.bz2 - works
jumpingflash2_movie-01.str.bz2 - works
lain.str - works
lunar2.str - works (video just under 20 fps)
river1.str - works (video at 12.5 fps)
st3.xa - works
logo.iki - works (from game "UmJammer Lammy")

Games requiring special handling
Serial Experiments Lain - works
FF7 - works
FF8 - works
FF9 - works
Chrono Cross - works
Alice in Cyberland - works
Sonic Wings Special - last movie seems like filler data, but can be converted if it is first copied off the disc normally
Ace Combat 3 - works
Legend of Mana

Gran Turismo?
G-Generation?
Ko'hloons Gate?
Maborosi (まぼろし月夜) Moonlit Night?
Formula 1?
Lunar 2?
BeatMania 4?

Saturday, October 27, 2007

Close the world, Open the nExt.

After watching and enjoying the Serial Experiments Lain anime series, my interest was piqued by something I saw on the disc extras.

A Lain Playstation game.

And I had to own it.

With the help of my Japanese co-worker during my trip to Japan, I managed to acquire a copy all of my own.

Jen's site was accurate when it said there was very little info about the game. Following her lead, I wanted to change that. I wanted to decode the video for all to see. The audio could be ripped just fine, but the video refused to decode. Endless Googles later and I was still left wanting.

While toying with the game in an emulator, it dawned on me that if I couldn't decode the video off the disc, maybe I could let the game do it for me. I got the open source P.E.Op.S. GPU plug-in and went to work grabbing the video frames before anything was drawn over them. Soon I had nearly all the media from disc 1 sitting on my hard drive.

However, I ran into a snag. The decoded audio from the disc wasn't lining up with the video frames I had captured.

I had big plans, but was burning out and couldn't ever find a reason for this discrepancy. The project was abandoned for another day.

Two years later...

Finding myself still stumped over the audio/video mismatching, I veered a different direction. Could I possibly learn how to decode PSX videos myself?

Another endless bout of Googles later and I learned about JPEG and MPEG encoding. Soon I had my own I-frame decoder. It was the Q-gears source code that finally pushed the decoder into aligning with PSX data. It was done. I was seeing video frames from games I'd never seen before, and without ever touching someone else's decoder.

I could do what existing decoders could do, but what of Lain? What is with all this video data? It doesn't add up to anything sensible. Again I hit a snag. The only way to know what the data means is to see what the game is doing, and how could I do that?

I was just about ready to settle with my mis-matched audio and video frames, but I couldn't leave well enough alone. I ran across the pSX emulator that provides debugging capabilities. So over a three day weekend I swam through a sea of R3051 assembly code. By the end I knew how it is all done.

Outraged at the lack of information and source code about the PSX, I decided to take my little decoder to the big time and share everything I have learned over the last few months.

And thus is the jPSXdec.