4 * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
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.
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.
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
27 // The master node of the background renderer needs a separate memory space
28 // because few of the codecs are reentrant.
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.
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.
40 // A BRenderThread client runs in the background and a BRender object
41 // interfaces the main window. The BRender client recieves commands to
42 // restart, start, and stop background rendering on its own time to avoid
43 // interrupting the main window.
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.
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.
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.
62 #include "arraylist.h"
63 #include "bcwindowbase.inc"
64 #include "brender.inc"
65 #include "condition.inc"
68 #include "mwindow.inc"
69 #include "packagedispatcher.inc"
70 #include "preferences.inc"
71 #include "renderfarm.inc"
73 #include "bctimer.inc"
81 class BRender : public Thread
84 BRender(MWindow *mwindow);
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
90 void restart(EDL *edl);
91 // Stop background rendering for a foreground render. This blocks until
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);
114 // Simple map of finished chunks
119 // Status of each map entry. This way we get the last contiguous as well as the
120 // ones which are actually rendered.
128 // Invalidate the map until reallocation when a new edit operation is performed.
131 // Constantly recalculate this after every frame instead of searching
134 // Wait until stop commands are finished
135 Condition *completion_lock;
136 BRenderThread *thread;
137 // PID of master node for killing.
140 char socket_path[BCTEXTLEN];
141 // Arguments for execvp
152 // Transfers EDL pointer but doesn't create a new EDL.
153 void copy_from(BRenderCommand *command);
155 void copy_edl(EDL *edl);
165 // The location of the last change.
167 // The earliest point to include in background rendering would be stored in the
171 class BRenderThread : public Thread
174 BRenderThread(MWindow *mwindow, BRender *brender);
177 int is_done(int do_lock);
178 void send_command(BRenderCommand *command);
186 BRenderCommand *command_queue;
187 BRenderCommand *command;
188 Condition *input_lock;
190 // Render farm server. Deleted when stopped. Created when restarted.
191 RenderFarmServer *farm_server;
192 PackageDispatcher *packages;
193 // Copy of preferences with modified render farm.
194 Preferences *preferences;
195 // Render farm polls these.
199 int64_t total_frames;
200 Mutex *total_frames_lock;