r370: Heroine Virutal's official release 1.2.1
[cinelerra_cv/mob.git] / hvirtual / cinelerra / commonrender.C
blobce302b2cd5edda69f0ae1288384968a0efc06441
1 #include "auto.h"
2 #include "cache.h"
3 #include "commonrender.h"
4 #include "condition.h"
5 #include "edl.h"
6 #include "edlsession.h"
7 #include "intautos.h"
8 #include "localsession.h"
9 #include "mainsession.h"
10 #include "module.h"
11 #include "mwindow.h"
12 #include "patchbay.h"
13 #include "patch.h"
14 #include "playabletracks.h"
15 #include "preferences.h"
16 #include "renderengine.h"
17 #include "track.h"
18 #include "tracks.h"
19 #include "transportque.h"
20 #include "virtualconsole.h"
22 CommonRender::CommonRender(RenderEngine *renderengine)
23  : Thread(1, 0, 0)
25         this->renderengine = renderengine;
26         reset_parameters();
27         start_lock = new Condition(0, "CommonRender::start_lock");
30 CommonRender::~CommonRender()
32         delete_vconsole();
33         if(modules)
34         {
35                 for(int i = 0; i < total_modules; i++)
36                         delete modules[i];
37                 delete [] modules;
38         }
39         delete start_lock;
42 void CommonRender::reset_parameters()
44         total_modules = 0;
45         modules = 0;
46         vconsole = 0;
47         done = 0;
48         interrupt = 0;
49         last_playback = 0;
50         asynchronous = 0;
51         restart_plugins = 0;
54 void CommonRender::arm_command()
56         int64_t temp_length = 1;
58         current_position = tounits(renderengine->command->playbackstart, 0);
60         init_output_buffers();
62         last_playback = 0;
63         if(test_reconfigure(current_position, temp_length))
64         {
65                 restart_playback();
66         }
67         else
68         {
69                 vconsole->start_playback();
70         }
72         done = 0;
73         interrupt = 0;
74         last_playback = 0;
75         restart_plugins = 0;
80 void CommonRender::create_modules()
82 // Create a module for every track, playable or not
83         Track *current = renderengine->edl->tracks->first;
84         int module = 0;
86         if(!modules)
87         {
88                 total_modules = get_total_tracks();
89                 modules = new Module*[total_modules];
91                 for(module = 0; module < total_modules && current; current = NEXT)
92                 {
93                         if(current->data_type == data_type)
94                         {
95                                 modules[module] = new_module(current);
96                                 modules[module]->create_objects();
97                                 module++;
98                         }
99                 }
100         }
101         else
102 // Update changes in plugins for existing modules
103         {
104                 for(module = 0; module < total_modules; module++)
105                 {
106                         modules[module]->create_objects();
107                 }
108         }
111 void CommonRender::start_plugins()
113 // Only start if virtual console was created
114         if(restart_plugins)
115         {
116                 for(int i = 0; i < total_modules; i++)
117                 {
118                         modules[i]->render_init();
119                 }
120         }
123 int CommonRender::test_reconfigure(int64_t position, int64_t &length)
125         if(!vconsole) return 1;
126         if(!modules) return 1;
127         
128         return vconsole->test_reconfigure(position, length, last_playback);
132 void CommonRender::build_virtual_console()
134 // Create new virtual console object
135         if(!vconsole)
136         {
137                 vconsole = new_vconsole_object();
138         }
140 // Create nodes
141         vconsole->create_objects();
144 void CommonRender::start_command()
146         if(renderengine->command->realtime)
147         {
148                 Thread::start();
149                 start_lock->lock("CommonRender::start_command");
150         }
153 int CommonRender::restart_playback()
155         delete_vconsole();
156         create_modules();
157         build_virtual_console();
158         start_plugins();
160         done = 0;
161         interrupt = 0;
162         last_playback = 0;
163         restart_plugins = 0;
164         return 0;
167 void CommonRender::delete_vconsole()
169         if(vconsole) delete vconsole;
170         vconsole = 0;
173 int CommonRender::get_boundaries(int64_t &current_render_length)
175         int64_t loop_end = tounits(renderengine->edl->local_session->loop_end, 1);
176         int64_t loop_start = tounits(renderengine->edl->local_session->loop_start, 0);
177         int64_t start_position = tounits(renderengine->command->start_position, 0);
178         int64_t end_position = tounits(renderengine->command->end_position, 1);
181 // test absolute boundaries if no loop and not infinite
182         if(renderengine->command->single_frame() || 
183                 (!renderengine->edl->local_session->loop_playback && 
184                 !renderengine->command->infinite))
185         {
186                 if(renderengine->command->get_direction() == PLAY_FORWARD)
187                 {
188                         if(current_position + current_render_length >= end_position)
189                         {
190                                 last_playback = 1;
191                                 current_render_length = end_position - current_position;
192                         }
193                 }
194 // reverse playback
195                 else               
196                 {
197                         if(current_position - current_render_length <= start_position)
198                         {
199                                 last_playback = 1;
200                                 current_render_length = current_position - start_position;
201                         }
202                 }
203         }
205 // test against loop boundaries
206         if(!renderengine->command->single_frame() &&
207                 renderengine->edl->local_session->loop_playback && 
208                 !renderengine->command->infinite)
209         {
210                 if(renderengine->command->get_direction() == PLAY_FORWARD)
211                 {
212                         int64_t segment_end = current_position + current_render_length;
213                         if(segment_end > loop_end)
214                         {
215                                 current_render_length = loop_end - current_position;
216                         }
217                 }
218                 else
219                 {
220                         int64_t segment_end = current_position - current_render_length;
221                         if(segment_end < loop_start)
222                         {
223                                 current_render_length = current_position - loop_start;
224                         }
225                 }
226         }
228         if(renderengine->command->single_frame())
229                 current_render_length = 1;
231         if(current_render_length < 0) current_render_length = 0;
232         return 0;
235 void CommonRender::run()
237         start_lock->unlock();
260 CommonRender::CommonRender(MWindow *mwindow, RenderEngine *renderengine)
261  : Thread()
263         this->mwindow = mwindow;
264         this->renderengine = renderengine;
265         current_position = 0;
266         interrupt = 0;
267         done = 0;
268         last_playback = 0;
269         vconsole = 0;
270         asynchronous = 1;
274 int CommonRender::wait_for_completion()
276         join();
283 int CommonRender::advance_position(int64_t current_render_length)
285         int64_t loop_end = tounits(renderengine->edl->local_session->loop_end, 1);
286         int64_t loop_start = tounits(renderengine->edl->local_session->loop_start, 0);
288 // advance the playback position
289         if(renderengine->command->get_direction() == PLAY_REVERSE)
290                 current_position -= current_render_length;
291         else
292                 current_position += current_render_length;
294 // test loop again
295         if(renderengine->edl->local_session->loop_playback && 
296                 !renderengine->command->infinite)
297         {
298                 if(renderengine->command->get_direction() == PLAY_REVERSE)
299                 {
300                         if(current_position <= loop_start)
301                                 current_position = loop_end;
302                 }
303                 else
304                 {
305                         if(current_position >= loop_end)
306                                 current_position = loop_start + (current_position - loop_end);
307                 }
308         }
309         return 0;
312 int64_t CommonRender::tounits(double position, int round)
314         return (int64_t)position;
317 double CommonRender::fromunits(int64_t position)
319         return (double)position;