Mercurial > mplayer.hg
annotate libmpcodecs/ae_twolame.c @ 25210:92204ff32b27
When IFO file is opened (detected by extension), set dvd-device to IFO file's
directory and start dvd:// stream instead of file://.
If VTS_<N>_*.IFO is opened, open stream as dvd://<N>
As Nico Sabbi said:
There is no no guarantie that title N is in titleset N,
but there are at least good chances.
The main purpose of this patch is ability to load DVDs, stored on HDD,
using OSD menu.
Modified patch from Benjamin Zores ben at geexbox dot org
author | voroshil |
---|---|
date | Sun, 02 Dec 2007 13:13:02 +0000 |
parents | ed8f90096c65 |
children | 39d9ff988bc0 |
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" |
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" |
15359 | 14 #include "ae_twolame.h" |
17012 | 15 #include "libmpdemux/mp3_hdr.h" |
15359 | 16 |
17 | |
18 static int | |
19 param_bitrate = 192, | |
20 param_psy = 3, | |
21 param_maxvbr = 0, | |
22 param_errprot = 0, | |
23 param_debug = 0; | |
24 | |
25 static float param_vbr = 0; | |
26 static char *param_mode = "stereo"; | |
27 | |
28 m_option_t twolameopts_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:
15359
diff
changeset
|
31 {"psy", ¶m_psy, CONF_TYPE_INT, CONF_RANGE, -1, 4, NULL}, |
15359 | 32 {"vbr", ¶m_vbr, CONF_TYPE_FLOAT, CONF_RANGE, -50, 50, NULL}, |
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 | |
40 static int bind_twolame(audio_encoder_t *encoder, muxer_stream_t *mux_a) | |
41 { | |
42 mpae_twolame_ctx *ctx = (mpae_twolame_ctx *) encoder->priv; | |
43 | |
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 = encoder->params.bitrate / 8; | |
49 | |
50 if(ctx->vbr || ((mux_a->wf->nAvgBytesPerSec * encoder->params.samples_per_frame) % mux_a->wf->nSamplesPerSec)) | |
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 | |
55 } | |
56 else | |
57 { | |
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; | |
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 | |
66 mux_a->wf->cbSize = 0; //12; | |
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_twolame(audio_encoder_t *encoder, uint8_t *dest, void *src, int len, int max_size) | |
85 { | |
86 mpae_twolame_ctx *ctx = (mpae_twolame_ctx *)encoder->priv; | |
87 int ret_size = 0, r2; | |
88 | |
89 len /= (2*encoder->params.channels); | |
90 ret_size = twolame_encode_buffer_interleaved(ctx->twolame_ctx, src, len, dest, max_size); | |
91 r2 = mp_decode_mp3_header(dest); | |
16482 | 92 mp_msg(MSGT_MENCODER, MSGL_DBG2, "\nSIZE: %d, max: %d, r2: %d\n", ret_size, max_size, r2); |
15359 | 93 if(r2 > 0) |
94 ret_size = r2; | |
95 return ret_size; | |
96 } | |
97 | |
98 int close_twolame(audio_encoder_t *encoder) | |
99 { | |
100 free(encoder->priv); | |
101 return 1; | |
102 } | |
103 | |
104 static int get_frame_size(audio_encoder_t *encoder) | |
105 { | |
106 int sz; | |
107 if(encoder->stream->buffer_len < 4) | |
108 return 0; | |
109 sz = mp_decode_mp3_header(encoder->stream->buffer); | |
110 if(sz <= 0) | |
111 return 0; | |
112 return sz; | |
113 } | |
114 | |
115 | |
116 int mpae_init_twolame(audio_encoder_t *encoder) | |
117 { | |
118 int mode; | |
119 mpae_twolame_ctx *ctx = NULL; | |
120 | |
121 if(encoder->params.channels == 1) | |
122 { | |
123 mp_msg(MSGT_MENCODER, MSGL_INFO, "ae_twolame, 1 audio channel, forcing mono mode\n"); | |
124 mode = TWOLAME_MONO; | |
125 } | |
126 else if(encoder->params.channels == 2) | |
127 { | |
128 if(! strcasecmp(param_mode, "dual")) | |
129 mode = TWOLAME_DUAL_CHANNEL; | |
130 else if(! strcasecmp(param_mode, "jstereo")) | |
131 mode = TWOLAME_JOINT_STEREO; | |
132 else if(! strcasecmp(param_mode, "stereo")) | |
133 mode = TWOLAME_STEREO; | |
134 else | |
135 { | |
136 mp_msg(MSGT_MENCODER, MSGL_ERR, "ae_twolame, unknown mode %s, exiting\n", param_mode); | |
137 } | |
138 } | |
139 else | |
140 mp_msg(MSGT_MENCODER, MSGL_ERR, "ae_twolame, Twolame can't encode > 2 channels, exiting\n"); | |
141 | |
142 ctx = (mpae_twolame_ctx *) calloc(1, sizeof(mpae_twolame_ctx)); | |
143 if(ctx == NULL) | |
144 { | |
145 mp_msg(MSGT_MENCODER, MSGL_ERR, "ae_twolame, couldn't alloc a %d bytes context, exiting\n", sizeof(mpae_twolame_ctx)); | |
146 return 0; | |
147 } | |
148 | |
149 ctx->twolame_ctx = twolame_init(); | |
150 if(ctx->twolame_ctx == NULL) | |
151 { | |
152 mp_msg(MSGT_MENCODER, MSGL_ERR, "ae_twolame, couldn't initial parameters from libtwolame, exiting\n"); | |
153 free(ctx); | |
154 return 0; | |
155 } | |
156 ctx->vbr = 0; | |
157 | |
158 if(twolame_set_num_channels(ctx->twolame_ctx, encoder->params.channels) != 0) | |
159 return 0; | |
160 if(twolame_set_mode(ctx->twolame_ctx, mode) != 0) | |
161 return 0; | |
162 | |
163 if(twolame_set_in_samplerate(ctx->twolame_ctx, encoder->params.sample_rate) != 0) | |
164 return 0; | |
165 | |
166 if(twolame_set_out_samplerate(ctx->twolame_ctx, encoder->params.sample_rate) != 0) | |
167 return 0; | |
168 | |
169 if(encoder->params.sample_rate < 32000) | |
170 twolame_set_version(ctx->twolame_ctx, TWOLAME_MPEG2); | |
171 else | |
172 twolame_set_version(ctx->twolame_ctx, TWOLAME_MPEG1); | |
173 | |
174 if(twolame_set_psymodel(ctx->twolame_ctx, param_psy) != 0) | |
175 return 0; | |
176 | |
177 if(twolame_set_bitrate(ctx->twolame_ctx, param_bitrate) != 0) | |
178 return 0; | |
179 | |
180 if(param_errprot) | |
181 if(twolame_set_error_protection(ctx->twolame_ctx, TRUE) != 0) | |
182 return 0; | |
183 | |
184 if(param_vbr != 0) | |
185 { | |
186 if(twolame_set_VBR(ctx->twolame_ctx, TRUE) != 0) | |
187 return 0; | |
188 if(twolame_set_VBR_q(ctx->twolame_ctx, param_vbr) != 0) | |
189 return 0; | |
190 if(twolame_set_padding(ctx->twolame_ctx, FALSE) != 0) | |
191 return 0; | |
192 if(param_maxvbr) | |
193 { | |
194 if(twolame_set_VBR_max_bitrate_kbps(ctx->twolame_ctx, param_maxvbr) != 0) | |
195 return 0; | |
196 } | |
197 ctx->vbr = 1; | |
198 } | |
199 | |
200 if(twolame_set_verbosity(ctx->twolame_ctx, param_debug) != 0) | |
201 return 0; | |
202 | |
203 if(twolame_init_params(ctx->twolame_ctx) != 0) | |
204 return 0; | |
205 | |
206 encoder->params.bitrate = param_bitrate * 1000; | |
207 encoder->params.samples_per_frame = 1152; | |
208 encoder->priv = ctx; | |
209 encoder->decode_buffer_size = 1152 * 2 * encoder->params.channels; | |
210 | |
211 encoder->bind = bind_twolame; | |
212 encoder->get_frame_size = get_frame_size; | |
213 encoder->encode = encode_twolame; | |
214 encoder->close = close_twolame; | |
215 | |
216 return 1; | |
217 } | |
218 |