fixes and accomodations for other operating systems by Andrew
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / recordthread.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 "asset.h"
23 #include "batch.h"
24 #include "channel.h"
25 #include "condition.h"
26 #include "edl.h"
27 #include "edlsession.h"
28 #include "mwindow.h"
29 #include "question.h"
30 #include "record.h"
31 #include "recordgui.h"
32 #include "recordthread.h"
33
34
35 RecordThread::RecordThread(MWindow *mwindow, Record *record)
36  : Thread(1, 0, 0)
37 {
38         this->mwindow = mwindow;
39         this->record = record;
40         batch_timed_lock = new Condition(0,"RecordThread::batch_timed_lock");
41
42         done = 0;
43         cron_active = 0;
44 }
45
46 RecordThread::~RecordThread()
47 {
48         if( Thread::running() ) {
49                 done = 1;
50                 batch_timed_lock->unlock();
51                 Thread::cancel();
52         }
53         Thread::join();
54         delete batch_timed_lock;
55 }
56
57 int RecordThread::cron(Batch *batch)
58 {
59         while( !done ) {
60                 batch->update_times();
61                 time_t t;  time(&t);
62                 int delay = (int)(batch->time_start - t);
63                 int duration = (int)(batch->time_end - t);
64                 if( delay <= 1 ) {
65                         if( duration < 1 ) return -1;
66                         batch->record_duration = duration+1;
67                         return 1;
68                 }
69                 if( delay < 0 || delay > 60 ) delay = 60;
70                 else if( (delay -= 3) < 0 ) delay = 1;
71                 delay *= 1000000;
72                 Thread::enable_cancel();
73                 batch_timed_lock->timed_lock(delay, "RecordThread::cron");
74                 Thread::disable_cancel();
75         }
76         return 0;
77 }
78
79 void RecordThread::run()
80 {
81         int batch_no = record->get_next_batch(0);
82         done = batch_no >= 0 ? 0 : 1;
83         if( done ) {
84                 QuestionWindow *qwindow = new QuestionWindow(mwindow);
85                 qwindow->create_objects(_("Re-enable batches and restart?"),1);
86                 int result = qwindow->run_window();
87                 delete qwindow;
88                 if( result == 2 ) {
89                         int n = record->record_batches.total();
90                         for( int i=0; i<n; ++i )
91                                 record->record_batches[i]->enabled = 1;
92                         record->activate_batch(batch_no = 0);
93                         record->record_gui->update_batches();
94                         done = 0;
95                 }
96         }
97
98         while( !done ) {
99                 batch_timed_lock->reset();
100                 Batch *batch = record->get_current_batch();
101                 Channel *current_channel = record->get_current_channel();
102                 Channel *batch_channel = batch->get_current_channel();
103 //printf("RecordThread::current channel %s\n",current_channel ? current_channel->title : "None");
104 //printf("RecordThread::batch channel %s\n",batch_channel ? batch_channel->title : "None");
105                 if( *current_channel != *batch_channel ) {
106                         if( batch_channel ) {
107                                 current_channel = batch_channel;
108 //printf("RecordThread::set channel %s\n",batch_channel->title);
109                                 record->set_channel(batch_channel);
110                                 record->has_signal();
111                         }
112                 }
113                 int result = cron(batch);
114                 if( result > 0 ) {
115                         cron_active = 1;
116                         batch->recorded = 0;
117                         record->pause_input_threads();
118                         record->record_gui->reset_audio();
119                         record->record_gui->reset_video();
120                         record->update_position();
121                         record->start_writing_file();
122                         record->resume_input_threads();
123 printf("RecordThread::Started\n");
124                         batch_timed_lock->lock("RecordThread::run");
125 printf("RecordThread::Done\n");
126                         record->stop_writing();
127                         cron_active = 0;
128                 }
129                 if( result ) {
130                         batch_no = record->get_next_batch();
131                         if( batch_no < 0 ) { done = -1; batch_no = 0; }
132                         record->activate_batch(batch_no);
133                 }
134         }
135
136         record->record_gui->update_cron_status(_("Done"));
137         record->record_gui->enable_batch_buttons();
138         if( record->power_off && done < 0 )
139         {
140                 mwindow->save_defaults();
141                 sleep(2);  sync();
142                 pid_t pid = vfork();
143                 if( pid == 0 ) {
144                         const char poweroff[] = "poweroff";
145                         char *const argv[] = { (char*)poweroff, 0 };
146                         execvp(poweroff ,&argv[0]);
147                         perror(_("execvp poweroff failed"));
148                         exit(1);
149                 }
150                 if( pid > 0 )
151                         fprintf(stderr,_("poweroff imminent!!!\n"));
152                 else
153                         perror(_("cant vfork poweroff process"));
154         }
155         cron_active = -1;
156 }
157
158