System requirements

System requirements describes as a whole, what your program should do, in what kind of environment. The latter is quite important: basicly, you're going to decide now what operating systems your program requires and what libraries and tools you are going to use.

It may seem way too early to decide this now. But you must: if you do not do this now, you'll get stuck later on because somebody (or yourself) came up with a good idea or request, you decide to add it to your program and then found out that your architecture doesn't really support it. So you hack it on. Then later, you come up with a second feature, find that your first hack is slightly in the way, so hack feature #1 to support feature #2, then hack on feature #2, fix the bugs you introduced in feature #1 by adding feature #2, etc. By the time you're ready to implement feature #7, your code is a mess, littered with #ifdef/#endif, and you keep hitting that 'bug' where you first have to do a make in subdir 'foo' in order to edit something in subdir 'bar'. Trust me, I've been there.

Now I admit I am cheating a bit here, since CamStream has been in development for quite some time, so I already have a headstart with respect to system requirements. However, I keep thinking to myself: "That would be a cool feature to have...", but then end up with huge amounts of work. Two examples:

  1. Currently, the development branch of CamStream runs on both Linux and Windows. Windows support was added later on (mainly due to the release of a free QT 2.3.1 version for Windows), and it required a rewrite of the VideoDevice class. In itself that isn't bad; although it is the 3rd incarnation of these classes, I now have a structure that I like and have confidence in.
  2. While I'm writing this documentation, I'm switching from handmade Makefile's to automake (mainly because I started using it at work and fell in love with it). However, I did not realize that I had to use automake throughout my whole project, or it wouldn't compile. Oops. So instead of gradually introducing automake, I had to build my Makefile structure again from scratch.

Having said that, making system requirements doesn't make the amount of work any less; however you can see the impact a lot earlier.

Decision time

Okay, so how, and with what, are we going to write CamStream. Now there's an overwhelming amount of options available if we want write a program for a computer, ranging from languages, libraries, operating systems, to editors, build systems and supported hardware. So we will have to choose. Oh boy. I don't know if you are one of those persons who takes forever to decide on the menu in a restaurant [1], but that's a bad habit when it comes to programming.

So, what do you choose? Well, there's a simple rule for that: choose whatever you're comfortable with, and you know well. Apart from small test projects, it is not a good idea to start a medium sized project (like CamStream) with all new technologies you have no experience with. I could have started writing CamStream in Perl, using automake, writing the documentation in DocBook and distribute it using RPMs. But I have little or no experience with those four technologies, and I would not have gotten far.

However, it is quite possible you discovered some new tool, language or library that you think is really worthwhile for your project. Then by all means try it, otherwise you would never learn anything new, would you? But choose one new thing only. One tool, one language, one platform.

So, what did I decide upon? Look at the list below. If you read the list carefully, you will see that some of the decisions influence each other.

A GUI design
CamStream is a GUI, with no command line options. There is not even going to be a command line version (and believe it or not, people have asked for it. How one is supposed to run a GUI program with nothing on the screen is a mystery to me....)
I have thought about writing a daemon that would do the low-level audio and video stuff and make it available to CamStream or other programs. But that would be a lot more complex, so for now it's going to be a single lump of code.
Programming languages: C++, assembly
No contest possible :-) Well, the main reason is my vast experience with the language, I like it and because the resulted code is still reasonably fast. Showing moving pictures on screen requires quite a bit of processing power, and you can't have your language slow you down in that way. Also, I need to do some low-level kernel interfacing which is based on C, so C++ is a good match.
For the real performance stuff I will use x86 assembly, including MMX instructions. Of course, for non-x86 platforms we still need plain C code.
Platforms: Linux and Windows
This is one of the toughest choices; cross-platform development can be a bitch (excuse the term), especially if you have to deal with low-level device drivers for audio and video, as in this case. In fact, at first I only supported Linux, but getting more experience with cross-platform development at my job, and the fact that Trolltech released a free Qt version for Windows, made that decision easier.
Also, I have to keep in mind that Linux runs on a lot more CPUs than just Intel chips. Even though the video and audio interfaces are the same on Linuxes, there's still an element of "cross-platformness" there.
Libraries: Qt
Once you get hooked to Qt, there's no way back :-) The completeness of the library, plus its multiplatform supports plus its signal/slot mechanism makes it a big winner.
There is one big dependancy here: choosing Windows as supported platform means I must limit features that I use in Qt to only what's supported in Qt 2.3.1, the only freely available Windows Qt library. However, Qt 3 is the main library in use on Linux, so it must compile and run on Qt 3 as well.
Video hardware: webcams and TV cards
Although the API for webcams and TV cards is the same, there are some fundamental differences between how these devices operate. In addition, I wanted to support all features my own Linux Philips webcam driver (PWC) has. So, actually that makes three hardware platforms. Oh yeah, on both Linux and Windows.
Audio hardware: using ALSA
In contrast to the video side, Linux has one excellent sound API, which is going to be in the new and upcoming 2.6.0 kernel tree: ALSA. After having compared the old OSS and ALSA API (and documentation), I made the decision only to support ALSA. OSS would be too much of a pain. So far, nobody complained :)
Build system: automake
Using Qt has the advantage of 'qmake', and .pro files. Unfortunately, Qt 2.3.1 for Linux is run with Perl and requires extra steps to setup. And it's too limited. After having used handmade Makefile and configure.in scripts for a long time, automake is now the way to go.
Compilers: GCC 2.95.3, GCC 3.2, Microsoft Visual Studio 6
Three compilers? Oh yes. GCC 3.2 is mainstream on most Linux distributions these days, but not all. However, that compiler is quite a lot stricter, so code writing will have to be more secure. I did not use CygWin or DJGPP for Windows. I simply need the Windows API to access the audio and video devices.
Support for RedHat's own GCC 2.96 brew will get low priority (it's not an official GNU version and has its own peculiar set of bugs).

So this list narrows it down quite a bit. From all these decisions, two technologies were really new: Windows and ALSA. Now you are probably saying: "But you said to pick only new thing..." True, but I did not decide upon using Windows and ALSA at the same time (remember, CamStream is work in progress). In fact, there has been quite some time between the introduction of Windows and ALSA, so they count as separate decisions.

Having made this list, I can now decide quickly if a new feature request can be honoured. You want CamStream for WinCE? Forget it, that OS doesn't even support video devices. Having trouble compiling it on RedHat? Well, fix the compiler.

Of course, this list is not immutable. Suppose you do want to support OSS for audio stuff anyway. Then you can look at this list, see where it fits in and estimate how much work that's going to be. Or want to support Mac OS X. Decide, then add or do not add. Then go through your requirements and see where it has impact. You may be surprised...


1 Not me, BTW. I've usually decided what I want to eat within 89 seconds flat. Even if it is something I've never eaten before.