summaryrefslogtreecommitdiffstats
path: root/audio/decode/ad_mpg123.c
blob: 30a479074672b75166357f9a62704ae7eed11a54 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
/*
 * MPEG 1.0/2.0/2.5 audio layer I, II, III decoding with libmpg123
 *
 * 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
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * MPlayer is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include "config.h"

#include "ad.h"
#include "common/msg.h"

#include <mpg123.h>

#if (defined MPG123_API_VERSION) && (MPG123_API_VERSION < 33)
#error "This should not happen"
#endif

struct ad_mpg123_context {
    mpg123_handle *handle;
    int sample_size;
    /* Running mean for bit rate, stream length estimation. */
    float mean_rate;
    unsigned int mean_count;
    /* Time delay for updates. */
    short delay;
    /* If the stream is actually VBR. */
    char vbr;
};

static void uninit(struct dec_audio *da)
{
    struct ad_mpg123_context *con = da->priv;

    mpg123_close(con->handle);
    mpg123_delete(con->handle);
    mpg123_exit();
}

/* This initializes libmpg123 and prepares the handle, including funky
 * parameters. */
static int init(struct dec_audio *da, const char *decoder)
{
    int err;
    struct ad_mpg123_context *con;
    /* Assumption: You always call preinit + init + uninit, on every file.
     * But you stop at preinit in case it fails.
     * If that is not true, one must ensure not to call mpg123_init / exit
     * twice in a row. */
    if (mpg123_init() != MPG123_OK)
        return 0;

    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)
        goto bad_end;

    /* Basic settings.
     * Don't spill messages, enable better resync with non-seekable streams.
     * Give both flags individually without error checking to keep going with
     * old libmpg123. Generally, it is not fatal if the flags are not
     * honored */
    mpg123_param(con->handle, MPG123_ADD_FLAGS, MPG123_QUIET, 0.0);
    /* Do not bail out on malformed streams at all.
     * MPlayer does not handle a decoder throwing the towel on crappy input. */
    mpg123_param(con->handle, MPG123_RESYNC_LIMIT, -1, 0.0);

    /* Open decisions: Configure libmpg123 to force encoding (or stay open about
     * library builds that support only float or int32 output), (de)configure
     * gapless decoding (won't work with seeking in MPlayer, though).
     * Don't forget to eventually enable ReplayGain/RVA support, too.
     * 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.
     * 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):
    mpg123_param(con->handle, MPG123_RVA, MPG123_RVA_MIX, 0.0) */

    /* Prevent funky automatic resampling.
     * This way, we can be sure that one frame will never produce
     * more than 1152 stereo samples.
     * Background:
     * Going to decode directly to the output buffer. It is important to have
     * MPG123_AUTO_RESAMPLE disabled for the buffer size being an all-time
     * limit.
     * We need at least 1152 samples. dec_audio.c normally guarantees this. */
    mpg123_param(con->handle, MPG123_REMOVE_FLAGS, MPG123_AUTO_RESAMPLE, 0.);

    err = mpg123_open_feed(con->handle);
    if (err != MPG123_OK)
        goto bad_end;

    return 1;

  bad_end:
    if (!con->handle) {
        MP_ERR(da, "mpg123 preinit error: %s\n", mpg123_plain_strerror(err));
    } else {
        MP_ERR(da, "mpg123 preinit error: %s\n", mpg123_strerror(con->handle));
    }

    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;
}

/* Compute bitrate from frame size. */
static int compute_bitrate(struct mpg123_frameinfo *i)
{
    static const int samples_per_frame[4][4] = {
        {-1, 384, 1152, 1152},  /* MPEG 1 */
        {-1, 384, 1152,  576},  /* MPEG 2 */
        {-1, 384, 1152,  576},  /* MPEG 2.5 */
        {-1,  -1,   -1,   -1},  /* Unknown */
    };
    return (int) ((i->framesize + 4) * 8 * i->rate /
                  samples_per_frame[i->version][i->layer] + 0.5);
}

/* Update mean bitrate. This could be dropped if accurate time display
 * on audio file playback is not desired. */
