r105: This commit was manufactured by cvs2svn to create tag
[cinelerra_cv/mob.git] / hvirtual / cinelerra / vmodule.C
blobe19eb561236054f40e9c522519252e4ca55ce587
1 #include "assets.h"
2 #include "cache.h"
3 #include "clip.h"
4 #include "commonrender.h"
5 #include "edits.h"
6 #include "edl.h"
7 #include "edlsession.h"
8 #include "file.h"
9 #include "filexml.h"
10 #include "floatautos.h"
11 #include "overlayframe.h"
12 #include "patch.h"
13 #include "renderengine.h"
14 #include "sharedlocation.h"
15 #include "transition.h"
16 #include "transportque.h"
17 #include "units.h"
18 #include "vattachmentpoint.h"
19 #include "vedit.h"
20 #include "vframe.h"
21 #include "vmodule.h"
22 #include "vplugin.h"
23 #include "vtrack.h"
24 #include <string.h>
26 VModule::VModule(RenderEngine *renderengine, 
27         CommonRender *commonrender, 
28         PluginArray *plugin_array,
29         Track *track)
30  : Module(renderengine, commonrender, plugin_array, track)
32         data_type = TRACK_VIDEO;
33         input_temp = transition_temp = 0;
34         overlayer = 0;
37 VModule::~VModule()
39         if(input_temp) 
40         {
41                 delete input_temp;
42         }
43         if(transition_temp) 
44         {
45                 delete transition_temp;
46         }
47         if(overlayer) delete overlayer;
51 AttachmentPoint* VModule::new_attachment(Plugin *plugin)
53         return new VAttachmentPoint(renderengine, plugin);
56 int VModule::get_buffer_size()
58         return 1;
61 CICache* VModule::get_cache()
63         if(renderengine) 
64                 return renderengine->get_vcache();
65         else
66                 return cache;
69 int VModule::import_frame(VFrame *output,
70         VEdit *current_edit,
71         int64_t input_position,
72         int direction)
74         int64_t corrected_position = input_position;
75         if(direction == PLAY_REVERSE) corrected_position--;
76 // Translation of edit
77         float in_x1;
78         float in_y1;
79         float in_w1;
80         float in_h1;
81         float out_x1;
82         float out_y1;
83         float out_w1;
84         float out_h1;
85         int result = 0;
87 //printf("VModule::import_frame 1 %p\n", current_edit);
88 // Load frame into output
89         if(current_edit &&
90                 current_edit->asset)
91         {
92 //printf("VModule::import_frame 1\n");
93                 File *source = get_cache()->check_out(current_edit->asset);
95                 if(source)
96                 {
97 //printf("VModule::import_frame 1\n");
98                         source->set_video_position(corrected_position - 
99                                 current_edit->startproject + 
100                                 current_edit->startsource,
101                                 get_edl()->session->frame_rate);
102                         source->set_layer(current_edit->channel);
103 //printf("VModule::import_frame 2\n");
105                         ((VTrack*)track)->calculate_input_transfer(current_edit->asset, 
106                                 input_position, 
107                                 direction, 
108                                 in_x1, 
109                                 in_y1, 
110                                 in_w1, 
111                                 in_h1,
112                                 out_x1, 
113                                 out_y1, 
114                                 out_w1, 
115                                 out_h1);
116 // printf("VModule::import_frame 1 %0.2f %0.2f %0.2f %0.2f -> %0.2f %0.2f %0.2f %0.2f\n",
117 //      in_x1,
118 //      in_y1,
119 //      in_w1,
120 //      in_h1,
121 //      out_x1,
122 //      out_y1,
123 //      out_w1,
124 //      out_h1);
128 // file -> temp -> output
129                         if( !EQUIV(in_x1, 0) || 
130                                 !EQUIV(in_y1, 0) || 
131                                 !EQUIV(in_w1, track->track_w) || 
132                                 !EQUIV(in_h1, track->track_h) || 
133                                 !EQUIV(out_x1, 0) ||
134                                 !EQUIV(out_y1, 0) ||
135                                 !EQUIV(out_w1, track->track_w) ||
136                                 !EQUIV(out_h1, track->track_h) ||
137                                 !EQUIV(in_w1, current_edit->asset->width) ||
138                                 !EQUIV(in_h1, current_edit->asset->height))
139                         {
140 // Fix buffers
141 //printf("VModule::import_frame 3\n");
142                                 if(input_temp && 
143                                         (input_temp->get_w() != current_edit->asset->width ||
144                                         input_temp->get_h() != current_edit->asset->height))
145                                 {
146 //printf("VModule::import_frame 3\n");
147                                         delete input_temp;
148                                         input_temp = 0;
149                                 }
155                                 if(!input_temp)
156                                 {
157 //printf("VModule::import_frame 4\n");
158                                         input_temp = new VFrame(0,
159                                                 current_edit->asset->width,
160                                                 current_edit->asset->height,
161                                                 get_edl()->session->color_model,
162                                                 -1);
163                                 }
164 //printf("VModule::import_frame 5\n");
166 // file -> temp
167                                 result = source->read_frame(input_temp);
168                                 if(!overlayer)
169                                 {
170                                         overlayer = new OverlayFrame(get_edl()->session->smp + 1);
171                                 }
172 // printf("VModule::import_frame 1 %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f\n", 
173 //      in_x1, 
174 //      in_y1, 
175 //      in_w1, 
176 //      in_h1, 
177 //      out_x1, 
178 //      out_y1, 
179 //      out_w1, 
180 //      out_h1);
182 // temp -> output
183 // for(int j = 0; j < output->get_w() * 3 * 5; j++)
184 //      output->get_rows()[0][j] = 255;
186                                 output->clear_frame();
189 // get_cache()->check_in(current_edit->asset);
190 // return;
192 // TRANSFER_REPLACE is the fastest transfer mode but it has the disadvantage
193 // of producing green borders in floating point translation of YUV
194                                 int mode = TRANSFER_REPLACE;
195                                 if(get_edl()->session->interpolation_type != NEAREST_NEIGHBOR &&
196                                         cmodel_is_yuv(output->get_color_model()))
197                                         mode = TRANSFER_NORMAL;
199                                 overlayer->overlay(output,
200                                         input_temp, 
201                                         in_x1,
202                                         in_y1,
203                                         in_x1 + in_w1,
204                                         in_y1 + in_h1,
205                                         out_x1,
206                                         out_y1,
207                                         out_x1 + out_w1,
208                                         out_y1 + out_h1,
209                                         1,
210                                         mode,
211                                         get_edl()->session->interpolation_type);
212                         }
213                         else
214 // file -> output
215                         {
217 //printf("VModule::import_frame 6\n");
218                                 result = source->read_frame(output);
219                         }
220 //printf("VModule::import_frame 6\n");
222                         get_cache()->check_in(current_edit->asset);
223                 }
224                 else
225                 {
226                         output->clear_frame();
227                         result = 1;
228                 }
229         }
230         else
231 // Silence
232         {
233                 output->clear_frame();
234         }
235 //printf("VModule::import_frame 7\n");
237         return result;
242 int VModule::render(VFrame *output,
243         int64_t input_position,
244         int direction)
246         int result = 0;
248 //printf("VModule::render 1 %d\n", input_position);
249         update_transition(input_position, direction);
251         VEdit* current_edit = (VEdit*)track->edits->editof(input_position, 
252                 direction);
253         VEdit* previous_edit = 0;
254 //printf("VModule::render 2\n");
256         if(!current_edit) 
257         {
258                 output->clear_frame();
259                 return 0;
260         }
262 //printf("VModule::render 3\n");
264 //printf("VModule::render 3 %p\n", transition);
265 // Process transition
266         if(transition)
267         {
268 // Load incoming frame
269                 if(!transition_temp)
270                 {
271                         transition_temp = new VFrame(0,
272                                 track->track_w,
273                                 track->track_h,
274                                 get_edl()->session->color_model,
275                                 -1);
276                 }
278                 result = import_frame(transition_temp, 
279                         current_edit, 
280                         input_position,
281                         direction);
284 // Load transition buffer
285 //printf("VModule::render 2\n");
286                 previous_edit = (VEdit*)current_edit->previous;
288 //printf("VModule::render 3\n");
289                 result |= import_frame(output, 
290                         previous_edit, 
291                         input_position,
292                         direction);
294 // Execute plugin with transition_temp and output here
295 //printf("VModule::render 4 %d - %d %d\n", input_position, current_edit->startproject, transition->length);
296                 transition_server->process_realtime(&transition_temp, 
297                         &output,
298                         (direction == PLAY_FORWARD) ? 
299                                 (input_position - current_edit->startproject) :
300                                 (input_position - current_edit->startproject - 1),
301                         transition->length);
302         }
303         else
304         {
305 // Load output buffer
306                 result = import_frame(output, 
307                         current_edit, 
308                         input_position,
309                         direction);
310         }
312 //printf("VModule::render 5\n");
313         return result;
321 void VModule::create_objects()
323         Module::create_objects();