FoxSol lookoutmars.com

Home/Work/Multi-angle video review

  • Windows desktop
  • .NET 8
  • WinUI 3
  • FFmpeg
  • Video

Several angles of one moment, in lock step.

A Windows application for reviewing an event that was filmed by more than one camera — built so that officials can put three or four angles of the same instant side by side and step through them frame by frame, together.

Read the full manual

The problem

Three players, three different moments.

When something contentious happens in a race, the question is almost never answerable from one camera. It needs two or three angles of the same instant, compared frame by frame.

Ordinary video players cannot do that. Open three of them and press play at the same moment and they drift apart within seconds, and there is no way to step all three back one frame together. Worse, the files themselves don't start together: cameras are switched on by hand, so one might begin twelve seconds before the start and another fifteen.

"Five seconds into the file" therefore points at a different real-world moment in every file. Before anything useful can happen, the software has to be told how the recordings relate to each other — and then never lose that relationship again.

The core idea

The operator marks one visible moment of the event — typically the start — in each angle. That becomes the zero point, and each file's offset is simply how far into it that moment falls.

Angle A starts12.4 s early
Angle B starts15.0 s early
Angle C starts9.8 s early

file position = offset + shared time

One line of arithmetic, applied per tile on every transport action. At shared time zero every angle sits on its own start; at shared time five, every angle is five seconds into the event. The alignment is done once and saved with the session.

The hard parts

Four problems that only appear once it's real.

The arithmetic is the easy half. Everything below was found by building the thing and running it on real footage on real hardware.

Keeping decoders in step

Each tile is an independent decoder with its own clock. Ganging them means every play, pause, scan, slider drag and single-frame step has to be applied to all of them at their own offsets, and the two operating modes — tiles free, tiles ganged — must switch without any tile moving so much as a frame. That last rule sounds minor and drives a surprising amount of the design.

Scrubbing backwards

Compressed video stores most frames as differences from earlier ones. Going forward that is efficient; going backward forces the decoder to jump to the previous keyframe and rebuild everything forward again. On high-resolution footage, across several tiles at once, that is the difference between usable and unusable. The fix was an optional GPU re-encode to densely spaced keyframes, swapped in underneath the tile without losing its position.

Running out of graphics memory

Four tiles of high-definition video decoding at once is a heavy load, and if the graphics card runs short of memory — usually because a browser is holding gigabytes of it — picture delivery collapses while audio carries on perfectly. It looks exactly like an application fault and isn't. Rather than hide it, the app surfaces a live memory readout, warns before loading into a starved session, and names the processes responsible.

Two clocks, never confused

There are two legitimate answers to "what time is it": position within one file, and time since the start of the event. Both are needed, and showing the wrong one is worse than showing neither — a timecode written into a report has to be right. The display states which clock it is quoting at all times, and the mode determines which one is meaningful.

Technology

Current .NET, and a video pipeline underneath it.

The choice worth explaining is the video layer. Rendering several independent, seekable, frame-accurate video surfaces in one window is not something the stock platform controls do well, so the application sits on an FFmpeg-backed library that exposes real decoder control — seek by timestamp, step by frame, query the actual position — rather than a play/pause abstraction over it.

The rest is deliberately ordinary. A desktop application, installed per-user, holding its own data locally, with no server to depend on and nothing to log in to.

Stack

Platform.NET 8, Windows desktop
InterfaceWinUI 3 / Windows App SDK
VideoFFmpeg-backed decoding and rendering, one surface per angle
Re-encodingHardware GPU encode for the seek-optimised copies
DataLocal reference database, with spreadsheet import and export
DiagnosticsSystem performance counters for live GPU memory reporting
DeliverySigned per-user installer, no administrator rights required

Points of interest

The details that came from watching it used.

None of these were in the original brief. Each one exists because someone doing the job repeatedly hit the same friction.

A detachable transport

The control bar undocks into its own window, so the video can fill one screen while the controls sit on another.

Programmable mouse mapping

Review is a one-handed job. The app maps the buttons of a multi-button mouse onto its transport, with an on-screen emulator for setting them up.

Sessions that reopen exactly

Alignment is work. It is saved as a package — angles, offsets, zero point and layout — and restored precisely, however long afterwards.

Splitting a combined source

Where the angles arrive as one composite recording, the app cuts them into separate files at clean boundaries and reloads them ready to align.

Why it's here

Specialist work, on ordinary foundations.

This is a long way from a database front end, and that is rather the point. The domain was new, the hard problems were in decoder behaviour and hardware limits rather than in business rules, and most of them only revealed themselves under real load.

What carried over from thirty years of line-of-business work was the discipline rather than the domain: model the thing honestly, be precise about which number is on screen and why, surface a problem instead of hiding it, and assume somebody else will have to maintain it.

The full manual What we do commercially

Got something equally awkward?

The interesting jobs rarely look like the last one. If you have a problem that doesn't fit the usual shapes, it's worth a conversation.