00001 #include "auto.h"
00002 #include "cache.h"
00003 #include "commonrender.h"
00004 #include "condition.h"
00005 #include "edl.h"
00006 #include "edlsession.h"
00007 #include "intautos.h"
00008 #include "localsession.h"
00009 #include "mainsession.h"
00010 #include "module.h"
00011 #include "mwindow.h"
00012 #include "patchbay.h"
00013 #include "patch.h"
00014 #include "playabletracks.h"
00015 #include "preferences.h"
00016 #include "renderengine.h"
00017 #include "track.h"
00018 #include "tracks.h"
00019 #include "transportque.h"
00020 #include "virtualconsole.h"
00021
00022 CommonRender::CommonRender(RenderEngine *renderengine)
00023 : Thread(1, 0, 0)
00024 {
00025 this->renderengine = renderengine;
00026 reset_parameters();
00027 start_lock = new Condition(0, "CommonRender::start_lock");
00028 }
00029
00030 CommonRender::~CommonRender()
00031 {
00032 delete_vconsole();
00033 if(modules)
00034 {
00035 for(int i = 0; i < total_modules; i++)
00036 delete modules[i];
00037 delete [] modules;
00038 }
00039 delete start_lock;
00040 }
00041
00042 void CommonRender::reset_parameters()
00043 {
00044 total_modules = 0;
00045 modules = 0;
00046 vconsole = 0;
00047 done = 0;
00048 interrupt = 0;
00049 last_playback = 0;
00050 asynchronous = 0;
00051 restart_plugins = 0;
00052 }
00053
00054 void CommonRender::arm_command()
00055 {
00056 int64_t temp_length = 1;
00057
00058 current_position = tounits(renderengine->command->playbackstart, 0);
00059
00060 init_output_buffers();
00061
00062 last_playback = 0;
00063 if(test_reconfigure(current_position, temp_length))
00064 {
00065 restart_playback();
00066 }
00067 else
00068 {
00069 vconsole->start_playback();
00070 }
00071
00072 done = 0;
00073 interrupt = 0;
00074 last_playback = 0;
00075 restart_plugins = 0;
00076 }
00077
00078
00079
00080 void CommonRender::create_modules()
00081 {
00082
00083 Track *current = renderengine->edl->tracks->first;
00084 int module = 0;
00085
00086 if(!modules)
00087 {
00088 total_modules = get_total_tracks();
00089 modules = new Module*[total_modules];
00090
00091 for(module = 0; module < total_modules && current; current = NEXT)
00092 {
00093 if(current->data_type == data_type)
00094 {
00095 modules[module] = new_module(current);
00096 modules[module]->create_objects();
00097 module++;
00098 }
00099 }
00100 }
00101 else
00102
00103 {
00104 for(module = 0; module < total_modules; module++)
00105 {
00106 modules[module]->create_objects();
00107 }
00108 }
00109 }
00110
00111 void CommonRender::start_plugins()
00112 {
00113
00114 if(restart_plugins)
00115 {
00116 for(int i = 0; i < total_modules; i++)
00117 {
00118 modules[i]->render_init();
00119 }
00120 }
00121 }
00122
00123 void CommonRender::stop_plugins()
00124 {
00125 for(int i = 0; i < total_modules; i++)
00126 {
00127 modules[i]->render_stop();
00128 }
00129 }
00130
00131 int CommonRender::test_reconfigure(int64_t position, int64_t &length)
00132 {
00133 if(!vconsole) return 1;
00134 if(!modules) return 1;
00135
00136 return vconsole->test_reconfigure(position, length, last_playback);
00137 }
00138
00139
00140 void CommonRender::build_virtual_console()
00141 {
00142
00143 if(!vconsole)
00144 {
00145 vconsole = new_vconsole_object();
00146 }
00147
00148
00149 vconsole->create_objects();
00150 }
00151
00152 void CommonRender::start_command()
00153 {
00154 if(renderengine->command->realtime)
00155 {
00156 Thread::set_realtime(renderengine->edl->session->real_time_playback &&
00157 data_type == TRACK_AUDIO);
00158 Thread::start();
00159 start_lock->lock("CommonRender::start_command");
00160 }
00161 }
00162
00163 int CommonRender::restart_playback()
00164 {
00165 delete_vconsole();
00166 create_modules();
00167 build_virtual_console();
00168 start_plugins();
00169
00170 done = 0;
00171 interrupt = 0;
00172 last_playback = 0;
00173 restart_plugins = 0;
00174 return 0;
00175 }
00176
00177 void CommonRender::delete_vconsole()
00178 {
00179 if(vconsole) delete vconsole;
00180 vconsole = 0;
00181 }
00182
00183 int CommonRender::get_boundaries(int64_t ¤t_render_length)
00184 {
00185 int64_t loop_end = tounits(renderengine->edl->local_session->loop_end, 1);
00186 int64_t loop_start = tounits(renderengine->edl->local_session->loop_start, 0);
00187 int64_t start_position = tounits(renderengine->command->start_position, 0);
00188 int64_t end_position = tounits(renderengine->command->end_position, 1);
00189
00190
00191
00192 if(renderengine->command->single_frame() ||
00193 (!renderengine->edl->local_session->loop_playback &&
00194 !renderengine->command->infinite))
00195 {
00196 if(renderengine->command->get_direction() == PLAY_FORWARD)
00197 {
00198 if(current_position + current_render_length >= end_position)
00199 {
00200 last_playback = 1;
00201 current_render_length = end_position - current_position;
00202 }
00203 }
00204
00205 else
00206 {
00207 if(current_position - current_render_length <= start_position)
00208 {
00209 last_playback = 1;
00210 current_render_length = current_position - start_position;
00211 }
00212 }
00213 }
00214
00215
00216 if(!renderengine->command->single_frame() &&
00217 renderengine->edl->local_session->loop_playback &&
00218 !renderengine->command->infinite)
00219 {
00220 if(renderengine->command->get_direction() == PLAY_FORWARD)
00221 {
00222 int64_t segment_end = current_position + current_render_length;
00223 if(segment_end > loop_end)
00224 {
00225 current_render_length = loop_end - current_position;
00226 }
00227 }
00228 else
00229 {
00230 int64_t segment_end = current_position - current_render_length;
00231 if(segment_end < loop_start)
00232 {
00233 current_render_length = current_position - loop_start;
00234 }
00235 }
00236 }
00237
00238 if(renderengine->command->single_frame())
00239 current_render_length = 1;
00240
00241 if(current_render_length < 0) current_render_length = 0;
00242 return 0;
00243 }
00244
00245 void CommonRender::run()
00246 {
00247 start_lock->unlock();
00248 }
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270 CommonRender::CommonRender(MWindow *mwindow, RenderEngine *renderengine)
00271 : Thread()
00272 {
00273 this->mwindow = mwindow;
00274 this->renderengine = renderengine;
00275 current_position = 0;
00276 interrupt = 0;
00277 done = 0;
00278 last_playback = 0;
00279 vconsole = 0;
00280 asynchronous = 1;
00281 }
00282
00283
00284 int CommonRender::wait_for_completion()
00285 {
00286 join();
00287 }
00288
00289
00290
00291
00292
00293 int CommonRender::advance_position(int64_t current_render_length)
00294 {
00295 int64_t loop_end = tounits(renderengine->edl->local_session->loop_end, 1);
00296 int64_t loop_start = tounits(renderengine->edl->local_session->loop_start, 0);
00297
00298
00299 if(renderengine->command->get_direction() == PLAY_REVERSE)
00300 current_position -= current_render_length;
00301 else
00302 current_position += current_render_length;
00303
00304
00305 if(renderengine->edl->local_session->loop_playback &&
00306 !renderengine->command->infinite)
00307 {
00308 if(renderengine->command->get_direction() == PLAY_REVERSE)
00309 {
00310 if(current_position <= loop_start)
00311 current_position = loop_end;
00312 }
00313 else
00314 {
00315 if(current_position >= loop_end)
00316 current_position = loop_start + (current_position - loop_end);
00317 }
00318 }
00319 return 0;
00320 }
00321
00322 int64_t CommonRender::tounits(double position, int round)
00323 {
00324 return (int64_t)position;
00325 }
00326
00327 double CommonRender::fromunits(int64_t position)
00328 {
00329 return (double)position;
00330 }