summaryrefslogtreecommitdiffstats
path: root/audio/decode/ad_mpg123.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-11-23 21:22:17 +0100
committerwm4 <wm4@nowhere>2013-11-23 21:22:17 +0100
commit0f5ec05d8f4ae02262dc79a895bce3b465b376f2 (patch)
treeba5fc3f640eeefa44a28695f8cd3f63ba2eec2c9 /audio/decode/ad_mpg123.c
parent705a7310e6c823a72c961720f8ae416962f1398a (diff)
downloadmpv-0f5ec05d8f4ae02262dc79a895bce3b465b376f2.tar.bz2
mpv-0f5ec05d8f4ae02262dc79a895bce3b465b376f2.tar.xz
audio: move decoder context from sh_audio into new struct
Move all state that basically changes during decoding or is needed in order to manage decoding itself into a new struct (dec_audio). sh_audio (defined in stheader.h) is supposed to be the audio stream header. This should reflect the file headers for the stream. Putting the decoder context there is strange design, to say the least.
Diffstat (limited to 'audio/decode/ad_mpg123.c')
-rw-r--r--audio/decode/ad_mpg123.c110
1 files changed, 54 insertions, 56 deletions
diff --git a/audio/decode/ad_mpg123.c b/audio/decode/ad_mpg123.c
index 8ea06dd5ab..1abda4e084 100644
--- a/audio/decode/ad_mpg123.c
+++ b/audio/decode/ad_mpg123.c
@@ -47,20 +47,18 @@ struct ad_mpg123_context {
char vbr;
};
-static void uninit(sh_audio_t *sh)
+static void uninit(struct dec_audio *da)
{
- struct ad_mpg123_context *con = (struct ad_mpg123_context*) sh->context;
+ struct ad_mpg123_context *con = da->priv;
mpg123_close(con->handle);
mpg123_delete(con->handle);
- talloc_free(sh->context);
- sh->context = NULL;
mpg123_exit();
}
/* This initializes libmpg123 and prepares the handle, including funky
* parameters. */
-static int preinit(sh_audio_t *sh)
+static int preinit(struct dec_audio *da)
{
int err;
struct ad_mpg123_context *con;
@@ -71,8 +69,8 @@ static int preinit(sh_audio_t *sh)
if (mpg123_init() != MPG123_OK)
return 0;
- sh->context = talloc_zero(NULL, struct ad_mpg123_context);
- con = sh->context;
+ da->priv = talloc_zero(NULL, struct ad_mpg123_context);
+ con = da->priv;
/* Auto-choice of optimized decoder (first argument NULL). */
con->handle = mpg123_new(NULL, &err);
if (!con->handle)
@@ -123,65 +121,65 @@ static int preinit(sh_audio_t *sh)
mp_msg(MSGT_DECAUDIO, MSGL_ERR, "mpg123 preinit error: %s\n",
mpg123_strerror(con->handle));
- uninit(sh);
+ uninit(da);
+ return 0;
+}
+
+static int mpg123_format_to_af(int mpg123_encoding)
+{
+ /* 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 (mpg123_encoding) {
+ case MPG123_ENC_SIGNED_8: return AF_FORMAT_S8;
+ case MPG123_ENC_SIGNED_16: return AF_FORMAT_S16;
+ case MPG123_ENC_SIGNED_32: return AF_FORMAT_S32;
+ case MPG123_ENC_FLOAT_32: return AF_FORMAT_FLOAT;
+ }
return 0;
}
/* libmpg123 has a new format ready; query and store, return return value
of mpg123_getformat() */
-static int set_format(sh_audio_t *sh)
+static int set_format(struct dec_audio *da)
{
- struct ad_mpg123_context *con = sh->context;
+ struct ad_mpg123_context *con = da->priv;
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;
- break;
- case MPG123_ENC_SIGNED_16:
- sh->sample_format = AF_FORMAT_S16;
- break;
- case MPG123_ENC_SIGNED_32:
- sh->sample_format = AF_FORMAT_S32;
- break;
- case MPG123_ENC_FLOAT_32:
- sh->sample_format = AF_FORMAT_FLOAT;
- break;
- default:
+ mp_chmap_from_channels(&da->header->audio->channels, channels);
+ da->header->audio->samplerate = rate;
+ int af = mpg123_format_to_af(encoding);
+ if (!af) {
/* 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;
}
- con->sample_size = channels * (af_fmt2bits(sh->sample_format) / 8);
+ da->header->audio->sample_format = af;
+ con->sample_size = channels * (af_fmt2bits(af) / 8);
con->new_format = 0;
}
return ret;
}
-static int feed_new_packet(sh_audio_t *sh)
+static int feed_new_packet(struct dec_audio *da)
{
- struct ad_mpg123_context *con = sh->context;
+ struct ad_mpg123_context *con = da->priv;
int ret;
- struct demux_packet *pkt = demux_read_packet(sh->gsh);
+ struct demux_packet *pkt = demux_read_packet(da->header);
if (!pkt)
return -1; /* EOF. */
/* Next bytes from that presentation time. */
if (pkt->pts != MP_NOPTS_VALUE) {
- sh->pts = pkt->pts;
- sh->pts_offset = 0;
+ da->pts = pkt->pts;
+ da->pts_offset = 0;
}
/* Have to use mpg123_feed() to avoid decoding here. */
@@ -201,9 +199,9 @@ static int feed_new_packet(sh_audio_t *sh)
* 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)
+static int init(struct dec_audio *da, const char *decoder)
{
- struct ad_mpg123_context *con = sh->context;
+ struct ad_mpg123_context *con = da->priv;
int ret;
ret = mpg123_open_feed(con->handle);
@@ -211,14 +209,14 @@ static int init(sh_audio_t *sh, const char *decoder)
goto fail;
for (int n = 0; ; n++) {
- if (feed_new_packet(sh) < 0) {
+ if (feed_new_packet(da) < 0) {
ret = MPG123_NEED_MORE;
goto fail;
}
size_t got_now = 0;
ret = mpg123_decode_frame(con->handle, NULL, NULL, &got_now);
if (ret == MPG123_OK || ret == MPG123_NEW_FORMAT) {
- ret = set_format(sh);
+ ret = set_format(da);
if (ret == MPG123_OK)
break;
}
@@ -241,7 +239,7 @@ fail:
mpg123_strerror(con->handle));
}
- uninit(sh);
+ uninit(da);
return 0;
}
@@ -260,9 +258,9 @@ static int compute_bitrate(struct mpg123_frameinfo *i)
/* Update mean bitrate. This could be dropped if accurate time display
* on audio file playback is not desired. */
-static void update_info(sh_audio_t *sh)
+static void update_info(struct dec_audio *da)
{
- struct ad_mpg123_context *con = sh->context;
+ struct ad_mpg123_context *con = da->priv;
struct mpg123_frameinfo finfo;
if (mpg123_info(con->handle, &finfo) != MPG123_OK)
return;
@@ -275,12 +273,12 @@ static void update_info(sh_audio_t *sh)
/* Might not be numerically optimal, but works fine enough. */
con->mean_rate = ((con->mean_count - 1) * con->mean_rate +
finfo.bitrate) / con->mean_count;
- sh->i_bps = (int) (con->mean_rate * 1000 / 8);
+ da->i_bps = (int) (con->mean_rate * 1000 / 8);
con->delay = 10;
}
} else {
- sh->i_bps = (finfo.bitrate ? finfo.bitrate : compute_bitrate(&finfo))
+ da->i_bps = (finfo.bitrate ? finfo.bitrate : compute_bitrate(&finfo))
* 1000 / 8;
con->delay = 1;
con->mean_rate = 0.;
@@ -288,14 +286,14 @@ static void update_info(sh_audio_t *sh)
}
}
-static int decode_audio(sh_audio_t *sh, struct mp_audio *buffer, int maxlen)
+static int decode_audio(struct dec_audio *da, struct mp_audio *buffer, int maxlen)
{
- struct ad_mpg123_context *con = sh->context;
+ struct ad_mpg123_context *con = da->priv;
void *buf = buffer->planes[0];
int ret;
if (con->new_format) {
- ret = set_format(sh);
+ ret = set_format(da);
if (ret == MPG123_OK) {
return 0; // let caller handle format change
} else if (ret == MPG123_NEED_MORE) {
@@ -306,13 +304,13 @@ static int decode_audio(sh_audio_t *sh, struct mp_audio *buffer, int maxlen)
}
if (con->need_data) {
- if (feed_new_packet(sh) < 0)
+ if (feed_new_packet(da) < 0)
return -1;
}
- if (sh->samplerate != buffer->rate ||
- !mp_chmap_equals(&sh->channels, &buffer->channels) ||
- sh->sample_format != buffer->format)
+ if (da->header->audio->samplerate != buffer->rate ||
+ !mp_chmap_equals(&da->header->audio->channels, &buffer->channels) ||
+ da->header->audio->sample_format != buffer->format)
return 0;
size_t got_now = 0;
@@ -324,7 +322,7 @@ static int decode_audio(sh_audio_t *sh, struct mp_audio *buffer, int maxlen)
int got_samples = got_now / con->sample_size;
buffer->samples += got_samples;
- sh->pts_offset += got_samples;
+ da->pts_offset += got_samples;
if (ret == MPG123_NEW_FORMAT) {
con->new_format = true;
@@ -334,7 +332,7 @@ static int decode_audio(sh_audio_t *sh, struct mp_audio *buffer, int maxlen)
goto mpg123_fail;
}
- update_info(sh);
+ update_info(da);
return 0;
mpg123_fail:
@@ -343,9 +341,9 @@ mpg123_fail:
return -1;
}
-static int control(sh_audio_t *sh, int cmd, void *arg)
+static int control(struct dec_audio *da, int cmd, void *arg)
{
- struct ad_mpg123_context *con = sh->context;
+ struct ad_mpg123_context *con = da->priv;
switch (cmd) {
case ADCTRL_RESYNC_STREAM: