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