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();
47 int FileBase::close_file()
49 delete [] row_pointers_in; row_pointers_in = 0;
50 delete [] row_pointers_out; row_pointers_out = 0;
51 delete [] float_buffer; float_buffer = 0;
54 for(int i = 0; i < history_channels; i++)
55 delete [] pcm_history[i];
56 delete [] pcm_history; pcm_history = 0;
64 void FileBase::update_pcm_history(int64_t len)
70 history_channels = asset->channels;
71 pcm_history = new double*[history_channels];
72 for(int i = 0; i < history_channels; i++)
73 pcm_history[i] = new double[HISTORY_MAX];
76 history_allocated = HISTORY_MAX;
80 //printf("FileBase::update_pcm_history current_sample=%jd history_start=%jd history_size=%jd\n",
81 //file->current_sample,
84 // Restart history. Don't bother shifting history back.
85 if(file->current_sample < history_start ||
86 file->current_sample > history_start + history_size)
89 history_start = file->current_sample;
90 decode_start = file->current_sample;
94 // Shift history forward to make room for new samples
95 if(file->current_sample > history_start + HISTORY_MAX)
97 int diff = file->current_sample - (history_start + HISTORY_MAX);
98 for(int i = 0; i < asset->channels; i++)
100 double *temp = pcm_history[i];
101 memcpy(temp, temp + diff, (history_size - diff) * sizeof(double));
104 history_start += diff;
105 history_size -= diff;
108 decode_start = history_start + history_size;
109 decode_len = file->current_sample + len - (history_start + history_size);
112 // Starting somewhere in the buffer
114 decode_start = history_start + history_size;
115 decode_len = file->current_sample + len - (history_start + history_size);
119 void FileBase::append_history(float **new_data, int len)
121 allocate_history(len);
123 for(int i = 0; i < history_channels; i++)
125 double *output = pcm_history[i] + history_size;
126 float *input = new_data[i];
127 for(int j = 0; j < len; j++)
128 *output++ = *input++;
135 void FileBase::append_history(short *new_data, int len)
137 allocate_history(len);
139 for(int i = 0; i < history_channels; i++)
141 double *output = pcm_history[i] + history_size;
142 short *input = new_data + i;
143 for(int j = 0; j < len; j++)
145 *output++ = (double)*input / 32768;
146 input += history_channels;
154 void FileBase::read_history(double *dst,
155 int64_t start_sample,
159 if(start_sample - history_start + len > history_size)
160 len = history_size - (start_sample - history_start);
161 //printf("FileBase::read_history start_sample=%jd history_start=%jd history_size=%jd len=%jd\n",
162 //start_sample, history_start, history_size, len);
163 double *input = pcm_history[channel] + start_sample - history_start;
164 for(int i = 0; i < len; i++)
170 void FileBase::allocate_history(int len)
172 if(history_size + len > history_allocated)
174 double **temp = new double*[history_channels];
176 for(int i = 0; i < history_channels; i++)
178 temp[i] = new double[history_size + len];
179 memcpy(temp[i], pcm_history[i], history_size * sizeof(double));
180 delete [] pcm_history[i];
183 delete [] pcm_history;
185 history_allocated = history_size + len;
189 int64_t FileBase::get_history_sample()
191 return history_start + history_size;
194 int FileBase::set_dither()
200 void FileBase::reset_parameters()
205 row_pointers_out = 0;
206 prev_buffer_position = -1;
207 prev_frame_position = -1;
212 ulawtofloat_table = 0;
213 floattoulaw_table = 0;
218 history_allocated = 0;
219 history_channels = 0;
222 delete_ulaw_tables();
223 reset_parameters_derived();
226 void FileBase::get_mode(char *mode, int rd, int wr)
228 if(rd && !wr) sprintf(mode, "rb");
229 else if(!rd && wr) sprintf(mode, "wb");
232 FILE *stream = fopen(asset->path, "rb");
237 sprintf(mode, exists ? "rb+" : "wb+");
241 int FileBase::get_best_colormodel(int driver, int vstream)
243 return File::get_best_colormodel(asset, driver);
247 // ======================================= audio codecs
249 int FileBase::get_video_buffer(unsigned char **buffer, int depth)
251 // get a raw video buffer for writing or compression by a library
254 // Video compression is entirely done in the library.
255 int64_t bytes = asset->width * asset->height * depth;
256 *buffer = new unsigned char[bytes];
261 int FileBase::get_row_pointers(unsigned char *buffer, unsigned char ***pointers, int depth)
263 // This might be fooled if a new VFrame is created at the same address with a different height.
264 if(*pointers && (*pointers)[0] != &buffer[0])
272 *pointers = new unsigned char*[asset->height];
273 for(int i = 0; i < asset->height; i++)
275 (*pointers)[i] = &buffer[i * asset->width * depth / 8];
281 int FileBase::match4(const char *in, const char *out)
283 return in[0] == out[0] && in[1] == out[1] &&
284 in[2] == out[2] && in[3] == out[3] ? 1 : 0;
287 int FileBase::search_render_strategies(ArrayList<int>* render_strategies, int render_strategy)
289 for(int i = 0; i < render_strategies->total; i++)
290 if(render_strategies->values[i] == render_strategy) return 1;
295 int64_t FileBase::base_memory_usage()
297 //printf("FileBase::base_memory_usage %d\n", __LINE__);
298 return !pcm_history ? 0 :
299 history_allocated * history_channels * sizeof(double);