Friday, July 10, 2009

Personal situations update: July 10, 2009

Hello. Just wanted to update you and tell you that Saya is NOT dead... by an inch.

The depression came back, but this time I've really managed to overcome it. It has been a very chaotic month. I began to feel lonely and in desperate need to seek a girlfriend. My delusions had made me believe that I could never find a girlfriend (in part because of my own depression), but thanks to a huge effort involving courage, asking girls out through third parties and joining several social networking websites, my self-esteem has finally stabilized to a non-negligible positive value.

On the other hand, I got a job! And a very good one. Not very good financially speaking, but one without excessive stress and which will allow me to occasionally work SOHO (at home).

Today is one of those days. I got a terrible stomach sickness (I'll omit the gross details) today's morning, and I had to stay at home. Even with a huge pressure to have the work finished by this monday, I feel fine. I've also upgraded my copy of Code::Blocks (which now has a lot of very-needed features) allowing me to code without problems.

This is where things are getting interesting. The combination of programming seriously while listening to my favorite music at home, has given me a second boost in the desire to keep working on Saya.

Unfortunately, i have very little time left. But at least Saya is getting a ray of hope as an in-hiatus project. Don't despair!

Maybe in a couple of months, if everything goes well, I'll be able to get back to work on the project.

I'd also like to thank everyone for their kind words of support during my darkest hours. Thanks to you, and to everyone who prayed for me, I'm still alive, and kicking!

Thank you all!


P.S. Receiving some money would also help. If someone charitative wants to give a poor programmer some financial support, he's welcome to do so ;-)

Sunday, June 7, 2009

The depression is over!


A week ago I joined, an online dating site based on questionaires so that you can find your match based on politics, moral, hygiene, religion, common interests, sexual tastes, attitudes towards life and whatnot. Answering over 1000 multiple-choice questions has helped me know myself and boost my self-esteem. I no longer feel lonely or doomed to die abandoned by everyone. I go to bed with hope instead of pain, and wake up with joy instead of the burden of having to live another day.

FINALLY, I am free!!

If a nerd girl (otaku preferred) wants to become my girlfriend and lives in Mexico City, feel free to visit my dating profile.

Anyway. My current job is still going to be very demanding for the next two weeks. Maybe then I'll be able to resume work on Saya.

Until then, so long!

Monday, June 1, 2009

First day at job

At least I got a new job, but I'm beginning to understand that phrase about earning the bread with one's sweat.

The job was supposed to be from 9 to 6, but due to schedule reasons, I'll have to be from 8 to 7, AND 4 additional hours on weekends. At least for these two weeks.

I don't think I'll be able to work on Saya for a while.

I'm beginning to wonder if the project is doomed to failure due to lack of time. Sigh.

Friday, May 29, 2009


Expect a couple of weeks so I can stabilize, and I'll be working on Saya again. Now... what was I doing before I suspended activities? :(

Anyway. Let's hope we haven't lost much time, and the Pitivi guys are really putting money into it. We cannot lose to them!!

Thanks for your prayers, everyone.

Thursday, May 28, 2009

Need to check my vision...

Just this evening, I noticed that reading seemed to be more difficult for me. I noticed that straight lines look wavy on the center of my vision when I look through the right eye.

I need to go to a doctor ASAP. Let's hope I don't wake up blind by tomorrow.


Update (one hour later): I got to bed and one hour later I realized my eye had been hurting a bit this day. I noticed because it stopped hurting. I can see normally again! :D

Thank God!

I guess I need to check myself for hypertension then.

First commit in a while!

Sashiburi guys. Long time, no see.

I can't really say that Saya development has restarted. I'm still unemployed and I still feel depressed every once in a while (btw, looking for a girlfriend in Mexico city. Anyone?).

In any case, I hope development will restart soon. There's a 50% chance that I get a new job this monday. Wish me luck!

Thursday, April 23, 2009

Alergic to certain brands of orange juice...

For the past 2 or three weeks I've tried to concentrate on developing, but a mild-yet-annoying-as-hell headache always interrupts me just when I try to code, which is around 10 or 11AM.

I just can't concentrate like that. I've tried taking antiacids (it happens to me, sometimes I get headaches when I get gastritis), painkillers, and I even began to fear it might be a tumor.

Today I ran out of the orange juice that mom had purchased. And I didn't get a headache after breakfast today. WTF!?

I feel like an idiot. Fearing cancer when in fact it was just a simple allergy. Stupid orange juice. Let's hope that tomorrow I can recover from these code-less weeks.

Wednesday, April 8, 2009

Restarting engine... vroom vroom... it works! :)

