ffmpeg api3 upgrade, rework bs filts, rm faac/d, fixes
[goodguy/history.git] / cinelerra-5.1 / cinelerra / fileac3.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
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 <stdio.h>
23 #include <stdint.h>
24 #include <stdlib.h>
25 #include <unistd.h>
26 #include <string.h>
27 #include <stdarg.h>
28 #include <ctype.h>
29 #include <limits.h>
30 // work around (centos) for __STDC_CONSTANT_MACROS
31 #include <lzma.h>
32 #ifndef INT64_MAX
33 #   define INT64_MAX 9223372036854775807LL
34 #endif
35
36 extern "C"
37 {
38 #include "libavcodec/avcodec.h"
39 }
40
41 #include "asset.h"
42 #include "clip.h"
43 #include "fileac3.h"
44 #include "file.h"
45 #include "filempeg.h"
46 #include "language.h"
47 #include "mainerror.h"
48
49
50
51 #include <string.h>
52
53 FileAC3::FileAC3(Asset *asset, File *file)
54  : FileBase(asset, file)
55 {
56         reset_parameters();
57         mpg_file = 0;
58 }
59
60 FileAC3::~FileAC3()
61 {
62         if( mpg_file ) delete mpg_file;
63         close_file();
64 }
65
66 int FileAC3::reset_parameters_derived()
67 {
68         codec = 0;
69         codec_context = 0;
70         resample_context = 0;
71         fd = 0;
72         temp_raw = 0;
73         temp_raw_size = 0;
74         temp_raw_allocated = 0;
75         return 0;
76 }
77
78 void FileAC3::get_parameters(BC_WindowBase *parent_window,
79                 Asset *asset,
80                 BC_WindowBase* &format_window,
81                 int audio_options,
82                 int video_options)
83 {
84         if(audio_options)
85         {
86
87                 AC3ConfigAudio *window = new AC3ConfigAudio(parent_window, asset);
88                 format_window = window;
89                 window->create_objects();
90                 window->run_window();
91                 delete window;
92         }
93 }
94
95 int FileAC3::check_sig()
96 {
97 // Libmpeg3 does this in FileMPEG.
98         return 0;
99 }
100
101 int64_t FileAC3::get_channel_layout(int channels)
102 {
103         switch( channels ) {
104         case 1: return AV_CH_LAYOUT_MONO;
105         case 2: return AV_CH_LAYOUT_STEREO;
106         case 3: return AV_CH_LAYOUT_SURROUND;
107         case 4: return AV_CH_LAYOUT_QUAD;
108         case 5: return AV_CH_LAYOUT_5POINT0;
109         case 6: return AV_CH_LAYOUT_5POINT1;
110         case 8: return AV_CH_LAYOUT_7POINT1;
111         }
112         return 0;
113 }
114
115 int FileAC3::open_file(int rd, int wr)
116 {
117         int result = 0;
118
119         if(rd)
120         {
121                 if( !mpg_file )
122                         mpg_file = new FileMPEG(file->asset, file);
123                 result = mpg_file->open_file(1, 0);
124                 if( result ) {
125                         eprintf(_("Error while opening \"%s\" for reading. \n%m\n"), asset->path);
126                 }
127         }
128
129         if( !result && wr )
130         {
131                 //avcodec_init();
132                 avcodec_register_all();
133                 codec = avcodec_find_encoder(AV_CODEC_ID_AC3);
134                 if(!codec)
135                 {
136                         eprintf(_("FileAC3::open_file codec not found.\n"));
137                         result = 1;
138                 }
139                 if( !result && !(fd = fopen(asset->path, "w")))
140                 {
141                         eprintf(_("Error while opening \"%s\" for writing. \n%m\n"), asset->path);
142                         result = 1;
143                 }
144                 if( !result ) {
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                         av_init_packet(&avpkt);
150                         codec_context = avcodec_alloc_context3(codec);
151                         codec_context->bit_rate = bitrate;
152                         codec_context->sample_rate = sample_rate;
153                         codec_context->channels = channels;
154                         codec_context->channel_layout = layout;
155                         codec_context->sample_fmt = codec->sample_fmts[0];
156                         resample_context = swr_alloc_set_opts(NULL,
157                                         layout, codec_context->sample_fmt, sample_rate,
158                                         layout, AV_SAMPLE_FMT_S16, sample_rate,
159                                         0, NULL);
160                         swr_init(resample_context);
161                         if(avcodec_open2(codec_context, codec, 0))
162                         {
163                                 eprintf(_("FileAC3::open_file failed to open codec.\n"));
164                                 result = 1;
165                         }
166                 }
167         }
168
169         return result;
170 }
171
172 int FileAC3::close_file()
173 {
174         if( mpg_file )
175         {
176                 delete mpg_file;
177                 mpg_file = 0;
178         }
179         if(codec_context)
180         {
181                 encode_flush();
182                 avcodec_close(codec_context);
183                 avcodec_free_context(&codec_context);
184                 codec = 0;
185         }
186         if( resample_context )
187                 swr_free(&resample_context);
188         if(fd)
189         {
190                 fclose(fd);
191                 fd = 0;
192         }
193         if(temp_raw)
194         {
195                 delete [] temp_raw;
196                 temp_raw = 0;
197         }
198         reset_parameters();
199         FileBase::close_file();
200         return 0;
201 }
202
203 int FileAC3::read_samples(double *buffer, int64_t len)
204 {
205         return !mpg_file ? 0 : mpg_file->read_samples(buffer, len);
206 }
207
208 int FileAC3::get_index(IndexFile *index_file, MainProgressBar *progress_bar)
209 {
210         return !mpg_file ? 1 : mpg_file->get_index(index_file, progress_bar);
211 }
212
213 // Channel conversion matrices because ffmpeg encodes a
214 // different channel order than liba52 decodes.
215 // Each row is an output channel.
216 // Each column is an input channel.
217 // static int channels5[] =
218 // {
219 //      { }
220 // };
221 //
222 // static int channels6[] =
223 // {
224 //      { }
225 // };
226
227 int FileAC3::write_packet()
228 {
229         AVCodecContext *&avctx = codec_context;
230         int ret = avcodec_receive_packet(avctx, &avpkt);
231         if( ret >= 0 ) {
232                 ret = 0;
233                 if( avpkt.data && avpkt.size > 0 ) {
234                         int sz = fwrite(avpkt.data, 1, avpkt.size, fd);
235                         if( sz == avpkt.size ) ret = 1;
236                 }
237                 if( !ret )
238                         eprintf(_("Error while writing samples. \n%m\n"));
239                 av_packet_unref(&avpkt);
240         }
241         else if( ret == AVERROR_EOF )
242                 ret = 0;
243         return ret;
244 }
245
246 int FileAC3::encode_frame(AVFrame *frame)
247 {
248         AVCodecContext *&avctx = codec_context;
249         int ret = 0, pkts = 0;
250         for( int retry=100; --retry>=0; ) {
251                 ret = avcodec_send_frame(avctx, frame);
252                 if( ret >= 0 ) return pkts;
253                 if( ret != AVERROR(EAGAIN) ) break;
254                 if( (ret=write_packet()) < 0 ) break;
255                 if( !ret ) return pkts;
256                 ++pkts;
257         }
258         if( ret < 0 ) {
259                 char errmsg[BCTEXTLEN];
260                 av_strerror(ret, errmsg, sizeof(errmsg));
261                 fprintf(stderr, "FileAC3::encode_frame: encode failed: %s\n", errmsg);
262         }
263         return ret;
264 }
265
266 int FileAC3::encode_flush()
267 {
268         AVCodecContext *&avctx = codec_context;
269         int ret = avcodec_send_frame(avctx, 0);
270         while( (ret=write_packet()) > 0 );
271         if( ret < 0 ) {
272                 char errmsg[BCTEXTLEN];
273                 av_strerror(ret, errmsg, sizeof(errmsg));
274                 fprintf(stderr, "FileAC3::encode_flush: encode failed: %s\n", errmsg);
275         }
276         return ret;
277 }
278
279 int FileAC3::write_samples(double **buffer, int64_t len)
280 {
281 // Convert buffer to encoder format
282         if(temp_raw_size + len > temp_raw_allocated)
283         {
284                 int new_allocated = temp_raw_size + len;
285                 int16_t *new_raw = new int16_t[new_allocated * asset->channels];
286                 if(temp_raw)
287                 {
288                         memcpy(new_raw,
289                                 temp_raw,
290                                 sizeof(int16_t) * temp_raw_size * asset->channels);
291                         delete [] temp_raw;
292                 }
293                 temp_raw = new_raw;
294                 temp_raw_allocated = new_allocated;
295         }
296
297 // Append buffer to temp raw
298         int16_t *out_ptr = temp_raw + temp_raw_size * asset->channels;
299         for(int i = 0; i < len; i++)
300         {
301                 for(int j = 0; j < asset->channels; j++)
302                 {
303                         int sample = (int)(buffer[j][i] * 32767);
304                         CLAMP(sample, -32768, 32767);
305                         *out_ptr++ = sample;
306                 }
307         }
308         temp_raw_size += len;
309
310         AVCodecContext *&avctx = codec_context;
311         int frame_size = avctx->frame_size;
312         int cur_sample = 0, ret = 0;
313         for(cur_sample = 0; ret >= 0 &&
314                 cur_sample + frame_size <= temp_raw_size;
315                 cur_sample += frame_size)
316         {
317                 AVFrame *frame = av_frame_alloc();
318                 frame->nb_samples = frame_size;
319                 frame->format = avctx->sample_fmt;
320                 frame->channel_layout = avctx->channel_layout;
321                 frame->sample_rate = avctx->sample_rate;
322                 ret = av_frame_get_buffer(frame, 0);
323                 if( ret >= 0 ) {
324                         const uint8_t *samples = (uint8_t *)temp_raw +
325                                 cur_sample * sizeof(int16_t) * asset->channels;
326                         ret = swr_convert(resample_context,
327                                 (uint8_t **)frame->extended_data, frame_size,
328                                 &samples, frame_size);
329                 }
330                 if( ret >= 0 ) {
331                         frame->pts = avctx->sample_rate && avctx->time_base.num ?
332                                 file->get_audio_position() : AV_NOPTS_VALUE ;
333                         ret = encode_frame(frame);
334                 }
335                 av_frame_free(&frame);
336         }
337
338 // Shift buffer back
339         memcpy(temp_raw,
340                 temp_raw + cur_sample * asset->channels,
341                 (temp_raw_size - cur_sample) * sizeof(int16_t) * asset->channels);
342         temp_raw_size -= cur_sample;
343
344         return 0;
345 }
346
347
348
349
350
351
352
353 AC3ConfigAudio::AC3ConfigAudio(BC_WindowBase *parent_window,
354         Asset *asset)
355  : BC_Window(_(PROGRAM_NAME ": Audio Compression"),
356         parent_window->get_abs_cursor_x(1),
357         parent_window->get_abs_cursor_y(1),
358         500,
359         BC_OKButton::calculate_h() + 100,
360         500,
361         BC_OKButton::calculate_h() + 100,
362         0,
363         0,
364         1)
365 {
366         this->parent_window = parent_window;
367         this->asset = asset;
368 }
369
370 void AC3ConfigAudio::create_objects()
371 {
372         int x = 10, y = 10;
373         int x1 = 150;
374         lock_window("AC3ConfigAudio::create_objects");
375         add_tool(new BC_Title(x, y, _("Bitrate (kbps):")));
376         AC3ConfigAudioBitrate *bitrate;
377         add_tool(bitrate =
378                 new AC3ConfigAudioBitrate(this,
379                         x1,
380                         y));
381         bitrate->create_objects();
382
383         add_subwindow(new BC_OKButton(this));
384         show_window(1);
385         unlock_window();
386 }
387
388 int AC3ConfigAudio::close_event()
389 {
390         set_done(0);
391         return 1;
392 }
393
394
395
396
397
398
399 AC3ConfigAudioBitrate::AC3ConfigAudioBitrate(AC3ConfigAudio *gui,
400         int x,
401         int y)
402  : BC_PopupMenu(x,
403         y,
404         150,
405         AC3ConfigAudioBitrate::bitrate_to_string(gui->string, gui->asset->ac3_bitrate))
406 {
407         this->gui = gui;
408 }
409
410 char* AC3ConfigAudioBitrate::bitrate_to_string(char *string, int bitrate)
411 {
412         sprintf(string, "%d", bitrate);
413         return string;
414 }
415
416 void AC3ConfigAudioBitrate::create_objects()
417 {
418         add_item(new BC_MenuItem("32"));
419         add_item(new BC_MenuItem("40"));
420         add_item(new BC_MenuItem("48"));
421         add_item(new BC_MenuItem("56"));
422         add_item(new BC_MenuItem("64"));
423         add_item(new BC_MenuItem("80"));
424         add_item(new BC_MenuItem("96"));
425         add_item(new BC_MenuItem("112"));
426         add_item(new BC_MenuItem("128"));
427         add_item(new BC_MenuItem("160"));
428         add_item(new BC_MenuItem("192"));
429         add_item(new BC_MenuItem("224"));
430         add_item(new BC_MenuItem("256"));
431         add_item(new BC_MenuItem("320"));
432         add_item(new BC_MenuItem("384"));
433         add_item(new BC_MenuItem("448"));
434         add_item(new BC_MenuItem("512"));
435         add_item(new BC_MenuItem("576"));
436         add_item(new BC_MenuItem("640"));
437 }
438
439 int AC3ConfigAudioBitrate::handle_event()
440 {
441         gui->asset->ac3_bitrate = atol(get_text());
442         return 1;
443 }
444
445
446