Skip to content

SageTV History (Good Architectural Overview)

Jeffrey Kardatzke edited this page Aug 24, 2016 · 4 revisions

###In the beginning..

It all started back in the fall of 2001, I was tired of working for others and wanted to do my own thing. I had a video capture card, could write good code and loved to watch TV....so I decided to create my own DVR software. The theory being that if I liked it, then other tech geeks would like it and I could build a business from there. :)

The first version, which was called TVMaster, was written in Java as a wrapper around the ATI Media Player using an ATI All-in-Wonder card. I also built my own IRBlaster for channel changing and used the IRMan serial infrared receiver for remote control. We (my brother and myself) formed an LLC in the Spring of 2002. The alpha/beta testing for SageTV 1.0 (and SageTV Recorder, now defunct) started in the fall of 2002. The product went on sale March 1st, 2003. At that time we did charge for programming guide data, but that ended within a couple months to become part of the product's overall cost.

Version 1

The 1.0 version of SageTV was a Java application, with native C/C++ components for doing capture/playback with DirectShow and supported only a single tuner. Later in version 1, we added support for multiple tuner cards.

While still on version 1, we created the SageTV Client. This was the PC based client version of SageTV (still included today). This was done by running the same Java application on another PC. SageTV had been built with a custom object database from the start; and that was the main source of data access in the application. The client/server protocol mainly consisted of a network synchronization mechanism for the database as well as various other RPC calls that would resolve any calls that needed to be executed on the server because the database itself did not have the information it needed (such as recording requests, file deletions, creation of Favorites, or anything else that requires writing/modifying to the system). There was also a mechanism for synchronizing the SageTV properties which is the main configuration mechanism in SageTV (based on Java properties files).

We also added network encoding in version 1. This was the ability to use a TCP/IP protocol in order to communicate with a capture card running on another machine and allow 3rd parties to write their own capture device components as well. The main driver was people didn't have enough PCI slots in their computers to hold all the capture cards they wanted to use. :)

In version 1, we only supported using Java2D rendering for the UI and 'punched through' the video overlay surface to get native video to render in a Java application.

###Version 2

In version 2, we added support for music and video playback, because this was fairly trivial to do since we already had a DirectShow based media player working. Picture support was also added at some point, which was trivial because we already did image display in the UI. We also integrated with Direct3D for UI rendering and for 3D compositing of video with the UI during playback so we'd have a proper alpha-blended user interface.

At this time, we also created the SageTV Studio. The driver behind this was because every user had an opinion on what the user interface should do...and I wanted to try to satisfy everyone. So I figured if I made a tool that allowed for much more rapid UI development, and then gave that to customers to use as well (which took a couple years until we made that decision) then everyone could get the UI they wanted....yeah, great theory...not reality, but it helped. :) The SageTV Studio is a graph-based custom language, which allows arranging and dynamically modifying everything in the UI. It also integrates execution of APIs/Java code so that the full functionality of the app can be modified...this goes far beyond 'skinning'. Every single thing in the user interface is modifiable through the SageTV Studio, I've even used it for creating completely different apps sometimes just because I can build things quickly with it.

The API in the Studio was also very convenient because it required creating one type of RPC mechanism that allowed remote or local execution of any API call in the Studio. Developers didn't need to worry about what needed to execute on the server or client, because it was all done automatically in the API.

###Version 3

Version 3 wasn't that big of a change, just extending more format support, capture cards, EPG sources and other peripheral features like RSS and Weather.

###Version 4

