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
30 // work around (centos) for __STDC_CONSTANT_MACROS
33 # define INT64_MAX 9223372036854775807LL
38 #include "libavcodec/avcodec.h"
47 #include "mwindow.inc"
48 #include "mainerror.h"
54 FileAC3::FileAC3(Asset *asset, File *file)
55 : FileBase(asset, file)
63 if( mpg_file ) delete mpg_file;
67 int FileAC3::reset_parameters_derived()
75 temp_raw_allocated = 0;
77 compressed_allocated = 0;
81 void FileAC3::get_parameters(BC_WindowBase *parent_window,
83 BC_WindowBase* &format_window,
90 AC3ConfigAudio *window = new AC3ConfigAudio(parent_window, asset);
91 format_window = window;
92 window->create_objects();
98 int FileAC3::check_sig()
100 // Libmpeg3 does this in FileMPEG.
104 int64_t FileAC3::get_channel_layout(int channels)
107 case 1: return AV_CH_LAYOUT_MONO;
108 case 2: return AV_CH_LAYOUT_STEREO;
109 case 3: return AV_CH_LAYOUT_SURROUND;
110 case 4: return AV_CH_LAYOUT_QUAD;
111 case 5: return AV_CH_LAYOUT_5POINT0;
112 case 6: return AV_CH_LAYOUT_5POINT1;
113 case 8: return AV_CH_LAYOUT_7POINT1;
118 int FileAC3::open_file(int rd, int wr)
125 mpg_file = new FileMPEG(file->asset, file);
126 result = mpg_file->open_file(1, 0);
132 avcodec_register_all();
133 codec = avcodec_find_encoder(CODEC_ID_AC3);
136 eprintf("FileAC3::open_file codec not found.\n");
139 if( !result && !(fd = fopen(asset->path, "w")))
141 perror("FileAC3::open_file");
145 int channels = asset->channels;
146 int sample_rate = asset->sample_rate;
147 int64_t layout = get_channel_layout(channels);
148 int bitrate = asset->ac3_bitrate * 1000;
149 codec_context = avcodec_alloc_context3(codec);
150 codec_context->bit_rate = bitrate;
151 codec_context->sample_rate = sample_rate;
152 codec_context->channels = channels;
153 codec_context->channel_layout = layout;
154 codec_context->sample_fmt = codec->sample_fmts[0];
155 resample_context = swr_alloc_set_opts(NULL,
156 layout, codec_context->sample_fmt, sample_rate,
157 layout, AV_SAMPLE_FMT_S16, sample_rate,
159 swr_init(resample_context);
160 if(avcodec_open2(codec_context, codec, 0))
162 eprintf("FileAC3::open_file failed to open codec.\n");
171 int FileAC3::close_file()
180 avcodec_close(codec_context);
185 if( resample_context )
186 swr_free(&resample_context);
199 delete [] temp_compressed;
203 FileBase::close_file();
207 int FileAC3::read_samples(double *buffer, int64_t len)
209 return !mpg_file ? 0 : mpg_file->read_samples(buffer, len);
212 int FileAC3::get_index(char *index_path)
214 return !mpg_file ? 1 : mpg_file->get_index(index_path);
217 // Channel conversion matrices because ffmpeg encodes a
218 // different channel order than liba52 decodes.
219 // Each row is an output channel.
220 // Each column is an input channel.
221 // static int channels5[] =
226 // static int channels6[] =
232 int FileAC3::write_samples(double **buffer, int64_t len)
234 // Convert buffer to encoder format
235 if(temp_raw_size + len > temp_raw_allocated)
237 int new_allocated = temp_raw_size + len;
238 int16_t *new_raw = new int16_t[new_allocated * asset->channels];
243 sizeof(int16_t) * temp_raw_size * asset->channels);
247 temp_raw_allocated = new_allocated;
250 // Allocate compressed data buffer
251 if(temp_raw_allocated * asset->channels * 2 > compressed_allocated)
253 compressed_allocated = temp_raw_allocated * asset->channels * 2;
254 delete [] temp_compressed;
255 temp_compressed = new unsigned char[compressed_allocated];
258 // Append buffer to temp raw
259 int16_t *out_ptr = temp_raw + temp_raw_size * asset->channels;
260 for(int i = 0; i < len; i++)
262 for(int j = 0; j < asset->channels; j++)
264 int sample = (int)(buffer[j][i] * 32767);
265 CLAMP(sample, -32768, 32767);
269 temp_raw_size += len;
271 AVCodecContext *&avctx = codec_context;
272 int frame_size = avctx->frame_size;
273 int output_size = 0, cur_sample = 0, ret = 0;
274 for(cur_sample = 0; !ret &&
275 cur_sample + frame_size <= temp_raw_size;
276 cur_sample += frame_size)
279 av_init_packet(&avpkt);
280 avpkt.data = temp_compressed + output_size;
281 avpkt.size = compressed_allocated - output_size;
282 AVFrame *frame = av_frame_alloc();
283 frame->nb_samples = frame_size;
284 frame->format = avctx->sample_fmt;
285 frame->channel_layout = avctx->channel_layout;
286 frame->sample_rate = avctx->sample_rate;
287 ret = av_frame_get_buffer(frame, 0);
289 const uint8_t *samples = (uint8_t *)temp_raw +
290 cur_sample * sizeof(int16_t) * asset->channels;
291 ret = swr_convert(resample_context,
292 (uint8_t **)frame->extended_data, frame_size,
293 &samples, frame_size);
296 frame->pts = avctx->sample_rate && avctx->time_base.num ?
297 file->get_audio_position() : AV_NOPTS_VALUE ;
299 ret = avcodec_encode_audio2(avctx, &avpkt, frame, &got_packet);
301 if(got_packet && avctx->coded_frame) {
302 avctx->coded_frame->pts = avpkt.pts;
303 avctx->coded_frame->key_frame = !!(avpkt.flags & AV_PKT_FLAG_KEY);
307 av_packet_free_side_data(&avpkt);
308 output_size += avpkt.size;
309 if(frame->extended_data != frame->data)
310 av_freep(&frame->extended_data);
311 av_frame_free(&frame);
316 temp_raw + cur_sample * asset->channels,
317 (temp_raw_size - cur_sample) * sizeof(int16_t) * asset->channels);
318 temp_raw_size -= cur_sample;
320 int bytes_written = fwrite(temp_compressed, 1, output_size, fd);
321 if(bytes_written < output_size)
323 eprintf("Error while writing samples. \n%m\n");
335 AC3ConfigAudio::AC3ConfigAudio(BC_WindowBase *parent_window,
337 : BC_Window(PROGRAM_NAME ": Audio Compression",
338 parent_window->get_abs_cursor_x(1),
339 parent_window->get_abs_cursor_y(1),
341 BC_OKButton::calculate_h() + 100,
343 BC_OKButton::calculate_h() + 100,
348 this->parent_window = parent_window;
352 void AC3ConfigAudio::create_objects()
356 lock_window("AC3ConfigAudio::create_objects");
357 add_tool(new BC_Title(x, y, "Bitrate (kbps):"));
358 AC3ConfigAudioBitrate *bitrate;
360 new AC3ConfigAudioBitrate(this,
363 bitrate->create_objects();
365 add_subwindow(new BC_OKButton(this));
370 int AC3ConfigAudio::close_event()
381 AC3ConfigAudioBitrate::AC3ConfigAudioBitrate(AC3ConfigAudio *gui,
387 AC3ConfigAudioBitrate::bitrate_to_string(gui->string, gui->asset->ac3_bitrate))
392 char* AC3ConfigAudioBitrate::bitrate_to_string(char *string, int bitrate)
394 sprintf(string, "%d", bitrate);
398 void AC3ConfigAudioBitrate::create_objects()
400 add_item(new BC_MenuItem("32"));
401 add_item(new BC_MenuItem("40"));
402 add_item(new BC_MenuItem("48"));
403 add_item(new BC_MenuItem("56"));
404 add_item(new BC_MenuItem("64"));
405 add_item(new BC_MenuItem("80"));
406 add_item(new BC_MenuItem("96"));
407 add_item(new BC_MenuItem("112"));
408 add_item(new BC_MenuItem("128"));
409 add_item(new BC_MenuItem("160"));
410 add_item(new BC_MenuItem("192"));
411 add_item(new BC_MenuItem("224"));
412 add_item(new BC_MenuItem("256"));
413 add_item(new BC_MenuItem("320"));
414 add_item(new BC_MenuItem("384"));
415 add_item(new BC_MenuItem("448"));
416 add_item(new BC_MenuItem("512"));
417 add_item(new BC_MenuItem("576"));
418 add_item(new BC_MenuItem("640"));
421 int AC3ConfigAudioBitrate::handle_event()
423 gui->asset->ac3_bitrate = atol(get_text());