Mercurial > mplayer.hg
annotate libmpcodecs/ae_twolame.c @ 17588:79081ba52e00
Move the v{Y,C}CoeffsBank vectors into the SwsContext, filling them in just
once when the scaler is initialized, instead of building them and freeing
them over and over. This gives massive performance improvements.
patch by Alan Curry, pacman*at*TheWorld*dot*com
author | diego |
---|---|
date | Sat, 11 Feb 2006 14:16:10 +0000 |
parents | 6ff3379a0862 |
children | ca9da45d13e9 |
rev | line source |
---|---|
15359 | 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" |
15359 | 9 #include "aviheader.h" |
17012 | 10 #include "libaf/af_format.h" |
15359 | 11 #include "ms_hdr.h" |
12 #include "muxer.h" | |
13 #include "ae_twolame.h" | |
17012 | 14 #include "libmpdemux/mp3_hdr.h" |
15359 | 15 |
16 | |
17 static int | |
18 param_bitrate = 192, | |
19 param_psy = 3, | |
20 param_maxvbr = 0, | |
21 param_errprot = 0, | |
22 param_debug = 0; | |
23 | |
24 static float param_vbr = 0; | |
25 static char *param_mode = "stereo"; | |
26 | |
27 m_option_t twolameopts_conf[] = { | |
28 {"br", ¶m_bitrate, CONF_TYPE_INT, 0, 0, 0, NULL}, | |
29 {"mode", ¶m_mode, CONF_TYPE_STRING, 0, 0, 0, NULL}, | |
15362
4ff00aa141ef
updated psycho model range; made a parameter file-static in ae_toolame.c
nicodvb
parents:
15359
diff
changeset
|
30 {"psy", ¶m_psy, CONF_TYPE_INT, CONF_RANGE, -1, 4, NULL}, |
15359 | 31 {"vbr", ¶m_vbr, CONF_TYPE_FLOAT, CONF_RANGE, -50, 50, NULL}, |
32 {"maxvbr", ¶m_maxvbr, CONF_TYPE_INT, 0, 0, 0, NULL}, | |
33 {"errprot", ¶m_errprot, CONF_TYPE_INT, CONF_RANGE, 0, 1, NULL}, | |
34 {"debug", ¶m_debug, CONF_TYPE_INT, CONF_RANGE, 0, 100000000, NULL}, | |
35 {NULL, NULL, 0, 0, 0, 0, NULL} | |
36 }; | |
37 | |
38 | |
39 static int bind_twolame(audio_encoder_t *encoder, muxer_stream_t *mux_a) | |
40 { | |
41 mpae_twolame_ctx *ctx = (mpae_twolame_ctx *) encoder->priv; | |
42 | |
43 mux_a->wf = malloc(sizeof(WAVEFORMATEX)+256); | |
44 mux_a->wf->wFormatTag = 0x50; | |
45 mux_a->wf->nChannels = encoder->params.channels; | |
46 mux_a->wf->nSamplesPerSec = encoder->params.sample_rate; | |
47 mux_a->wf->nAvgBytesPerSec = encoder->params.bitrate / 8; | |
48 | |
49 if(ctx->vbr || ((mux_a->wf->nAvgBytesPerSec * encoder->params.samples_per_frame) % mux_a->wf->nSamplesPerSec)) | |
50 { | |
51 mux_a->h.dwScale = encoder->params.samples_per_frame; | |
52 mux_a->h.dwRate = encoder->params.sample_rate; | |
53 mux_a->h.dwSampleSize = 0; // Blocksize not constant | |
54 } | |
55 else | |
56 { | |
57 mux_a->h.dwScale = (mux_a->wf->nAvgBytesPerSec * encoder->params.samples_per_frame)/ mux_a->wf->nSamplesPerSec; /* for cbr */ | |
58 mux_a->h.dwRate = mux_a->wf->nAvgBytesPerSec; | |
59 mux_a->h.dwSampleSize = mux_a->h.dwScale; | |
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 = 0; //12; | |
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 encoder->input_format = AF_FORMAT_S16_NE; | |
77 encoder->min_buffer_size = mux_a->h.dwSuggestedBufferSize; | |
78 encoder->max_buffer_size = mux_a->h.dwSuggestedBufferSize*2; | |
79 | |
80 return 1; | |
81 } | |
82 | |
83 static int encode_twolame(audio_encoder_t *encoder, uint8_t *dest, void *src, int len, int max_size) | |
84 { | |
85 mpae_twolame_ctx *ctx = (mpae_twolame_ctx *)encoder->priv; | |
86 int ret_size = 0, r2; | |
87 | |
88 len /= (2*encoder->params.channels); | |
89 ret_size = twolame_encode_buffer_interleaved(ctx->twolame_ctx, src, len, dest, max_size); | |
90 r2 = mp_decode_mp3_header(dest); | |
16482 | 91 mp_msg(MSGT_MENCODER, MSGL_DBG2, "\nSIZE: %d, max: %d, r2: %d\n", ret_size, max_size, r2); |
15359 | 92 if(r2 > 0) |
93 ret_size = r2; | |
94 return ret_size; | |
95 } | |
96 | |
97 int close_twolame(audio_encoder_t *encoder) | |
98 { | |
99 free(encoder->priv); | |
100 return 1; | |
101 } | |
102 | |
103 static int get_frame_size(audio_encoder_t *encoder) | |
104 { | |
105 int sz; | |
106 if(encoder->stream->buffer_len < 4) | |
107 return 0; | |
108 sz = mp_decode_mp3_header(encoder->stream->buffer); | |
109 if(sz <= 0) | |
110 return 0; | |
111 return sz; | |
112 } | |
113 | |
114 | |
115 int mpae_init_twolame(audio_encoder_t *encoder) | |
116 { | |
117 int mode; | |
118 mpae_twolame_ctx *ctx = NULL; | |
119 | |
120 if(encoder->params.channels == 1) | |
121 { | |
122 mp_msg(MSGT_MENCODER, MSGL_INFO, "ae_twolame, 1 audio channel, forcing mono mode\n"); | |
123 mode = TWOLAME_MONO; | |
124 } | |
125 else if(encoder->params.channels == 2) | |
126 { | |
127 if(! strcasecmp(param_mode, "dual")) | |
128 mode = TWOLAME_DUAL_CHANNEL; | |
129 else if(! strcasecmp(param_mode, "jstereo")) | |
130 mode = TWOLAME_JOINT_STEREO; | |
131 else if(! strcasecmp(param_mode, "stereo")) | |
132 mode = TWOLAME_STEREO; | |
133 else | |
134 { | |
135 mp_msg(MSGT_MENCODER, MSGL_ERR, "ae_twolame, unknown mode %s, exiting\n", param_mode); | |
136 } | |
137 } | |
138 else | |
139 mp_msg(MSGT_MENCODER, MSGL_ERR, "ae_twolame, Twolame can't encode > 2 channels, exiting\n"); | |
140 | |
141 ctx = (mpae_twolame_ctx *) calloc(1, sizeof(mpae_twolame_ctx)); | |
142 if(ctx == NULL) | |
143 { | |
144 mp_msg(MSGT_MENCODER, MSGL_ERR, "ae_twolame, couldn't alloc a %d bytes context, exiting\n", sizeof(mpae_twolame_ctx)); | |
145 return 0; | |
146 } | |
147 | |
148 ctx->twolame_ctx = twolame_init(); | |
149 if(ctx->twolame_ctx == NULL) | |
150 { | |
151 mp_msg(MSGT_MENCODER, MSGL_ERR, "ae_twolame, couldn't initial parameters from libtwolame, exiting\n"); | |
152 free(ctx); | |
153 return 0; | |
154 } | |
155 ctx->vbr = 0; | |
156 | |
157 if(twolame_set_num_channels(ctx->twolame_ctx, encoder->params.channels) != 0) | |
158 return 0; | |
159 if(twolame_set_mode(ctx->twolame_ctx, mode) != 0) | |
160 return 0; | |
161 | |
162 if(twolame_set_in_samplerate(ctx->twolame_ctx, encoder->params.sample_rate) != 0) | |
163 return 0; | |
164 | |
165 if(twolame_set_out_samplerate(ctx->twolame_ctx, encoder->params.sample_rate) != 0) | |
166 return 0; | |
167 | |
168 if(encoder->params.sample_rate < 32000) | |
169 twolame_set_version(ctx->twolame_ctx, TWOLAME_MPEG2); | |
170 else | |
171 twolame_set_version(ctx->twolame_ctx, TWOLAME_MPEG1); | |
172 | |
173 if(twolame_set_psymodel(ctx->twolame_ctx, param_psy) != 0) | |
174 return 0; | |
175 | |
176 if(twolame_set_bitrate(ctx->twolame_ctx, param_bitrate) != 0) | |
177 return 0; | |
178 | |
179 if(param_errprot) | |
180 if(twolame_set_error_protection(ctx->twolame_ctx, TRUE) != 0) | |
181 return 0; | |
182 | |
183 if(param_vbr != 0) | |
184 { | |
185 if(twolame_set_VBR(ctx->twolame_ctx, TRUE) != 0) | |
186 return 0; | |
187 if(twolame_set_VBR_q(ctx->twolame_ctx, param_vbr) != 0) | |
188 return 0; | |
189 if(twolame_set_padding(ctx->twolame_ctx, FALSE) != 0) | |
190 return 0; | |
191 if(param_maxvbr) | |
192 { | |
193 if(twolame_set_VBR_max_bitrate_kbps(ctx->twolame_ctx, param_maxvbr) != 0) | |
194 return 0; | |
195 } | |
196 ctx->vbr = 1; | |
197 } | |
198 | |
199 if(twolame_set_verbosity(ctx->twolame_ctx, param_debug) != 0) | |
200 return 0; | |
201 | |
202 if(twolame_init_params(ctx->twolame_ctx) != 0) | |
203 return 0; | |
204 | |
205 encoder->params.bitrate = param_bitrate * 1000; | |
206 encoder->params.samples_per_frame = 1152; | |
207 encoder->priv = ctx; | |
208 encoder->decode_buffer_size = 1152 * 2 * encoder->params.channels; | |
209 | |
210 encoder->bind = bind_twolame; | |
211 encoder->get_frame_size = get_frame_size; | |
212 encoder->encode = encode_twolame; | |
213 encoder->close = close_twolame; | |
214 | |
215 return 1; | |
216 } | |
217 |