Finally! My first day of coding since a full month. Getting my brain to start after a full month of not seeing the code was like losing my way back in a maze. "Huh? Where did this go? What do I do now?"

So I had to start with the simplest of things: The project panel. It only needed a tree and a context menu. Man, did I have to dig in the user manual to find it.

But it worked! :) I'm fresh and ready to start coding again!

... tomorrow :P

On the other hand, I realized why it took me so long to start programming. It seems I have gastritis (or perhaps a stomach ulcer). If I stayed too much without eating, I began feeling hungry, dizzy and with headaches. So now I'm taking medications (omeprazole) to restore my stomach to pristine conditions. Since the first day of medications, I felt better and with more energy. Who would've thought?

On the bad news, I'm STILL unemployed :( Let's hope I find a good job after Easter! :)

Thursday, March 26, 2009

The Exhaustion of Saya Developer: Book 2

It was two weeks of being sick. I was horribly bored and exhausted at the same time. Some friends of my family invited us to take a vacation, invitation which I accepted joyfully. We went to [place undisclosed for security reasons] and I had a good time. Finally, I returned home yesterday (with a horrible headache, btw).

Now I'm finally resting and preparing myself to continue working on Saya (after a full month of interruptions) and to search for a new job next monday.

Boy, what a month.

Monday, March 9, 2009

Quit my job, got the flu...

Hi guys. I'd like to inform you that due to health reasons I'll be unable to work on Saya for the next few days (a horrible flu). Also I had to quit my job for health concerns (and other reasons I won't be detailing here).

Still, thanks for your support. Sincerely,

Wednesday, March 4, 2009

Converted Project Pane, first bugs appeared...

The good news: I managed to convert around 90% of the Project Pane (the tree window and popup menus still need conversion), and moved the code away from the main window.

The bad news: The window state saving and loading routines seem buggy... the project pane is not shown when it should, so I had to comment the call that hides it when the main window is invisible.

I do think I spotted the bug - Qt saves the window layout data in binary form, so I had to convert it to base64. However, I haven't tested if the state loading routines work after the change.

(Update (March 9, 2009) : The window state saving/loading routines are now fixed!)

I also spotted some functions that aren't called by the main menu. I need to fix them, too. But now the code seems much cleaner (I removed a lot of wxWidgets UI code that now is generated automatically by QtDesigner.

After seeing how much the code is simplified, I can finally say that I don't regret switching to Qt.

Sunday, February 22, 2009

Qt's aboutToShow() signal: Did we find a bug?

While converting the wxWidgets code to Qt, I realized something. A QMenu's "aboutToShow()" signal is triggered around 30 TIMES whenever you open that menu. So my menu refreshing routines will be called that many times.

The question is: How to work around it?

Update (Feb 23, 2009, 19:35): Alexandru wrote a sample application, and surprisingly for me, the application does NOT trigger the aboutToShow() signal a lot of times per menu, but rather, only once. Which means only one thing:

The bug's mine. Now I need to check out what went wrong.

Update (Feb 23, 2009, 19:43): I see now what happened. The function I used to automate the connection creation was recursive, but I added the aboutToShow() connections on that same function, which, obviously, got called a lot of times.

I moved the aboutToShow connections elsewhere, and problem solved :)

Alexandru gets a trust point for helping me fix this bug. Yay!

Thursday, February 19, 2009

Mom's feeling better, and progress has been made!

Good news people!

The first, is that my mom is feeling better :). She's under treatment and the fever is gone. In a month we'll see how her kidney is doing.

The second good news, is that the event handling code has been finished and the Welcome dialog is functional (but still ugly).

The one-month goal for the Qt4 conversion deadline now seems possible. Stay tuned.

Sunday, February 15, 2009

Alexandru's video demo.

Alexandru sent me a demo of filling an area of the screen with a determinate pattern of pixels. I modified his demo a bit so it would display random pixels, and so I could find out which bits corresponded to which color.

After a while, here's what I got:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>