static void update_info(struct dec_audio *da)
{
    struct ad_mpg123_context *con = da->priv;
    struct mpg123_frameinfo finfo;
    if (mpg123_info(con->handle, &finfo) != MPG123_OK)
        return;

    /* finfo.bitrate is expressed in kilobits */
    const int bitrate = finfo.bitrate * 1000;

    if (finfo.vbr != MPG123_CBR) {
        if (--con->delay < 1) {
            if (++con->mean_count > ((unsigned int) -1) / 2)
                con->mean_count = ((unsigned int) -1) / 4;

            /* Might not be numerically optimal, but works fine enough. */
            con->mean_rate = ((con->mean_count - 1) * con->mean_rate +
                              bitrate) / con->mean_count;
            da->bitrate = (int) (con->mean_rate + 0.5);

            con->delay = 10;
        }
    } else {
        da->bitrate = bitrate ? bitrate : compute_bitrate(&finfo);
        con->delay      = 1;
        con->mean_rate  = 0.;
        con->mean_count = 0;
    }
}

/* libmpg123 has a new format ready; query and store, return return value
   of mpg123_getformat() */
static int set_format(struct dec_audio *da)
{
    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_audio_set_num_channels(&da->decoded, channels);
        da->decoded.rate = 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_ERR(da, "Bad encoding from mpg123: %i.\n", encoding);
            return MPG123_ERR;
        }
        mp_audio_set_format(&da->decoded, af);
        con->sample_size = channels * af_fmt2bps(af);
    }
    return ret;
}

static int decode_packet(struct dec_audio *da)
{
    struct ad_mpg123_context *con = da->priv;
    int ret;

    mp_audio_set_null_data(&da->decoded);

    struct demux_packet *pkt;
    if (demux_read_packet_async(da->header, &pkt) == 0)
        return AD_WAIT;
    if (!pkt)
        return AD_EOF;

    /* Next bytes from that presentation time. */
    if (pkt->pts != MP_NOPTS_VALUE) {
        da->pts        = pkt->pts;
        da->pts_offset = 0;
    }

    /* Have to use mpg123_feed() to avoid decoding here. */
    ret = mpg123_feed(con->handle, pkt->buffer, pkt->len);
    talloc_free(pkt);

    if (ret != MPG123_OK)
        goto mpg123_fail;

    unsigned char *audio = NULL;
    size_t bytes = 0;
    ret = mpg123_decode_frame(con->handle, NULL, &audio, &bytes);

    if (ret == MPG123_NEED_MORE)
        return 0;

    if (ret != MPG123_OK && ret != MPG123_DONE && ret != MPG123_NEW_FORMAT)
        goto mpg123_fail;

    ret = set_format(da);
    if (ret != MPG123_OK)
        goto mpg123_fail;

    if (con->sample_size < 1) {
        MP_ERR(da, "no sample size\n");
        return AD_ERR;
    }

    int got_samples = bytes / con->sample_size;
    da->decoded.planes[0] = audio;
    da->decoded.samples = got_samples;

    update_info(da);
    return 0;

mpg123_fail:
    MP_ERR(da, "mpg123 decoding error: %s\n", mpg123_strerror(con->handle));
    return AD_ERR;
}

static int control(struct dec_audio *da, int cmd, void *arg)
{
    struct ad_mpg123_context *con = da->priv;

    switch (cmd) {
    case ADCTRL_RESET:
        mp_audio_set_null_data(&da->decoded);
        mpg123_close(con->handle);

        if (mpg123_open_feed(con->handle) != MPG123_OK) {
            MP_ERR(da, "mpg123 failed to reopen stream: %s\n",
                   mpg123_strerror(con->handle));
            return CONTROL_FALSE;
        }
        return CONTROL_TRUE;
    }
    return CONTROL_UNKNOWN;
}

static void add_decoders(struct mp_decoder_list *list)
{
    mp_add_decoder(list, "mpg123", "mp3", "mp3",
                   "High-performance decoder using libmpg123");
}

const struct ad_functions ad_mpg123 = {
    .name = "mpg123",
    .add_decoders = add_decoders,
    .init = init,
    .uninit = uninit,
    .control = control,
    .decode_packet = decode_packet,
};