no longer need ffmpeg patch0 which was for Termux
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / fileref.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2020 William Morrow
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 "arender.h"
24 #include "cache.h"
25 #include "filebase.h"
26 #include "file.h"
27 #include "fileref.h"
28 #include "language.h"
29 #include "mainerror.h"
30 #include "renderengine.h"
31 #include "samples.h"
32 #include "edlsession.h"
33 #include "tracks.h"
34 #include "transportque.h"
35 #include "vframe.h"
36 #include "vrender.h"
37 #include "filexml.h"
38
39
40 FileREF::FileREF(Asset *asset, File *file)
41  : FileBase(asset, file)
42 {
43         is_open = 0;
44         audio_position = 0;
45         video_position = 0;
46         samples_position = -1;
47         samples_length = -1;
48         channel = 0;
49         layer = 0;
50         ref = 0;
51         command = 0;
52         render_engine = 0;
53         acache = 0;
54         vcache = 0;
55         temp = 0;
56         for( int i=0; i<MAX_CHANNELS; ++i ) samples[i] = 0;
57 }
58
59 FileREF::~FileREF()
60 {
61         close_file();
62 }
63
64 int FileREF::open_file(int rd, int wr)
65 {
66         if( is_open ) return 1;
67         if(wr) {
68                 eprintf(_("Reference files cant be created by rendering\n"));
69                 return 1;
70         }
71         if(rd) {
72                 FileXML file_xml;
73                 if( file_xml.read_from_file(asset->path) ) return 1;
74 //              file_xml.check_version();
75                 if( ref ) ref->remove_user();
76                 ref = new EDL;
77                 ref->create_objects();
78                 if( ref->load_xml(&file_xml, LOAD_ALL) ) {
79                         ref->remove_user();
80                         ref = 0;
81                         eprintf(_("Error loading Reference file:\n%s"), asset->path);
82                         return 1;
83                 }
84                 if( !asset->layers ) asset->layers = ref->get_video_layers();
85                 asset->video_data = asset->layers > 0 ? 1 : 0;
86                 asset->video_length = asset->video_data ? ref->get_video_frames() : 0;
87                 asset->actual_width = asset->video_data ? ref->get_w() : 0;
88                 asset->actual_height = asset->video_data ? ref->get_h() : 0;
89                 if( !asset->width ) asset->width = asset->actual_width;
90                 if( !asset->height ) asset->height = asset->actual_height;
91                 if( !asset->frame_rate ) asset->frame_rate = ref->get_frame_rate();
92                 strcpy(asset->vcodec, "REF");
93                 asset->channels = ref->get_audio_channels();
94                 asset->audio_data = asset->channels > 0 ? 1 : 0;
95                 asset->sample_rate = ref->get_sample_rate();
96                 asset->audio_length = asset->audio_data ? ref->get_audio_samples() : 0;
97                 strcpy(asset->acodec, "REF");
98                 command = new TransportCommand();
99                 command->reset();
100                 command->get_edl()->copy_all(ref);
101                 command->command = NORMAL_FWD;
102                 command->change_type = CHANGE_ALL;
103                 command->realtime = 0;
104                 samples_position = -1;
105                 samples_length = -1;
106                 audio_position = 0;
107                 render_engine = new RenderEngine(0, file->preferences, 0, 0);
108                 render_engine->set_acache(acache = new CICache(file->preferences));
109                 render_engine->set_vcache(vcache = new CICache(file->preferences));
110                 render_engine->arm_command(command);
111                 is_open = 1;
112         }
113         return 0;
114 }
115
116 int FileREF::close_file()
117 {
118         if( !is_open ) return 1;
119         if( ref ) ref->remove_user();
120         ref = 0;
121         delete render_engine;  render_engine = 0;
122         delete command;  command = 0;
123         if( acache ) { acache->remove_user();  acache = 0; }
124         if( vcache ) { vcache->remove_user();  vcache = 0; }
125         delete temp;     temp = 0;
126         for( int i=0; i<MAX_CHANNELS; ++i ) {
127                 delete samples[i];  samples[i] = 0;
128         }
129         audio_position = 0;
130         video_position = 0;
131         channel = 0;
132         samples_position = -1;
133         samples_length = -1;
134         layer = 0;
135         is_open = 0;
136         return 0;
137 }
138
139 int64_t FileREF::get_video_position()
140 {
141         return video_position;
142 }
143
144 int64_t FileREF::get_audio_position()
145 {
146         return audio_position;
147 }
148
149 int FileREF::set_video_position(int64_t pos)
150 {
151         this->video_position = pos;
152         return 0;
153 }
154 int FileREF::set_layer(int layer)
155 {
156         this->layer = layer;
157         return 0;
158 }
159
160 int FileREF::set_audio_position(int64_t pos)
161 {
162         this->audio_position = pos;
163         return 0;
164 }
165 int FileREF::set_channel(int channel)
166 {
167         this->channel = channel;
168         return 0;
169 }
170
171 int FileREF::read_samples(double *buffer, int64_t len)
172 {
173         int result = len > 0 ? 0 : 1;
174         if( !render_engine || !render_engine->arender ) result = 1;
175         if( !result ) {
176                 if( samples_length != len ) {
177                         samples_length = -1;
178                         for( int i=0; i<MAX_CHANNELS; ++i ) {
179                                 delete samples[i];  samples[i] = 0;
180                         }
181                 }
182                 if( samples_length < 0 ) {
183                         samples_length = len;
184                         int ch = 0, channels = asset->channels;
185                         while( ch < channels ) samples[ch++] = new Samples(samples_length);
186                         samples_position = -1;
187                 }
188                 if( samples_position != audio_position ) {
189                         result = render_engine->arender->process_buffer(samples, len, audio_position);
190                         samples_position = audio_position;
191                 }
192         }
193         Samples *cbfr = samples[channel];
194         double *data = cbfr ? cbfr->get_data() : 0;
195         if( !data ) result = 1;
196         int64_t sz = len*(sizeof(*buffer));
197         if( !result )
198                 memcpy(buffer, data, sz);
199         else
200                 memset(buffer, 0, sz);
201         return result;
202 }
203
204 int FileREF::read_frame(VFrame *frame)
205 {
206         int result = render_engine && render_engine->vrender ? 0 : 1;
207         EDLSession *render_session = render_engine->get_edl()->session;
208         int color_model = render_session->color_model;
209         int out_w = render_session->output_w, out_h = render_session->output_h;
210         VFrame *vframe = frame;
211         if( color_model != frame->get_color_model() ||
212             out_w != frame->get_w() || out_h != frame->get_h() ) {
213                 VFrame::get_temp(temp, out_w, out_h, color_model);
214                 vframe = temp;
215         }
216         if( !result )
217                 result = render_engine->vrender->process_buffer(vframe, video_position++, 0);
218         if( vframe != frame )
219                 frame->transfer_from(vframe);
220         return result;
221 }
222
223 int FileREF::colormodel_supported(int colormodel)
224 {
225         return colormodel;
226 }
227
228
229 int FileREF::get_best_colormodel(Asset *asset, int driver)
230 {
231         return BC_RGBA_FLOAT;
232 }
233