add bluray dv, misc fixes
[goodguy/history.git] / cinelerra-5.1 / cinelerra / renderfarm.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 RENDERFARM_H
23 #define RENDERFARM_H
24
25
26 #include "arraylist.h"
27 #include "asset.inc"
28 #include "brender.inc"
29 #include "bchash.inc"
30 #include "condition.inc"
31 #include "edl.inc"
32 #include "mutex.inc"
33 #include "mwindow.inc"
34 #include "packagedispatcher.inc"
35 #include "pluginserver.inc"
36 #include "preferences.inc"
37 #include "render.inc"
38 #include "renderfarm.inc"
39 #include "renderfarmclient.inc"
40 //#include "renderfarmfsserver.inc"
41 #include "thread.h"
42
43 #include <stdint.h>
44
45
46 // Renderfarm theory:
47 // The renderfarm starts a RenderFarmServerThread for each client
48 // listed in the preferences.
49 // The RenderFarmServerThread starts a RenderFarmWatchdog thread.
50 // write_socket and read_socket start the watchdog thread.  If they don't
51 // return in a certain time, the watchdog thread assumes the client has crashed
52 // and kills RenderFarmServerThread.
53 // RenderFarmServerThread handles requests from the client once the
54 // connection is open.  All the RenderFarmServerThread's are joined by the
55 // RenderFarmServer when the jobs are finished.
56 //
57 // On the client side, the process started by the user is a RenderFarmClient.
58 // It waits for connections from the server and starts a RenderFarmClientThread
59 // for each connection.  RenderFarmClientThread is a thread but it in turn
60 // starts a fork for the actual rendering.   A fork instead of a thread is
61 // used to avoid reentrancy problems with the
62 // codecs, but we still need a thread to join the process.
63 //
64 // The fork requests jobs from the server until the job table is empty
65 // or the server reports an error.  This fork must poll the server
66 // after every frame for the error status.  Also the fork creates a
67 // RenderFarmWatchdog thread to kill itself if a write_socket or read_socket
68 // doesn't return.
69 //
70 // RenderFarmClientThread detaches when finished.
71 // It doesn't account for the server command loop, which waits for read_socket
72 // indefinitely.  This needs to be pinged periodically to keep the read_socket
73 // alive.
74 //
75 // Once, it tried to use a virtual file system to allow rendering clients without
76 // mounting the filesystem of the server.  This proved impractical because of
77 // the many odd schemes used by file libraries.  Abstracting "open" didn't
78 // work.  Read ahead and caching were required to get decent performance.
79 //
80 // Whether it cleans up when timed out is unknown.
81
82 // Request format
83 // 1 byte -> request code
84 // 4 bytes -> size of packet exclusive
85 // size of packet -> data
86
87
88
89 // General reply format
90 // 4 bytes -> size of packet exclusive
91 // size of packet -> data
92
93 #define STORE_INT32(value) \
94         datagram[i++] = (((uint32_t)(value)) >> 24) & 0xff; \
95         datagram[i++] = (((uint32_t)(value)) >> 16) & 0xff; \
96         datagram[i++] = (((uint32_t)(value)) >> 8) & 0xff; \
97         datagram[i++] = ((uint32_t)(value)) & 0xff;
98
99 #define STORE_INT64(value) \
100         datagram[i++] = (((uint64_t)(value)) >> 56) & 0xff; \
101         datagram[i++] = (((uint64_t)(value)) >> 48) & 0xff; \
102         datagram[i++] = (((uint64_t)(value)) >> 40) & 0xff; \
103         datagram[i++] = (((uint64_t)(value)) >> 32) & 0xff; \
104         datagram[i++] = (((uint64_t)(value)) >> 24) & 0xff; \
105         datagram[i++] = (((uint64_t)(value)) >> 16) & 0xff; \
106         datagram[i++] = (((uint64_t)(value)) >> 8) & 0xff; \
107         datagram[i++] = ((uint64_t)(value)) & 0xff;
108
109 #define READ_INT32(data) \
110         ((((uint32_t)(data)[0]) << 24) |  \
111         (((uint32_t)(data)[1]) << 16) |  \
112         (((uint32_t)(data)[2]) << 8) |  \
113         ((uint32_t)(data)[3]))
114
115 #define READ_INT64(data) \
116         ((((uint64_t)(data)[0]) << 56) |  \
117         (((uint64_t)(data)[1]) << 48) |  \
118         (((uint64_t)(data)[2]) << 40) |  \
119         (((uint64_t)(data)[3]) << 32) |  \
120         (((uint64_t)(data)[4]) << 24) |  \
121         (((uint64_t)(data)[5]) << 16) |  \
122         (((uint64_t)(data)[6]) << 8) |  \
123         ((uint64_t)(data)[7]))
124
125
126 // Request codes to be used in both client and server.
127 enum
128 {
129         RENDERFARM_NONE,
130         RENDERFARM_PREFERENCES,  // 0 Get preferences on startup
131         RENDERFARM_ASSET,        // Get output format on startup
132         RENDERFARM_EDL,          // Get EDL on startup
133         RENDERFARM_PACKAGE,      // Get one package after another to render
134         RENDERFARM_PROGRESS,     // Update completion total
135         RENDERFARM_SET_RESULT,   // Update error status
136         RENDERFARM_GET_RESULT,   // Retrieve error status
137         RENDERFARM_DONE,         // Quit
138         RENDERFARM_SET_VMAP,     // 8 Update video map in background rendering
139         RENDERFARM_COMMAND,      // Get the client to run
140         RENDERFARM_TUNER,        // Run a tuner server
141         RENDERFARM_PACKAGES,     // Run packages
142         RENDERFARM_KEEPALIVE,    // Keep alive
143
144 // VFS commands
145         RENDERFARM_FOPEN,
146         RENDERFARM_FCLOSE,
147         RENDERFARM_REMOVE,
148         RENDERFARM_RENAME,
149         RENDERFARM_FGETC,
150         RENDERFARM_FPUTC,
151         RENDERFARM_FREAD,
152         RENDERFARM_FWRITE,
153         RENDERFARM_FSEEK,
154         RENDERFARM_FTELL,
155         RENDERFARM_STAT,
156         RENDERFARM_STAT64,
157         RENDERFARM_FGETS,
158         RENDERFARM_FILENO
159 };
160
161
162 class RenderFarmServer
163 {
164 public:
165         RenderFarmServer(
166 // Can be 0
167                 MWindow *mwindow,
168                 PackageDispatcher *packages,
169                 Preferences *preferences,
170                 int use_local_rate,
171                 int *result_return,
172                 int64_t *total_return,
173                 Mutex *total_return_lock,
174                 Asset *default_asset,
175                 EDL *edl,
176                 BRender *brender);
177         virtual ~RenderFarmServer();
178
179
180 // Open connections to clients.
181         int start_clients();
182 // The render farm must wait for all the clients to finish.
183         int wait_clients();
184
185 // Likewise the render farm must check the internal render loop before
186 // dispatching the next job and whenever a client queries for errors.
187
188
189         ArrayList<RenderFarmServerThread*> clients;
190 // Can be 0
191         MWindow *mwindow;
192         PackageDispatcher *packages;
193         Preferences *preferences;
194 // Use master node's framerate
195         int use_local_rate;
196 // These values are shared between the local renderer and the
197 // renderfarm server threads.
198 // The error code.
199 // Any nonzero value is an error and stops rendering.
200         int *result_return;
201 // The total number of frames completed
202         int64_t *total_return;
203         Mutex *total_return_lock;
204         Asset *default_asset;
205         EDL *edl;
206         Mutex *client_lock;
207         BRender *brender;
208 };
209
210
211 class RenderFarmServerThread : public Thread
212 {
213 public:
214         RenderFarmServerThread(RenderFarmServer *server,
215                 int number);
216         ~RenderFarmServerThread();
217
218
219 // Used by both client and server
220         int write_int64(int64_t value);
221         int64_t read_int64(int *error);
222 // Inserts header and writes string to socket
223         void write_string(char *string);
224         static int open_client(const char *hostname, int port);
225
226
227
228 // Used by server only
229         int read_socket(char *data, int len);
230         int write_socket(char *data, int len);
231         int start_loop();
232         void send_preferences();
233         void send_asset();
234         void send_edl();
235         void send_package(unsigned char *buffer);
236         void set_progress(unsigned char *buffer);
237         int set_video_map(unsigned char *buffer);
238         void set_result(unsigned char *buffer);
239         void get_result();
240         void reallocate_buffer(int size);
241
242
243         void run();
244
245         RenderFarmServer *server;
246         RenderFarmWatchdog *watchdog;
247         int socket_fd;
248         int number;
249 // Rate of last job or 0
250         double frames_per_second;
251 // Pointer to default asset
252         Asset *default_asset;
253 // These objects can be left dangling of the watchdog kills the thread.
254 // They are deleted in the destructor.
255         unsigned char *buffer;
256         int64_t buffer_allocated;
257         char *datagram;
258 };
259
260 class RenderFarmWatchdog : public Thread
261 {
262 public:
263 // use_pid - causes it to kill the pid instead of cancel the thread
264 // Used for client.
265         RenderFarmWatchdog(RenderFarmServerThread *server,
266                 RenderFarmClientThread *client);
267         ~RenderFarmWatchdog();
268
269 // Called at the beginning of a socket read
270         void begin_request();
271 // Called when a socket read succeeds
272         void end_request();
273         void run();
274
275         RenderFarmServerThread *server;
276         RenderFarmClientThread *client;
277         Condition *next_request;
278         Condition *request_complete;
279         int done;
280         int pid;
281 };
282
283
284
285
286
287 #endif