4 * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
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.
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.
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
24 #include "byteorder.h"
25 #include "bccmodels.h"
28 #include "overlayframe.h"
34 FileBase::FileBase(Asset *asset, File *file)
38 internal_byte_order = get_byte_order();
45 if(row_pointers_in) delete [] row_pointers_in;
46 if(row_pointers_out) delete [] row_pointers_out;
47 if(float_buffer) delete [] float_buffer;
50 int FileBase::close_file()
52 if(row_pointers_in) delete [] row_pointers_in;
53 if(row_pointers_out) delete [] row_pointers_out;
54 if(float_buffer) delete [] float_buffer;
59 for(int i = 0; i < history_channels; i++)
60 delete [] pcm_history[i];
61 delete [] pcm_history;
70 void FileBase::update_pcm_history(int64_t len)
77 history_channels = asset->channels;
78 pcm_history = new double*[history_channels];
79 for(int i = 0; i < history_channels; i++)
80 pcm_history[i] = new double[HISTORY_MAX];
83 history_allocated = HISTORY_MAX;
87 //printf("FileBase::update_pcm_history current_sample=%jd history_start=%jd history_size=%jd\n",
88 //file->current_sample,
91 // Restart history. Don't bother shifting history back.
92 if(file->current_sample < history_start ||
93 file->current_sample > history_start + history_size)
96 history_start = file->current_sample;
97 decode_start = file->current_sample;
101 // Shift history forward to make room for new samples
102 if(file->current_sample > history_start + HISTORY_MAX)
104 int diff = file->current_sample - (history_start + HISTORY_MAX);
105 for(int i = 0; i < asset->channels; i++)
107 double *temp = pcm_history[i];
108 memcpy(temp, temp + diff, (history_size - diff) * sizeof(double));
111 history_start += diff;
112 history_size -= diff;
115 decode_start = history_start + history_size;
116 decode_len = file->current_sample + len - (history_start + history_size);
119 // Starting somewhere in the buffer
121 decode_start = history_start + history_size;
122 decode_len = file->current_sample + len - (history_start + history_size);
126 void FileBase::append_history(float **new_data, int len)
128 allocate_history(len);
130 for(int i = 0; i < history_channels; i++)
132 double *output = pcm_history[i] + history_size;
133 float *input = new_data[i];
134 for(int j = 0; j < len; j++)
135 *output++ = *input++;
142 void FileBase::append_history(short *new_data, int len)
144 allocate_history(len);
146 for(int i = 0; i < history_channels; i++)
148 double *output = pcm_history[i] + history_size;
149 short *input = new_data + i;
150 for(int j = 0; j < len; j++)
152 *output++ = (double)*input / 32768;
153 input += history_channels;
161 void FileBase::read_history(double *dst,
162 int64_t start_sample,
166 if(start_sample - history_start + len > history_size)
167 len = history_size - (start_sample - history_start);
168 //printf("FileBase::read_history start_sample=%jd history_start=%jd history_size=%jd len=%jd\n",
169 //start_sample, history_start, history_size, len);
170 double *input = pcm_history[channel] + start_sample - history_start;
171 for(int i = 0; i < len; i++)
177 void FileBase::allocate_history(int len)
179 if(history_size + len > history_allocated)
181 double **temp = new double*[history_channels];
183 for(int i = 0; i < history_channels; i++)
185 temp[i] = new double[history_size + len];
186 memcpy(temp[i], pcm_history[i], history_size * sizeof(double));
187 delete [] pcm_history[i];
190 delete [] pcm_history;
192 history_allocated = history_size + len;
196 int64_t FileBase::get_history_sample()
198 return history_start + history_size;
201 int FileBase::set_dither()
207 void FileBase::reset_parameters()
212 row_pointers_out = 0;
213 prev_buffer_position = -1;
214 prev_frame_position = -1;
219 ulawtofloat_table = 0;
220 floattoulaw_table = 0;
225 history_allocated = 0;
226 history_channels = 0;
229 delete_ulaw_tables();
230 reset_parameters_derived();
233 void FileBase::get_mode(char *mode, int rd, int wr)
235 if(rd && !wr) sprintf(mode, "rb");
236 else if(!rd && wr) sprintf(mode, "wb");
239 FILE *stream = fopen(asset->path, "rb");
244 sprintf(mode, exists ? "rb+" : "wb+");
249 // ======================================= audio codecs
251 int FileBase::get_video_buffer(unsigned char **buffer, int depth)
253 // get a raw video buffer for writing or compression by a library
256 // Video compression is entirely done in the library.
257 int64_t bytes = asset->width * asset->height * depth;
258 *buffer = new unsigned char[bytes];
263 int FileBase::get_row_pointers(unsigned char *buffer, unsigned char ***pointers, int depth)
265 // This might be fooled if a new VFrame is created at the same address with a different height.
266 if(*pointers && (*pointers)[0] != &buffer[0])
274 *pointers = new unsigned char*[asset->height];
275 for(int i = 0; i < asset->height; i++)
277 (*pointers)[i] = &buffer[i * asset->width * depth / 8];
283 int FileBase::match4(const char *in, const char *out)
285 return in[0] == out[0] && in[1] == out[1] &&
286 in[2] == out[2] && in[3] == out[3] ? 1 : 0;
289 int FileBase::search_render_strategies(ArrayList<int>* render_strategies, int render_strategy)
291 for(int i = 0; i < render_strategies->total; i++)
292 if(render_strategies->values[i] == render_strategy) return 1;
297 int64_t FileBase::base_memory_usage()
299 //printf("FileBase::base_memory_usage %d\n", __LINE__);
300 return !pcm_history ? 0 :
301 history_allocated * history_channels * sizeof(double);