r807: Minor fix...
[cinelerra_cv/mob.git] / cinelerra / virtualconsole.C
blobd0c210fcd673e74bb82d630709f002dbaa2d6c93
1 #include "auto.h"
2 #include "automation.h"
3 #include "autos.h"
4 #include "commonrender.h"
5 #include "condition.h"
6 #include "edl.h"
7 #include "edlsession.h"
8 #include "virtualconsole.h"
9 #include "module.h"
10 #include "mutex.h"
11 #include "playabletracks.h"
12 #include "renderengine.h"
13 #include "intautos.h"
14 #include "tracks.h"
15 #include "transportque.h"
16 #include "virtualnode.h"
19 VirtualConsole::VirtualConsole(RenderEngine *renderengine, 
20         CommonRender *commonrender,
21         int data_type)
23         this->renderengine = renderengine;
24         this->commonrender = commonrender;
25         this->data_type = data_type;
26         total_entry_nodes = 0;
27         playable_tracks = 0;
28         entry_nodes = 0;
29         debug_tree = 0;
33 VirtualConsole::~VirtualConsole()
35         delete_virtual_console();
37         delete playable_tracks;
41 void VirtualConsole::create_objects()
43         interrupt = 0;
44         done = 0;
46         get_playable_tracks();
47         total_entry_nodes = playable_tracks->total;
48         build_virtual_console(1);
49 //dump();
52 void VirtualConsole::start_playback()
54         interrupt = 0;
55         done = 0;
58 void VirtualConsole::get_playable_tracks()
62 Module* VirtualConsole::module_of(Track *track)
64         for(int i = 0; i < commonrender->total_modules; i++)
65         {
66                 if(commonrender->modules[i]->track == track) 
67                         return commonrender->modules[i];
68         }
69         return 0;
72 Module* VirtualConsole::module_number(int track_number)
74 // The track number is an absolute number of the track independant of
75 // the tracks with matching data type but virtual modules only exist for
76 // the matching data type.
77 // Convert from absolute track number to data type track number.
78         Track *current = renderengine->edl->tracks->first;
79         int data_type_number = 0, number = 0;
81         for( ; current; current = NEXT, number++)
82         {
83                 if(current->data_type == data_type)
84                 {
85                         if(number == track_number)
86                                 return commonrender->modules[data_type_number];
87                         else
88                                 data_type_number++;
89                 }
90         }
93         return 0;
96 void VirtualConsole::build_virtual_console(int persistent_plugins)
98 // allocate the entry nodes
99         if(!entry_nodes)
100         {
101                 entry_nodes = new VirtualNode*[total_entry_nodes];
103                 for(int i = 0; i < total_entry_nodes; i++)
104                 {
105                         entry_nodes[i] = new_entry_node(playable_tracks->values[i], 
106                                 module_of(playable_tracks->values[i]), 
107                                 i);
109 // Expand the trees
110                         entry_nodes[i]->expand(persistent_plugins, 
111                                 commonrender->current_position);
112                 }
113                 commonrender->restart_plugins = 1;
114         }
115 //dump();
118 VirtualNode* VirtualConsole::new_entry_node(Track *track, 
119         Module *module, 
120         int track_number)
122         printf("VirtualConsole::new_entry_node should not be called\n");
123         return 0;
126 void VirtualConsole::append_exit_node(VirtualNode *node)
128         node->is_exit = 1;
129         exit_nodes.append(node);
132 void VirtualConsole::reset_attachments()
134         for(int i = 0; i < commonrender->total_modules; i++)
135         {
136                 commonrender->modules[i]->reset_attachments();
137         }
140 void VirtualConsole::dump()
142         printf("VirtualConsole\n");
143         printf(" Modules\n");
144         for(int i = 0; i < commonrender->total_modules; i++)
145                 commonrender->modules[i]->dump();
146         printf(" Nodes\n");
147         for(int i = 0; i < total_entry_nodes; i++)
148                 entry_nodes[i]->dump(0);
152 int VirtualConsole::test_reconfigure(int64_t position, 
153         int64_t &length, 
154         int &last_playback)
156         int result = 0;
157         Track *current_track;
158         Module *module;
160 // Test playback status against virtual console for current position.
161         for(current_track = renderengine->edl->tracks->first;
162                 current_track && !result;
163                 current_track = current_track->next)
164         {
165                 if(current_track->data_type == data_type)
166                 {
167 // Playable status changed
168                         if(playable_tracks->is_playable(current_track, 
169                                 commonrender->current_position,
170                                 1))
171                         {
172                                 if(!playable_tracks->is_listed(current_track))
173                                         result = 1;
174                         }
175                         else
176                         if(playable_tracks->is_listed(current_track))
177                         {
178                                 result = 1;
179                         }
180                 }
181         }
183 // Test plugins against virtual console at current position
184         for(int i = 0; i < commonrender->total_modules && !result; i++)
185                 result = commonrender->modules[i]->test_plugins();
191 // Now get the length of time until next reconfiguration.
192 // This part is not concerned with result.
193 // Don't clip input length if only rendering 1 frame.
194         if(length == 1) return result;
200         int direction = renderengine->command->get_direction();
201 // GCC 3.2 requires this or optimization error results.
202         int64_t longest_duration1;
203         int64_t longest_duration2;
204         int64_t longest_duration3;
206 // Length of time until next transition, edit, or effect change.
207 // Why do we need the edit change?  Probably for changing to and from silence.
208         for(current_track = renderengine->edl->tracks->first;
209                 current_track;
210                 current_track = current_track->next)
211         {
212                 if(current_track->data_type == data_type)
213                 {
214 // Test the transitions
215                         longest_duration1 = current_track->edit_change_duration(
216                                 commonrender->current_position, 
217                                 length, 
218                                 direction == PLAY_REVERSE, 
219                                 1,
220                                 1);
223 // Test the edits
224                         longest_duration2 = current_track->edit_change_duration(
225                                 commonrender->current_position, 
226                                 length, 
227                                 direction, 
228                                 0,
229                                 1);
232 // Test the plugins
233                         longest_duration3 = current_track->plugin_change_duration(
234                                 commonrender->current_position,
235                                 length,
236                                 direction == PLAY_REVERSE,
237                                 1);
239                         if(longest_duration1 < length)
240                         {
241                                 length = longest_duration1;
242                                 last_playback = 0;
243                         }
244                         if(longest_duration2 < length)
245                         {
246                                 length = longest_duration2;
247                                 last_playback = 0;
248                         }
249                         if(longest_duration3 < length)
250                         {
251                                 length = longest_duration3;
252                                 last_playback = 0;
253                         }
255                 }
256         }
258         return result;
265 int VirtualConsole::delete_virtual_console()
267 // delete the virtual node tree
268         for(int i = 0; i < total_entry_nodes; i++)
269         {
270                 delete entry_nodes[i];
271         }
272 // Seems to get allocated even if new[0].
273         if(entry_nodes) delete [] entry_nodes;
274         entry_nodes = 0;
275         exit_nodes.remove_all();