Skip to content


asquared edited this page Feb 8, 2011 · 24 revisions

Update 2010-09-05: The Control Console might make your life slightly easier in the near future.

Update 2010-11-17: An openreplay mailing list has been established via Google Groups. Anyone should be able to join at

Update 2010-11-27: Integration with HockeyBoard has started. Stay tuned (to RPI TV, that is, as well as this page…)

Update 2010-12-02: Digitally-stored graphics can now be overlaid on playout streams. For now that’s “instantreplay_title.png”, overlaid at some coordinates hard-coded in playoutd.cpp. Press ‘k’ to toggle the key on and off. Also, HockeyBoard clock overlay is working with a patched HockeyBoard and the new “clockd” program in Openreplay. See untested branch for some details. At the moment, “clockd” has to be running for things to work properly. Also, a shared memory region mapped from the “clock_ipc” file is used for clock communication, so “dd if=/dev/zero of=clock_ipc bs=256 count=1” before starting any captures with the untested branch. Use the ‘b’ key (scoreBoard) to toggle the clock on and off. Crude screenshot (Please note that the RPI TV graphical theme in use in the screenshot may not be used outside of RPI TV.)

Update 2010-02-08: Openreplay is 1 year old as of a couple days ago! It’s come a long way since those late-night commit messages I’ve come to regret. Anyway, in addition to lots of bug fixes and a better-structured output adapter system, today I’ve pushed support for up to 8 DSK titles. These are now toggled with the 0k, 1k, …, 7k commands; the files to load are currently hardcoded in playoutd.cpp. This accompanies a significant advance in RPI TV’s instant replay possibilities… to be announced and hopefully discussed further tonight!

Bleeding edge is currently the ‘master’ branch (mostly-working, should compile). ‘untested’ is code I’ve written, but that hasn’t been tested on real hardware yet. Most likely it compiles and is worth a shot. Other branches are old and have generally been merged into master.

In case of issues with openreplay, please use the issue tracker at Thanks!

New Features

Hardware You'll Need/Want

Building Openreplay – start here

Capture Setup and Examples

sdl_gui Usage – tape this to the wall

playoutd Usage

ffoutput Usage

Openreplay Internals

Sample Video:

  • Beyond this point, things are vaguely deprecated. Some information may still be useful, but key bindings are probably wrong. Proceed with caution! **

