Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

menueffects.C

Go to the documentation of this file.
00001 #include "asset.h"
00002 #include "clip.h"
00003 #include "confirmsave.h"
00004 #include "defaults.h"
00005 #include "edl.h"
00006 #include "edlsession.h"
00007 #include "errorbox.h"
00008 #include "file.h"
00009 #include "formatcheck.h"
00010 #include "indexfile.h"
00011 #include "keyframe.h"
00012 #include "keys.h"
00013 #include "labels.h"
00014 #include "language.h"
00015 #include "loadmode.h"
00016 #include "localsession.h"
00017 #include "mainmenu.h"
00018 #include "mainsession.h"
00019 #include "mainundo.h"
00020 #include "mwindow.h"
00021 #include "mwindowgui.h"
00022 #include "menueffects.h"
00023 #include "playbackengine.h"
00024 #include "pluginarray.h"
00025 #include "pluginserver.h"
00026 #include "preferences.h"
00027 #include "render.h"
00028 #include "sighandler.h"
00029 #include "theme.h"
00030 #include "tracks.h"
00031 
00032 
00033 
00034 MenuEffects::MenuEffects(MWindow *mwindow)
00035  : BC_MenuItem(_("Render effect..."))
00036 {
00037         this->mwindow = mwindow;
00038 }
00039 
00040 MenuEffects::~MenuEffects()
00041 {
00042 }
00043 
00044 
00045 int MenuEffects::handle_event()
00046 {
00047         thread->set_title("");
00048         thread->start();
00049 }
00050 
00051 
00052 
00053 
00054 
00055 MenuEffectPacket::MenuEffectPacket(char *path, int64_t start, int64_t end)
00056 {
00057         this->start = start;
00058         this->end = end;
00059         strcpy(this->path, path);
00060 }
00061 
00062 MenuEffectPacket::~MenuEffectPacket()
00063 {
00064 }
00065 
00066 
00067 
00068 
00069 
00070 
00071 MenuEffectThread::MenuEffectThread(MWindow *mwindow)
00072 {
00073         this->mwindow = mwindow;
00074         sprintf(title, "");
00075 }
00076 
00077 MenuEffectThread::~MenuEffectThread()
00078 {
00079 }
00080 
00081 
00082 
00083 
00084 
00085 int MenuEffectThread::set_title(char *title)
00086 {
00087         strcpy(this->title, title);
00088 }
00089 
00090 // for recent effect menu items and running new effects
00091 // prompts for an effect if title is blank
00092 void MenuEffectThread::run()
00093 {
00094 // get stuff from main window
00095         ArrayList<PluginServer*> *plugindb = mwindow->plugindb;
00096         Defaults *defaults = mwindow->defaults;
00097         ArrayList<BC_ListBoxItem*> plugin_list;
00098         ArrayList<PluginServer*> local_plugindb;
00099         char string[1024];
00100         int i;
00101         int result = 0;
00102 // Default configuration
00103         Asset default_asset;
00104 // Output
00105         ArrayList<Asset*> assets;
00106 
00107 
00108 // check for recordable tracks
00109         if(!get_recordable_tracks(&default_asset))
00110         {
00111                 sprintf(string, _("No recordable tracks specified."));
00112                 ErrorBox error(PROGRAM_NAME ": Error");
00113                 error.create_objects(string);
00114                 error.run_window();
00115                 return;
00116         }
00117 
00118 // check for plugins
00119         if(!plugindb->total)
00120         {
00121                 sprintf(string, _("No plugins available."));
00122                 ErrorBox error(PROGRAM_NAME ": Error");
00123                 error.create_objects(string);
00124                 error.run_window();
00125                 return;
00126         }
00127 
00128 
00129 // get default attributes for output file
00130 // used after completion
00131         get_derived_attributes(&default_asset, defaults);
00132 //      to_tracks = defaults->get("RENDER_EFFECT_TO_TRACKS", 1);
00133         load_mode = defaults->get("RENDER_EFFECT_LOADMODE", LOAD_PASTE);
00134         strategy = defaults->get("RENDER_EFFECT_STRATEGY", SINGLE_PASS);
00135 
00136 // get plugin information
00137         int need_plugin;
00138         if(!strlen(title)) 
00139                 need_plugin = 1; 
00140         else 
00141                 need_plugin = 0;
00142 
00143 // generate a list of plugins for the window
00144         if(need_plugin)
00145         {
00146                 mwindow->create_plugindb(default_asset.audio_data, 
00147                         default_asset.video_data, 
00148                         -1, 
00149                         0,
00150                         0,
00151                         local_plugindb);
00152 
00153                 for(int i = 0; i < local_plugindb.total; i++)
00154                 {
00155                         plugin_list.append(new BC_ListBoxItem(_(local_plugindb.values[i]->title)));
00156                 }
00157         }
00158 
00159 // find out which effect to run and get output file
00160         int plugin_number, format_error = 0;
00161 
00162         do
00163         {
00164                 {
00165                         MenuEffectWindow window(mwindow, 
00166                                 this, 
00167                                 need_plugin ? &plugin_list : 0, 
00168                                 &default_asset);
00169                         window.create_objects();
00170                         result = window.run_window();
00171                         plugin_number = window.result;
00172                 }
00173 
00174                 if(!result)
00175                 {
00176                         FormatCheck format_check(&default_asset);
00177                         format_error = format_check.check_format();
00178                 }
00179         }while(format_error && !result);
00180 
00181 // save defaults
00182         save_derived_attributes(&default_asset, defaults);
00183         defaults->update("RENDER_EFFECT_LOADMODE", load_mode);
00184         defaults->update("RENDER_EFFECT_STRATEGY", strategy);
00185         mwindow->save_defaults();
00186 
00187 // get plugin server to use and delete the plugin list
00188         PluginServer *plugin_server = 0;
00189         PluginServer *plugin = 0;
00190         if(need_plugin)
00191         {
00192                 plugin_list.remove_all_objects();
00193                 if(plugin_number > -1)
00194                 {
00195                         plugin_server = local_plugindb.values[plugin_number];
00196                         strcpy(title, plugin_server->title);
00197                 }
00198         }
00199         else
00200         {
00201                 for(int i = 0; i < plugindb->total && !plugin_server; i++)
00202                 {
00203                         if(!strcmp(plugindb->values[i]->title, title))
00204                         {
00205                                 plugin_server = plugindb->values[i];
00206                                 plugin_number = i;
00207                         }
00208                 }
00209         }
00210 
00211 // Update the  most recently used effects and copy the plugin server.
00212         if(plugin_server)
00213         {
00214                 plugin = new PluginServer(*plugin_server);
00215                 fix_menu(title);
00216         }
00217 
00218         if(!result && !strlen(default_asset.path))
00219         {
00220                 result = 1;        // no output path given
00221                 ErrorBox error(PROGRAM_NAME ": Error");
00222                 error.create_objects(_("No output file specified."));
00223                 error.run_window();
00224         }
00225 
00226         if(!result && plugin_number < 0)
00227         {
00228                 result = 1;        // no output path given
00229                 ErrorBox error(PROGRAM_NAME ": Error");
00230                 error.create_objects(_("No effect selected."));
00231                 error.run_window();
00232         }
00233 
00234 // Configuration for realtime plugins.
00235         KeyFrame plugin_data;        
00236 
00237 // get selection to render
00238 // Range
00239         double total_start, total_end;
00240 
00241         total_start = mwindow->edl->local_session->get_selectionstart();
00242 
00243 
00244         if(mwindow->edl->local_session->get_selectionend() == 
00245                 mwindow->edl->local_session->get_selectionstart())
00246                 total_end = mwindow->edl->tracks->total_playable_length();
00247         else
00248                 total_end = mwindow->edl->local_session->get_selectionend();
00249 
00250 
00251 
00252 // get native units for range
00253         total_start = to_units(total_start, 0);
00254         total_end = to_units(total_end, 1);
00255 
00256 
00257 
00258 // Trick boundaries in case of a non-realtime synthesis plugin
00259         if(plugin && 
00260                 !plugin->realtime && 
00261                 total_end == total_start) total_end = total_start + 1;
00262 
00263 // Units are now in the track's units.
00264         int64_t total_length = (int64_t)total_end - (int64_t)total_start;
00265 // length of output file
00266         int64_t output_start, output_end;        
00267 
00268         if(!result && total_length <= 0)
00269         {
00270                 result = 1;        // no output path given
00271                 ErrorBox error(PROGRAM_NAME ": Error");
00272                 error.create_objects(_("No selected range to process."));
00273                 error.run_window();
00274         }
00275 
00276 // ========================= get keyframe from user
00277         if(!result)
00278         {
00279 // ========================= realtime plugin 
00280 // no get_parameters
00281                 if(plugin->realtime)
00282                 {
00283 // Open a prompt GUI
00284                         MenuEffectPrompt prompt(mwindow);
00285                         prompt.create_objects();
00286                         char title[BCTEXTLEN];
00287                         sprintf(title, PROGRAM_NAME ": %s", plugin->title);
00288 
00289 // Open the plugin GUI
00290                         plugin->set_mwindow(mwindow);
00291                         plugin->set_keyframe(&plugin_data);
00292                         plugin->set_prompt(&prompt);
00293                         plugin->open_plugin(0, mwindow->preferences, mwindow->edl, 0, -1);
00294 // Must set parameters since there is no plugin object to draw from.
00295                         plugin->get_parameters((int64_t)total_start,
00296                                 (int64_t)total_end,
00297                                 1);
00298                         plugin->show_gui();
00299 
00300 // wait for user input
00301                         result = prompt.run_window();
00302 
00303 // Close plugin.
00304                         plugin->save_data(&plugin_data);
00305                         delete plugin;
00306                         default_asset.sample_rate = mwindow->edl->session->sample_rate;
00307                         default_asset.frame_rate = mwindow->edl->session->frame_rate;
00308                         realtime = 1;
00309                 }
00310                 else
00311 // ============================non realtime plugin 
00312                 {
00313                         plugin->set_mwindow(mwindow);
00314                         plugin->open_plugin(0, mwindow->preferences, mwindow->edl, 0, -1);
00315                         result = plugin->get_parameters((int64_t)total_start, 
00316                                 (int64_t)total_end, 
00317                                 get_recordable_tracks(&default_asset));
00318 // some plugins can change the sample rate and the frame rate
00319 
00320 
00321                         if(!result)
00322                         {
00323                                 default_asset.sample_rate = plugin->get_samplerate();
00324                                 default_asset.frame_rate = plugin->get_framerate();
00325                         }
00326                         delete plugin;
00327                         realtime = 0;
00328                 }
00329 
00330 // Should take from first recordable track
00331                 default_asset.width = mwindow->edl->session->output_w;
00332                 default_asset.height = mwindow->edl->session->output_h;
00333         }
00334 
00335 // Process the total length in fragments
00336         ArrayList<MenuEffectPacket*> packets;
00337         if(!result)
00338         {
00339                 Label *current_label = mwindow->edl->labels->first;
00340                 mwindow->stop_brender();
00341 
00342                 int current_number;
00343                 int number_start;
00344                 int total_digits;
00345                 Render::get_starting_number(default_asset.path, 
00346                         current_number,
00347                         number_start, 
00348                         total_digits);
00349 
00350 
00351 
00352 // Construct all packets for single overwrite confirmation
00353                 for(int64_t fragment_start = (int64_t)total_start, fragment_end;
00354                         fragment_start < (int64_t)total_end;
00355                         fragment_start = fragment_end)
00356                 {
00357 // Get fragment end
00358                         if(strategy == FILE_PER_LABEL || strategy == FILE_PER_LABEL_FARM)
00359                         {
00360                                 while(current_label  &&
00361                                         to_units(current_label->position, 0) <= fragment_start)
00362                                         current_label = current_label->next;
00363                                 if(!current_label)
00364                                         fragment_end = (int64_t)total_end;
00365                                 else
00366                                         fragment_end = to_units(current_label->position, 0);
00367                         }
00368                         else
00369                         {
00370                                 fragment_end = (int64_t)total_end;
00371                         }
00372 
00373 // Get path
00374                         char path[BCTEXTLEN];
00375                         if(strategy == FILE_PER_LABEL || strategy == FILE_PER_LABEL_FARM) 
00376                                 Render::create_filename(path, 
00377                                         default_asset.path, 
00378                                         current_number,
00379                                         total_digits,
00380                                         number_start);
00381                         else
00382                                 strcpy(path, default_asset.path);
00383                         current_number++;
00384 
00385                         MenuEffectPacket *packet = new MenuEffectPacket(path, 
00386                                 fragment_start,
00387                                 fragment_end);
00388                         packets.append(packet);
00389                 }
00390 
00391 
00392 // Test existence of files
00393                 ArrayList<char*> paths;
00394                 for(int i = 0; i < packets.total; i++)
00395                 {
00396                         paths.append(packets.values[i]->path);
00397                 }
00398                 result = ConfirmSave::test_files(mwindow, &paths);
00399                 paths.remove_all();
00400         }
00401 
00402 
00403 
00404         for(int current_packet = 0; 
00405                 current_packet < packets.total && !result; 
00406                 current_packet++)
00407         {
00408                 Asset *asset = new Asset(default_asset);
00409                 MenuEffectPacket *packet = packets.values[current_packet];
00410                 int64_t fragment_start = packet->start;
00411                 int64_t fragment_end = packet->end;
00412                 strcpy(asset->path, packet->path);
00413 
00414                 assets.append(asset);
00415                 File *file = new File;
00416 
00417 // Open the output file after getting the information because the sample rate
00418 // is needed here.
00419                 if(!result)
00420                 {
00421 // open output file in write mode
00422                         file->set_processors(mwindow->preferences->processors);
00423                         if(file->open_file(mwindow->preferences, 
00424                                 asset, 
00425                                 0, 
00426                                 1, 
00427                                 mwindow->edl->session->sample_rate, 
00428                                 mwindow->edl->session->frame_rate))
00429                         {
00430 // open failed
00431                                 sprintf(string, _("Couldn't open %s"), asset->path);
00432                                 ErrorBox error(PROGRAM_NAME ": Error");
00433                                 error.create_objects(string);
00434                                 error.run_window();
00435                                 result = 1;
00436                         }
00437                         else
00438                         {
00439                                 mwindow->sighandler->push_file(file);
00440                                 IndexFile::delete_index(mwindow->preferences, asset);
00441                         }
00442                 }
00443 
00444 // run plugins
00445                 if(!result)
00446                 {
00447 // position file
00448                         output_start = 0;
00449 
00450                         PluginArray *plugin_array;
00451                         plugin_array = create_plugin_array();
00452 
00453                         plugin_array->start_plugins(mwindow, 
00454                                 mwindow->edl, 
00455                                 plugin_server, 
00456                                 &plugin_data,
00457                                 fragment_start,
00458                                 fragment_end,
00459                                 file);
00460                         plugin_array->run_plugins();
00461 
00462                         plugin_array->stop_plugins();
00463                         mwindow->sighandler->pull_file(file);
00464                         file->close_file();
00465                         asset->audio_length = file->asset->audio_length;
00466                         asset->video_length = file->asset->video_length;
00467                         delete plugin_array;
00468                 }
00469 
00470                 delete file;
00471         }
00472 
00473         packets.remove_all_objects();
00474 
00475 // paste output to tracks
00476         if(!result && load_mode != LOAD_NOTHING)
00477         {
00478                 mwindow->gui->lock_window("MenuEffectThread::run");
00479 
00480                 if(load_mode == LOAD_PASTE)
00481                         mwindow->clear(0);
00482                 mwindow->load_assets(&assets,
00483                         -1,
00484                         load_mode,
00485                         0,
00486                         0,
00487                         mwindow->edl->session->labels_follow_edits, 
00488                         mwindow->edl->session->plugins_follow_edits);
00489 
00490 
00491                 mwindow->save_backup();
00492                 mwindow->undo->update_undo(title, LOAD_ALL);
00493 
00494 
00495 
00496                 mwindow->restart_brender();
00497                 mwindow->update_plugin_guis();
00498                 mwindow->gui->update(1, 
00499                         2,
00500                         1,
00501                         1,
00502                         1,
00503                         1,
00504                         0);
00505                 mwindow->sync_parameters(CHANGE_ALL);
00506                 mwindow->gui->unlock_window();
00507         }
00508 
00509         assets.remove_all_objects();
00510 }
00511 
00512 
00513 
00514 
00515 MenuEffectItem::MenuEffectItem(MenuEffects *menueffect, char *string)
00516  : BC_MenuItem(string)
00517 {
00518         this->menueffect = menueffect; 
00519 }
00520 int MenuEffectItem::handle_event()
00521 {
00522         menueffect->thread->set_title(get_text());
00523         menueffect->thread->start();
00524 }
00525 
00526 
00527 
00528 
00529 
00530 
00531 
00532 
00533 
00534 
00535 
00536 
00537 MenuEffectWindow::MenuEffectWindow(MWindow *mwindow, 
00538         MenuEffectThread *menueffects, 
00539         ArrayList<BC_ListBoxItem*> *plugin_list, 
00540         Asset *asset)
00541  : BC_Window(PROGRAM_NAME ": Render effect", 
00542                 mwindow->gui->get_abs_cursor_x(1),
00543                 mwindow->gui->get_abs_cursor_y(1) - mwindow->session->menueffect_h / 2,
00544                 mwindow->session->menueffect_w, 
00545                 mwindow->session->menueffect_h, 
00546                 580,
00547                 350,
00548                 1,
00549                 0,
00550                 1)
00551 { 
00552         this->menueffects = menueffects; 
00553         this->plugin_list = plugin_list; 
00554         this->asset = asset;
00555         this->mwindow = mwindow;
00556 }
00557 
00558 MenuEffectWindow::~MenuEffectWindow()
00559 {
00560         delete format_tools;
00561 }
00562 
00563 
00564 
00565 int MenuEffectWindow::create_objects()
00566 {
00567         int x, y;
00568         result = -1;
00569         mwindow->theme->get_menueffect_sizes(plugin_list ? 1 : 0);
00570 
00571 // only add the list if needed
00572         if(plugin_list)
00573         {
00574                 add_subwindow(list_title = new BC_Title(mwindow->theme->menueffect_list_x, 
00575                         mwindow->theme->menueffect_list_y, 
00576                         _("Select an effect")));
00577                 add_subwindow(list = new MenuEffectWindowList(this, 
00578                         mwindow->theme->menueffect_list_x, 
00579                         mwindow->theme->menueffect_list_y + list_title->get_h() + 5, 
00580                         mwindow->theme->menueffect_list_w,
00581                         mwindow->theme->menueffect_list_h - list_title->get_h() - 5,
00582                         plugin_list));
00583         }
00584 
00585         add_subwindow(file_title = new BC_Title(mwindow->theme->menueffect_file_x, 
00586                 mwindow->theme->menueffect_file_y, 
00587                 (char*)((menueffects->strategy == FILE_PER_LABEL  || menueffects->strategy == FILE_PER_LABEL_FARM) ? 
00588                         _("Select the first file to render to:") : 
00589                         _("Select a file to render to:"))));
00590 
00591         x = mwindow->theme->menueffect_tools_x;
00592         y = mwindow->theme->menueffect_tools_y;
00593         format_tools = new FormatTools(mwindow,
00594                                         this, 
00595                                         asset);
00596         format_tools->create_objects(x, 
00597                                         y, 
00598                                         asset->audio_data, 
00599                                         asset->video_data, 
00600                                         0, 
00601                                         0, 
00602                                         0,
00603                                         1,
00604                                         0,
00605                                         0,
00606                                         &menueffects->strategy,
00607                                         0);
00608 
00609         loadmode = new LoadMode(mwindow, 
00610                 this, 
00611                 x, 
00612                 y, 
00613                 &menueffects->load_mode, 
00614                 1);
00615         loadmode->create_objects();
00616 
00617         add_subwindow(new MenuEffectWindowOK(this));
00618         add_subwindow(new MenuEffectWindowCancel(this));
00619         show_window();
00620         flush();
00621         return 0;
00622 }
00623 
00624 int MenuEffectWindow::resize_event(int w, int h)
00625 {
00626         mwindow->session->menueffect_w = w;
00627         mwindow->session->menueffect_h = h;
00628         mwindow->theme->get_menueffect_sizes(plugin_list ? 1 : 0);
00629 
00630         if(plugin_list)
00631         {
00632                 list_title->reposition_window(mwindow->theme->menueffect_list_x, 
00633                         mwindow->theme->menueffect_list_y);
00634                 list->reposition_window(mwindow->theme->menueffect_list_x, 
00635                         mwindow->theme->menueffect_list_y + list_title->get_h() + 5, 
00636                         mwindow->theme->menueffect_list_w,
00637                         mwindow->theme->menueffect_list_h - list_title->get_h() - 5);
00638         }
00639 
00640         file_title->reposition_window(mwindow->theme->menueffect_file_x, 
00641                 mwindow->theme->menueffect_file_y);
00642         int x = mwindow->theme->menueffect_tools_x;
00643         int y = mwindow->theme->menueffect_tools_y;
00644         format_tools->reposition_window(x, y);
00645         loadmode->reposition_window(x, y);
00646 }
00647 
00648 
00649 
00650 MenuEffectWindowOK::MenuEffectWindowOK(MenuEffectWindow *window)
00651  : BC_OKButton(window)
00652 { 
00653         this->window = window; 
00654 }
00655 
00656 int MenuEffectWindowOK::handle_event() 
00657 { 
00658         if(window->plugin_list) 
00659                 window->result = window->list->get_selection_number(0, 0); 
00660         
00661         window->set_done(0); 
00662 }
00663 
00664 int MenuEffectWindowOK::keypress_event() 
00665 { 
00666         if(get_keypress() == RETURN) 
00667         { 
00668                 handle_event(); 
00669                 return 1; 
00670         }
00671         return 0;
00672 }
00673 
00674 MenuEffectWindowCancel::MenuEffectWindowCancel(MenuEffectWindow *window)
00675  : BC_CancelButton(window)
00676 { 
00677         this->window = window; 
00678 }
00679 
00680 int MenuEffectWindowCancel::handle_event() 
00681 { 
00682         window->set_done(1); 
00683 }
00684 
00685 int MenuEffectWindowCancel::keypress_event() 
00686 { 
00687         if(get_keypress() == ESC) 
00688         { 
00689                 handle_event(); 
00690                 return 1; 
00691         }
00692         return 0;
00693 }
00694 
00695 MenuEffectWindowList::MenuEffectWindowList(MenuEffectWindow *window, 
00696         int x, 
00697         int y, 
00698         int w, 
00699         int h, 
00700         ArrayList<BC_ListBoxItem*> *plugin_list)
00701  : BC_ListBox(x, 
00702                 y, 
00703                 w, 
00704                 h, 
00705                 LISTBOX_TEXT, 
00706                 plugin_list)
00707 { 
00708         this->window = window; 
00709 }
00710 
00711 int MenuEffectWindowList::handle_event() 
00712 {
00713         window->result = get_selection_number(0, 0);
00714         window->set_done(0); 
00715 }
00716 
00717 #define PROMPT_TEXT _("Set up effect panel and hit \"OK\"")
00718 
00719 MenuEffectPrompt::MenuEffectPrompt(MWindow *mwindow)
00720  : BC_Window(PROGRAM_NAME ": Effect Prompt", 
00721                 mwindow->gui->get_abs_cursor_x(1) - 260 / 2,
00722                 mwindow->gui->get_abs_cursor_y(1) - 300,
00723                 MenuEffectPrompt::calculate_w(mwindow->gui), 
00724                 MenuEffectPrompt::calculate_h(mwindow->gui), 
00725                 MenuEffectPrompt::calculate_w(mwindow->gui),
00726                 MenuEffectPrompt::calculate_h(mwindow->gui),
00727                 0,
00728                 0,
00729                 1)
00730 {
00731 }
00732 
00733 int MenuEffectPrompt::calculate_w(BC_WindowBase *gui)
00734 {
00735         int w = BC_Title::calculate_w(gui, PROMPT_TEXT) + 10;
00736         w = MAX(w, BC_OKButton::calculate_w() + BC_CancelButton::calculate_w() + 30);
00737         return w;
00738 }
00739 
00740 int MenuEffectPrompt::calculate_h(BC_WindowBase *gui)
00741 {
00742         int h = BC_Title::calculate_h(gui, PROMPT_TEXT);
00743         h += BC_OKButton::calculate_h() + 30;
00744         return h;
00745 }
00746 
00747 
00748 int MenuEffectPrompt::create_objects()
00749 {
00750         int x = 10, y = 10;
00751         BC_Title *title;
00752         add_subwindow(title = new BC_Title(x, y, PROMPT_TEXT));
00753         add_subwindow(new BC_OKButton(this));
00754         add_subwindow(new BC_CancelButton(this));
00755         show_window();
00756         raise_window();
00757         flush();
00758         return 0;
00759 }
00760 

Generated on Sun Jan 8 13:38:57 2006 for Cinelerra-svn by  doxygen 1.4.4