Mercurial > mplayer.hg
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 |
rev | line source |
---|---|
15259 | 1 #include <stdio.h> |
2 #include <stdlib.h> | |
3 #include <inttypes.h> | |
4 #include <unistd.h> | |
5 #include <string.h> | |
6 #include <sys/types.h> | |
7 #include "m_option.h" | |
17012 | 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 | 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 | 14 #include <faac.h> |
15 #include "ae.h" | |
16 | |
17 | |
18 static faacEncHandle faac; | |
19 static faacEncConfigurationPtr config = NULL; | |
20 static int | |
21 param_bitrate = 128, | |
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 | 24 param_mpeg = 2, |
25 param_tns = 0, | |
26 param_raw = 0, | |
27 param_cutoff = 0, | |
28 param_format = 16, | |
29 param_debug = 0; | |
30 | |
31 static int enc_frame_size = 0, divisor; | |
32 static unsigned long samples_input, max_bytes_output; | |
33 static unsigned char *decoder_specific_buffer = NULL; | |
34 static unsigned long decoder_specific_len = 0; | |
35 | |
36 m_option_t faacopts_conf[] = { | |
37 {"br", ¶m_bitrate, CONF_TYPE_INT, 0, 0, 0, NULL}, | |
38 {"quality", ¶m_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", ¶m_object_type, CONF_TYPE_INT, CONF_RANGE, 1, 4, NULL}, |
15259 | 40 {"mpeg", ¶m_mpeg, CONF_TYPE_INT, CONF_RANGE, 2, 4, NULL}, |
41 {"tns", ¶m_tns, CONF_TYPE_FLAG, 0, 0, 1, NULL}, | |
42 {"cutoff", ¶m_cutoff, CONF_TYPE_INT, 0, 0, 0, NULL}, | |
43 {"format", ¶m_format, CONF_TYPE_INT, 0, 0, 0, NULL}, | |
44 {"raw", ¶m_raw, CONF_TYPE_FLAG, 0, 0, 1, NULL}, | |
45 {"debug", ¶m_debug, CONF_TYPE_INT, CONF_RANGE, 0, 100000000, NULL}, | |
46 {NULL, NULL, 0, 0, 0, 0, NULL} | |
47 }; | |
48 | |
49 | |
50 static int bind_faac(audio_encoder_t *encoder, muxer_stream_t *mux_a) | |
51 { | |
52 mux_a->wf = calloc(1, sizeof(WAVEFORMATEX) + decoder_specific_len + 256); | |
53 mux_a->wf->wFormatTag = 0x706D; | |
54 mux_a->wf->nChannels = encoder->params.channels; | |
55 mux_a->h.dwSampleSize=0; // VBR | |
56 mux_a->h.dwRate=encoder->params.sample_rate; | |
57 mux_a->h.dwScale=encoder->params.samples_per_frame; | |
58 mux_a->wf->nSamplesPerSec=mux_a->h.dwRate; | |
15276 | 59 mux_a->wf->nAvgBytesPerSec = encoder->params.bitrate / 8; |
15259 | 60 |
61 mux_a->wf->nBlockAlign = mux_a->h.dwScale; | |
62 mux_a->h.dwSuggestedBufferSize = (encoder->params.audio_preload*mux_a->wf->nAvgBytesPerSec)/1000; | |
63 mux_a->h.dwSuggestedBufferSize -= mux_a->h.dwSuggestedBufferSize % mux_a->wf->nBlockAlign; | |
64 | |
65 mux_a->wf->cbSize = decoder_specific_len; | |
66 mux_a->wf->wBitsPerSample = 0; /* does not apply */ | |
67 ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->wID = 1; | |
68 ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->fdwFlags = 2; | |
69 ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->nBlockSize = mux_a->wf->nBlockAlign; | |
70 ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->nFramesPerBlock = 1; | |
71 ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->nCodecDelay = 0; | |
72 | |
73 // Fix allocation | |
74 mux_a->wf = realloc(mux_a->wf, sizeof(WAVEFORMATEX)+mux_a->wf->cbSize); | |
75 | |
76 if(config->inputFormat == FAAC_INPUT_FLOAT) | |
77 encoder->input_format = AF_FORMAT_FLOAT_NE; | |
78 else if(config->inputFormat == FAAC_INPUT_32BIT) | |
79 encoder->input_format = AF_FORMAT_S32_NE; | |
80 else | |
81 encoder->input_format = AF_FORMAT_S16_NE; | |
82 | |
83 encoder->min_buffer_size = mux_a->h.dwSuggestedBufferSize; | |
84 encoder->max_buffer_size = mux_a->h.dwSuggestedBufferSize*2; | |
85 | |
86 if(decoder_specific_buffer && decoder_specific_len) | |
87 memcpy(mux_a->wf + 1, decoder_specific_buffer, decoder_specific_len); | |
88 | |
89 return 1; | |
90 } | |
91 | |
92 static int get_frame_size(audio_encoder_t *encoder) | |
93 { | |
94 int sz = enc_frame_size; | |
95 enc_frame_size = 0; | |
96 return sz; | |
97 } | |
98 | |
99 static int encode_faac(audio_encoder_t *encoder, uint8_t *dest, void *src, int len, int max_size) | |
100 { | |
101 // len is divided by the number of bytes per sample | |
102 enc_frame_size = faacEncEncode(faac, (int32_t*) src, len / divisor, dest, max_size); | |
103 | |
104 return enc_frame_size; | |
105 } | |
106 | |
107 int close_faac(audio_encoder_t *encoder) | |
108 { | |
109 return 1; | |
110 } | |
111 | |
112 int mpae_init_faac(audio_encoder_t *encoder) | |
113 { | |
114 if(encoder->params.channels < 1 || encoder->params.channels > 6 || (param_mpeg != 2 && param_mpeg != 4)) | |
115 { | |
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); | |
117 return 0; | |
118 } | |
119 | |
120 faac = faacEncOpen(encoder->params.sample_rate, encoder->params.channels, &samples_input, &max_bytes_output); | |
121 if(!faac) | |
122 { | |
123 mp_msg(MSGT_MENCODER, MSGL_FATAL, "AE_FAAC, couldn't init, exit\n"); | |
124 return 0; | |
125 } | |
17366 | 126 mp_msg(MSGT_MENCODER, MSGL_V, "AE_FAAC, sample_input: %lu, max_bytes_output: %lu\n", samples_input, max_bytes_output); |
15259 | 127 config = faacEncGetCurrentConfiguration(faac); |
128 if(!config) | |
129 { | |
130 mp_msg(MSGT_MENCODER, MSGL_FATAL, "AE_FAAC, couldn't get init configuration, exit\n"); | |
131 return 0; | |
132 } | |
133 | |
134 param_bitrate *= 1000; | |
135 if(param_quality) | |
136 config->quantqual = param_quality; | |
137 else | |
138 config->bitRate = param_bitrate / encoder->params.channels; | |
139 | |
140 if(param_format==33) | |
141 { | |
142 config->inputFormat = FAAC_INPUT_FLOAT; | |
143 divisor = 4; | |
144 } | |
145 else if(param_format==32) | |
146 { | |
147 config->inputFormat = FAAC_INPUT_32BIT; | |
148 divisor = 4; | |
149 } | |
150 else | |
151 { | |
152 config->inputFormat = FAAC_INPUT_16BIT; | |
153 divisor = 2; | |
154 } | |
155 config->outputFormat = param_raw ? 0 : 1; // 1 is ADTS | |
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 | 158 config->mpegVersion = (param_mpeg == 4 ? MPEG4 : MPEG2); |
159 config->useTns = param_tns; | |
160 config->allowMidside = 1; | |
161 config->shortctl = SHORTCTL_NORMAL; | |
162 param_cutoff = param_cutoff ? param_cutoff : encoder->params.sample_rate / 2; | |
163 if(param_cutoff > encoder->params.sample_rate / 2) | |
164 param_cutoff = encoder->params.sample_rate / 2; | |
165 config->bandWidth = param_cutoff; | |
166 if(encoder->params.channels == 6) | |
167 config->useLfe = 1; | |
168 | |
169 if(!faacEncSetConfiguration(faac, config)) | |
170 { | |
171 mp_msg(MSGT_MENCODER, MSGL_FATAL, "AE_FAAC, counldn't set specified parameters, exiting\n"); | |
172 return 0; | |
173 } | |
174 | |
175 if(param_raw) | |
176 faacEncGetDecoderSpecificInfo(faac, &decoder_specific_buffer, &decoder_specific_len); | |
177 else | |
178 decoder_specific_len = 0; | |
179 | |
180 encoder->params.bitrate = param_bitrate; | |
181 encoder->params.samples_per_frame = 1024; | |
182 encoder->decode_buffer_size = divisor * samples_input; //samples * 16 bits_per_sample | |
183 | |
184 encoder->bind = bind_faac; | |
185 encoder->get_frame_size = get_frame_size; | |
186 encoder->encode = encode_faac; | |
187 encoder->close = close_faac; | |
188 | |
189 return 1; | |
190 } |