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:
- 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.
- 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.