Thursday, August 27, 2020

LaserDisc Capture Device Ecosystem

Diagram of the capture system

I've been doing a bit off and on with my Apple IIc (Early model, upgraded to Rom4X) and my LaserDisc player (Pioneer CLD-V2400), now that I have it all working.   I've created a video switching device (less prototype-ish version of it coming soon) and have made a few different serial interface adapters so I can control the LDP from the Apple IIc, Tandy "Model T" line, and my Amiga.  I plan on having stub BASIC programs for each in github eventually, here on my LaserDisc catch-all repository.

But this brings up the issue that it's a niche project for a very esoteric and specific audience.  That is to say, vintage computer enthusiasts WHO ALSO have a LaserDisc player, WHO ALSO have specific LaserDisc titles... It's the Sega 32X issue all over again. ;)

So... how to bring playability ("play" in the sense of "playing games created" as well as "playing the video discs") to a larger subset of the vintage computer enthusiasts... and also reduce reliance on super heavy players with large spinning plastic discs in them...  Of course the answer is Raspberry Pi!

The Idea 

The basic idea is to use a Raspberry Pi (Zero hopefully) as a standalone LaserDisc Player simulator.  More on that specifically in a future post, but the goal of this post is to talk about getting content for this simulator.  And, yes, there are LD simulators/emulators out there, like "Daphne", but they're generally for Arcade machine use, and simulate older players (like for Dragon's Lair), and they work VERY well, but they're quite expensive.  This will be a solution that may not work for arcade machine applications, but for home/game/toy/experimenter use, it will be super-cheap (no more than $20 total for the Pi + Serial interface... lowering the bar of entry substantially.

So for capturing a disc, One method might be to just capture the audio and composite output of a disc, and have the PI run something like the VLC player application, which might still be the solution, but I thought I'd experiment with making a custom player, since it will probably be cumbersome to do this with VLC, being how there is a large level of control needed.

The issue comes in when you realize that playback requires frame-specific actions being done with the disc itself.  This is usually fine, but for some content, there's a 2-3 pulldown put in to convert the original 24fps film content to 29.97fps NTSC composite-video LaserDisc content.  The short-short version of this is that if you were to just step through frame by frame, you'd see repeated frames, as well as some frames that are interleaved with each other.  This is not what consumers expect when they hit frame-forward or frame-backwards on their player.  Instead, when you use those functions, the player jumps around, skipping duplicated as well as interleaved frames.  This is handled invisibly by the player, as it accesses the frames from the disc, which are marked as being "full frames".  (this is a gross overview, but generally correct-ish.)

So you can capture the video stream, and play that back via VLC (or other media player) but the results won't be accurate to a LDP.  You'll have to manually skip frames, and offset per the 2-3 pulldown... it gets messy, but you can get an "okayish" approximation.  This is what my Javascript "Rollercoaster" laserdisc simulation did.  And it worked decently.  But it's not good enough.

The Domesday Duplicator Project

I had the idea to capture discs in a more "raw" form, so I started looking into what was available for this.  I looked into the Domesday Duplicator for capturing LaserDiscs, and use their "ld-decode" software to decode it and play it back, since it would be ideal.  I could capture the raw RF content stored on the LD, and play it back exactly as a LDP.  There are some issues with this though...

First of all, I do not have the right LaserDisc player to capture the content, nor full documentation about the hack necessary, nor the expensive hardware needed to sample the RF stream... It is a substantial overhead to capture discs.  Perfect for their archival use, but it's massive overkill for playing some homebrew games.

Secondly, for their captures, each side of a disk requires approximately 103 gigabytes of storage space, which is inconvenient. ;)

My Solution

The solution I decided to run with is to simply step through the disc, frame by frame, and capture each composite video frame individually, then capture the audio separately, and sync them back up in the playback application.

Video would be captured frame-specific on the disc... that is to say only unique 480p-ish frames will be captured, so file "32908.png" will be frame 32908.  No need to convert or deal with if a title has 
a 3-2 pulldown, or it's 29.97 fps, or whatever...  Playback of video might be odd, but this could always be augmented with video files for playback of segments, using these files as still-frame files.

For video capture, I'm using my Canon Optura Xi DV camcorder as a video-firewire bridge, and capturing the video frames using imagesnap, which can save jpeg or png images captured from standard Mac video sources, including firewire-DV connected devices.  It could just as easily been done through some USB Composite AV capture device, but I do not have access to one.

Each of the pairs of audio tracks will be captured directly from the analog audio output from the player.  (I have not done this part, but I plan on using sox to do this, probably, although some tests I've done so far have had dropouts while recording... which is less than ideal... audio capture could be accomplished using a more modern computer or recording device...)

The diagram at the top of this post shows this workflow.

For controlling the LDP, I have a simple python script that connects using the standard serial libraries to a USB-Serial interface, which is wired to my player via RS/232 (4800 baud).  I don't have a store-bought USB serial device, but any of them should work fine.  I decided to just throw together something using stuff I had, which can be seen in this image:

This is my USB-RS232 interface. There are many functionally like it, but this one is mine.

There really is nothing special to this, it's just a USB-RS232 adapter.... using an old USB-Ipod serial dock adapter, FTDI extension wire, and then a cobbled-together TTL-RS232 level shifter. :)


All of this is working as expected. (python script will be posted to github soon.)  I have the LDP spin up the disk ("PL"), seek to the lead-out (end) of the side ("FRLOSE"), get the frame count ("F?"), then seek back to frame 0 ("FR00000SE").  Most discs seem to have between 32,000 and 45,000 frames per side, providing about 30 minutes of content.

Each frame of 704x480 (I know, i was expecting 720x480, but this is what I got.) as JPG is about 140 kilobytes, and as PNG is about 600 kilobytes.  The issue with it though is that it was slow to capture.  The frame seek and stepping was quick, but the capture tool was slow, capturing about 27 PNG frames per minute, or about 35 JPG files per minute.  This would be hours to capture a single side of a disc.  Which is fine, since it's completely automated.  It would produce about 7 gigabytes of video frames per side.

I experimented with capturing audio as well.  I couldn't capture from the firewire/DV stream, but I just hooked the LDP directly in to the Mac Mini I was testing with.  I used SOX to capture some content, and it had a few dropouts.  This could have been because the computer is ancient... So more tests are necessary on that front.

The plan for the capture software is to have it query the LDP to get more meta-content out of the disc as well.  It can get data about the disc, player serial number, number of audio tracks, etc.  From that it could completely automate capturing each of the two potential pairs of  audio streams, or as individual tracks, depending on the needs of the disc... as well as all video frames, and perhaps a DV stream as well... maybe.  

Remember to set the DV Camcorder/Bridge for "video in"

Currently, I've got the software doing the following process:

  • Initialize the player:
    • "PL" Spin up the disc, and "Play"
    • "FRLOSE" When that's done, seek to the frame at the lead-out at the end of the disk
    • "F?" Query to get the current frame number (the number of frames)
    • "FR1SE" seek back to frame 1 on the disc (*)
    • "SR" Step in reverse, back 1 step (*)
  • For each frame:
    • "FRxSE" seek to frame x (the current frame number)
    • run: "imagesnap outdir/x.png" to capture a video frame to a PNG file

This is currently working.  Eventually, I'll add in the additional commands to query available audio tracks, and run "sox -d discname_audio.wav" to capture that.