r885: Don't delete a borrowed frame.
[cinelerra_cv/ct.git] / cinelerra / fileac3.C
blob495c98da2c6cef7e527f885eb9a8a603c3f71bb6
1 #include "asset.h"
2 #include "clip.h"
3 #include "fileac3.h"
4 #include "language.h"
5 #include "mwindow.inc"
10 #include <string.h>
12 FileAC3::FileAC3(Asset *asset, File *file)
13  : FileBase(asset, file)
15         reset_parameters();
18 FileAC3::~FileAC3()
20         close_file();
23 int FileAC3::reset_parameters_derived()
25         codec = 0;
26         codec_context = 0;
27         fd = 0;
28         temp_raw = 0;
29         temp_raw_size = 0;
30         temp_raw_allocated = 0;
31         temp_compressed = 0;
32         compressed_allocated = 0;
35 void FileAC3::get_parameters(BC_WindowBase *parent_window, 
36                 Asset *asset, 
37                 BC_WindowBase* &format_window,
38                 int audio_options,
39                 int video_options)
41         if(audio_options)
42         {
44                 AC3ConfigAudio *window = new AC3ConfigAudio(parent_window, asset);
45                 format_window = window;
46                 window->create_objects();
47                 window->run_window();
48                 delete window;
49         }
52 int FileAC3::check_sig()
54 // Libmpeg3 does this in FileMPEG.
55         return 0;
58 int FileAC3::open_file(int rd, int wr)
60         this->wr = wr;
61         this->rd = rd;
64         if(wr)
65         {
66                 avcodec_init();
67                 avcodec_register_all();
68                 codec = avcodec_find_encoder(CODEC_ID_AC3);
69                 if(!codec)
70                 {
71                         fprintf(stderr, 
72                                 "FileAC3::open_file codec not found.\n");
73                         return 1;
74                 }
75                 codec_context = avcodec_alloc_context();
76                 codec_context->bit_rate = asset->ac3_bitrate * 1000;
77                 codec_context->sample_rate = asset->sample_rate;
78                 codec_context->channels = asset->channels;
79                 if(avcodec_open(codec_context, codec))
80                 {
81                         fprintf(stderr, 
82                                 "FileAC3::open_file failed to open codec.\n");
83                         return 1;
84                 }
86                 if(!(fd = fopen(asset->path, "w")))
87                 {
88                         perror("FileAC3::open_file");
89                         return 1;
90                 }
91         }
92         else
93         {
94                 if(!(fd = fopen(asset->path, "r")))
95                 {
96                         perror("FileAC3::open_file");
97                         return 1;
98                 }
99         }
104         return 0;
107 int FileAC3::close_file()
109         if(codec_context)
110         {
111                 avcodec_close(codec_context);
112                 free(codec_context);
113                 codec_context = 0;
114                 codec = 0;
115         }
116         if(fd)
117         {
118                 fclose(fd);
119                 fd = 0;
120         }
121         if(temp_raw)
122         {
123                 delete [] temp_raw;
124                 temp_raw = 0;
125         }
126         if(temp_compressed)
127         {
128                 delete [] temp_compressed;
129                 temp_compressed = 0;
130         }
131         reset_parameters();
132         FileBase::close_file();
135 // Channel conversion matrices because ffmpeg encodes a
136 // different channel order than liba52 decodes.
137 // Each row is an output channel.
138 // Each column is an input channel.
139 // static int channels5[] = 
140 // {
141 //      { }
142 // };
143 // 
144 // static int channels6[] = 
145 // {
146 //      { }
147 // };
150 int FileAC3::write_samples(double **buffer, int64_t len)
152 // Convert buffer to encoder format
153         if(temp_raw_size + len > temp_raw_allocated)
154         {
155                 int new_allocated = temp_raw_size + len;
156                 int16_t *new_raw = new int16_t[new_allocated * asset->channels];
157                 if(temp_raw)
158                 {
159                         memcpy(new_raw, 
160                                 temp_raw, 
161                                 sizeof(int16_t) * temp_raw_size * asset->channels);
162                         delete [] temp_raw;
163                 }
164                 temp_raw = new_raw;
165                 temp_raw_allocated = new_allocated;
166         }
168 // Allocate compressed data buffer
169         if(temp_raw_allocated * asset->channels * 2 > compressed_allocated)
170         {
171                 compressed_allocated = temp_raw_allocated * asset->channels * 2;
172                 delete [] temp_compressed;
173                 temp_compressed = new unsigned char[compressed_allocated];
174         }
176 // Append buffer to temp raw
177         int16_t *out_ptr = temp_raw + temp_raw_size * asset->channels;
178         for(int i = 0; i < len; i++)
179         {
180                 for(int j = 0; j < asset->channels; j++)
181                 {
182                         int sample = (int)(buffer[j][i] * 32767);
183                         CLAMP(sample, -32768, 32767);
184                         *out_ptr++ = sample;
185                 }
186         }
187         temp_raw_size += len;
189         int frame_size = codec_context->frame_size;
190         int output_size = 0;
191         int current_sample = 0;
192         for(current_sample = 0; 
193                 current_sample + frame_size <= temp_raw_size; 
194                 current_sample += frame_size)
195         {
196                 int compressed_size = avcodec_encode_audio(
197                         codec_context, 
198                         temp_compressed + output_size, 
199                         compressed_allocated - output_size, 
200             temp_raw + current_sample * asset->channels);
201                 output_size += compressed_size;
202         }
204 // Shift buffer back
205         memcpy(temp_raw,
206                 temp_raw + current_sample * asset->channels,
207                 (temp_raw_size - current_sample) * sizeof(int16_t) * asset->channels);
208         temp_raw_size -= current_sample;
210         int bytes_written = fwrite(temp_compressed, 1, output_size, fd);
211         if(bytes_written < output_size)
212         {
213                 perror("FileAC3::write_samples");
214                 return 1;
215         }
216         return 0;
225 AC3ConfigAudio::AC3ConfigAudio(BC_WindowBase *parent_window,
226         Asset *asset)
227  : BC_Window(PROGRAM_NAME ": Audio Compression",
228         parent_window->get_abs_cursor_x(1),
229         parent_window->get_abs_cursor_y(1),
230         500,
231         BC_OKButton::calculate_h() + 100,
232         500,
233         BC_OKButton::calculate_h() + 100,
234         0,
235         0,
236         1)
238         this->parent_window = parent_window;
239         this->asset = asset;
242 void AC3ConfigAudio::create_objects()
244         int x = 10, y = 10;
245         int x1 = 150;
246         add_tool(new BC_Title(x, y, "Bitrate (kbps):"));
247         AC3ConfigAudioBitrate *bitrate;
248         add_tool(bitrate = 
249                 new AC3ConfigAudioBitrate(this,
250                         x1, 
251                         y));
252         bitrate->create_objects();
254         add_subwindow(new BC_OKButton(this));
255         show_window();
256         flush();
259 int AC3ConfigAudio::close_event()
261         set_done(0);
262         return 1;
270 AC3ConfigAudioBitrate::AC3ConfigAudioBitrate(AC3ConfigAudio *gui, 
271         int x, 
272         int y)
273  : BC_PopupMenu(x,
274         y,
275         150,
276         AC3ConfigAudioBitrate::bitrate_to_string(gui->string, gui->asset->ac3_bitrate))
278         this->gui = gui;
281 char* AC3ConfigAudioBitrate::bitrate_to_string(char *string, int bitrate)
283         sprintf(string, "%d", bitrate);
284         return string;
287 void AC3ConfigAudioBitrate::create_objects()
289         add_item(new BC_MenuItem("32"));
290         add_item(new BC_MenuItem("40"));
291         add_item(new BC_MenuItem("48"));
292         add_item(new BC_MenuItem("56"));
293         add_item(new BC_MenuItem("64"));
294         add_item(new BC_MenuItem("80"));
295         add_item(new BC_MenuItem("96"));
296         add_item(new BC_MenuItem("112"));
297         add_item(new BC_MenuItem("128"));
298         add_item(new BC_MenuItem("160"));
299         add_item(new BC_MenuItem("192"));
300         add_item(new BC_MenuItem("224"));
301         add_item(new BC_MenuItem("256"));
302         add_item(new BC_MenuItem("320"));
303         add_item(new BC_MenuItem("384"));
304         add_item(new BC_MenuItem("448"));
305         add_item(new BC_MenuItem("512"));
306         add_item(new BC_MenuItem("576"));
307         add_item(new BC_MenuItem("640"));
310 int AC3ConfigAudioBitrate::handle_event()
312         gui->asset->ac3_bitrate = atol(get_text());
313         return 1;