Version 4 brought a new feature which was critical to our long term success. This was support for the Hauppauge MediaMVP. This was a PowerPC based device that hardware decodes SD video and properly outputs it in 480i with interlacing the way it should be (most PC video cards did a very poor job of that at the time). We created the 'miniclient' which was a native C application which ran on the MediaMVP. This then allowed users to network SageTV to all the TVs in their house without having to put a PC in front of every TV (HD wasn't big yet, so they were happy with SD). We also created the miniclient protocol which consisted of 2 streams. One was the graphics/event stream which sent all the graphics rendering commands to the client and also received events back from the client. The other was the media stream which pushed the video bits to the client and also sent all of the corresponding playback controls as well.

We then realized this same protocol could be used for remote connections, not just local. So we created the SageTV Placeshifter which used the same protocol as the miniclient. We also integrated FFMPEG support so we could transcode the video in real time for streaming at more acceptable bitrates (which back then was a few hundred kbps, you could dream about megabit connections at that time for your home). Because the graphics protocol was just drawing commands (aside from when images were needed initially, and then they were sent over in compressed form to be referenced later) this ended up with a great low-bandwidth solution that was very responsive for remoting the entire experience.

The other great part about this protocol was we already had a system for abstracting the rendering engine in the UI (Java2D or Direct3D); so we just added another rendering engine which sent everything over the network. This meant whatever we did for the user interface for SageTV got automatically extended to work with SageTV Client, the MediaMVP (and future media extenders) as well as the SageTV Placeshifter. Giving a consistent experience no matter how it was accessed.

###Version 5

Version 5 was mainly solidifying what we had. Lots of cleanup was done to various parts of the UI, more capture cards with more TV formats (worldwide digital TV like DVB-T, DVB-C, DVB-S, etc.) were supported. More options for transcoding were added. We also added support for full DVD playback on the media extender as well. At some point before this we also publicly released the Studio...not sure exactly when though. :) And we also added support for Mac & Linux around this time. The Mac code never was that great, so it only has some parts of it in the open source repo. But the Linux code is rock solid (that's what I've been running for years). Only problem is that we don't have a great client for Linux, the Placeshifter is the only current option and there's sometimes issues with video rendering in the Linux destkop. But it's a great server for the media extenders or Windows PC clients (and now also the Android SageTV client).

###Version 6

Lots happened during version 6, as it spanned over a 3 year period. On the software end, it had an updated UI and we also filled out our media player support even better to handle more formats, subtitles, multiple audio tracks, chaptering, BluRays (no menus) and cleanup any playback related bugs in these areas. The main thing was the introduction of the HD SageTV Media Extender. Overall, we did 3 versions of this. The HD100, HD200 and HD300 (but the HD300 was probably during Version 7).

The HD100 was simply a media extender. It had very little headroom, so we created a C version of the UI rendering system and then hardcoded the UI behaviors rather than having it handle Studio generated files (that was just for the setup/config UI before you connected to the server). We also created a miniclient for it as well. This product was a huge hit, and we had trouble meeting demand for awhile after we introduced it. HDTV was getting very popular, so this was a critical step in ensuring we could provide the whole home media solution our users were looking for.

The HD200 also was a standalone media player. We ran a JVM on it (Sun Microsystems CVM), with a forked version of the SageTV core Java application. The main issue was there was no FPU on the device, so we had to convert lots of code to be integer only for performance reasons. Forking code in your own repo sucks...especially when you do it for a few years straight. On the plus side, this allowed the device to be a media player that could be used without a SageTV server at all. In hindsight, that was sort of a waste...because nearly every customer used it as a media extender, very few used it as a standalone media player because it just ran so much faster when the server was doing the UI logic (but the device still did all the rendering itself).

The HD300 was similar in function to the HD200, but ran faster, and supported larger media libraries in standalone mode because it had more RAM. It also had an FPU, so we got to unfork a lot of the code...but the JVM on it didn't have as much support as the desktop variants, so there was still a fork for some of the code.

###Version 7

Version 7 introduced another UI (which is the main one in the open source repo) and also introduced the SageTV Plugin system so that it would become much easier for users to integrate STV (the files the Studio creates) modifications into their systems or other external components. One of the beautiful things about the Studio is that every object in it has a UID associated with it. So you can make changes to it and then easily export them as an .stvi (STV import) file which is essentially a delta between two different UIs. So long as you weren't modifying the exact same thing as somebody else, you could pile a whole bunch of these on and they would all work beautifully together...I'm still really fond of that architecture, it was very powerful and allowed for so much user customization. We also were on the 3rd version of the animation in SageTV by this point. The first one was pretty lame...just put your own timing code in the Studio and then modify stuff when it refreshes...very inefficient and not user friendly at all. The second version involved layers, where you needed to specify what was a 'layer' in the UI and then you could only animate those layers...not bad, but very limiting still. The final one was the 'effects' system, which allowed you to specify any type of effect such as slide, fade, rotate, etc. and also do tweening associated with it. Then the core UI system was smart enough to figure out if it needed to cache stuff in composited layers for performance reasons and would only refresh areas that actually had active animations being performed. This allowed a major advancement in the capabilities of the UI....the goal was to be able to match the cool stuff we were seeing in XBMC, and we achieved that (there is even an XBMC skin importer, which I spent tons of time creating, which nobody ever really used because XBMC didn't have any decent DVR UIs for it).

###You did what??

Then we sold to Google....that was pretty damn awesome (yeah, for us...sorry...but I did end up open sourcing this, albeit 4 years later...and the SageTV train moves on).

Hopefully this helps some people in learning more about the SageTV architecture and its history. :)

Clone this wiki locally