/*demo took from a saya example*/
void fill_image(char *data, int w, int h, int bpp) {
int x, y;

char *adr;
for (y=0; y<h; y++) {
for (x=0; x<w; x++) {
adr = data + (y * w + x) * bpp;

unsigned long pixel;
// if(!(x % 10)) {
// pixel = 0xFFFF0000;
// } else if (x & 1) {
// pixel = 0xFF00FF00;
// } else {
// pixel = 0XFFFFFFFF;
// }
unsigned int r = rand() & 255;
unsigned int g = rand() & 255;
unsigned int b = rand() & 255;
pixel = (b << 24) | (g << 16) | r << 8;

*adr = pixel>>24;
*(adr + 1) = pixel>>16;
*(adr + 2) = pixel>>8;
*(adr + 3) = pixel;

void clear_image(char *data, int w, int h, int bpp) {
memset(data, 0xFF, w * h * bpp);

int main() {
Display *m_display;
Window m_window;
GC m_gc;
Visual *m_visual;
int m_screen;
unsigned int m_width;
unsigned int m_height;
unsigned int m_x;
unsigned int m_y;

XImage *image;

XEvent event;

XSizeHints hints;
XSetWindowAttributes attributes;

int format;
int offset;
char *data;
int bitmap_pad;
int bytes_per_line;

unsigned int depth;
int bpp;

if ((m_display = XOpenDisplay((char *)0)) == NULL) {
printf("cant open x connection\n");
return -1;
m_screen = XDefaultScreen(m_display);

m_visual = DefaultVisual(m_display, m_screen);

depth = XDefaultDepth(m_display, m_screen);

/*list supported depth for demo purposes*/
int count_return;
int *depths = XListDepths(m_display, m_screen, &count_return);
if (depths) {
int i;
printf("supported depths:\n");
for (i=0; i<count_return; i++) {
if (depths[i] == depth) {
printf("%d [default]\n", depths[i]);
} else {
printf("%d\n", depths[i]);


/*list pixmap formats for demo purposes*/
XPixmapFormatValues defaultPixmapFormat;
XPixmapFormatValues *pixmapFormats = XListPixmapFormats(m_display, &count_return);
if (pixmapFormats) {
int i;
for (i=0; i<count_return; i++) {
printf("depth: %d\n", (pixmapFormats + i)->depth);
printf("bits_per_pixel: %d\n", (pixmapFormats + i)->bits_per_pixel);
printf("scanline_pad: %d\n\n", (pixmapFormats + i)->scanline_pad);
if (depth == (pixmapFormats + i)->depth) {
memcpy(&defaultPixmapFormat, pixmapFormats + i, sizeof(XPixmapFormatValues));


bpp = defaultPixmapFormat.bits_per_pixel / 8;

m_width = 200;
m_height = 100;
m_x = 500;
m_y = 500;

attributes.event_mask = ExposureMask | KeyPressMask;
attributes.background_pixel = BlackPixel(m_display, m_screen);

/*depth 32 doesnt work !!*/
m_window = XCreateWindow(m_display, XDefaultRootWindow(m_display), m_x, m_y,
m_width, m_height, 0, depth, InputOutput, m_visual, CWEventMask | CWBackPixel, &attributes);

if (!m_window) {
printf("error creating window\n");
return -1;

/*set size hints for window*/
hints.min_width = hints.max_width = m_width;
hints.min_height = hints.max_height = m_height;
hints.flags = PSize | PMinSize | PMaxSize;
XSetWMNormalHints(m_display, m_window, &hints);

/*set windows title*/
XStoreName(m_display, m_window, "X11 Saya");

/*create graphic context*/
m_gc = XCreateGC(m_display, m_window, 0, NULL);

/*display the window*/
XMapWindow(m_display, m_window);

offset = 0;

/*alloc data buffer for storing image*/
if ((data = (char *) malloc(m_width * m_height * bpp)) == NULL) {
printf("error malloc");
//free x structures
return -1;
memset(data, 0, m_width * m_height * bpp);

bitmap_pad = 32;
bytes_per_line = m_width * bpp;

image = XCreateImage(m_display, m_visual, depth, ZPixmap, offset, data, m_width, m_height,
bitmap_pad, bytes_per_line);

if (image == NULL) {
printf("error creating image\n");
return -1;

int step = 1;
while (1) {
XNextEvent(m_display, &event);
if (event.type == Expose) {
// printf("expose\n");
XClearWindow(m_display, m_window);
// if (step % 2 == 0) {
// clear_image(data, m_width, m_height, bpp);
// } else {
fill_image(data, m_width, m_height, bpp);
// }
XPutImage(m_display, m_window, m_gc, image, 0, 0, 0, 0, m_width, m_height);
} else if (event.type == KeyPress) {
/*size up the image*/

m_width += step*5;
m_height += step*5;


data = (char *) malloc(m_width * m_height * bpp);
image = XCreateImage(m_display, m_visual, depth, ZPixmap, offset, data, m_width, m_height,
bitmap_pad, 0);
if (image == NULL) {
printf("error creating image\n");
return -1;

XResizeWindow(m_display, m_window, m_width, m_height);

if (step == 10)


XFreeGC(m_display, m_gc);

if (m_window) {
XDestroyWindow(m_display, m_window);
if (m_display) {

return 0;

And here's the result:


With some more effort, we'll be able to reproduce a computer-generated video in realtime. At least in X11, the windows driver will use other code. Thanks a lot, Alexandru! Keep up the good work!

Saturday, February 14, 2009

Mother's ill...

My mother got a kidney stone, and until she gets the stone removed I'll have to help her do the dialy chores, so I guess I won't have free time to work on Saya for the next 2 or 3 weeks.

Sorry guys. I'll keep in touch.

Wednesday, February 4, 2009

My books finally arrived!

Herb Stutter: Exceptional C++


Hughes & Hughes: Professional Multicore Programming.


Monday, February 2, 2009

Programmer's block

I hate it when this happens. The conversion to Qt might seem easy at a glance, but then you realize there's so much to do, and don't even know where to start.

The worst part is that I had the whole day to program, and I couldn't do anything (well, I updated the website). What a waste.

Anyway, finally I realized I should leave the main frame for the end, when the rest of the functionality is ported. So I'll start to work on the welcome dialog. Let's hope I can do that this week.


Wednesday, January 28, 2009

Status update...

The only work I've been able to do on Saya this week is copying the Main Menu from wx to Qt, and that was on the weekend.

The reason: I had to sleep at 3 o'clock on Monday and this has exhausted me. Probably I won't be able to work on Saya until Saturday after I've had a VERY GOOD sleep.

On the other hand, this Friday we'll have the developers meeting. Two people will be joining the team, and two people will be leaving. Let's hope that I can finish the Qt conversion for the end-of-March meeting so we can move on.

Wish me luck!

Monday, January 19, 2009

Report on the non-advance of the project.

My job's killing me. I haven't been able to work on Saya the last week, and I this week there will be only a 50/50 chance I can get to work on it.

On the other hand, it seems I've managed to gather not one, but TWO volunteers. One will work on the mascot (yay! ^_^) and also has some Qt experience. The other one... I forgot, sorry.

Wish me luck and some free time!

Good night.

Sunday, January 11, 2009

Report on the Qt conversion

Hi everyone. Just a quick report on what I've been doing today.

I've been having a hard time converting the application to Qt. Basically, I've had to take a decision: To adapt the C++ code directly to use the eventid#'s and get rid of Qt designer advantages, or workaround the autogenerated code by writing some wrapper functions and write LOTS, LOTS AND LOTS OF CODE.

The advantages to the Qt designer are obvious. Easy code generation, forward compatibility, etc.
But I've grown tired of how wxWidgets loads the UI using xml libraries. Is that REALLY necessary?

I realized I wouldn't need to choose between the two. Why? Because Qt designer lets you see the generated code! :D

I only have to copy/paste the code, just like I've been doing with wxFormBuilder. Also, I realized I didn't need to write a lot of code. Remember this?

int idFileOpen = XRCID("idFileOpen");

I can easily rewrite the Id registering functions into this:

unsigned int idFileOpen = syActionEvent::RegisterId("idFileOpen","OnFileOpen()");

Wait, what's that second string for?
This is the beauty of thinking out of the box. We don't have to follow wxWidgets' model anymore! We're FREE To do whatever we want! So besides registering a numeric id for the File-Open event, I can also register the Qt slot name that gets triggered by the corresponding action!

Later I only have to write a small function that recursively iterates over all QActions in the main menu, gets the corresponding Id, and connects to the slot at the same time.

But all this thinking really made me get tired of the Qt conversion issue. Yes, I have to admit it, it's boring (coding without visual feedback isn't exactly a rollercoaster ride). So it's better if I rest for a bit and then later next week I'll go on with the conversion.

Oyasumi nasai (good night).

Saturday, January 10, 2009

Actions, events, slots, OH MY!

I've come to realize that Menu Event Handling in Qt is versatile, but it suffers from a fatal flaw:
It relies on slots. In other words, if I have to run a specific event (like Opening a File), I need to call the object's specific slot either directly, or via a signal. For that I need to actually include the class' header file. And that's a no-no.

So what am I gonna do? At this time I'm glad I implemented Saya's event system. With it, I can replicate the old "call an event with a specific ID" behavior. That's much better IMHO than having to include a huge header file.

But before that, we need to create a new class: syActionEvent. Which basically is a reimplementation of wxWidgets' menu event.

Update (Jan 10, 2008, 21:50):

I just realized that to send a menu event you just have to allocate an action. So you'll end up
with a series of action pointers. That would be the elegant solution - but isn't it more elegant to simply have a series of integer values, with no pointers allocated to them? So that's what we're doing in here. Yes, I know, we'll have to create the actions ANYWAY because that's how Qt works. But as I already said, I don't want to be tied to a specific event model. And using numeric id's for events is simpler, IMHO.

Thursday, January 8, 2009


There's so much code to convert to Qt!!!! (sorry, had to get it out of my system)

I need to take a break.

(On the other hand, I'm so glad I decided to convert before advancing any further! :D )

The MOC: Qt's lethal trap!

Having learned how cool the QT+Python combo is, it had never occurred to me that for C++ you need to go through a very different path to implement signals and slots with Qt.

What are signals and slots? They're the coolest possible way to implement events. A slot is defined by a specific type of function (which receives a specific type of parameters). A signal is just a function. When you connect a signal and a slot (or various slots), all slots get triggered by the same signal.

But to implement this in C++, the Qt guys chose to use a meta-object-compiler (MOC), which means you have to PREPROCESS your cpp file in order to compile it. UGH!

I've been trying to find an alternative way, but all my attempts have failed. The code generated by the moc is both cryptic and hideous, worthy of an obfuscated C contest.

But not everything is lost: After we change a c++ file, all we have to do is run the MOC on the file and redirect it to a moc header (which we will manually include by the cpp file). The trick is generating the moc file automatically.

Enter Qmake.

*disc scratch sound* NOOOOOOOOOOOOOO! I don't want to run Qmake, dammit!

OK then, enter CMake.

Ah, that's much better :)

Guess what? CMake has built-in support for Qt's MOC! All you have to do is add some parameters to your CMake file, and voila... I think.

Sigh. I didn't want to do this already, it's too soon! I don't want to be a father! (sob). Sorry, got carried away :P

For now, I'll build the moc files by hand (which will suffice for now), and then, I'll add the necessary stuff when I make the move to CMake.

This is Rick, and I approve this message.

Monday, January 5, 2009

It's official: We're moving to Qt4!

I finally made up my mind. After an e-mail conversation with one of the VLC developers, I was told that they submitted quite a few bug reports to wxWidgets, and they were all dismissed. I was also told that wxWidgets was very difficult to work with, and recommended to work with GTK, QT, or anything _else_ (wow, is wxWidgets that bad?).

And my experience confirms it.

Now, I tried the QT4 dialog designer, and once you get the hang of it (you need to use a right-click menu to put all the controls in a layout, there's no standard button for that), it's a bliss. But is it compatible with GPLv3? Version 4.3.4 and up are. Hurray! :)

Sigh, so here goes YET ANOTHER month of changing existing code for arbitrary reasons. I'm lucky I had already adapted a lot of code from wxWidgets ;-).

I'll close this announcement with a famous quote:

"Chance favors the prepared mind".
Louis Pasteur

Saturday, January 3, 2009

VLC knows best.

I hadn't realized it, but turns out that VLC, my favorite video player (due to its stability, etc), uses wxWidgets!

And I just found a Doxygen page documenting every single bit of it. Man, this thing is a masterpiece of art. I think I'm going to start stealing^H^H^H^H^H^H^H^H borrrowing code from VLC :).

So far, I learned that VLC uses the following approaches to draw video:

XV (hardware-accelerated Xvideo extension to the X11 server)
X11 (100% software)

All of these, in the form of plugins. Just what I was looking for.

Unfortunately, that means one thing: My current framework design doesn't seem to be extensible enough. I wrote a VideoOutputDevice class, which was supposed to take care of this. But, how to integrate it with a hardwired set of video control widgets?

VideoOutputDevice has a function to Set the size. And now I'm starting to see something else that I missed. Before now, I didn't actually NEED the VideoOutputDevice to remember the width and height - that was something that wxVideoPanel had. But now I'll need to specify not only the width and height, but also top and left (relative to the current screen), so that we can use any direct rendering plugins.

I'll also need to add a registry of VideoOutputDevice classes, and generalize wxVideoOutputDevice into a more generic class. Or actually, add a new class: syBitmapSink. The only thing this class will do is to load data from a syBitmap. This way, we will be able to use a "Default" VideoOutputDevice, which on Flushing, will send the data to a syBitmapSink. And wxVideoPanel will be that sink.

Since the object coordinates, width and height will change dynamically, the new VideoOutputDevice subclasses will have everything they need to perform the rendering. So it's all matter of which class gets instantiated on startup.

Neat, huh? :)

...and Pandora's Box was opened.

Oh my, look at all these bugs! Will the Playback framework will ever be completed?

And just when I thought everything was going fine, I realized that playback had a lot of bugs and design flaws.

* Playback didn't sleep at all, so it was caught in a loop waiting for the time when the next frame had to be painted. (fixed in my PC).

* The current frame is reset exactly at 4.0 seconds from playback. This is a very curious behavior, but I haven't found out (yet) why it happens.

* After pressing pause, pressing play resets the current frame to 0 again. And I don't know either why this happens. Sigh.

* Rendering the current frame into the screen is SLOW AS HELL. Why? Because we're using wxWidgets events for painting, and that's just wrong. Rendering should be done IN THE RENDERING THREAD. But there's a problem... how do I paint directly to the client window from a thread? I need to research more about this.

In any case, I'm glad I wrote one unit test for the time/frame conversion. I also wrote some other unit tests in the form of painting algorithms. The two bugs mentioned above were caught with a straight line painting video: A vertical line, whose x coordinates are equal to the current frame. I don't have the means to print a text in a bitmap, so I have to use what is available.

Friday, January 2, 2009

Video playback engine WORKS!

Finally I realized why the CPU hogging. I hadn't implemented the Video Output code (all video output was still done in the testing code, in the main thread :P ). But now we can play, pause, fast forward... reverse playback hasn't been tested yet. I need to modify the Demo Video code to see if it actually works (audio, on the other hand, hasn't been taken care of yet).

On the other hand, a friend JUST recommended me to use the Xine engine. Sigh. Why didn't I find out earlier!! Still, xine only works partially on Windows... on CVS. Oh well, what can we do about it?

This leds me to think about it. Why is it that when someone tries to make something that works, nobody helps him but everyone is eager to criticize? People from IRC laughed at me. Meanwhile, support and/or suggestions didn't come. Well, some people did help me, that's why they're on the team. But still, no experienced programmer. What am I supposed to do all alone? Oh, I forgot about the mailing list guys, they also provided valuable help. Unfortunately, everyone's working on his own project.

If a good C++ programmer is reading this, PLEASE HELP! I can't do it all by myself! It's been more than 7 months already, and I'm still on my own. Maybe someone will help when the project advances further.

See ya.

Thursday, January 1, 2009

It's alive, Igor!!! It's... having seizures?

After a lot of debugging and refactoring code, I finally got the Playback manager to work... and crash / hang.

First of all, I had overlooked a lot of things while coding the playback framework. I hadn't been given a single opportunity to ACTUALLY test it. But now that it kinda works... the bugs/flaws started to appear, one after another.

For starters, CPU utilization goes to 50% when PAUSED, and 30% when RUNNING. O.o
Second, on exit, for some reason that I haven't determined yet, sometimes I get segfaults, and sometimes hangs.

But at least I'm getting closer: The play/pause button interrupts and continues playback :)

I'll commit the code to the SVN tree when these bugs get fixed.

Update (Jan 1st, 2009):

I *think* I know what's happening. It's during ~AVController(). The VideoInputDevice object generates a segfault when accessing one of its mutexes. But if we get a segfault, it means that this location is no longer valid. In other words, we're dealing with a dangling pointer. Which means that somehow, the VideoInputDevice already got deleted somewhere else. But when, and how?

Update (Jan 1st, 2009, 19:55):

Ah, I see what happened.

AVController's destructor calls AVDevice::ShutDown(). But when InputMonitor (which is a subclass of AVDevice) deletes its Video Input Device on destruction, it fails to reset the pointer. So when ~AVController() calls ShutDown(), we're operating on an already-released object. In other words, in the destructor chain of InputMonitor, we deleted an object prematurely. The problem was easily fixed by simply commenting the deletion line.

Also, there's no resource problem with ~InputMonitor, because it always uses the same InputDevice. Besides, InputMonitor only gets created and deleted once. So how is InputMonitor's FileVID object deleted?

With a new class I created, AVDeviceRegistry. On deletion (that means the program's shutdown) it deletes all created AVDevices. And when an AVDevice is deleted, it unregisters itself from the list. Ta-da!

Now that the app doesn't crash on exit anymore, we're ready to commit to SVN, and later fix the CPU-thrashing Issue. Yay!