Mercurial > mplayer.hg
comparison libmpcodecs/ad_mpg123.c @ 36365:de83009f96bd
mpeg123: Support in-stream format changes.
Also fixes bugzilla #2149.
Patch by Thomas Orgis [thomas-forum orgis org].
author | reimar |
---|---|
date | Fri, 04 Oct 2013 17:22:22 +0000 |
parents | 079b53acda6d |
children | 85c8e2989c90 |
comparison
equal
deleted
inserted
replaced
36364:4f8cf378dba4 | 36365:de83009f96bd |
---|---|
1 /* | 1 /* |
2 * MPEG 1.0/2.0/2.5 audio layer I, II, III decoding with libmpg123 | 2 * MPEG 1.0/2.0/2.5 audio layer I, II, III decoding with libmpg123 |
3 * | 3 * |
4 * Copyright (C) 2010-2012 Thomas Orgis <thomas@orgis.org> | 4 * Copyright (C) 2010-2013 Thomas Orgis <thomas@orgis.org> |
5 * | 5 * |
6 * MPlayer is free software; you can redistribute it and/or modify | 6 * MPlayer is free software; you can redistribute it and/or modify |
7 * it under the terms of the GNU General Public License as published by | 7 * it under the terms of the GNU General Public License as published by |
8 * the Free Software Foundation; either version 2 of the License, or | 8 * the Free Software Foundation; either version 2 of the License, or |
9 * (at your option) any later version. | 9 * (at your option) any later version. |
57 /* Switch for updating bitrate info of VBR files. Not essential. */ | 57 /* Switch for updating bitrate info of VBR files. Not essential. */ |
58 #define AD_MPG123_MEAN_BITRATE | 58 #define AD_MPG123_MEAN_BITRATE |
59 | 59 |
60 struct ad_mpg123_context { | 60 struct ad_mpg123_context { |
61 mpg123_handle *handle; | 61 mpg123_handle *handle; |
62 char new_format; | |
62 #ifdef AD_MPG123_MEAN_BITRATE | 63 #ifdef AD_MPG123_MEAN_BITRATE |
63 /* Running mean for bit rate, stream length estimation. */ | 64 /* Running mean for bit rate, stream length estimation. */ |
64 float mean_rate; | 65 float mean_rate; |
65 unsigned int mean_count; | 66 unsigned int mean_count; |
66 /* Time delay for updates. */ | 67 /* Time delay for updates. */ |
114 * gapless decoding (won't work with seeking in MPlayer, though). | 115 * gapless decoding (won't work with seeking in MPlayer, though). |
115 * Don't forget to eventually enable ReplayGain/RVA support, too. | 116 * Don't forget to eventually enable ReplayGain/RVA support, too. |
116 * Let's try to run with the default for now. */ | 117 * Let's try to run with the default for now. */ |
117 | 118 |
118 /* That would produce floating point output. | 119 /* That would produce floating point output. |
119 * You can get 32 and 24 bit ints, even 8 bit via format matrix. */ | 120 * You can get 32 and 24 bit ints, even 8 bit via format matrix. |
121 * If wanting a specific encoding here, configure format matrix and | |
122 * make sure it is in set_format(). */ | |
120 /* mpg123_param(con->handle, MPG123_ADD_FLAGS, MPG123_FORCE_FLOAT, 0.); */ | 123 /* mpg123_param(con->handle, MPG123_ADD_FLAGS, MPG123_FORCE_FLOAT, 0.); */ |
121 | 124 |
122 /* Example for RVA choice (available since libmpg123 1.0.0): | 125 /* Example for RVA choice (available since libmpg123 1.0.0): |
123 mpg123_param(con->handle, MPG123_RVA, MPG123_RVA_MIX, 0.0) */ | 126 mpg123_param(con->handle, MPG123_RVA, MPG123_RVA_MIX, 0.0) */ |
124 | 127 |
203 } | 206 } |
204 mp_msg(MSGT_DECAUDIO, MSGL_V, ", %ld Hz %s\n", i->rate, | 207 mp_msg(MSGT_DECAUDIO, MSGL_V, ", %ld Hz %s\n", i->rate, |
205 smodes[i->mode]); | 208 smodes[i->mode]); |
206 } | 209 } |
207 | 210 |
208 /* This tries to extract a requested amount of decoded data. | 211 /* libmpg123 has a new format ready; query and store, return return value |
209 * Even when you request 0 bytes, it will feed enough input so that | 212 of mpg123_getformat() */ |
210 * the decoder _could_ have delivered something. | 213 static int set_format(sh_audio_t *sh, struct ad_mpg123_context *con) |
211 * Returns byte count >= 0, -1 on error. | 214 { |
212 * | 215 int ret; |
213 * Thoughts on exact pts keeping: | 216 long rate; |
214 * We have to assume that MPEG frames are cut in pieces by packet boundaries. | 217 int channels; |
215 * Also, it might be possible that the first packet does not contain enough | 218 int encoding; |
216 * data to ensure initial stream sync... or re-sync on erroneous streams. | 219 ret = mpg123_getformat(con->handle, &rate, &channels, &encoding); |
217 * So we need something robust to relate the decoded byte count to the correct | 220 if(ret == MPG123_OK) { |
218 * time stamp. This is tricky, though. From the outside, you cannot tell if, | |
219 * after having fed two packets until the first output arrives, one should | |
220 * start counting from the first packet's pts or the second packet's. | |
221 * So, let's just count from the last fed package's pts. If the packets are | |
222 * exactly cut to MPEG frames, this will cause one frame mismatch in the | |
223 * beginning (when mpg123 peeks ahead for the following header), but will | |
224 * be corrected with the third frame already. One might add special code to | |
225 * not increment the base pts past the first packet's after a resync before | |
226 * the first decoded bytes arrived. */ | |
227 static int decode_a_bit(sh_audio_t *sh, unsigned char *buf, int count) | |
228 { | |
229 int ret = MPG123_OK; | |
230 int got = 0; | |
231 struct ad_mpg123_context *con = sh->context; | |
232 | |
233 /* There will be one MPG123_NEW_FORMAT message on first open. | |
234 * This will be handled in init(). */ | |
235 do { | |
236 size_t got_now = 0; | |
237 | |
238 /* Feed the decoder. This will only fire from the second round on. */ | |
239 if (ret == MPG123_NEED_MORE) { | |
240 int incount; | |
241 double pts; | |
242 unsigned char *inbuf; | |
243 /* Feed more input data. */ | |
244 incount = ds_get_packet_pts(sh->ds, &inbuf, &pts); | |
245 if (incount <= 0) | |
246 break; /* Apparently that's it. EOF. */ | |
247 | |
248 /* Next bytes from that presentation time. */ | |
249 if (pts != MP_NOPTS_VALUE) { | |
250 sh->pts = pts; | |
251 sh->pts_bytes = 0; | |
252 } | |
253 | |
254 #ifdef AD_MPG123_FRAMEWISE | |
255 /* Have to use mpg123_feed() to avoid decoding here. */ | |
256 ret = mpg123_feed(con->handle, inbuf, incount); | |
257 #else | |
258 /* Do not use mpg123_feed(), added in later libmpg123 versions. */ | |
259 ret = mpg123_decode(con->handle, inbuf, incount, NULL, 0, NULL); | |
260 #endif | |
261 if (ret == MPG123_ERR) | |
262 break; | |
263 } | |
264 /* Theoretically, mpg123 could return MPG123_DONE, so be prepared. | |
265 * Should not happen in our usage, but it is a valid return code. */ | |
266 else if (ret == MPG123_ERR || ret == MPG123_DONE) | |
267 break; | |
268 | |
269 /* Try to decode a bit. This is the return value that counts | |
270 * for the loop condition. */ | |
271 #ifdef AD_MPG123_FRAMEWISE | |
272 if (!buf) { /* fake call just for feeding to get format */ | |
273 ret = mpg123_getformat(con->handle, NULL, NULL, NULL); | |
274 } else { /* This is the decoding. One frame at a time. */ | |
275 ret = mpg123_replace_buffer(con->handle, buf, count); | |
276 if (ret == MPG123_OK) | |
277 ret = mpg123_decode_frame(con->handle, NULL, NULL, &got_now); | |
278 } | |
279 #else | |
280 ret = mpg123_decode(con->handle, NULL, 0, buf + got, count - got, | |
281 &got_now); | |
282 #endif | |
283 | |
284 got += got_now; | |
285 sh->pts_bytes += got_now; | |
286 | |
287 #ifdef AD_MPG123_FRAMEWISE | |
288 } while (ret == MPG123_NEED_MORE || (got == 0 && count != 0)); | |
289 #else | |
290 } while (ret == MPG123_NEED_MORE || got < count); | |
291 #endif | |
292 | |
293 if (ret == MPG123_ERR) { | |
294 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "mpg123 decoding failed: %s\n", | |
295 mpg123_strerror(con->handle)); | |
296 mpg123_close(con->handle); | |
297 return -1; | |
298 } | |
299 | |
300 return got; | |
301 } | |
302 | |
303 /* Close, reopen stream. Feed data until we know the format of the stream. | |
304 * 1 on success, 0 on error */ | |
305 static int reopen_stream(sh_audio_t *sh) | |
306 { | |
307 struct ad_mpg123_context *con = (struct ad_mpg123_context*) sh->context; | |
308 | |
309 mpg123_close(con->handle); | |
310 /* No resetting of the context: | |
311 * We do not want to loose the mean bitrate data. */ | |
312 | |
313 /* Open and make sure we have fed enough data to get stream properties. */ | |
314 if (MPG123_OK == mpg123_open_feed(con->handle) && | |
315 /* Feed data until mpg123 is ready (has found stream beginning). */ | |
316 !decode_a_bit(sh, NULL, 0)) { | |
317 return 1; | |
318 } else { | |
319 mp_msg(MSGT_DECAUDIO, MSGL_ERR, | |
320 "mpg123 failed to reopen stream: %s\n", | |
321 mpg123_strerror(con->handle)); | |
322 mpg123_close(con->handle); | |
323 return 0; | |
324 } | |
325 } | |
326 | |
327 /* Now we really start accessing some data and determining file format. | |
328 * Paranoia note: The mpg123_close() on errors is not really necessary, | |
329 * But it ensures that we don't accidentally continue decoding with a | |
330 * bad state (possibly interpreting the format badly or whatnot). */ | |
331 static int init(sh_audio_t *sh) | |
332 { | |
333 long rate = 0; | |
334 int channels = 0; | |
335 int encoding = 0; | |
336 mpg123_id3v2 *v2; | |
337 struct mpg123_frameinfo finfo; | |
338 struct ad_mpg123_context *con = sh->context; | |
339 | |
340 /* We're open about any output format that libmpg123 will suggest. | |
341 * Note that a standard build will always default to 16 bit signed and | |
342 * the native sample rate of the file. */ | |
343 if (MPG123_OK == mpg123_format_all(con->handle) && | |
344 reopen_stream(sh) && | |
345 MPG123_OK == mpg123_getformat(con->handle, &rate, &channels, &encoding) && | |
346 /* Forbid the format to change later on. */ | |
347 MPG123_OK == mpg123_format_none(con->handle) && | |
348 MPG123_OK == mpg123_format(con->handle, rate, channels, encoding) && | |
349 /* Get MPEG header info. */ | |
350 MPG123_OK == mpg123_info(con->handle, &finfo) && | |
351 /* Since we queried format, mpg123 should have read past ID3v2 tags. | |
352 * We need to decide if printing of UTF-8 encoded text info is wanted. */ | |
353 MPG123_OK == mpg123_id3(con->handle, NULL, &v2)) { | |
354 /* If we are here, we passed all hurdles. Yay! Extract the info. */ | |
355 print_header_compact(&finfo); | |
356 /* Do we want to print out the UTF-8 Id3v2 info? | |
357 if (v2) | |
358 print_id3v2(v2); */ | |
359 | |
360 /* Have kb/s, want B/s | |
361 * For VBR, the first frame will be a bad estimate. */ | |
362 sh->i_bps = (finfo.bitrate ? finfo.bitrate : compute_bitrate(&finfo)) | |
363 * 1000 / 8; | |
364 #ifdef AD_MPG123_MEAN_BITRATE | |
365 con->delay = 1; | |
366 con->mean_rate = 0.; | |
367 con->mean_count = 0; | |
368 #endif | |
369 con->vbr = (finfo.vbr != MPG123_CBR); | |
370 sh->channels = channels; | 221 sh->channels = channels; |
371 sh->samplerate = rate; | 222 sh->samplerate = rate; |
372 /* Without external force, mpg123 will always choose signed encoding, | 223 /* Without external force, mpg123 will always choose signed encoding, |
373 * and non-16-bit only on builds that don't support it. | 224 * and non-16-bit only on builds that don't support it. |
374 * Be reminded that it doesn't matter to the MPEG file what encoding | 225 * Be reminded that it doesn't matter to the MPEG file what encoding |
392 case 0x200: /* MPG123_ENC_FLOAT_32 */ | 243 case 0x200: /* MPG123_ENC_FLOAT_32 */ |
393 sh->sample_format = AF_FORMAT_FLOAT_NE; | 244 sh->sample_format = AF_FORMAT_FLOAT_NE; |
394 sh->samplesize = 4; | 245 sh->samplesize = 4; |
395 break; | 246 break; |
396 default: | 247 default: |
248 /* This means we got a funny custom build of libmpg123 that only supports an unknown format. */ | |
397 mp_msg(MSGT_DECAUDIO, MSGL_ERR, | 249 mp_msg(MSGT_DECAUDIO, MSGL_ERR, |
398 "Bad encoding from mpg123: %i.\n", encoding); | 250 "Bad encoding from mpg123: %i.\n", encoding); |
399 mpg123_close(con->handle); | 251 return MPG123_ERR; |
400 return 0; | |
401 } | 252 } |
402 #ifdef AD_MPG123_FRAMEWISE | 253 #ifdef AD_MPG123_FRAMEWISE |
403 /* Going to decode directly to MPlayer's memory. It is important | 254 /* Going to decode directly to MPlayer's memory. It is important |
404 * to have MPG123_AUTO_RESAMPLE disabled for the buffer size | 255 * to have MPG123_AUTO_RESAMPLE disabled for the buffer size |
405 * being an all-time limit. */ | 256 * being an all-time limit. */ |
406 sh->audio_out_minsize = 1152 * 2 * sh->samplesize; | 257 sh->audio_out_minsize = 1152 * 2 * sh->samplesize; |
407 #endif | 258 #endif |
259 con->new_format = 0; | |
260 } | |
261 return ret; | |
262 } | |
263 | |
264 /* This tries to extract a requested amount of decoded data. | |
265 * Even when you request 0 bytes, it will feed enough input so that | |
266 * the decoder _could_ have delivered something. | |
267 * Returns byte count >= 0, -1 on error. | |
268 * | |
269 * Thoughts on exact pts keeping: | |
270 * We have to assume that MPEG frames are cut in pieces by packet boundaries. | |
271 * Also, it might be possible that the first packet does not contain enough | |
272 * data to ensure initial stream sync... or re-sync on erroneous streams. | |
273 * So we need something robust to relate the decoded byte count to the correct | |
274 * time stamp. This is tricky, though. From the outside, you cannot tell if, | |
275 * after having fed two packets until the first output arrives, one should | |
276 * start counting from the first packet's pts or the second packet's. | |
277 * So, let's just count from the last fed package's pts. If the packets are | |
278 * exactly cut to MPEG frames, this will cause one frame mismatch in the | |
279 * beginning (when mpg123 peeks ahead for the following header), but will | |
280 * be corrected with the third frame already. One might add special code to | |
281 * not increment the base pts past the first packet's after a resync before | |
282 * the first decoded bytes arrived. */ | |
283 static int decode_a_bit(sh_audio_t *sh, unsigned char *buf, int count) | |
284 { | |
285 int ret = MPG123_OK; | |
286 int got = 0; | |
287 struct ad_mpg123_context *con = sh->context; | |
288 | |
289 /* There will be one MPG123_NEW_FORMAT message on first open. | |
290 * This will be handled in init(). */ | |
291 do { | |
292 size_t got_now = 0; | |
293 /* Fetch new format now, after old data has been used. */ | |
294 if(con->new_format) | |
295 ret = set_format(sh, con); | |
296 | |
297 /* Feed the decoder. This will only fire from the second round on. */ | |
298 if (ret == MPG123_NEED_MORE) { | |
299 int incount; | |
300 double pts; | |
301 unsigned char *inbuf; | |
302 /* Feed more input data. */ | |
303 incount = ds_get_packet_pts(sh->ds, &inbuf, &pts); | |
304 if (incount <= 0) | |
305 break; /* Apparently that's it. EOF. */ | |
306 | |
307 /* Next bytes from that presentation time. */ | |
308 if (pts != MP_NOPTS_VALUE) { | |
309 sh->pts = pts; | |
310 sh->pts_bytes = 0; | |
311 } | |
312 | |
313 #ifdef AD_MPG123_FRAMEWISE | |
314 /* Have to use mpg123_feed() to avoid decoding here. */ | |
315 ret = mpg123_feed(con->handle, inbuf, incount); | |
316 #else | |
317 /* Do not use mpg123_feed(), added in later libmpg123 versions. */ | |
318 ret = mpg123_decode(con->handle, inbuf, incount, NULL, 0, NULL); | |
319 #endif | |
320 if (ret == MPG123_ERR) | |
321 break; | |
322 | |
323 /* Indication of format change is possible here (from mpg123_decode()). */ | |
324 if(ret == MPG123_NEW_FORMAT) { | |
325 con->new_format = 1; | |
326 if(got) | |
327 break; /* Do not switch format during a chunk. */ | |
328 | |
329 ret = set_format(sh, con); | |
330 } | |
331 } | |
332 /* Theoretically, mpg123 could return MPG123_DONE, so be prepared. | |
333 * Should not happen in our usage, but it is a valid return code. */ | |
334 else if (ret == MPG123_ERR || ret == MPG123_DONE) | |
335 break; | |
336 | |
337 /* Try to decode a bit. This is the return value that counts | |
338 * for the loop condition. */ | |
339 #ifdef AD_MPG123_FRAMEWISE | |
340 if (!buf) { /* fake call just for feeding to get format */ | |
341 ret = set_format(sh, con); | |
342 } else { /* This is the decoding. One frame at a time. */ | |
343 ret = mpg123_replace_buffer(con->handle, buf, count); | |
344 if (ret == MPG123_OK) | |
345 ret = mpg123_decode_frame(con->handle, NULL, NULL, &got_now); | |
346 } | |
347 #else | |
348 ret = mpg123_decode(con->handle, NULL, 0, buf + got, count - got, | |
349 &got_now); | |
350 #endif | |
351 | |
352 got += got_now; | |
353 sh->pts_bytes += got_now; | |
354 | |
355 /* Indication of format change should happen here. */ | |
356 if(ret == MPG123_NEW_FORMAT) { | |
357 con->new_format = 1; | |
358 if(got) | |
359 break; /* Do not switch format during a chunk. */ | |
360 | |
361 ret = set_format(sh, con); | |
362 } | |
363 | |
364 #ifdef AD_MPG123_FRAMEWISE | |
365 } while (ret == MPG123_NEED_MORE || (got == 0 && count != 0)); | |
366 #else | |
367 } while (ret == MPG123_NEED_MORE || got < count); | |
368 #endif | |
369 | |
370 if (ret == MPG123_ERR) { | |
371 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "mpg123 decoding failed: %s\n", | |
372 mpg123_strerror(con->handle)); | |
373 } | |
374 | |
375 return got; | |
376 } | |
377 | |
378 /* Close, reopen stream. Feed data until we know the format of the stream. | |
379 * 1 on success, 0 on error */ | |
380 static int reopen_stream(sh_audio_t *sh) | |
381 { | |
382 struct ad_mpg123_context *con = (struct ad_mpg123_context*) sh->context; | |
383 | |
384 mpg123_close(con->handle); | |
385 /* No resetting of the context: | |
386 * We do not want to loose the mean bitrate data. */ | |
387 | |
388 /* Open and make sure we have fed enough data to get stream properties. */ | |
389 if (MPG123_OK == mpg123_open_feed(con->handle) && | |
390 /* Feed data until mpg123 is ready (has found stream beginning). */ | |
391 !decode_a_bit(sh, NULL, 0) && | |
392 set_format(sh, con) == MPG123_OK) { /* format setting again just for return value */ | |
393 return 1; | |
394 } else { | |
395 mp_msg(MSGT_DECAUDIO, MSGL_ERR, | |
396 "mpg123 failed to reopen stream: %s\n", | |
397 mpg123_strerror(con->handle)); | |
398 return 0; | |
399 } | |
400 } | |
401 | |
402 /* Now we really start accessing some data and determining file format. | |
403 * Format now is allowed to change on-the-fly. Here is the only point | |
404 * that has MPlayer react to errors. We have to pray that exceptional | |
405 * erros in other places simply cannot occur. */ | |
406 static int init(sh_audio_t *sh) | |
407 { | |
408 mpg123_id3v2 *v2; | |
409 struct mpg123_frameinfo finfo; | |
410 struct ad_mpg123_context *con = sh->context; | |
411 | |
412 con->new_format = 0; | |
413 if (reopen_stream(sh) && | |
414 /* Get MPEG header info. */ | |
415 MPG123_OK == mpg123_info(con->handle, &finfo) && | |
416 /* Since we queried format, mpg123 should have read past ID3v2 tags. | |
417 * We need to decide if printing of UTF-8 encoded text info is wanted. */ | |
418 MPG123_OK == mpg123_id3(con->handle, NULL, &v2)) { | |
419 /* If we are here, we passed all hurdles. Yay! Extract the info. */ | |
420 print_header_compact(&finfo); | |
421 /* Do we want to print out the UTF-8 Id3v2 info? | |
422 if (v2) | |
423 print_id3v2(v2); */ | |
424 | |
425 /* Have kb/s, want B/s | |
426 * For VBR, the first frame will be a bad estimate. */ | |
427 sh->i_bps = (finfo.bitrate ? finfo.bitrate : compute_bitrate(&finfo)) | |
428 * 1000 / 8; | |
429 #ifdef AD_MPG123_MEAN_BITRATE | |
430 con->delay = 1; | |
431 con->mean_rate = 0.; | |
432 con->mean_count = 0; | |
433 #endif | |
434 con->vbr = (finfo.vbr != MPG123_CBR); | |
408 | 435 |
409 return 1; | 436 return 1; |
410 } else { | 437 } else { |
411 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "mpg123 init error: %s\n", | 438 mp_msg(MSGT_DECAUDIO, MSGL_ERR, "mpg123 init error: %s\n", |
412 mpg123_strerror(con->handle)); | 439 mpg123_strerror(con->handle)); |
413 mpg123_close(con->handle); | |
414 return 0; | 440 return 0; |
415 } | 441 } |
416 } | 442 } |
417 | 443 |
418 static void uninit(sh_audio_t *sh) | 444 static void uninit(sh_audio_t *sh) |
453 int maxlen) | 479 int maxlen) |
454 { | 480 { |
455 int bytes; | 481 int bytes; |
456 | 482 |
457 bytes = decode_a_bit(sh, buf, maxlen); | 483 bytes = decode_a_bit(sh, buf, maxlen); |
484 /* This EOF is ignored, apparently, until input data is exhausted. */ | |
458 if (bytes == 0) | 485 if (bytes == 0) |
459 return -1; /* EOF */ | 486 return -1; /* EOF */ |
460 | 487 |
461 #ifdef AD_MPG123_MEAN_BITRATE | 488 #ifdef AD_MPG123_MEAN_BITRATE |
462 update_info(sh); | 489 update_info(sh); |