annotate libmpcodecs/ae_faac.c @ 17135:d2bafb1e217c

Every contribution deserves to be listed on the "about" window of the gui. Change the way this list is done by following the layout of AUTHORS
author gpoirier
date Wed, 07 Dec 2005 21:17:29 +0000
parents 6ff3379a0862
children 934380353fd6
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
15259
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
1 #include <stdio.h>
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
2 #include <stdlib.h>
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
3 #include <inttypes.h>
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
4 #include <unistd.h>
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
5 #include <string.h>
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
6 #include <sys/types.h>
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
7 #include "m_option.h"
17012
6ff3379a0862 Unify include path handling, -I.. is in CFLAGS.
diego
parents: 15276
diff changeset
8 #include "mp_msg.h"
15259
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
9 #include "aviheader.h"
17012
6ff3379a0862 Unify include path handling, -I.. is in CFLAGS.
diego
parents: 15276
diff changeset
10 #include "libaf/af_format.h"
15259
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
11 #include "ms_hdr.h"
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
12 #include "muxer.h"
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
13 #include <faac.h>
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
14 #include "ae.h"
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
15
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
16
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
17 static faacEncHandle faac;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
18 static faacEncConfigurationPtr config = NULL;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
19 static int
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
20 param_bitrate = 128,
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
21 param_quality = 0,
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
22 param_object_type = MAIN,
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
23 param_mpeg = 2,
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
24 param_tns = 0,
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
25 param_raw = 0,
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
26 param_cutoff = 0,
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
27 param_format = 16,
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
28 param_debug = 0;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
29
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
30 static int enc_frame_size = 0, divisor;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
31 static unsigned long samples_input, max_bytes_output;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
32 static unsigned char *decoder_specific_buffer = NULL;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
33 static unsigned long decoder_specific_len = 0;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
34
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
35 m_option_t faacopts_conf[] = {
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
36 {"br", &param_bitrate, CONF_TYPE_INT, 0, 0, 0, NULL},
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
37 {"quality", &param_quality, CONF_TYPE_INT, CONF_RANGE, 0, 1000, NULL},
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
38 {"object", &param_object_type, CONF_TYPE_INT, CONF_RANGE, MAIN, LTP, NULL},
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
39 {"mpeg", &param_mpeg, CONF_TYPE_INT, CONF_RANGE, 2, 4, NULL},
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
40 {"tns", &param_tns, CONF_TYPE_FLAG, 0, 0, 1, NULL},
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
41 {"cutoff", &param_cutoff, CONF_TYPE_INT, 0, 0, 0, NULL},
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
42 {"format", &param_format, CONF_TYPE_INT, 0, 0, 0, NULL},
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
43 {"raw", &param_raw, CONF_TYPE_FLAG, 0, 0, 1, NULL},
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
44 {"debug", &param_debug, CONF_TYPE_INT, CONF_RANGE, 0, 100000000, NULL},
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
45 {NULL, NULL, 0, 0, 0, 0, NULL}
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
46 };
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
47
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
48
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
49 static int bind_faac(audio_encoder_t *encoder, muxer_stream_t *mux_a)
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
50 {
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
51 mux_a->wf = calloc(1, sizeof(WAVEFORMATEX) + decoder_specific_len + 256);
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
52 mux_a->wf->wFormatTag = 0x706D;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
53 mux_a->wf->nChannels = encoder->params.channels;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
54 mux_a->h.dwSampleSize=0; // VBR
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
55 mux_a->h.dwRate=encoder->params.sample_rate;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
56 mux_a->h.dwScale=encoder->params.samples_per_frame;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
57 mux_a->wf->nSamplesPerSec=mux_a->h.dwRate;
15276
f331ff9ff453 10l, fix wrong byterate in waveformat
nicodvb
parents: 15259
diff changeset
58 mux_a->wf->nAvgBytesPerSec = encoder->params.bitrate / 8;
15259
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
59
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
60 mux_a->wf->nBlockAlign = mux_a->h.dwScale;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
61 mux_a->h.dwSuggestedBufferSize = (encoder->params.audio_preload*mux_a->wf->nAvgBytesPerSec)/1000;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
62 mux_a->h.dwSuggestedBufferSize -= mux_a->h.dwSuggestedBufferSize % mux_a->wf->nBlockAlign;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
63
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
64 mux_a->wf->cbSize = decoder_specific_len;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
65 mux_a->wf->wBitsPerSample = 0; /* does not apply */
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
66 ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->wID = 1;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
67 ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->fdwFlags = 2;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
68 ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->nBlockSize = mux_a->wf->nBlockAlign;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
69 ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->nFramesPerBlock = 1;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
70 ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->nCodecDelay = 0;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
71
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
72 // Fix allocation
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
73 mux_a->wf = realloc(mux_a->wf, sizeof(WAVEFORMATEX)+mux_a->wf->cbSize);
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
74
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
75 if(config->inputFormat == FAAC_INPUT_FLOAT)
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
76 encoder->input_format = AF_FORMAT_FLOAT_NE;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
77 else if(config->inputFormat == FAAC_INPUT_32BIT)
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
78 encoder->input_format = AF_FORMAT_S32_NE;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
79 else
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
80 encoder->input_format = AF_FORMAT_S16_NE;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
81
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
82 encoder->min_buffer_size = mux_a->h.dwSuggestedBufferSize;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
83 encoder->max_buffer_size = mux_a->h.dwSuggestedBufferSize*2;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
84
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
85 if(decoder_specific_buffer && decoder_specific_len)
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
86 memcpy(mux_a->wf + 1, decoder_specific_buffer, decoder_specific_len);
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
87
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
88 return 1;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
89 }
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
90
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
91 static int get_frame_size(audio_encoder_t *encoder)
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
92 {
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
93 int sz = enc_frame_size;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
94 enc_frame_size = 0;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
95 return sz;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
96 }
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
97
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
98 static int encode_faac(audio_encoder_t *encoder, uint8_t *dest, void *src, int len, int max_size)
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
99 {
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
100 // len is divided by the number of bytes per sample
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
101 enc_frame_size = faacEncEncode(faac, (int32_t*) src, len / divisor, dest, max_size);
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
102
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
103 return enc_frame_size;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
104 }
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
105
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
106 int close_faac(audio_encoder_t *encoder)
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
107 {
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
108 return 1;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
109 }
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
110
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
111 int mpae_init_faac(audio_encoder_t *encoder)
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
112 {
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
113 if(encoder->params.channels < 1 || encoder->params.channels > 6 || (param_mpeg != 2 && param_mpeg != 4))
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
114 {
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
115 mp_msg(MSGT_MENCODER, MSGL_FATAL, "AE_FAAC, unsupported number of channels: %d, or mpeg version: %d, exit\n", encoder->params.channels, param_mpeg);
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
116 return 0;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
117 }
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
118
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
119 faac = faacEncOpen(encoder->params.sample_rate, encoder->params.channels, &samples_input, &max_bytes_output);
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
120 if(!faac)
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
121 {
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
122 mp_msg(MSGT_MENCODER, MSGL_FATAL, "AE_FAAC, couldn't init, exit\n");
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
123 return 0;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
124 }
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
125 mp_msg(MSGT_MENCODER, MSGL_V, "AE_FAAC, sample_input: %u, max_bytes_output: %u\n", samples_input, max_bytes_output);
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
126 config = faacEncGetCurrentConfiguration(faac);
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
127 if(!config)
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
128 {
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
129 mp_msg(MSGT_MENCODER, MSGL_FATAL, "AE_FAAC, couldn't get init configuration, exit\n");
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
130 return 0;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
131 }
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
132
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
133 param_bitrate *= 1000;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
134 if(param_quality)
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
135 config->quantqual = param_quality;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
136 else
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
137 config->bitRate = param_bitrate / encoder->params.channels;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
138
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
139 if(param_format==33)
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
140 {
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
141 config->inputFormat = FAAC_INPUT_FLOAT;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
142 divisor = 4;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
143 }
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
144 else if(param_format==32)
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
145 {
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
146 config->inputFormat = FAAC_INPUT_32BIT;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
147 divisor = 4;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
148 }
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
149 else
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
150 {
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
151 config->inputFormat = FAAC_INPUT_16BIT;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
152 divisor = 2;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
153 }
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
154 config->outputFormat = param_raw ? 0 : 1; // 1 is ADTS
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
155 config->aacObjectType = param_object_type;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
156 config->mpegVersion = (param_mpeg == 4 ? MPEG4 : MPEG2);
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
157 config->useTns = param_tns;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
158 config->allowMidside = 1;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
159 config->shortctl = SHORTCTL_NORMAL;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
160 param_cutoff = param_cutoff ? param_cutoff : encoder->params.sample_rate / 2;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
161 if(param_cutoff > encoder->params.sample_rate / 2)
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
162 param_cutoff = encoder->params.sample_rate / 2;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
163 config->bandWidth = param_cutoff;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
164 if(encoder->params.channels == 6)
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
165 config->useLfe = 1;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
166
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
167 if(!faacEncSetConfiguration(faac, config))
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
168 {
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
169 mp_msg(MSGT_MENCODER, MSGL_FATAL, "AE_FAAC, counldn't set specified parameters, exiting\n");
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
170 return 0;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
171 }
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
172
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
173 if(param_raw)
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
174 faacEncGetDecoderSpecificInfo(faac, &decoder_specific_buffer, &decoder_specific_len);
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
175 else
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
176 decoder_specific_len = 0;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
177
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
178 encoder->params.bitrate = param_bitrate;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
179 encoder->params.samples_per_frame = 1024;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
180 encoder->decode_buffer_size = divisor * samples_input; //samples * 16 bits_per_sample
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
181
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
182 encoder->bind = bind_faac;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
183 encoder->get_frame_size = get_frame_size;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
184 encoder->encode = encode_faac;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
185 encoder->close = close_faac;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
186
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
187 return 1;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
188 }