Credit Andrew R for finding the direct copy mods for exr and ppm sequences
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / vattachmentpoint.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2008 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 "bcsignals.h"
23 #include "clip.h"
24 #include "datatype.h"
25 #include "edl.h"
26 #include "edlsession.h"
27 #include "plugin.h"
28 #include "pluginserver.h"
29 #include "renderengine.h"
30 #include "transportque.h"
31 #include "vattachmentpoint.h"
32 #include "vdevicex11.h"
33 #include "videodevice.h"
34 #include "vframe.h"
35
36 VAttachmentPoint::VAttachmentPoint(RenderEngine *renderengine, Plugin *plugin)
37 : AttachmentPoint(renderengine, plugin, TRACK_VIDEO)
38 {
39         buffer_vector = 0;
40 }
41
42 VAttachmentPoint::~VAttachmentPoint()
43 {
44         delete_buffer_vector();
45 }
46
47 void VAttachmentPoint::delete_buffer_vector()
48 {
49         void *This = this;
50         if(!This) printf("VAttachmentPoint::delete_buffer_vector NULL\n");
51         if(buffer_vector)
52         {
53                 for(int i = 0; i < virtual_plugins.total; i++)
54                         delete buffer_vector[i];
55                 delete [] buffer_vector;
56         }
57         buffer_vector = 0;
58 }
59
60 void VAttachmentPoint::new_buffer_vector(int width, int height, int colormodel)
61 {
62         void *This = this;
63         if(!This) printf("VAttachmentPoint::new_buffer_vector NULL\n");
64         if(buffer_vector &&
65                 (width != buffer_vector[0]->get_w() ||
66                 height != buffer_vector[0]->get_h() ||
67                 colormodel != buffer_vector[0]->get_color_model()))
68         {
69                 delete_buffer_vector();
70         }
71
72         if(!buffer_vector)
73         {
74                 buffer_vector = new VFrame*[virtual_plugins.total];
75                 for(int i = 0; i < virtual_plugins.total; i++)
76                 {
77                         buffer_vector[i] = new VFrame(width, height, colormodel);
78                 }
79         }
80 }
81
82 int VAttachmentPoint::get_buffer_size()
83 {
84         return 1;
85 }
86
87 void VAttachmentPoint::render(VFrame *output,
88         int buffer_number,
89         int64_t start_position,
90         double frame_rate,
91         int debug_render,
92         int use_opengl)
93 {
94         void *This = this;
95         if(!This) printf("VAttachmentPoint::render NULL\n");
96         if(!plugin_server || !plugin->on) return;
97
98         if(debug_render)
99                 printf("    VAttachmentPoint::render \"%s\" multi=%d opengl=%d\n",
100                         plugin_server->title,
101                         plugin_server->multichannel,
102                         use_opengl);
103
104         if(plugin_server->multichannel)
105         {
106 // Test against previous parameters for reuse of previous data
107                 if( !is_processed || this->start_position != start_position ||
108                     !EQUIV(this->frame_rate, frame_rate)) {
109                         is_processed = 1;
110                         this->start_position = start_position;
111                         this->frame_rate = frame_rate;
112
113 // Allocate buffer vector for subsequent render calls
114                         new_buffer_vector(output->get_w(), output->get_h(),
115                                 output->get_color_model());
116 // Process plugin
117 //printf("VAttachmentPoint::render 1 %d\n", buffer_number);
118                         if(renderengine)
119                                 plugin_servers.values[0]->set_use_opengl(use_opengl,
120                                         renderengine->video);
121                         plugin_servers.values[0]->process_buffer(buffer_vector,
122                                 start_position, frame_rate,
123                                 (int64_t)Units::round(plugin->length * frame_rate /
124                                         renderengine->get_edl()->session->frame_rate),
125                                 renderengine->command->get_direction());
126                 }
127 //printf("VAttachmentPoint::render 3\n");
128 // Need to copy PBuffer if OpenGL, regardless of use_opengl
129                 int opengl_state = buffer_vector[buffer_number]->get_opengl_state();
130                 if( opengl_state == VFrame::RAM ) {
131                         output->transfer_from(buffer_vector[buffer_number],
132                                 0, 0,0, output->get_w(), output->get_h());
133                         output->set_opengl_state(VFrame::RAM);
134                 }
135                 else if( opengl_state != VFrame::UNKNOWN &&
136                          renderengine && renderengine->video) {
137 // Need to copy PBuffer to texture
138 // printf("VAttachmentPoint::render temp=%p output=%p\n",
139 // buffer_vector[buffer_number],
140 // output);
141                         VDeviceX11 *x11_device = (VDeviceX11*)renderengine->video->get_output_base();
142                         x11_device->copy_frame(output, buffer_vector[buffer_number]);
143                 }
144         }
145         else
146 // process single track
147         {
148                 VFrame *output_temp[1];
149                 output_temp[0] = output;
150                 if(renderengine)
151                         plugin_servers.values[buffer_number]->set_use_opengl(use_opengl,
152                                 renderengine->video);
153                 plugin_servers.values[buffer_number]->process_buffer(output_temp,
154                         start_position,
155                         frame_rate,
156                         (int64_t)Units::round(plugin->length *
157                                 frame_rate /
158                                 renderengine->get_edl()->session->frame_rate),
159                         renderengine->command->get_direction());
160         }
161 }
162
163