initial commit
[goodguy/history.git] / cinelerra-5.0 / cinelerra / virtualconsole.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2008-2013 Adam Williams <broadcast at earthling dot net>
5  * 
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  * 
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  * 
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  * 
20  */
21
22 #include "auto.h"
23 #include "automation.h"
24 #include "autos.h"
25 #include "bcsignals.h"
26 #include "commonrender.h"
27 #include "condition.h"
28 #include "edl.h"
29 #include "edlsession.h"
30 #include "intautos.h"
31 #include "module.h"
32 #include "mutex.h"
33 #include "playabletracks.h"
34 #include "renderengine.h"
35 #include "tracks.h"
36 #include "transportque.h"
37 #include "virtualconsole.h"
38 #include "virtualnode.h"
39
40
41 VirtualConsole::VirtualConsole(RenderEngine *renderengine, 
42         CommonRender *commonrender,
43         int data_type)
44 {
45         this->renderengine = renderengine;
46         this->commonrender = commonrender;
47         this->data_type = data_type;
48         total_exit_nodes = 0;
49         playable_tracks = 0;
50         entry_nodes = 0;
51         debug_tree = 0;
52 //printf("VirtualConsole::VirtualConsole\n");
53 }
54
55
56 VirtualConsole::~VirtualConsole()
57 {
58         delete_virtual_console();
59
60         delete playable_tracks;
61 //printf("VirtualConsole::~VirtualConsole\n");
62 }
63
64
65 void VirtualConsole::create_objects()
66 {
67         interrupt = 0;
68         done = 0;
69
70         get_playable_tracks();
71         total_exit_nodes = playable_tracks->size();
72         build_virtual_console(1);
73 //dump();
74 }
75
76 void VirtualConsole::start_playback()
77 {
78         interrupt = 0;
79         done = 0;
80 }
81
82 void VirtualConsole::get_playable_tracks()
83 {
84 }
85
86 Module* VirtualConsole::module_of(Track *track)
87 {
88         for(int i = 0; i < commonrender->total_modules; i++)
89         {
90                 if(commonrender->modules[i]->track == track) 
91                         return commonrender->modules[i];
92         }
93         return 0;
94 }
95
96 Module* VirtualConsole::module_number(int track_number)
97 {
98 // The track number is an absolute number of the track independant of
99 // the tracks with matching data type but virtual modules only exist for
100 // the matching data type.
101 // Convert from absolute track number to data type track number.
102         Track *current = renderengine->get_edl()->tracks->first;
103         int data_type_number = 0, number = 0;
104
105         for( ; current; current = NEXT, number++)
106         {
107                 if(current->data_type == data_type)
108                 {
109                         if(number == track_number)
110                                 return commonrender->modules[data_type_number];
111                         else
112                                 data_type_number++;
113                 }
114         }
115
116
117         return 0;
118 }
119
120 void VirtualConsole::build_virtual_console(int persistent_plugins)
121 {
122 // allocate the entry nodes
123         if(!entry_nodes)
124         {
125                 entry_nodes = new VirtualNode*[total_exit_nodes];
126
127 // printf("VirtualConsole::build_virtual_console %d total_exit_nodes=%d\n", 
128 // __LINE__,
129 // total_exit_nodes);
130                 for(int i = 0; i < total_exit_nodes; i++)
131                 {
132 // printf("VirtualConsole::build_virtual_console %d track=%p module=%p\n",
133 // __LINE__,
134 // playable_tracks->get(i),
135 // module_of(playable_tracks->get(i)));
136                         entry_nodes[i] = new_entry_node(playable_tracks->get(i), 
137                                 module_of(playable_tracks->get(i)), 
138                                 i);
139
140 // Expand the trees
141                         entry_nodes[i]->expand(persistent_plugins, 
142                                 commonrender->current_position);
143                 }
144                 commonrender->restart_plugins = 1;
145         }
146 //dump();
147 }
148
149 VirtualNode* VirtualConsole::new_entry_node(Track *track, 
150         Module *module, 
151         int track_number)
152 {
153         printf("VirtualConsole::new_entry_node should not be called\n");
154         return 0;
155 }
156
157 void VirtualConsole::append_exit_node(VirtualNode *node)
158 {
159         node->is_exit = 1;
160         exit_nodes.append(node);
161 }
162
163 void VirtualConsole::reset_attachments()
164 {
165         for(int i = 0; i < commonrender->total_modules; i++)
166         {
167                 commonrender->modules[i]->reset_attachments();
168         }
169 }
170
171 void VirtualConsole::dump()
172 {
173         printf("VirtualConsole\n");
174         printf(" Modules\n");
175         for(int i = 0; i < commonrender->total_modules; i++)
176                 commonrender->modules[i]->dump();
177         printf(" Nodes\n");
178         for(int i = 0; i < total_exit_nodes; i++)
179                 entry_nodes[i]->dump(0);
180 }
181
182
183 int VirtualConsole::test_reconfigure(int64_t position, 
184         int64_t &length)
185 {
186         int result = 0;
187         Track *current_track;
188         int direction = renderengine->command->get_direction();
189
190 // Test playback status against virtual console for current position.
191         for(current_track = renderengine->get_edl()->tracks->first;
192                 current_track && !result;
193                 current_track = current_track->next)
194         {
195                 if(current_track->data_type == data_type)
196                 {
197 // Playable status changed
198                         if(playable_tracks->is_playable(current_track, 
199                                 commonrender->current_position,
200                                 direction,
201                                 1))
202                         {
203                                 if(!playable_tracks->is_listed(current_track))
204                                         result = 1;
205                         }
206                         else
207                         if(playable_tracks->is_listed(current_track))
208                         {
209                                 result = 1;
210                         }
211                 }
212         }
213
214 // Test plugins against virtual console at current position
215         for(int i = 0; i < commonrender->total_modules && !result; i++)
216                 result = commonrender->modules[i]->test_plugins();
217
218
219
220
221
222 // Now get the length of time until next reconfiguration.
223 // This part is not concerned with result.
224 // Don't clip input length if only rendering 1 frame.
225         if(length == 1) return result;
226
227
228
229
230
231 // GCC 3.2 requires this or optimization error results.
232         int64_t longest_duration1;
233         int64_t longest_duration2;
234         int64_t longest_duration3;
235
236 // Length of time until next transition, edit, or effect change.
237 // Why do we need the edit change?  Probably for changing to and from silence.
238         for(current_track = renderengine->get_edl()->tracks->first;
239                 current_track;
240                 current_track = current_track->next)
241         {
242                 if(current_track->data_type == data_type)
243                 {
244 // Test the transitions
245                         longest_duration1 = current_track->edit_change_duration(
246                                 commonrender->current_position, 
247                                 length, 
248                                 direction == PLAY_REVERSE, 
249                                 1,
250                                 1);
251
252
253 // Test the edits
254                         longest_duration2 = current_track->edit_change_duration(
255                                 commonrender->current_position, 
256                                 length, 
257                                 direction, 
258                                 0,
259                                 1);
260
261
262 // Test the plugins
263                         longest_duration3 = current_track->plugin_change_duration(
264                                 commonrender->current_position,
265                                 length,
266                                 direction == PLAY_REVERSE,
267                                 1);
268
269                         if(longest_duration1 < length)
270                         {
271                                 length = longest_duration1;
272                         }
273                         if(longest_duration2 < length)
274                         {
275                                 length = longest_duration2;
276                         }
277                         if(longest_duration3 < length)
278                         {
279                                 length = longest_duration3;
280                         }
281
282                 }
283         }
284
285         return result;
286 }
287
288
289
290
291
292 int VirtualConsole::delete_virtual_console()
293 {
294 // delete the virtual node tree
295         for(int i = 0; i < total_exit_nodes; i++)
296         {
297                 delete entry_nodes[i];
298         }
299 // Seems to get allocated even if new[0].
300         if(entry_nodes) delete [] entry_nodes;
301         entry_nodes = 0;
302         exit_nodes.remove_all();
303         return 0;
304 }
305
306