ad_mpeg123: support in-stream format changes

git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@36461 b3059339-0415-0410-9bf9-f77b7e298cf2

Fixes playback of http://mpg123.org/test/44and22.mp3

Cherry-picked from MPlayer SVN rev. #36461, a patch by
Thomas Orgis, committed by by Reimar Döffinger.
This commit is contained in:
Thomas Orgis 2013-10-04 17:22:22 +00:00 committed by wm4
parent 8304046180
commit 55883943c5
1 changed files with 88 additions and 61 deletions

View File

@ -1,7 +1,7 @@
/*
* MPEG 1.0/2.0/2.5 audio layer I, II, III decoding with libmpg123
*
* Copyright (C) 2010-2012 Thomas Orgis <thomas@orgis.org>
* Copyright (C) 2010-2013 Thomas Orgis <thomas@orgis.org>
*
* MPlayer is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -47,6 +47,7 @@
struct ad_mpg123_context {
mpg123_handle *handle;
char new_format;
#ifdef AD_MPG123_MEAN_BITRATE
/* Running mean for bit rate, stream length estimation. */
float mean_rate;
@ -95,7 +96,9 @@ static int preinit(sh_audio_t *sh)
* Let's try to run with the default for now. */
/* That would produce floating point output.
* You can get 32 and 24 bit ints, even 8 bit via format matrix. */
* You can get 32 and 24 bit ints, even 8 bit via format matrix.
* If wanting a specific encoding here, configure format matrix and
* make sure it is in set_format(). */
/* mpg123_param(con->handle, MPG123_ADD_FLAGS, MPG123_FORCE_FLOAT, 0.); */
/* Example for RVA choice (available since libmpg123 1.0.0):
@ -184,6 +187,59 @@ static void print_header_compact(struct mpg123_frameinfo *i)
smodes[i->mode]);
}
/* libmpg123 has a new format ready; query and store, return return value
of mpg123_getformat() */
static int set_format(sh_audio_t *sh, struct ad_mpg123_context *con)
{
int ret;
long rate;
int channels;
int encoding;
ret = mpg123_getformat(con->handle, &rate, &channels, &encoding);
if(ret == MPG123_OK) {
mp_chmap_from_channels(&sh->channels, channels);
sh->samplerate = rate;
/* Without external force, mpg123 will always choose signed encoding,
* and non-16-bit only on builds that don't support it.
* Be reminded that it doesn't matter to the MPEG file what encoding
* is produced from it. */
switch (encoding) {
case MPG123_ENC_SIGNED_8:
sh->sample_format = AF_FORMAT_S8;
sh->samplesize = 1;
break;
case MPG123_ENC_SIGNED_16:
sh->sample_format = AF_FORMAT_S16_NE;
sh->samplesize = 2;
break;
/* To stay compatible with the oldest libmpg123 headers, do not rely
* on float and 32 bit encoding symbols being defined.
* Those formats came later */
case 0x1180: /* MPG123_ENC_SIGNED_32 */
sh->sample_format = AF_FORMAT_S32_NE;
sh->samplesize = 4;
break;
case 0x200: /* MPG123_ENC_FLOAT_32 */
sh->sample_format = AF_FORMAT_FLOAT_NE;
sh->samplesize = 4;
break;
default:
/* This means we got a funny custom build of libmpg123 that only supports an unknown format. */
mp_msg(MSGT_DECAUDIO, MSGL_ERR,
"Bad encoding from mpg123: %i.\n", encoding);
return MPG123_ERR;
}
#ifdef AD_MPG123_FRAMEWISE
/* Going to decode directly to MPlayer's memory. It is important
* to have MPG123_AUTO_RESAMPLE disabled for the buffer size
* being an all-time limit. */
sh->audio_out_minsize = 1152 * 2 * sh->samplesize;
#endif
con->new_format = 0;
}
return ret;
}
/* This tries to extract a requested amount of decoded data.
* Even when you request 0 bytes, it will feed enough input so that
* the decoder _could_ have delivered something.
@ -213,6 +269,9 @@ static int decode_a_bit(sh_audio_t *sh, unsigned char *buf, int count)
* This will be handled in init(). */
do {
size_t got_now = 0;
/* Fetch new format now, after old data has been used. */
if(con->new_format)
ret = set_format(sh, con);
/* Feed the decoder. This will only fire from the second round on. */
if (ret == MPG123_NEED_MORE) {
@ -237,6 +296,15 @@ static int decode_a_bit(sh_audio_t *sh, unsigned char *buf, int count)
talloc_free(pkt);
if (ret == MPG123_ERR)
break;
/* Indication of format change is possible here (from mpg123_decode()). */
if(ret == MPG123_NEW_FORMAT) {
con->new_format = 1;
if(got)
break; /* Do not switch format during a chunk. */
ret = set_format(sh, con);
}
}
/* Theoretically, mpg123 could return MPG123_DONE, so be prepared.
* Should not happen in our usage, but it is a valid return code. */
@ -247,7 +315,7 @@ static int decode_a_bit(sh_audio_t *sh, unsigned char *buf, int count)
* for the loop condition. */
#ifdef AD_MPG123_FRAMEWISE
if (!buf) { /* fake call just for feeding to get format */
ret = mpg123_getformat(con->handle, NULL, NULL, NULL);
ret = set_format(sh, con);
} else { /* This is the decoding. One frame at a time. */
ret = mpg123_replace_buffer(con->handle, buf, count);
if (ret == MPG123_OK)
@ -261,6 +329,15 @@ static int decode_a_bit(sh_audio_t *sh, unsigned char *buf, int count)
got += got_now;
sh->pts_bytes += got_now;
/* Indication of format change should happen here. */
if(ret == MPG123_NEW_FORMAT) {
con->new_format = 1;
if(got)
break; /* Do not switch format during a chunk. */
ret = set_format(sh, con);
}
#ifdef AD_MPG123_FRAMEWISE
} while (ret == MPG123_NEED_MORE || (got == 0 && count != 0));
#else
@ -270,8 +347,6 @@ static int decode_a_bit(sh_audio_t *sh, unsigned char *buf, int count)
if (ret == MPG123_ERR) {
mp_msg(MSGT_DECAUDIO, MSGL_ERR, "mpg123 decoding failed: %s\n",
mpg123_strerror(con->handle));
mpg123_close(con->handle);
return -1;
}
return got;
@ -290,39 +365,29 @@ static int reopen_stream(sh_audio_t *sh)
/* Open and make sure we have fed enough data to get stream properties. */
if (MPG123_OK == mpg123_open_feed(con->handle) &&
/* Feed data until mpg123 is ready (has found stream beginning). */
!decode_a_bit(sh, NULL, 0)) {
!decode_a_bit(sh, NULL, 0) &&
set_format(sh, con) == MPG123_OK) { /* format setting again just for return value */
return 1;
} else {
mp_msg(MSGT_DECAUDIO, MSGL_ERR,
"mpg123 failed to reopen stream: %s\n",
mpg123_strerror(con->handle));
mpg123_close(con->handle);
return 0;
}
}
/* Now we really start accessing some data and determining file format.
* Paranoia note: The mpg123_close() on errors is not really necessary,
* But it ensures that we don't accidentally continue decoding with a
* bad state (possibly interpreting the format badly or whatnot). */
* Format now is allowed to change on-the-fly. Here is the only point
* that has MPlayer react to errors. We have to pray that exceptional
* erros in other places simply cannot occur. */
static int init(sh_audio_t *sh, const char *decoder)
{
long rate = 0;
int channels = 0;
int encoding = 0;
mpg123_id3v2 *v2;
struct mpg123_frameinfo finfo;
struct ad_mpg123_context *con = sh->context;
/* We're open about any output format that libmpg123 will suggest.
* Note that a standard build will always default to 16 bit signed and
* the native sample rate of the file. */
if (MPG123_OK == mpg123_format_all(con->handle) &&
reopen_stream(sh) &&
MPG123_OK == mpg123_getformat(con->handle, &rate, &channels, &encoding) &&
/* Forbid the format to change later on. */
MPG123_OK == mpg123_format_none(con->handle) &&
MPG123_OK == mpg123_format(con->handle, rate, channels, encoding) &&
con->new_format = 0;
if (reopen_stream(sh) &&
/* Get MPEG header info. */
MPG123_OK == mpg123_info(con->handle, &finfo) &&
/* Since we queried format, mpg123 should have read past ID3v2 tags.
@ -344,50 +409,11 @@ static int init(sh_audio_t *sh, const char *decoder)
con->mean_count = 0;
#endif
con->vbr = (finfo.vbr != MPG123_CBR);
mp_chmap_from_channels(&sh->channels, channels);
sh->samplerate = rate;
/* Without external force, mpg123 will always choose signed encoding,
* and non-16-bit only on builds that don't support it.
* Be reminded that it doesn't matter to the MPEG file what encoding
* is produced from it. */
switch (encoding) {
case MPG123_ENC_SIGNED_8:
sh->sample_format = AF_FORMAT_S8;
sh->samplesize = 1;
break;
case MPG123_ENC_SIGNED_16:
sh->sample_format = AF_FORMAT_S16_NE;
sh->samplesize = 2;
break;
/* To stay compatible with the oldest libmpg123 headers, do not rely
* on float and 32 bit encoding symbols being defined.
* Those formats came later */
case 0x1180: /* MPG123_ENC_SIGNED_32 */
sh->sample_format = AF_FORMAT_S32_NE;
sh->samplesize = 4;
break;
case 0x200: /* MPG123_ENC_FLOAT_32 */
sh->sample_format = AF_FORMAT_FLOAT_NE;
sh->samplesize = 4;
break;
default:
mp_msg(MSGT_DECAUDIO, MSGL_ERR,
"Bad encoding from mpg123: %i.\n", encoding);
mpg123_close(con->handle);
return 0;
}
#ifdef AD_MPG123_FRAMEWISE
/* Going to decode directly to MPlayer's memory. It is important
* to have MPG123_AUTO_RESAMPLE disabled for the buffer size
* being an all-time limit. */
sh->audio_out_minsize = 1152 * 2 * sh->samplesize;
#endif
return 1;
} else {
mp_msg(MSGT_DECAUDIO, MSGL_ERR, "mpg123 init error: %s\n",
mpg123_strerror(con->handle));
mpg123_close(con->handle);
return 0;
}
}
@ -432,6 +458,7 @@ static int decode_audio(sh_audio_t *sh, unsigned char *buf, int minlen,
int bytes;
bytes = decode_a_bit(sh, buf, maxlen);
/* This EOF is ignored, apparently, until input data is exhausted. */
if (bytes == 0)
return -1; /* EOF */