Mercurial > mplayer.hg
annotate libmpcodecs/ae_toolame.c @ 25376:382aeacc771f
The buffer used for pread need be aligned, but currently it got an offset 23
to the structure head. This will cause the pread always got random data
on some machines (such as my iMac G5 PPC with 10.5 os) so can not play vcd.
I also tried use DKIOCCDREAD ioctl call, but the result is same -- buffer need
be aligned. It could be a bug of os x or its dev lib.
Now fix this problem by move the buffer to a good aligned position in structure.
author | ulion |
---|---|
date | Sat, 15 Dec 2007 12:17:51 +0000 |
parents | ed8f90096c65 |
children | 0f1b5b68af32 |
rev | line source |
---|---|
15234 | 1 #include <stdio.h> |
2 #include <stdlib.h> | |
3 #include <inttypes.h> | |
15238 | 4 #include <unistd.h> |
15234 | 5 #include <string.h> |
15240 | 6 #include <sys/types.h> |
13425 | 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" |
13425 | 14 #include "ae_toolame.h" |
17012 | 15 #include "libmpdemux/mp3_hdr.h" |
13425 | 16 |
17 | |
18 static int | |
19 param_bitrate = 192, | |
20 param_psy = 3, | |
15265 | 21 param_maxvbr = 0, |
13425 | 22 param_errprot = 0, |
23 param_debug = 0; | |
24 | |
15362
4ff00aa141ef
updated psycho model range; made a parameter file-static in ae_toolame.c
nicodvb
parents:
15281
diff
changeset
|
25 static float param_vbr = 0; |
13425 | 26 static char *param_mode = "stereo"; |
27 | |
28 m_option_t toolameopts_conf[] = { | |
29 {"br", ¶m_bitrate, CONF_TYPE_INT, 0, 0, 0, NULL}, | |
30 {"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:
15281
diff
changeset
|
31 {"psy", ¶m_psy, CONF_TYPE_INT, CONF_RANGE, -1, 4, NULL}, |
15281 | 32 {"vbr", ¶m_vbr, CONF_TYPE_FLOAT, CONF_RANGE, -50, 50, NULL}, |
13425 | 33 {"maxvbr", ¶m_maxvbr, CONF_TYPE_INT, 0, 0, 0, NULL}, |
34 {"errprot", ¶m_errprot, CONF_TYPE_INT, CONF_RANGE, 0, 1, NULL}, | |
35 {"debug", ¶m_debug, CONF_TYPE_INT, CONF_RANGE, 0, 100000000, NULL}, | |
36 {NULL, NULL, 0, 0, 0, 0, NULL} | |
37 }; | |
38 | |
39 | |
15234 | 40 static int bind_toolame(audio_encoder_t *encoder, muxer_stream_t *mux_a) |
41 { | |
15265 | 42 mpae_toolame_ctx *ctx = (mpae_toolame_ctx *) encoder->priv; |
43 | |
15234 | 44 mux_a->wf = malloc(sizeof(WAVEFORMATEX)+256); |
45 mux_a->wf->wFormatTag = 0x50; | |
46 mux_a->wf->nChannels = encoder->params.channels; | |
47 mux_a->wf->nSamplesPerSec = encoder->params.sample_rate; | |
48 mux_a->wf->nAvgBytesPerSec = 125 * encoder->params.bitrate; | |
49 | |
15265 | 50 if(ctx->vbr || ((mux_a->wf->nAvgBytesPerSec * encoder->params.samples_per_frame) % mux_a->wf->nSamplesPerSec)) |
15234 | 51 { |
52 mux_a->h.dwScale = encoder->params.samples_per_frame; | |
53 mux_a->h.dwRate = encoder->params.sample_rate; | |
54 mux_a->h.dwSampleSize = 0; // Blocksize not constant | |
15265 | 55 } |
56 else | |
15234 | 57 { |
15265 | 58 mux_a->h.dwScale = (mux_a->wf->nAvgBytesPerSec * encoder->params.samples_per_frame)/ mux_a->wf->nSamplesPerSec; /* for cbr */ |
59 mux_a->h.dwRate = mux_a->wf->nAvgBytesPerSec; | |
15234 | 60 mux_a->h.dwSampleSize = mux_a->h.dwScale; |
61 } | |
62 mux_a->wf->nBlockAlign = mux_a->h.dwScale; | |
63 mux_a->h.dwSuggestedBufferSize = (encoder->params.audio_preload*mux_a->wf->nAvgBytesPerSec)/1000; | |
64 mux_a->h.dwSuggestedBufferSize -= mux_a->h.dwSuggestedBufferSize % mux_a->wf->nBlockAlign; | |
65 | |
15265 | 66 mux_a->wf->cbSize = 0; //12; |
15234 | 67 mux_a->wf->wBitsPerSample = 0; /* does not apply */ |
68 ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->wID = 1; | |
69 ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->fdwFlags = 2; | |
70 ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->nBlockSize = mux_a->wf->nBlockAlign; | |
71 ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->nFramesPerBlock = 1; | |
72 ((MPEGLAYER3WAVEFORMAT *) (mux_a->wf))->nCodecDelay = 0; | |
73 | |
74 // Fix allocation | |
75 mux_a->wf = realloc(mux_a->wf, sizeof(WAVEFORMATEX)+mux_a->wf->cbSize); | |
76 | |
77 encoder->input_format = AF_FORMAT_S16_NE; | |
78 encoder->min_buffer_size = mux_a->h.dwSuggestedBufferSize; | |
79 encoder->max_buffer_size = mux_a->h.dwSuggestedBufferSize*2; | |
80 | |
81 return 1; | |
82 } | |
83 | |
84 static int encode_toolame(audio_encoder_t *encoder, uint8_t *dest, void *src, int len, int max_size) | |
85 { | |
86 mpae_toolame_ctx *ctx = (mpae_toolame_ctx *)encoder->priv; | |
15265 | 87 int ret_size = 0, r2, i, nsamples; |
15234 | 88 int16_t *buffer; |
89 | |
90 nsamples = len / (2*encoder->params.channels); | |
91 buffer = (uint16_t *) src; | |
92 for(i = 0; i < nsamples; i++) | |
93 { | |
94 ctx->left_pcm[i] = buffer[ctx->channels * i]; | |
95 ctx->right_pcm[i] = buffer[(ctx->channels * i) + (ctx->channels - 1)]; | |
96 } | |
97 | |
98 toolame_encode_buffer(ctx->toolame_ctx, ctx->left_pcm, ctx->right_pcm, nsamples, dest, max_size, &ret_size); | |
15265 | 99 r2 = mp_decode_mp3_header(dest); |
16482 | 100 mp_msg(MSGT_MENCODER, MSGL_DBG2, "\nSIZE: %d, max: %d, r2: %d\n", ret_size, max_size, r2); |
15265 | 101 if(r2 > 0) |
102 ret_size = r2; | |
15234 | 103 return ret_size; |
104 } | |
105 | |
106 int close_toolame(audio_encoder_t *encoder) | |
107 { | |
108 free(encoder->priv); | |
109 return 1; | |
110 } | |
111 | |
112 static int get_frame_size(audio_encoder_t *encoder) | |
113 { | |
114 int sz; | |
115 if(encoder->stream->buffer_len < 4) | |
116 return 0; | |
117 sz = mp_decode_mp3_header(encoder->stream->buffer); | |
118 if(sz <= 0) | |
119 return 0; | |
120 return sz; | |
121 } | |
122 | |
123 | |
124 int mpae_init_toolame(audio_encoder_t *encoder) | |
13425 | 125 { |
126 int mode; | |
127 mpae_toolame_ctx *ctx = NULL; | |
128 | |
15234 | 129 if(encoder->params.channels == 1) |
13425 | 130 { |
131 mp_msg(MSGT_MENCODER, MSGL_INFO, "ae_toolame, 1 audio channel, forcing mono mode\n"); | |
132 mode = MPG_MD_MONO; | |
133 } | |
15234 | 134 else if(encoder->params.channels == 2) |
13425 | 135 { |
136 if(! strcasecmp(param_mode, "dual")) | |
137 mode = MPG_MD_DUAL_CHANNEL; | |
138 else if(! strcasecmp(param_mode, "jstereo")) | |
139 mode = MPG_MD_JOINT_STEREO; | |
140 else if(! strcasecmp(param_mode, "stereo")) | |
141 mode = MPG_MD_STEREO; | |
142 else | |
143 { | |
144 mp_msg(MSGT_MENCODER, MSGL_ERR, "ae_toolame, unknown mode %s, exiting\n", param_mode); | |
145 } | |
146 } | |
147 else | |
148 mp_msg(MSGT_MENCODER, MSGL_ERR, "ae_toolame, Toolame can't encode > 2 channels, exiting\n"); | |
149 | |
150 ctx = (mpae_toolame_ctx *) calloc(1, sizeof(mpae_toolame_ctx)); | |
151 if(ctx == NULL) | |
152 { | |
153 mp_msg(MSGT_MENCODER, MSGL_ERR, "ae_toolame, couldn't alloc a %d bytes context, exiting\n", sizeof(mpae_toolame_ctx)); | |
15234 | 154 return 0; |
13425 | 155 } |
156 | |
157 ctx->toolame_ctx = toolame_init(); | |
158 if(ctx->toolame_ctx == NULL) | |
159 { | |
160 mp_msg(MSGT_MENCODER, MSGL_ERR, "ae_toolame, couldn't initial parameters from libtoolame, exiting\n"); | |
161 free(ctx); | |
15234 | 162 return 0; |
13425 | 163 } |
15265 | 164 ctx->vbr = 0; |
15234 | 165 ctx->channels = encoder->params.channels; |
166 ctx->srate = encoder->params.sample_rate; | |
13425 | 167 |
168 if(toolame_setMode(ctx->toolame_ctx, mode) != 0) | |
15234 | 169 return 0; |
13425 | 170 |
171 if(toolame_setPsymodel(ctx->toolame_ctx, param_psy) != 0) | |
15234 | 172 return 0; |
13425 | 173 |
15234 | 174 if(toolame_setSampleFreq(ctx->toolame_ctx, encoder->params.sample_rate) != 0) |
175 return 0; | |
13425 | 176 |
177 if(toolame_setBitrate(ctx->toolame_ctx, param_bitrate) != 0) | |
15234 | 178 return 0; |
13425 | 179 |
180 if(param_errprot) | |
181 if(toolame_setErrorProtection(ctx->toolame_ctx, TRUE) != 0) | |
15234 | 182 return 0; |
13425 | 183 |
15281 | 184 if(param_vbr != 0) |
13425 | 185 { |
186 if(toolame_setVBR(ctx->toolame_ctx, TRUE) != 0) | |
15234 | 187 return 0; |
15265 | 188 if(toolame_setVBRLevel(ctx->toolame_ctx, param_vbr) != 0) |
15234 | 189 return 0; |
13425 | 190 if(toolame_setPadding(ctx->toolame_ctx, FALSE) != 0) |
15234 | 191 return 0; |
15265 | 192 if(param_maxvbr) |
193 { | |
194 if(toolame_setVBRUpperBitrate(ctx->toolame_ctx, param_maxvbr) != 0) | |
195 return 0; | |
196 } | |
197 ctx->vbr = 1; | |
13425 | 198 } |
199 | |
200 if(toolame_setVerbosity(ctx->toolame_ctx, param_debug) != 0) | |
15234 | 201 return 0; |
13425 | 202 |
203 if(toolame_init_params(ctx->toolame_ctx) != 0) | |
15234 | 204 return 0; |
13425 | 205 |
206 ctx->bitrate = param_bitrate; | |
15234 | 207 encoder->params.bitrate = ctx->bitrate; |
208 encoder->params.samples_per_frame = 1152; | |
209 encoder->priv = ctx; | |
210 encoder->decode_buffer_size = 1152 * 2 * encoder->params.channels; | |
13425 | 211 |
15234 | 212 encoder->bind = bind_toolame; |
213 encoder->get_frame_size = get_frame_size; | |
214 encoder->encode = encode_toolame; | |
215 encoder->close = close_toolame; | |
216 | |
217 return 1; | |
13425 | 218 } |
219 |