birds like wires

Search

Oculus Rift Over Fibre Optic

Well here’s a niche article if ever there was one.

In our recording studios, we have no computers. Rather, the computers are kept in a separate room, connected to each studio by a mixture of analogue audio cabling, CAT5e and fibre optic. The fibre is used for FireWire and any display connectivity we may need, using whichever converters are suitable.

This results in super-silent rooms with no whirring or squeaking or clicking, but it does present some odd challenges. Not all conversion systems are made equal and not all devices will happily get along with the adapters we use, for whole host of reasons. So when we started exploring the world of immersive 3D with Oculus Rift, I suspected I may have some headaches.

Display Chatter

Adding a new display in most places involves nothing more than plugging it in, but in our setup we first have to program the transmission end of the fibre converter with the EDID of the display we’re about to use. This way the computer knows what it’s talking to without actually being connected to the real thing. Seeing as the Rift’s video is nothing more than a display on a HDMI cable, you might assume that the same technique would work just fine. This is not the case.

The Rift will not output it’s EDID until it is connected to a HDMI-compliant device. It does not recognise our adapters as such, and so the little Rift status LED stays orange and no information is sent. Connect to a computer and voilĂ ! Blue LED, EDID sent, all is well. But you can’t put the transmitter in the signal path to read that data. How very annoying!

One possibility would be to make a two-wire DVI cable from an adapter and take the DDC pins off to another DVI plug that would side-connect to our transmitter. That might work, but it’s a faff. Instead, doing some Googling took me to this helpful video about custom resolutions in OS X, which sparked the possibility of getting the Mac to do the work for me.

Custom Display Overrides

It turns out that a displays EDID can be augmented or replaced by a file in /System/Library/Displays/Overrides/. The directories are named by Vendor ID and the files named to reflect the Product ID, so DisplayVendorID-610 represents Apple and DisplayProductID-1f4 relates to the old Apple Studio Display. It seems that Apple makes extensive use of this system to ensure that the correct display settings are applied for every Mac display; with them shipping a lot of iMacs and laptops, that’s a lot of different display panels to configure correctly.

Back to the Rift. Because I can’t get the EDID or Vendor ID or Product ID to be stored and reported by the fibre optic adapter, I decided to program it with a display that will never really be connected to the studio Mac Pro and then use an override to target that display and change how it is reported to the system. I used a random Dell display, which when connected gave me this:

ioreg -lw0 | grep IODisplayPrefsKey
"IODisplayPrefsKey" = "IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/P0P2@1/IOPP/GFX0@0/ATY,Hydrilla@1/ATIFramebufferNI/display0/AppleDisplay-10ac-405b"

That bit at the end tells us the Vendor ID (10ac) and the Product ID (405b) of the Dell panel that will be used by the override system, so we head to /System/Library/Displays/Overrides/DisplayVendorID-10ac. There’s no override for this display at the moment, so I used Xcode to create a new Property List file on the desktop called DisplayProductID-405b. But what do we want it to tell our system?

Building the Override File

First of all, we need to change that Vendor ID and Product ID. Connect the Rift to your Mac and run ioreg -lw0 | grep IODisplayPrefsKey again, which should show another line with the Rift’s details; in my case, that last element read ‘AppleDisplay-3ed2-3’. So the Rift DK2 has a Vendor ID (3ed2) and Product ID (3). We need them both as decimal integers, so the Vendor ID becomes ‘16082’ and the Product ID stays as ‘3’.

Using Xcode, I added two new rows to the .plist file; one with a Key of ‘DisplayVendorID’, the Type being ‘Number’ and the value being ‘16082’, the other with key ‘DisplayProductID’, ‘Number’ again for the Type, the Value being ‘3’.

We’re not done yet.

Now we need to replace the Dell’s EDID with the one from the Rift. With the Rift still connected:

ioreg -lw0 | grep IODisplayEDID
"IODisplayEDID" = <00ffffffffffff003ed20300000000000a18010380000078e260b1aa5540b6230c5054000000010101010101010101010101010101017240383a40800d70210a1600477e0000001a000000fc005269667420444b320a20202020000000ff0048314445343334364b48433833000000fd00384d1e9611000a2020202020200168020304038e33383a40800d70210a1600477e0000001ade3d383a40800d70210a1600477e0000001ad933383a40b41830210ac600477e0000001a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f0>

Looking at other files, it would appear that the override system likes this spaced into octets, so:

echo "00ffffffffffff003ed20300000000000a18010380000078e260b1aa5540b6230c5054000000010101010101010101010101010101017240383a40800d70210a1600477e0000001a000000fc005269667420444b320a20202020000000ff0048314445343334364b48433833000000fd00384d1e9611000a2020202020200168020304038e33383a40800d70210a1600477e0000001ade3d383a40800d70210a1600477e0000001ad933383a40b41830210ac600477e0000001a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f0" | sed 's/.\{8\}/& /g'
00ffffff ffffff00 3ed20300 00000000 0a180103 80000078 e260b1aa 5540b623 0c505400 00000101 01010101 01010101 01010101 01017240 383a4080 0d70210a 1600477e 0000001a 000000fc 00526966 7420444b 320a2020 20200000 00ff0048 31444534 3334364b 48433833 000000fd 00384d1e 9611000a 20202020 20200168 02030403 8e33383a 40800d70 210a1600 477e0000 001ade3d 383a4080 0d70210a 1600477e 0000001a d933383a 40b41830 210ac600 477e0000 001a0000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 000000f0

Now we add a row to the file in Xcode, with a Key of ‘IODisplayEDID’, a Type of ‘Data’ and a Value of the above output, wrapped in ‘< >’.

Convince the Oculus SDK

Now here’s where it gets tricksy. If you copy that file into /System/Library/Displays/Overrides/DisplayVendorID-10ac and connect either the original Dell display or the adapter with the cloned EDID, you will find that, miraculously, OS X will tell you that a Rift DK 2 is connected. Our DK2 connected over the fibre system burst into life at this point and started displaying the desktop. Success! Or so I thought.

Unfortunately, it’s not just OS X that you’ve got to convince. You also need the Oculus SDK to play nicely, otherwise it’s game over. The SDK doesn’t care about what OS X is saying, but looks straight into I/O kit (just as ioreg does) to determine if there’s a Rift present. So, although I had video on my DK2 and the USB was connected, I only ever received “No HMD Detected” messages and RiftConfigUtil showed me a big question mark. Bad Times.

At this point I took a total punt; remember that IODisplayPrefsKey we’ve been pulling the Vendor ID and Product ID from? What if the override system was good enough to spoof that as well?

The output was:

ioreg -lw0 | grep IODisplayPrefsKey
"IODisplayPrefsKey" = "IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/P0P2@1/IOPP/GFX0@0/ATY,Hydrilla@1/ATIFramebufferNI/display0/AppleDisplay-3ed2-3"

You should run this command to check your exact output with the Rift properly connected; I took that output from my system and created a new line in the property list in Xcode. This time the Key is ‘IODisplayPrefsKey’, the Type is ‘String’ and the Value is whatever your output from the command above is giving you, in my case:

IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/P0P2@1/IOPP/GFX0@0/ATY,Hydrilla@1/ATIFramebufferNI/display0/AppleDisplay-3ed2-3

Install

After all that you should now be able to copy the DisplayProductID-405b.plist file (or your equivalent depending on the display you’ll be spoofing) into the /System/Library/Displays/Overrides/DisplayVendorID-10ac or equivalent. Rename it to remove the .plist extension and now, when you reconnect your adapter with the cloned EDID (or the display itself, of course) it should appear to OS X and the Oculus SDK as a real Rift DK2.

For all that work, this is what the override file looks like when it’s done:

Loading ‘DisplayProductID-405b’ from GitHub...

Now wasn’t that fun?