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