<a href="http://evilboris.sonic-cult.net/!trash/SP6104.SFD" target="_blank">http://evilboris.sonic-cult.net/!trash/SP6104.SFD</a> <a href="http://evilboris.sonic-cult.net/!trash/SP6105.SFD" target="_blank">http://evilboris.sonic-cult.net/!trash/SP6105.SFD</a> These files were taken from later-generation Saturn titles, which used CRI Sofdec, the same middleware format that was later used on the Dreamcast, and PS2/Xbox/GCN (with MPEG2 video). Much like the Dreamcast SFD files, they contain MPEG1 video and ADX audio. The catch is: they all have TWO video streams. A low-resolution version intended for playback using a software mpeg decoder application, and a glorious full-resolution version, using the optional MPEG Card. I could not find any SFD converters that could process these files. Any ideas?
Have you tried using something like ps2str to demux them, or does that only work with MPEG-2 program streams?
I tried mplayer and sfd2mpg. ps2str looks like a tool specifically built for Playstation 2 STR files, not Middleware CRI Sofdec files.
Well, from doing some cursory reading, I was under the impression that these were either Program Streams or Transport Streams, and PSS files are really just Program Streams, so I figured it might have been worth a shot to demux them. I tried bbdmux and got three tiny files for the first video, but the second one gave me two 0-byte files and one impossibly-large file. bbinfo tols me that they were TS, not PS, but as the bbdmux output seemed wrong, that might be too. TMPGEnc claims to be able to decode Sofdec files, so maybe it can demux them too.
The problem is, there are about a hundred different kinds of SFD formats, and the existing converters only support the most popular Dreamcast/PS2 versions (none of which had 2 videos inside).
The bigger problem is that the structure of this SFD format is completely different from the existing ones. Dreamcast era and onward always uses the 2048 sector size with a 30 byte header on each sector with 0x01C007 used in the sector headers to identify the ADX audio streams. The files you linked still appear to use 2048 byte sectors, but the sector headers are completely different. They only appear to be 8 bytes in this file, and the ADX audio stream isn't just a normal ADX file with it's own header interleaved so the audio stream can't easily be located. However, I am seeing several distinct repeating values in the sector headers. 0x00010400, 0x00010200, and 0x00020200 seem to represent the 3 different streams you mentioned. A simple application to pull those out should do the job. Check back in an hour. Edit: Here. The following code will get you the 3 streams out of the files you posted. However, out of the 3 only video1 seems to be playable in a video player and for me it's always a black screen unless I seek then sometimes a frame will appear. The first video you posted appears to have a rocket in it, but I can't see much else. Maybe once you have the split streams you can do something from there to repair them. Code (Text): using namespace std; #include <iostream> #include <fstream> int readfour(ifstream &infile){ int temp = 0; int value = 0; infile.read((char*) &temp,1); //Read 1 byte temp = temp * 16777216; value += temp; temp = 0; infile.read((char*) &temp,1); //Read 1 byte temp = temp * 65536; value += temp; temp = 0; infile.read((char*) &temp,1); //Read 1 byte temp = temp * 256; value += temp; temp = 0; infile.read((char*) &temp,1); //Read 1 byte value += temp; return value; } int main(int argc, char* argv[]){ char inname[128]; ifstream infile; ofstream outvideo1; ofstream outvideo2; ofstream outaudio; char letter; char altletter; int value = 0; int segment = 1; cout << "Enter input filename: "; cin >> inname; infile.open(inname, ios::binary | ios::in); //Open the file outvideo1.open("video1.mpg", ios::binary | ios::out); outvideo2.open("video2.mpg", ios::binary | ios::out); outaudio.open("audio.adx", ios::binary | ios::out); do { infile.seekg((segment*2048)+4, ios::beg); value = readfour(infile); if (value == 0x010200){ //This is video 1 data! infile.seekg((segment*2048)+8, ios::beg); for (int x = 0; x<1020; x++){ infile.get(letter); infile.get(altletter); outvideo1.put(letter); outvideo1.put(altletter); } } if (value == 0x010400){ //This is video 2 data! infile.seekg((segment*2048)+8, ios::beg); for (int x = 0; x<1020; x++){ infile.get(letter); infile.get(altletter); outvideo2.put(letter); outvideo2.put(altletter); } } if (value == 0x020200){ //This is audio data! infile.seekg((segment*2048)+8, ios::beg); for (int x = 0; x<1020; x++){ infile.get(letter); infile.get(altletter); outaudio.put(letter); outaudio.put(altletter); } } segment++; } while (infile.peek() != EOF); infile.close(); outvideo1.close(); outvideo2.close(); outaudio.close(); return 0; }
Awesome. Can I have an exe version of that? One where I can set the stream start offsets manually, in case I run into files with different data. Where did you those offsets listed in the files? It's the final Segata commercial.
Huh, normally I have no problem demuxing SFDs (even the later scrambled ones with multiple audio tracks) using TMpegEnc but these give an error. Weird.
I think it's due to the fact that there are two video streams. I don't believe TMPGEnc properly supports Transport Streams, but they might work with only one video stream. Unless this is a version of the Sofdec container that isn't a modified Program or Transport Stream. The fact that "normal" SFDs demux properly under TMPGEnc means that they're at least close enough to a PS/TS for it to work properly in those cases.
Okay. So that app is not processing any of the other samples I have. After half an hour, it turns out that the samples I uploaded are modified by the server. That's where the "010400" headers come from, the original files don't have anything like it. Terribly sorry for wasting anybodies time with the bad samples. Here are some good ones, zipped so the server doesn't screw them up with mime type bullshit. <a href="http://evilboris.sonic-cult.net/!trash/SOFDEC.zip" target="_blank">http://evilboris.sonic-cult.net/!trash/SOFDEC.zip</a> Strangely enough your converter actually did manage to grab the first, low-res video from the files, with almost no errors. So that makes me think that the false headers were actually at a right place by sheer coincidence. The data stream in all the files seem to start at 0x800, with what looks like an ADX header without loop info.
OK, this is just silly. I started bruteforcing one of the files based on ADX data samples: Code (Text): SP6104.SFD begin - end hex size content --------------------------------------- 0 - 0x800 800 header 0x800 - 0x1d000 1c800 ADX + header 0x1d000 - 0x1e000 1000 ? (contains MPEG1 sequence header) 0x1e000 - 0x1e800 800 ADX 0x1e800 - 0x20000 1800 ? 0x20000 - 0x20800 800 ADX 0x20800 - 0x21800 1000 ? 0x21800 - 0x22000 800 ADX 0x22000 - 0x24000 2000 ? 0x24000 - 0x25000 1000 ADX 0x25000 - 0x26800 1800 ? 0x26800 - 0x27000 800 ADX 0x27000 - 0x29000 2000 ? 0x29000 - 0x29800 800 ADX 0x29800 - 0x2a800 1000 ? 0x2a800 - 0x2b000 800 ADX 0x2b000 - 0x2c800 1800 ? 0x2c800 - 0x2d000 800 ADX 0x2d000 - 0x2f000 2000 ? 0x2f000 - 0x2f800 800 ADX 0x2f800 - 0x31800 2000 ? 0x31800 - 0x32800 1000 ADX 0x32800 - 0x34000 1800 ? 0x34000 - 0x35000 1000 ADX 0x35000 - 0x36800 1800 ? (contains MPEG1 sequence header) 0x36800 - 0x37000 800 ADX 0x37000 - 0x38800 1800 ? 0x38800 - 0x39800 1000 ADX 0x39800 - 0x3c000 2800 ? 0x3c000 - 0x3d800 1800 ADX What the hell is this? Random interleaving?
If you swap two of the files, will those two still play properly? I don't see anything in these fixed files that would identify the sector types. The only thing it has in common with Dreamcast era SFD is the sectors are still 0x800 bytes.
Yeah, they still play properly. Even though the swapped out files have different data on sectors. Even the MPEG sequence header seems bogus: according to them the videos are 29.97 fps, but they certainly don't play at that framerate. Maybe the full resolution ones do, however those videos are not 240x160, they are fullscreen. Here are the program files that run the code on this demo cd, maybe they can be reverse engineered. Both SH2s and the SCU DSP is active as well when the files are being played, so the video decoder may not be in sh2 language. <a href="http://evilboris.sonic-cult.net/!trash/SFDPLAY.zip" target="_blank">http://evilboris.sonic-cult.net/!trash/SFDPLAY.zip</a>
Bit of a bump, but I've had some troubles with SFD files too. I examined the XBLA leak of Sonic Adventure, and to my surprise it contained unique variations of the intro SFDs not found in the DC or GC versions. (PC uses WMV of course.) The US and JP DX videos decode fine, but the DC original is not decoding properly in Media Player Classic, Winamp, FFPlay, or VirtualDub. What's the big deal? The Dreamcast intro was encoded at the strange resolution of 320x448. The XBLA version is in 640x480. I'm hopeful that, once properly decoded, it show itself to be a higher resolution encode from the source, and not just a sizeup. Compare: I copied these three strings out of the MPEG file: TMPGEXS TMPGEXE IDCPREC
I'm back with more SFD woes. Someone try getting this to play: <a href="http://home.comcast.net/~doa4/movie.sfd" target="_blank">http://home.comcast.net/~doa4/movie.sfd</a> 401MB from Initial D Extreme Stage on PS3. TMPEG says that the video track is an MPEG-1 VBR stream but it's messy like others and the audio seems to be some CRX AIX or AIXP thing.