allow ffmpeg video to resample curr_pos, add bluray format
[goodguy/history.git] / cinelerra-5.0 / cinelerra / threadfork.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 "threadfork.h"
23
24 #include <stdlib.h>
25 #include <string.h>
26 #include <sys/types.h>
27 #include <sys/wait.h>
28 #include <unistd.h>
29
30 #define MAX_ARGS 32
31
32
33
34
35 ThreadFork::ThreadFork()
36 {
37         pid = 0;
38         tid = 0;
39         pthread_mutexattr_t attr;
40         pthread_mutexattr_init(&attr);
41         pthread_mutex_init(&start_lock, &attr);
42
43
44
45         arguments = new char*[MAX_ARGS];
46         total_arguments = 0;
47         stdin_fd = 0;
48         pipe_stdin = 0;
49         command_line = "";
50 }
51
52 ThreadFork::~ThreadFork()
53 {
54 //      if(pipe_stdin)
55 //      {
56                 pclose(stdin_fd);
57 //              if(stdin_fd) fclose(stdin_fd);
58 //              close(filedes[0]);
59 //              close(filedes[1]);
60 //      }
61
62 //      pthread_join(tid, 0);
63
64         for(int i = 0; i < total_arguments; i++)
65                 delete [] arguments[i];
66
67         pthread_mutex_destroy(&start_lock);
68         delete [] arguments;
69 }
70
71 void* ThreadFork::entrypoint(void *ptr)
72 {
73         ThreadFork *threadfork = (ThreadFork*)ptr;
74         threadfork->run();
75         return 0;
76 }
77
78 void ThreadFork::start_command(const char *command_line, int pipe_stdin)
79 {
80         this->command_line = command_line;
81         this->pipe_stdin = pipe_stdin;
82
83         pthread_attr_t  attr;
84         pthread_attr_init(&attr);
85
86
87         stdin_fd = popen(command_line, "w");
88         
89 //      pthread_mutex_lock(&start_lock);
90
91
92 //      pthread_create(&tid, &attr, entrypoint, this);
93 //      pthread_mutex_lock(&start_lock);
94 //      pthread_mutex_unlock(&start_lock);
95 }
96
97
98 void ThreadFork::run()
99 {
100         char *path_ptr;
101         char *ptr;
102         char *argument_ptr;
103         char argument[BCTEXTLEN];
104         char command_line[BCTEXTLEN];
105         int new_pid;
106
107         strcpy(command_line, this->command_line);
108
109
110
111 // Set up arguments for exec
112         ptr = command_line;
113         path_ptr = path;
114         while(*ptr != ' ' && *ptr != 0)
115         {
116                 *path_ptr++ = *ptr++;
117         }
118         *path_ptr = 0;
119
120         arguments[total_arguments] = new char[strlen(path) + 1];
121         strcpy(arguments[total_arguments], path);
122
123         total_arguments++;
124         arguments[total_arguments] = 0;
125
126         while(*ptr != 0)
127         {
128                 ptr++;
129                 argument_ptr = argument;
130                 while(*ptr != ' ' && *ptr != 0)
131                 {
132                         *argument_ptr++ = *ptr++;
133                 }
134                 *argument_ptr = 0;
135
136                 arguments[total_arguments] = new char[strlen(argument) + 1];
137                 strcpy(arguments[total_arguments], argument);
138                 total_arguments++;
139                 arguments[total_arguments] = 0;
140         }
141
142
143
144
145
146
147
148
149
150
151         if(pipe_stdin)
152         {
153                 (void)pipe(filedes);
154                 stdin_fd = fdopen(filedes[1], "w");
155         }
156
157         pthread_mutex_unlock(&start_lock);
158
159
160
161         new_pid = vfork();
162
163 // Redirect stdin
164         if(new_pid == 0)
165         {
166                 if(pipe_stdin) dup2(filedes[0], fileno(stdin));
167
168
169
170                 execvp(path, arguments);
171
172
173
174                 perror("execvp");
175                 _exit(0);
176         }
177         else
178         {
179                 pid = new_pid;
180                 pthread_mutex_unlock(&start_lock);
181                 
182                 int return_value;
183                 if(waitpid(pid, &return_value, WUNTRACED) == -1)
184                 {
185                         perror("ThreadFork::run: waitpid");
186                 }
187         }
188
189
190 }
191
192
193 FILE* ThreadFork::get_stdin()
194 {
195         return stdin_fd;
196 }