Credit Andrew - improve in-tree documentation
[goodguy/cinelerra.git] / cinelerra / brender.h
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 #ifndef BRENDER_H
23 #define BRENDER_H
24
25
26
27 // The master node of the background renderer needs a separate memory space
28 // because few of the codecs are reentrant.
29
30 // To solve the problem, the master node forks itself and treats the forked
31 // master node as the first node of a renderfarm.  There is no real master node
32 // of the renderfarm.  The BRender object is a thread in order to
33 // join the forked master node.
34
35 // If renderfarm is enabled, the extra renderfarm nodes are treated normally.
36 // Unfortunately because of the codec problem, only one copy of Cinelerra
37 // can be running on a single renderfarm.  This means either background
38 // rendering or foreground rendering can be happening but not both.
39
40 // A BRenderThread client runs in the background and a BRender object
41 // interfaces the main window.  The BRender client receives commands to
42 // restart, start, and stop background rendering on its own time to avoid
43 // interrupting the main window.
44
45 // Whenever a change happens to the timeline, we calculate the last position
46 // which hasn't changed and the end of the contiguous renderfarm output.
47 // Then we restart the background renderfarm at the
48 // lesser of the positions.  You can't conditionally restart only
49 // if one of the current jobs was after the position because you need a new EDL.
50
51 // The two problems to emerge are which job is the last job in the contiguous
52 // set of finished jobs and if position of change is before the last job,
53 // how to truncate and restart the output file.
54
55 // It's easy to use image sequences as the output file to solve the
56 // file truncation problem.
57 // Figuring out the end of the contiguous output means recording the
58 // state of every output file and constructing a kind of EDL for the
59 // background output as certain output files cluster together.
60 // This is needed anyway for playback.
61
62 #include "arraylist.h"
63 #include "bcwindowbase.inc"
64 #include "brender.inc"
65 #include "condition.inc"
66 #include "edl.inc"
67 #include "mutex.inc"
68 #include "mwindow.inc"
69 #include "packagedispatcher.inc"
70 #include "preferences.inc"
71 #include "renderfarm.inc"
72 #include "thread.h"
73 #include "bctimer.inc"
74
75
76
77
78
79
80
81 class BRender : public Thread
82 {
83 public:
84         BRender(MWindow *mwindow);
85         ~BRender();
86
87 // Give the last position of the EDL which hasn't changed.
88 // We copy the EDL and restart rendering at the lesser of position and
89 // our position.
90         void restart(EDL *edl);
91 // Stop background rendering for a foreground render.  This blocks until
92 // it really stops.
93         void stop();
94
95
96 // Get last contiguous frame from map, with locking.
97 // Only needed by BRenderThread::start but nothing really uses it.
98         int get_last_contiguous(int64_t brender_start);
99 // Allocate map with locking
100         void allocate_map(int64_t brender_start, int64_t start, int64_t end);
101 // Mark a frame as finished
102         int set_video_map(int64_t position, int value);
103
104         void initialize();
105         void run();
106
107
108
109         MWindow *mwindow;
110
111
112
113
114 // Simple map of finished chunks
115         unsigned char *map;
116         int64_t map_size;
117         Mutex *map_lock;
118
119 // Status of each map entry.  This way we get the last contiguous as well as the
120 // ones which are actually rendered.
121         enum
122         {
123                 NOT_SCANNED,
124                 SCANNED,
125                 RENDERED
126         };
127
128 // Invalidate the map until reallocation when a new edit operation is performed.
129         int map_valid;
130
131 // Constantly recalculate this after every frame instead of searching
132         int last_contiguous;
133
134 // Wait until stop commands are finished
135         Condition *completion_lock;
136         BRenderThread *thread;
137 // PID of master node for killing.
138         int master_pid;
139 // Path of socket
140         char socket_path[BCTEXTLEN];
141 // Arguments for execvp
142         char *arguments[4];
143         Timer *timer;
144 };
145
146 class BRenderCommand
147 {
148 public:
149         BRenderCommand();
150         ~BRenderCommand();
151
152 // Transfers EDL pointer but doesn't create a new EDL.
153         void copy_from(BRenderCommand *command);
154 // Make new EDL
155         void copy_edl(EDL *edl);
156
157         EDL *edl;
158         enum
159         {
160                 BRENDER_NONE,
161                 BRENDER_RESTART,
162                 BRENDER_STOP
163         };
164         int command;
165 // The location of the last change.
166         double position;
167 // The earliest point to include in background rendering would be stored in the
168 // EDL.
169 };
170
171 class BRenderThread : public Thread
172 {
173 public:
174         BRenderThread(MWindow *mwindow, BRender *brender);
175         ~BRenderThread();
176
177         void send_command(BRenderCommand *command);
178         void run();
179         void stop();
180         void start();
181         void initialize();
182
183         MWindow *mwindow;
184         BRender *brender;
185         BRenderCommand *command_queue;
186         BRenderCommand *command;
187         Condition *input_lock;
188         Mutex *thread_lock;
189 // Render farm server.  Deleted when stopped.  Created when restarted.
190         RenderFarmServer *farm_server;
191         PackageDispatcher *packages;
192 // Copy of preferences with modified render farm.
193         Preferences *preferences;
194 // Render farm polls these.
195         int farm_result;
196         double fps_result;
197 // Not used
198         int64_t total_frames;
199         Mutex *total_frames_lock;
200         int done;
201 };
202
203
204
205
206
207
208
209 #endif