2 #include "automation.h"
4 #include "commonrender.h"
6 #include "edlsession.h"
7 #include "virtualconsole.h"
10 #include "playabletracks.h"
11 #include "renderengine.h"
14 #include "transportque.h"
15 #include "virtualnode.h"
18 VirtualConsole::VirtualConsole(RenderEngine *renderengine,
19 CommonRender *commonrender,
23 this->renderengine = renderengine;
24 this->commonrender = commonrender;
25 this->data_type = data_type;
27 startup_lock = new Mutex;
34 VirtualConsole::~VirtualConsole()
36 //printf("VirtualConsole::~VirtualConsole 1\n");
37 delete_virtual_console();
38 delete_input_buffers();
41 if(playable_tracks) delete playable_tracks;
44 int VirtualConsole::total_ring_buffers()
50 void VirtualConsole::create_objects()
54 current_input_buffer = 0;
55 current_vconsole_buffer = 0;
57 get_playable_tracks();
58 total_tracks = playable_tracks->total;
59 allocate_input_buffers();
60 build_virtual_console(1);
61 sort_virtual_console();
66 void VirtualConsole::start_playback()
70 current_input_buffer = 0;
71 current_vconsole_buffer = 0;
72 //printf("VirtualConsole::start_playback 1 %d %d\n", renderengine->command->realtime, data_type);
73 if(renderengine->command->realtime && data_type == TRACK_AUDIO)
75 // don't start a thread unless writing to an audio device
77 for(int ring_buffer = 0; ring_buffer < ring_buffers; ring_buffer++)
79 input_lock[ring_buffer]->reset();
80 output_lock[ring_buffer]->reset();
81 input_lock[ring_buffer]->lock();
83 Thread::set_synchronous(1); // prepare thread base class
84 //printf("VirtualConsole::start_playback 2 %d\n", renderengine->edl->session->real_time_playback);
86 //printf("VirtualConsole::start_playback 3 %d\n", renderengine->edl->session->real_time_playback);
88 startup_lock->unlock();
93 Module* VirtualConsole::module_of(Track *track)
95 for(int i = 0; i < commonrender->total_modules; i++)
97 //printf("VirtualConsole::module_of %p %p\n", (Track*)commonrender->modules[i]->track, track);
98 if(commonrender->modules[i]->track == track) return commonrender->modules[i];
103 Module* VirtualConsole::module_number(int track_number)
105 // The track number is an absolute number of the track independant of
106 // the tracks with matching data type but virtual modules only exist for
107 // the matching data type.
108 // Convert from absolute track number to data type track number.
109 Track *current = renderengine->edl->tracks->first;
110 int data_type_number = 0, number = 0;
112 for( ; current; current = NEXT, number++)
114 if(current->data_type == data_type)
116 if(number == track_number)
117 return commonrender->modules[data_type_number];
127 int VirtualConsole::allocate_input_buffers()
131 ring_buffers = total_ring_buffers();
133 // allocate the drive read buffers
134 for(int ring_buffer = 0;
135 ring_buffer < ring_buffers;
138 input_lock[ring_buffer] = new Mutex;
139 output_lock[ring_buffer] = new Mutex;
140 last_playback[ring_buffer] = 0;
141 new_input_buffer(ring_buffer);
148 void VirtualConsole::build_virtual_console(int persistant_plugins)
150 // allocate the virtual modules
151 //printf("VirtualConsole::build_virtual_console 1\n");
154 virtual_modules = new VirtualNode*[total_tracks];
156 //printf("VirtualConsole::build_virtual_console 2 %d %d\n", data_type, total_tracks);
157 for(int i = 0; i < total_tracks; i++)
159 //printf("VirtualConsole::build_virtual_console 3\n");
160 virtual_modules[i] = new_toplevel_node(playable_tracks->values[i],
161 module_of(playable_tracks->values[i]),
165 virtual_modules[i]->expand(persistant_plugins, commonrender->current_position);
166 //printf("VirtualConsole::build_virtual_console 3\n");
168 commonrender->restart_plugins = 1;
172 int VirtualConsole::sort_virtual_console()
175 int done = 0, result = 0;
176 int64_t attempts = 0;
179 //printf("VirtualConsole::sort_virtual_console 1\n");
180 if(!render_list.total)
182 while(!done && attempts < 50)
184 // Sort iteratively until all the remaining plugins can be rendered.
185 // Iterate backwards so video is composited properly
187 for(i = total_tracks - 1; i >= 0; i--)
189 result = virtual_modules[i]->sort(&render_list);
195 //printf("VirtualConsole::sort_virtual_console 2 %d\n", render_list.total);
196 // prevent short circuts
199 printf("VirtualConsole::sort_virtual_console: Recursive.\n");
201 //printf("VirtualConsole::sort_virtual_console 2\n");
206 void VirtualConsole::dump()
208 printf("VirtualConsole\n");
209 printf(" Modules\n");
210 for(int i = 0; i < commonrender->total_modules; i++)
211 commonrender->modules[i]->dump();
213 for(int i = 0; i < total_tracks; i++)
214 virtual_modules[i]->dump(0);
218 int VirtualConsole::test_reconfigure(int64_t position,
223 Track *current_track;
226 //printf("VirtualConsole::test_reconfigure 1\n");
228 // Test playback status against virtual console for current position.
229 for(current_track = renderengine->edl->tracks->first;
230 current_track && !result;
231 current_track = current_track->next)
233 if(current_track->data_type == data_type)
235 // Playable status changed
236 if(playable_tracks->is_playable(current_track,
237 commonrender->current_position))
239 if(!playable_tracks->is_listed(current_track))
243 if(playable_tracks->is_listed(current_track))
250 // Test plugins against virtual console at current position
251 for(int i = 0; i < commonrender->total_modules && !result; i++)
252 result = commonrender->modules[i]->test_plugins();
258 // Now get the length of time until next reconfiguration.
259 // This part is not concerned with result.
260 // Don't clip input length if only rendering 1 frame.
261 if(length == 1) return result;
267 int direction = renderengine->command->get_direction();
268 // GCC 3.2 requires this or optimization error results.
269 int64_t longest_duration1;
270 int64_t longest_duration2;
271 int64_t longest_duration3;
273 //printf("VirtualConsole::test_reconfigure 6 %d %d\n", length, result);
274 // Length of time until next transition, edit, or effect change.
275 // Why do we need the edit change? Probably for changing to and from silence.
276 for(current_track = renderengine->edl->tracks->first;
278 current_track = current_track->next)
280 if(current_track->data_type == data_type)
282 // Test the transitions
283 longest_duration1 = current_track->edit_change_duration(
284 commonrender->current_position,
286 direction == PLAY_REVERSE,
289 //printf("VirtualConsole::test_reconfigure 10 %d\n", length);
292 longest_duration2 = current_track->edit_change_duration(
293 commonrender->current_position,
298 //printf("VirtualConsole::test_reconfigure 20 %d\n", length);
301 longest_duration3 = current_track->plugin_change_duration(
302 commonrender->current_position,
304 direction == PLAY_REVERSE);
306 if(longest_duration1 < length)
308 length = longest_duration1;
311 if(longest_duration2 < length)
313 length = longest_duration2;
316 if(longest_duration3 < length)
318 length = longest_duration3;
322 //printf("VirtualConsole::test_reconfigure 30 %d\n", length);
325 //printf("VirtualConsole::test_reconfigure 11 %d %d\n", length, result);
330 void VirtualConsole::run()
332 startup_lock->unlock();
356 int VirtualConsole::delete_virtual_console()
358 // delete the virtual modules
359 for(int i = 0; i < total_tracks; i++)
361 delete virtual_modules[i];
363 // Seems to get allocated even if new[0].
364 if(virtual_modules) delete [] virtual_modules;
368 render_list.remove_all();
371 int VirtualConsole::delete_input_buffers()
373 // delete input buffers
374 for(int buffer = 0; buffer < ring_buffers; buffer++)
376 delete_input_buffer(buffer);
379 for(int i = 0; i < ring_buffers; i++)
381 delete input_lock[i];
382 delete output_lock[i];
390 int VirtualConsole::start_rendering(int duplicate)
394 if(renderengine->command->realtime && commonrender->asynchronous)
396 // don't start a thread unless writing to an audio device
397 startup_lock->lock();
398 set_synchronous(1); // prepare thread base class
404 int VirtualConsole::wait_for_completion()
406 if(renderengine->command->realtime && commonrender->asynchronous)
413 int VirtualConsole::swap_input_buffer()
415 current_input_buffer++;
416 if(current_input_buffer >= total_ring_buffers()) current_input_buffer = 0;
420 int VirtualConsole::swap_thread_buffer()
422 current_vconsole_buffer++;
423 if(current_vconsole_buffer >= total_ring_buffers()) current_vconsole_buffer = 0;