upgrade libvpx+lv2, fix dbl tap play bug, add multi nest/unnest clips, add del top...
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / mainindexes.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 "bcsignals.h"
24 #include "bchash.h"
25 #include "edl.h"
26 #include "file.h"
27 #include "filesystem.h"
28 #include "indexfile.h"
29 #include "indexstate.h"
30 #include "condition.h"
31 #include "language.h"
32 #include "loadfile.h"
33 #include "guicast.h"
34 #include "mainerror.h"
35 #include "mainindexes.h"
36 #include "mainprogress.h"
37 #include "mutex.h"
38 #include "mwindow.h"
39 #include "mwindowgui.h"
40 #include "preferences.h"
41
42 #include <string.h>
43
44
45 MainIndexes::MainIndexes(MWindow *mwindow)
46  : Thread(1, 0, 0)
47 {
48         set_synchronous(1);
49         this->mwindow = mwindow;
50         input_lock = new Condition(0, "MainIndexes::input_lock");
51         next_lock = new Mutex("MainIndexes::next_lock");
52         index_lock = new Mutex("MainIndexes::index_lock");
53         interrupt_lock = new Condition(1, "MainIndexes::interrupt_lock");
54         interrupt_flag = 0;
55         indexfile = 0;
56         done = 0;
57 }
58
59 MainIndexes::~MainIndexes()
60 {
61         mwindow->mainprogress->cancelled = 1;
62         stop_loop();
63         delete next_lock;
64         delete input_lock;
65         delete interrupt_lock;
66         delete indexfile;
67         delete index_lock;
68 }
69
70 void MainIndexes::add_next_asset(File *file, Indexable *indexable)
71 {
72         next_lock->lock("MainIndexes::add_next_asset");
73
74 SET_TRACE
75 // Test current asset
76         IndexFile indexfile(mwindow, indexable);
77         IndexState *index_state = indexable->index_state;
78
79 SET_TRACE
80         int ret = indexfile.open_index();
81         if( !ret ) {
82                 index_state->index_status = INDEX_READY;
83                 indexfile.close_index();
84         }
85         else {
86 // Put source in stack
87                 index_state->index_status = INDEX_NOTTESTED;
88                 next_indexables.append(indexable);
89                 indexable->add_user();
90         }
91         next_lock->unlock();
92 }
93
94 void MainIndexes::start_loop()
95 {
96         interrupt_flag = 0;
97         Thread::start();
98 }
99
100 void MainIndexes::stop_loop()
101 {
102         interrupt_flag = 1;
103         done = 1;
104         input_lock->unlock();
105         interrupt_lock->unlock();
106         Thread::join();
107 }
108
109
110 void MainIndexes::start_build()
111 {
112         if( !current_indexables.size() ) return;
113 //printf("MainIndexes::start_build 1\n");
114         interrupt_flag = 0;
115 // Locked up when indexes were already being built and an indexable was
116 // pasted.
117 //      interrupt_lock.lock();
118         input_lock->unlock();
119 }
120
121 void MainIndexes::interrupt_build()
122 {
123 //printf("MainIndexes::interrupt_build 1\n");
124         interrupt_flag = 1;
125         index_lock->lock("MainIndexes::interrupt_build");
126         if(indexfile) indexfile->interrupt_index();
127         index_lock->unlock();
128 //printf("MainIndexes::interrupt_build 2\n");
129         interrupt_lock->lock("MainIndexes::interrupt_build");
130 //printf("MainIndexes::interrupt_build 3\n");
131         interrupt_lock->unlock();
132 //printf("MainIndexes::interrupt_build 4\n");
133 }
134
135 void MainIndexes::load_next_sources()
136 {
137 // Transfer from new list
138         next_lock->lock("MainIndexes::load_next_sources");
139         for(int i = 0; i < next_indexables.size(); i++)
140                 current_indexables.append(next_indexables.get(i));
141
142 // Clear pointers from new list only
143         next_indexables.remove_all();
144         next_lock->unlock();
145 }
146
147
148 void MainIndexes::run()
149 {
150         while(!done) {
151 // Wait for new indexables to be released
152                 input_lock->lock("MainIndexes::run 1");
153                 if(done) return;
154
155                 interrupt_lock->lock("MainIndexes::run 2");
156                 load_next_sources();
157                 interrupt_flag = 0;
158
159 // test index of each indexable
160                 MainProgressBar *progress = 0;
161
162                 next_lock->lock("MainIndexes::run");
163                 for( int i=0; i<current_indexables.size() && !interrupt_flag; ++i ) {
164                         Indexable *indexable = current_indexables[i];
165                         IndexState *index_state = indexable->index_state;
166 // if status is known, no probe
167                         if( index_state->index_status != INDEX_NOTTESTED ) continue;
168                         next_lock->unlock();
169
170                         IndexFile indexfile(mwindow, indexable);
171                         int ret = indexfile.open_index();
172                         if( !ret ) {
173                                 indexfile.close_index();
174 // use existing index
175                                 index_state->index_status = INDEX_READY;
176                                 if(mwindow->gui) mwindow->gui->lock_window("MainIndexes::run 2");
177                                 mwindow->edl->set_index_file(indexable);
178                                 if(mwindow->gui) mwindow->gui->unlock_window();
179                                 continue;
180                         }
181 // Doesn't exist
182                         if( !progress ) {
183                                 if(mwindow->gui) mwindow->gui->lock_window("MainIndexes::run 1");
184                                 progress = mwindow->mainprogress->start_progress(_("Building Indexes..."), 1);
185                                 if(mwindow->gui) mwindow->gui->unlock_window();
186                         }
187 // only if audio tracks
188                         indexfile.create_index(progress);
189                         if( progress->is_cancelled() )
190                                 interrupt_flag = 1;
191                         next_lock->lock("MainIndexes::run");
192                 }
193
194                 for( int i=0; i<current_indexables.size(); ++i )
195                         current_indexables[i]->remove_user();
196                 current_indexables.remove_all();
197                 next_lock->unlock();
198
199                 if(progress) {  // progress box is only created when an index is built
200                         if(mwindow->gui) mwindow->gui->lock_window("MainIndexes::run 3");
201                         progress->stop_progress();
202                         delete progress;
203                         if(mwindow->gui) mwindow->gui->unlock_window();
204                         progress = 0;
205                 }
206
207                 interrupt_lock->unlock();
208         }
209 }
210