Openreplay is open-source video instant replay for Linux. It is currently alpha code, but it has been used successfully in a number of sports productions of RPI TV ( It supports multi-camera capture, live cut playback, and slow-motion and freeze frame capabilities. Please note that most of the code to date has been written between the hours of 12:00am and 7:00pm, so refactoring is necessary, but it works!

A sample video is now available at

Right now, only NTSC video is supported. 25fps PAL sources should function more-or-less correctly, but certain code makes assumptions about frame rate and size. Your time code display will be off, and playout will be a bit on the fast side, if adjustments aren’t made. The GUI won’t display the entire frame either.

To get started, you’ll probably want to invest in at least one Blackmagic Design capture card, as they’re currently the only supported devices for playout. The “bmdplayoutd” program can be modified to write raw NTSC UYVY data to stdout, by using the “StdoutOutput” class in place of the “DecklinkOutput” one. You will need to get the Blackmagic Decklink SDK installed (it’s available on their website), and edit the Makefile to point at its paths. You will need to install libavcodec and related development packages. (On Debian: sudo apt-get install libavcodec-dev libavformat-dev libavutil-dev libswscale-dev should do it. Makefile tweaks may be necessary.) You will need to install SDL and development libraries (sudo apt-get install libsdl1.2-dev libsdl-image1.2-dev libsdl-ttf2.0-dev, if memory serves). You will also want to install ffmpeg, in all likelihood. From there, run make decklink_capture sdl_gui mjpeg_ingest bmdplayoutd to build the essential components of openreplay.

There is no “make install” yet. I recommend an installation like this…
bc. cd wherever/openreplay
mkdir ~/bin (if you don’t already have it)
cp bmdplayoutd mjpeg_ingest sdl_gui decklink_capture mkcontrolfile mkdatafile ~/bin

You will want a large scratch disk. Due to possible bugs in the ring buffer code, I recommend using a buffer of at least 60 gigabytes per camera, and resetting it about every 30-40 minutes. (Coincidentally, this corresponds almost exactly to the typical length of a period of hockey.)

Make a directory on that scratch disk, and “cd” into it. Make sure the “font.bmp” file from the distribution makes it in there as well.

You must now create the buffer files for your camera feeds. Each buffer requires two files: control and data. The control file is used for shared state between the ingest processes and the GUI. The data file stores MJPEG frames. Use the “mkcontrolfile” and “mkdatafile” scripts to generate these files. I recommend creating a script “reset” containing the following commands (adjust to fit your setup), or you can just type them at the command line.

rm cam1_ctrl cam1_data cam2_ctrl cam2_data # anything else goes here
mkcontrolfile cam1_ctrl
mkdatafile cam1_ctrl 60G
mkcontrolfile cam2_ctrl
mkdatafile cam2_ctrl 60G
# add more control and data files for more cameras

So we’ve got control and data files. Let’s start ingesting some video into the buffers. Something like this will work for a Decklink card.

decklink_capture 1 | ffmpeg -f rawvideo -pix_fmt uyvy422 -s 720x486 -i - -f mjpeg -s 720x480 -qscale 6 - | mjpeg_ingest cam1_ctrl cam1_data

See how the control and data files are passed to the ingest process? This controls the video routing. It is extremely unwise to run two ingest processes on the same data and control files. Things will probably break amusingly. The argument to decklink_capture determines the card to use.

It is also possible to ingest from a FireWire source. I usually use something like the following…
bc. dvgrab – | ffmpeg -i – -f mjpeg -s 720×480 -qscale 6 – | mjpeg_ingest cam2_ctrl cam2_data

You can even capture from a FireWire source on a remote machine, like so…
bc. ssh your_account@your_remote_machine ‘dvgrab – | ffmpeg -i – -f mjpeg -s 720×480 -qscale 6 -’ | mjpeg_ingest cam3_ctrl cam3_data

The “-qscale” flag to ffmpeg can be used to adjust the compression quality. Bigger numbers = higher quality but more bandwidth usage. I/O bandwidth was an issue with raw video, so don’t ramp it up too high.

So, video is being ingested. You can run the “sdl_gui” binary to see it, like so…

sdl_gui cam1_ctrl cam1_data cam2_ctrl cam2_data (and so on...)

Just pass in as many control and data files as you like. You may reach a point where things stop fitting on your screen. Try to avoid that for now. Press ESC to exit.

There are a lot of other buttons to be pressed here. Keypad + will mark an event, and begin saving a MJPEG clip. Keypad ENTER initiates playout of the most recent clip. (This only works if “bmdplayoutd” is running. More on that to come.) The numeric keypad is used for numeric data entry. For example, typing “150” on the num pad followed by “e” sets the preroll interval to 150 frames. (This means that 150 frames will be saved from before the marked event.) “150d” does the same for postroll. “3c” sets playback speed to 30%. You can probably tell what my favorite text editor is right about now.

Onwards to playout. Start bmdplayoutd. Just running “bmdplayoutd” is sufficient. This will automatically open the first Blackmagic card in the system for output. It should output green. Going back over to the UI, hit keypad + to mark a clip, then hit keypad enter to play it out. You should see it play out on the monitor attached to your card. If you get black instead, it means bmdplayoutd crashed for some reason. Send me the mjpeg file it crashed on. That should be in its output somewhere.

Now, while it’s playing, hit one of the “1”, “2”, “3”, through “9” keys across the top of the keyboard. Hit “Page Down”. You just cut to another source. Try again, but this time, hit “End” instead. Now you cut to another source, and also restarted the replay.

You probably noticed “LOGGED CLIP: 1” when you first hit “+”. You can key in those clip numbers and use the keypad “.” key to select a previous clip. Then use the keypad “-” key to initiate playout of that clip.

The keypad “/” and “*” keys adjust the speed (increase and decrease, respectively.) These adjust the speed of live playouts as well, so be careful. If you don’t want to do that, hold down the “Ctrl” key while using them.

F10 pauses the current playout. F11 advances by one frame. F12 continues at the currently selected speed.

Make sure “Num Lock” is on. Numeric entry misbehaves otherwise.

If you’ve marked a replay, and want to find the best camera angles, hit “Insert.” This will preview starting at the beginning of the preroll interval, instead of showing live feeds. To quickly return to the live preview, hit “Home.”

Once again, when you’re done playing around, press “Esc” to exit the GUI. The rest of the processes can be terminated with “Ctrl-C”.

Enjoy Openreplay! If you use it, I’d like to hear about it!

Andrew Armenia

Something went wrong with that request. Please try again.