prevent popup deactivation while button_down
[goodguy/history.git] / cinelerra-5.0 / cinelerra / vedit.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2009 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 "cache.h"
25 #include "edl.h"
26 #include "edlsession.h"
27 #include "file.h"
28 #include "format.inc"
29 #include "mwindow.h"
30 #include "patch.h"
31 #include "playabletracks.h"
32 #include "preferences.h"
33 #include "mainsession.h"
34 #include "trackcanvas.h"
35 #include "tracks.h"
36 #include "transportque.h"
37 #include "units.h"
38 #include "vedit.h"
39 #include "vedits.h"
40 #include "vframe.h"
41 #include "vtrack.h"
42
43 VEdit::VEdit(EDL *edl, Edits *edits)
44  : Edit(edl, edits)
45 {
46 }
47
48
49 VEdit::~VEdit() { }
50
51 int VEdit::load_properties_derived(FileXML *xml)
52 {
53         channel = xml->tag.get_property("CHANNEL", (int64_t)0);
54         return 0;
55 }
56
57
58
59
60
61 Asset* VEdit::get_nested_asset(int64_t *source_position,
62         int64_t position,
63         int direction)
64 {
65         const int debug = 0;
66         Asset *result = 0;
67 // Make position relative to edit
68         *source_position = position - startproject + startsource;
69
70 if(debug) printf("VEdit::get_nested_asset %d " _LD " " _LD " " _LD " " _LD "\n", 
71 __LINE__, *source_position, position, startproject, startsource);
72
73 // Descend into nested EDLs
74         if(nested_edl)
75         {
76 // Convert position to nested EDL rate
77 if(debug) printf("VEdit::get_nested_asset %d\n", 
78 __LINE__);
79                 int64_t pos = *source_position;
80                 if(direction == PLAY_REVERSE && pos > 0) --pos;
81                 *source_position = Units::to_int64((double)pos *
82                         nested_edl->session->frame_rate /
83                         edl->session->frame_rate);
84                 PlayableTracks *playable_tracks = new PlayableTracks(
85                         nested_edl, 
86                         *source_position, 
87                         direction,
88                         TRACK_VIDEO,
89                         1);
90                 if(playable_tracks->size())
91                 {
92                         VTrack *nested_track = (VTrack*)playable_tracks->get(0);
93                         VEdit* nested_edit = (VEdit*)nested_track->edits->editof(
94                                 *source_position, 
95                                 direction,
96                                 1);
97                         if(nested_edit)
98                         {
99                                 result = nested_edit->get_nested_asset(
100                                         source_position,
101                                         *source_position,
102                                         direction);
103                         }
104                 }
105
106                 delete playable_tracks;
107 if(debug) printf("VEdit::get_nested_asset %d\n", 
108 __LINE__);
109                 return result;
110         }
111         else
112         {
113 // Convert position to asset rate
114 if(debug) printf("VEdit::get_nested_asset %d " _LD " %f %f\n", 
115 __LINE__, 
116 *source_position, 
117 asset->frame_rate,
118 edl->session->frame_rate);
119                 int64_t pos = *source_position;
120                 if(direction == PLAY_REVERSE && pos > 0) --pos;
121                 *source_position = Units::to_int64((double)pos * 
122                         asset->frame_rate / 
123                         edl->session->frame_rate);
124
125                 return asset;
126         }
127 }
128
129
130 int VEdit::read_frame(VFrame *video_out, 
131         int64_t input_position, 
132         int direction,
133         CICache *cache,
134         int use_nudge,
135         int use_cache,
136         int use_asynchronous)
137 {
138         int64_t source_position = 0;
139         const int debug = 0;
140
141         if(use_nudge) input_position += track->nudge;
142 if(debug) printf("VEdit::read_frame %d source_position=" _LD " input_position=" _LD "\n", 
143   __LINE__, source_position, input_position);
144
145         Asset *asset = get_nested_asset(&source_position,
146                 input_position,
147                 direction);
148
149 if(debug) printf("VEdit::read_frame %d source_position=" _LD " input_position=" _LD "\n", 
150 __LINE__, source_position, input_position);
151
152         File *file = cache->check_out(asset,
153                 edl);
154         int result = 0;
155
156 if(debug) printf("VEdit::read_frame %d path=%s source_position=" _LD "\n", 
157 __LINE__, asset->path, source_position);
158
159         if(file)
160         {
161
162 if(debug) printf("VEdit::read_frame %d\n", __LINE__);
163                 source_position = (direction == PLAY_FORWARD) ? 
164                         source_position : 
165                         (source_position - 1);
166 if(debug) printf("VEdit::read_frame %d " _LD " " _LD "\n", 
167   __LINE__, input_position, source_position);
168
169                 if(use_asynchronous)
170                         file->start_video_decode_thread();
171                 else
172                         file->stop_video_thread();
173 if(debug) printf("VEdit::read_frame %d\n", __LINE__);
174
175                 file->set_layer(channel);
176 //printf("VEdit::read_frame %d %lld\n", __LINE__, source_position);
177                 file->set_video_position(source_position, 0);
178
179                 if(use_cache) file->set_cache_frames(use_cache);
180                 result = file->read_frame(video_out);
181
182 if(debug) printf("VEdit::read_frame %d\n", __LINE__);
183                 if(use_cache) file->set_cache_frames(0);
184
185 if(debug) printf("VEdit::read_frame %d\n", __LINE__);
186                 cache->check_in(asset);
187 if(debug) printf("VEdit::read_frame %d\n", __LINE__);
188         }
189         else
190                 result = 1;
191
192         return result;
193 }
194
195 int VEdit::copy_properties_derived(FileXML *xml, int64_t length_in_selection)
196 {
197         return 0;
198 }
199
200 int VEdit::dump_derived()
201 {
202         printf("        VEdit::dump_derived\n");
203         printf("                startproject " _LD "\n", startproject);
204         printf("                length " _LD "\n", length);
205         return 0;
206 }
207
208 int64_t VEdit::get_source_end(int64_t default_)
209 {
210         if(!nested_edl && !asset) return default_;   // Infinity
211
212         if(nested_edl)
213         {
214                 return (int64_t)(nested_edl->tracks->total_playable_length() *
215                         edl->session->frame_rate + 0.5);
216         }
217
218         return (int64_t)((double)asset->video_length / 
219                 asset->frame_rate * 
220                 edl->session->frame_rate + 0.5);
221 }