annotate libmpcodecs/ae_faac.c @ 24892:80180dc13565

Change decode_audio() interface Rewrite decode_audio to better deal with filters that handle input in large blocks. It now always places output in sh_audio->a_out_buffer (which was always given as a parameter before) and reallocates the buffer if needed. After the changes filters can return arbitrarily large blocks of data without some of it being lost. The new version also allows simplifying some code.
author uau
date Thu, 01 Nov 2007 06:52:19 +0000
parents ed8f90096c65
children dfa8a510c81c
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"
22601
ed8f90096c65 Add explicit location for headers from the libmpdemux/ directory.
diego
parents: 22600
diff changeset
9 #include "libmpdemux/aviheader.h"
17012
6ff3379a0862 Unify include path handling, -I.. is in CFLAGS.
diego
parents: 15276
diff changeset
10 #include "libaf/af_format.h"
22601
ed8f90096c65 Add explicit location for headers from the libmpdemux/ directory.
diego
parents: 22600
diff changeset
11 #include "libmpdemux/ms_hdr.h"
22600
3c2b4a866c6a Add explicit location for headers from the stream/ directory.
diego
parents: 21660
diff changeset
12 #include "stream/stream.h"
22601
ed8f90096c65 Add explicit location for headers from the libmpdemux/ directory.
diego
parents: 22600
diff changeset
13 #include "libmpdemux/muxer.h"
15259
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
14 #include <faac.h>
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
15 #include "ae.h"
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
16
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
17
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
18 static faacEncHandle faac;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
19 static faacEncConfigurationPtr config = NULL;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
20 static int
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
21 param_bitrate = 128,
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
22 param_quality = 0,
20080
5aab07acf0b5 workaround redefinition of object_type as prev(object_type)+1
nicodvb
parents: 17366
diff changeset
23 param_object_type = 1,
15259
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
24 param_mpeg = 2,
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
25 param_tns = 0,
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
26 param_raw = 0,
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
27 param_cutoff = 0,
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
28 param_format = 16,
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
29 param_debug = 0;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
30
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
31 static int enc_frame_size = 0, divisor;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
32 static unsigned long samples_input, max_bytes_output;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
33 static unsigned char *decoder_specific_buffer = NULL;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
34 static unsigned long decoder_specific_len = 0;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
35
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
36 m_option_t faacopts_conf[] = {
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
37 {"br", &param_bitrate, CONF_TYPE_INT, 0, 0, 0, NULL},
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
38 {"quality", &param_quality, CONF_TYPE_INT, CONF_RANGE, 0, 1000, NULL},
20080
5aab07acf0b5 workaround redefinition of object_type as prev(object_type)+1
nicodvb
parents: 17366
diff changeset
39 {"object", &param_object_type, CONF_TYPE_INT, CONF_RANGE, 1, 4, NULL},
15259
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
40 {"mpeg", &param_mpeg, CONF_TYPE_INT, CONF_RANGE, 2, 4, NULL},
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
41 {"tns", &param_tns, CONF_TYPE_FLAG, 0, 0, 1, NULL},
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
42 {"cutoff", &param_cutoff, CONF_TYPE_INT, 0, 0, 0, NULL},
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
43 {"format", &param_format, CONF_TYPE_INT, 0, 0, 0, NULL},
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
44 {"raw", &param_raw, CONF_TYPE_FLAG, 0, 0, 1, NULL},
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
45 {"debug", &param_debug, CONF_TYPE_INT, CONF_RANGE, 0, 100000000, NULL},
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
46 {NULL, NULL, 0, 0, 0, 0, NULL}
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
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
50 static int bind_faac(audio_encoder_t *encoder, muxer_stream_t *mux_a)
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
51 {
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
52 mux_a->wf = calloc(1, sizeof(WAVEFORMATEX) + decoder_specific_len + 256);
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
53 mux_a->wf->wFormatTag = 0x706D;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
54 mux_a->wf->nChannels = encoder->params.channels;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
55 mux_a->h.dwSampleSize=0; // VBR
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
56 mux_a->h.dwRate=encoder->params.sample_rate;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
57 mux_a->h.dwScale=encoder->params.samples_per_frame;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
58 mux_a->wf->nSamplesPerSec=mux_a->h.dwRate;
15276
f331ff9ff453 10l, fix wrong byterate in waveformat
nicodvb
parents: 15259
diff changeset
59 mux_a->wf->nAvgBytesPerSec = encoder->params.bitrate / 8;
15259
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
60
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
61 mux_a->wf->nBlockAlign = mux_a->h.dwScale;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
62 mux_a->h.dwSuggestedBufferSize = (encoder->params.audio_preload*mux_a->wf->nAvgBytesPerSec)/1000;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
63 mux_a->h.dwSuggestedBufferSize -= mux_a->h.dwSuggestedBufferSize % mux_a->wf->nBlockAlign;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
64
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
65 mux_a->wf->cbSize = decoder_specific_len;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
66 mux_a->wf->wBitsPerSample = 0; /* does not apply */
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
67 ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->wID = 1;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
68 ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->fdwFlags = 2;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
69 ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->nBlockSize = mux_a->wf->nBlockAlign;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
70 ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->nFramesPerBlock = 1;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
71 ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->nCodecDelay = 0;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
72
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
73 // Fix allocation
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
74 mux_a->wf = realloc(mux_a->wf, sizeof(WAVEFORMATEX)+mux_a->wf->cbSize);
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
75
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
76 if(config->inputFormat == FAAC_INPUT_FLOAT)
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
77 encoder->input_format = AF_FORMAT_FLOAT_NE;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
78 else if(config->inputFormat == FAAC_INPUT_32BIT)
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
79 encoder->input_format = AF_FORMAT_S32_NE;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
80 else
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
81 encoder->input_format = AF_FORMAT_S16_NE;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
82
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
83 encoder->min_buffer_size = mux_a->h.dwSuggestedBufferSize;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
84 encoder->max_buffer_size = mux_a->h.dwSuggestedBufferSize*2;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
85
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
86 if(decoder_specific_buffer && decoder_specific_len)
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
87 memcpy(mux_a->wf + 1, decoder_specific_buffer, decoder_specific_len);
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
88
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
89 return 1;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
90 }
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
91
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
92 static int get_frame_size(audio_encoder_t *encoder)
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
93 {
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
94 int sz = enc_frame_size;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
95 enc_frame_size = 0;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
96 return sz;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
97 }
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
98
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
99 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
100 {
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
101 // len is divided by the number of bytes per sample
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
102 enc_frame_size = faacEncEncode(faac, (int32_t*) src, len / divisor, dest, max_size);
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
103
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
104 return enc_frame_size;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
105 }
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
106
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
107 int close_faac(audio_encoder_t *encoder)
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
108 {
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
109 return 1;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
110 }
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
111
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
112 int mpae_init_faac(audio_encoder_t *encoder)
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
113 {
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
114 if(encoder->params.channels < 1 || encoder->params.channels > 6 || (param_mpeg != 2 && param_mpeg != 4))
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
115 {
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
116 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
117 return 0;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
118 }
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
119
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
120 faac = faacEncOpen(encoder->params.sample_rate, encoder->params.channels, &samples_input, &max_bytes_output);
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
121 if(!faac)
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
122 {
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
123 mp_msg(MSGT_MENCODER, MSGL_FATAL, "AE_FAAC, couldn't init, exit\n");
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
124 return 0;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
125 }
17366
934380353fd6 massive attack: mp_msg printf format fixes
rathann
parents: 17012
diff changeset
126 mp_msg(MSGT_MENCODER, MSGL_V, "AE_FAAC, sample_input: %lu, max_bytes_output: %lu\n", samples_input, max_bytes_output);
15259
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
127 config = faacEncGetCurrentConfiguration(faac);
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
128 if(!config)
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
129 {
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
130 mp_msg(MSGT_MENCODER, MSGL_FATAL, "AE_FAAC, couldn't get init configuration, exit\n");
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
131 return 0;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
132 }
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
133
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
134 param_bitrate *= 1000;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
135 if(param_quality)
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
136 config->quantqual = param_quality;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
137 else
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
138 config->bitRate = param_bitrate / encoder->params.channels;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
139
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
140 if(param_format==33)
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
141 {
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
142 config->inputFormat = FAAC_INPUT_FLOAT;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
143 divisor = 4;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
144 }
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
145 else if(param_format==32)
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
146 {
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
147 config->inputFormat = FAAC_INPUT_32BIT;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
148 divisor = 4;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
149 }
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
150 else
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
151 {
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
152 config->inputFormat = FAAC_INPUT_16BIT;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
153 divisor = 2;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
154 }
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
155 config->outputFormat = param_raw ? 0 : 1; // 1 is ADTS
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
156 config->aacObjectType = param_object_type;
20080
5aab07acf0b5 workaround redefinition of object_type as prev(object_type)+1
nicodvb
parents: 17366
diff changeset
157 if(MAIN==0) config->aacObjectType--;
15259
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
158 config->mpegVersion = (param_mpeg == 4 ? MPEG4 : MPEG2);
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
159 config->useTns = param_tns;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
160 config->allowMidside = 1;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
161 config->shortctl = SHORTCTL_NORMAL;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
162 param_cutoff = param_cutoff ? param_cutoff : encoder->params.sample_rate / 2;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
163 if(param_cutoff > encoder->params.sample_rate / 2)
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
164 param_cutoff = encoder->params.sample_rate / 2;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
165 config->bandWidth = param_cutoff;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
166 if(encoder->params.channels == 6)
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
167 config->useLfe = 1;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
168
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
169 if(!faacEncSetConfiguration(faac, config))
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
170 {
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
171 mp_msg(MSGT_MENCODER, MSGL_FATAL, "AE_FAAC, counldn't set specified parameters, exiting\n");
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
172 return 0;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
173 }
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
174
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
175 if(param_raw)
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
176 faacEncGetDecoderSpecificInfo(faac, &decoder_specific_buffer, &decoder_specific_len);
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
177 else
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
178 decoder_specific_len = 0;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
179
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
180 encoder->params.bitrate = param_bitrate;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
181 encoder->params.samples_per_frame = 1024;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
182 encoder->decode_buffer_size = divisor * samples_input; //samples * 16 bits_per_sample
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
183
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
184 encoder->bind = bind_faac;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
185 encoder->get_frame_size = get_frame_size;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
186 encoder->encode = encode_faac;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
187 encoder->close = close_faac;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
188
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
189 return 1;
854990f357ee added faac audio encoder
nicodvb
parents:
diff changeset
190 }