diff options
Diffstat (limited to 'audio/decode')
-rw-r--r-- | audio/decode/ad.h | 11 | ||||
-rw-r--r-- | audio/decode/ad_lavc.c | 68 | ||||
-rw-r--r-- | audio/decode/ad_mpg123.c | 110 | ||||
-rw-r--r-- | audio/decode/ad_spdif.c | 30 | ||||
-rw-r--r-- | audio/decode/dec_audio.c | 161 | ||||
-rw-r--r-- | audio/decode/dec_audio.h | 30 |
6 files changed, 219 insertions, 191 deletions
diff --git a/audio/decode/ad.h b/audio/decode/ad.h index 6c76e8dfd0..ed9f4fff75 100644 --- a/audio/decode/ad.h +++ b/audio/decode/ad.h @@ -25,6 +25,7 @@ #include "audio/format.h" #include "audio/audio.h" +#include "dec_audio.h" struct mp_decoder_list; @@ -32,11 +33,11 @@ struct mp_decoder_list; struct ad_functions { const char *name; void (*add_decoders)(struct mp_decoder_list *list); - int (*preinit)(sh_audio_t *sh); - int (*init)(sh_audio_t *sh, const char *decoder); - void (*uninit)(sh_audio_t *sh); - int (*control)(sh_audio_t *sh, int cmd, void *arg); - int (*decode_audio)(sh_audio_t *sh, struct mp_audio *buffer, int maxlen); + int (*preinit)(struct dec_audio *da); + int (*init)(struct dec_audio *da, const char *decoder); + void (*uninit)(struct dec_audio *da); + int (*control)(struct dec_audio *da, int cmd, void *arg); + int (*decode_audio)(struct dec_audio *da, struct mp_audio *buffer, int maxlen); }; enum ad_ctrl { diff --git a/audio/decode/ad_lavc.c b/audio/decode/ad_lavc.c index 2e0cade8c5..143990414b 100644 --- a/audio/decode/ad_lavc.c +++ b/audio/decode/ad_lavc.c @@ -48,8 +48,8 @@ struct priv { struct demux_packet *packet; }; -static void uninit(sh_audio_t *sh); -static int decode_new_packet(struct sh_audio *sh); +static void uninit(struct dec_audio *da); +static int decode_new_packet(struct dec_audio *da); #define OPT_BASE_STRUCT struct MPOpts @@ -128,15 +128,16 @@ static const char *find_pcm_decoder(const struct pcm_map *map, int format, return NULL; } -static int preinit(sh_audio_t *sh) +static int preinit(struct dec_audio *da) { return 1; } -static int setup_format(sh_audio_t *sh_audio) +static int setup_format(struct dec_audio *da) { - struct priv *priv = sh_audio->context; + struct priv *priv = da->priv; AVCodecContext *lavc_context = priv->avctx; + struct sh_audio *sh_audio = da->header->audio; int sample_format = af_from_avformat(lavc_context->sample_fmt); if (!sample_format) @@ -181,15 +182,16 @@ static void set_from_wf(AVCodecContext *avctx, MP_WAVEFORMATEX *wf) } } -static int init(sh_audio_t *sh_audio, const char *decoder) +static int init(struct dec_audio *da, const char *decoder) { - struct MPOpts *mpopts = sh_audio->opts; + struct MPOpts *mpopts = da->opts; struct ad_lavc_param *opts = &mpopts->ad_lavc_param; AVCodecContext *lavc_context; AVCodec *lavc_codec; + struct sh_audio *sh_audio = da->header->audio; struct priv *ctx = talloc_zero(NULL, struct priv); - sh_audio->context = ctx; + da->priv = ctx; if (sh_audio->wf && strcmp(decoder, "pcm") == 0) { decoder = find_pcm_decoder(tag_map, sh_audio->format, @@ -203,7 +205,7 @@ static int init(sh_audio_t *sh_audio, const char *decoder) if (!lavc_codec) { mp_tmsg(MSGT_DECAUDIO, MSGL_ERR, "Cannot find codec '%s' in libavcodec...\n", decoder); - uninit(sh_audio); + uninit(da); return 0; } @@ -227,7 +229,7 @@ static int init(sh_audio_t *sh_audio, const char *decoder) if (parse_avopts(lavc_context, opts->avopt) < 0) { mp_msg(MSGT_DECVIDEO, MSGL_ERR, "ad_lavc: setting AVOptions '%s' failed.\n", opts->avopt); - uninit(sh_audio); + uninit(da); return 0; } } @@ -256,7 +258,7 @@ static int init(sh_audio_t *sh_audio, const char *decoder) /* open it */ if (avcodec_open2(lavc_context, lavc_codec, NULL) < 0) { mp_tmsg(MSGT_DECAUDIO, MSGL_ERR, "Could not open codec.\n"); - uninit(sh_audio); + uninit(da); return 0; } mp_msg(MSGT_DECAUDIO, MSGL_V, "INFO: libavcodec \"%s\" init OK!\n", @@ -264,27 +266,27 @@ static int init(sh_audio_t *sh_audio, const char *decoder) // Decode at least 1 sample: (to get header filled) for (int tries = 1; ; tries++) { - int x = decode_new_packet(sh_audio); + int x = decode_new_packet(da); if (x >= 0 && ctx->frame.samples > 0) break; if (tries >= 5) { mp_msg(MSGT_DECAUDIO, MSGL_ERR, "ad_lavc: initial decode failed\n"); - uninit(sh_audio); + uninit(da); return 0; } } - sh_audio->i_bps = lavc_context->bit_rate / 8; + da->i_bps = lavc_context->bit_rate / 8; if (sh_audio->wf && sh_audio->wf->nAvgBytesPerSec) - sh_audio->i_bps = sh_audio->wf->nAvgBytesPerSec; + da->i_bps = sh_audio->wf->nAvgBytesPerSec; return 1; } -static void uninit(sh_audio_t *sh) +static void uninit(struct dec_audio *da) { - struct priv *ctx = sh->context; + struct priv *ctx = da->priv; if (!ctx) return; AVCodecContext *lavc_context = ctx->avctx; @@ -296,13 +298,11 @@ static void uninit(sh_audio_t *sh) av_freep(&lavc_context); } avcodec_free_frame(&ctx->avframe); - talloc_free(ctx); - sh->context = NULL; } -static int control(sh_audio_t *sh, int cmd, void *arg) +static int control(struct dec_audio *da, int cmd, void *arg) { - struct priv *ctx = sh->context; + struct priv *ctx = da->priv; switch (cmd) { case ADCTRL_RESYNC_STREAM: avcodec_flush_buffers(ctx->avctx); @@ -314,16 +314,16 @@ static int control(sh_audio_t *sh, int cmd, void *arg) return CONTROL_UNKNOWN; } -static int decode_new_packet(struct sh_audio *sh) +static int decode_new_packet(struct dec_audio *da) { - struct priv *priv = sh->context; + struct priv *priv = da->priv; AVCodecContext *avctx = priv->avctx; priv->frame.samples = 0; struct demux_packet *mpkt = priv->packet; if (!mpkt) - mpkt = demux_read_packet(sh->gsh); + mpkt = demux_read_packet(da->header); if (!mpkt) return -1; // error or EOF @@ -335,8 +335,8 @@ static int decode_new_packet(struct sh_audio *sh) mp_set_av_packet(&pkt, mpkt); if (mpkt->pts != MP_NOPTS_VALUE) { - sh->pts = mpkt->pts; - sh->pts_offset = 0; + da->pts = mpkt->pts; + da->pts_offset = 0; } int got_frame = 0; int ret = avcodec_decode_audio4(avctx, priv->avframe, &got_frame, &pkt); @@ -362,13 +362,13 @@ static int decode_new_packet(struct sh_audio *sh) if (!got_frame) return 0; - if (setup_format(sh) < 0) + if (setup_format(da) < 0) return -1; priv->frame.samples = priv->avframe->nb_samples; - mp_audio_set_format(&priv->frame, sh->sample_format); - mp_audio_set_channels(&priv->frame, &sh->channels); - priv->frame.rate = sh->samplerate; + mp_audio_set_format(&priv->frame, da->header->audio->sample_format); + mp_audio_set_channels(&priv->frame, &da->header->audio->channels); + priv->frame.rate = da->header->audio->samplerate; for (int n = 0; n < priv->frame.num_planes; n++) priv->frame.planes[n] = priv->avframe->data[n]; @@ -377,12 +377,12 @@ static int decode_new_packet(struct sh_audio *sh) return 0; } -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 priv *priv = sh->context; + struct priv *priv = da->priv; if (!priv->frame.samples) { - if (decode_new_packet(sh) < 0) + if (decode_new_packet(da) < 0) return -1; } @@ -392,7 +392,7 @@ static int decode_audio(sh_audio_t *sh, struct mp_audio *buffer, int maxlen) buffer->samples = MPMIN(priv->frame.samples, maxlen); mp_audio_copy(buffer, 0, &priv->frame, 0, buffer->samples); mp_audio_skip_samples(&priv->frame, buffer->samples); - sh->pts_offset += buffer->samples; + da->pts_offset += buffer->samples; return 0; } 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: diff --git a/audio/decode/ad_spdif.c b/audio/decode/ad_spdif.c index e6e94489a6..2630cc89b9 100644 --- a/audio/decode/ad_spdif.c +++ b/audio/decode/ad_spdif.c @@ -57,9 +57,9 @@ static int write_packet(void *p, uint8_t *buf, int buf_size) return buf_size; } -static void uninit(sh_audio_t *sh) +static void uninit(struct dec_audio *da) { - struct spdifContext *spdif_ctx = sh->context; + struct spdifContext *spdif_ctx = da->priv; AVFormatContext *lavf_ctx = spdif_ctx->lavf_ctx; if (lavf_ctx) { @@ -70,18 +70,17 @@ static void uninit(sh_audio_t *sh) av_freep(&lavf_ctx->pb); avformat_free_context(lavf_ctx); } - talloc_free(spdif_ctx); } -static int preinit(sh_audio_t *sh) +static int preinit(struct dec_audio *da) { return 1; } -static int init(sh_audio_t *sh, const char *decoder) +static int init(struct dec_audio *da, const char *decoder) { struct spdifContext *spdif_ctx = talloc_zero(NULL, struct spdifContext); - sh->context = spdif_ctx; + da->priv = spdif_ctx; AVFormatContext *lavf_ctx = avformat_alloc_context(); if (!lavf_ctx) @@ -117,6 +116,7 @@ static int init(sh_audio_t *sh, const char *decoder) AVDictionary *format_opts = NULL; int num_channels = 0; + struct sh_audio *sh = da->header->audio; switch (stream->codec->codec_id) { case AV_CODEC_ID_AAC: spdif_ctx->iec61937_packet_size = 16384; @@ -181,16 +181,16 @@ static int init(sh_audio_t *sh, const char *decoder) return 1; fail: - uninit(sh); + uninit(da); return 0; } -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 spdifContext *spdif_ctx = sh->context; + struct spdifContext *spdif_ctx = da->priv; AVFormatContext *lavf_ctx = spdif_ctx->lavf_ctx; - int sstride = 2 * sh->channels.num; + int sstride = 2 * da->header->audio->channels.num; assert(sstride == buffer->sstride); if (maxlen * sstride < spdif_ctx->iec61937_packet_size) @@ -200,7 +200,7 @@ static int decode_audio(sh_audio_t *sh, struct mp_audio *buffer, int maxlen) spdif_ctx->out_buffer_size = maxlen * sstride; spdif_ctx->out_buffer = buffer->planes[0]; - struct demux_packet *mpkt = demux_read_packet(sh->gsh); + struct demux_packet *mpkt = demux_read_packet(da->header); if (!mpkt) return -1; @@ -209,13 +209,13 @@ static int decode_audio(sh_audio_t *sh, struct mp_audio *buffer, int maxlen) pkt.pts = pkt.dts = 0; mp_msg(MSGT_DECAUDIO, MSGL_V, "spdif packet, size=%d\n", pkt.size); if (mpkt->pts != MP_NOPTS_VALUE) { - sh->pts = mpkt->pts; - sh->pts_offset = 0; + da->pts = mpkt->pts; + da->pts_offset = 0; } int ret = av_write_frame(lavf_ctx, &pkt); avio_flush(lavf_ctx->pb); buffer->samples = spdif_ctx->out_buffer_len / sstride; - sh->pts_offset += buffer->samples; + da->pts_offset += buffer->samples; talloc_free(mpkt); if (ret < 0) return -1; @@ -223,7 +223,7 @@ static int decode_audio(sh_audio_t *sh, struct mp_audio *buffer, int maxlen) return 0; } -static int control(sh_audio_t *sh, int cmd, void *arg) +static int control(struct dec_audio *da, int cmd, void *arg) { return CONTROL_UNKNOWN; } diff --git a/audio/decode/dec_audio.c b/audio/decode/dec_audio.c index e2200918ef..39ee3d5695 100644 --- a/audio/decode/dec_audio.c +++ b/audio/decode/dec_audio.c @@ -64,46 +64,59 @@ static const struct ad_functions * const ad_drivers[] = { #define DECODE_BUFFER_SAMPLES (8192 + DECODE_MAX_UNIT) // Drop audio buffer and reinit it (after format change) -static void reinit_audio_buffer(sh_audio_t *sh) +static void reinit_audio_buffer(struct dec_audio *da) { - mp_audio_buffer_reinit_fmt(sh->decode_buffer, sh->sample_format, + struct sh_audio *sh = da->header->audio; + mp_audio_buffer_reinit_fmt(da->decode_buffer, sh->sample_format, &sh->channels, sh->samplerate); - mp_audio_buffer_preallocate_min(sh->decode_buffer, DECODE_BUFFER_SAMPLES); + mp_audio_buffer_preallocate_min(da->decode_buffer, DECODE_BUFFER_SAMPLES); } -static int init_audio_codec(sh_audio_t *sh_audio, const char *decoder) +static void uninit_decoder(struct dec_audio *d_audio) { - assert(!sh_audio->initialized); - resync_audio_stream(sh_audio); - if (!sh_audio->ad_driver->preinit(sh_audio)) { + if (d_audio->initialized) { + mp_tmsg(MSGT_DECAUDIO, MSGL_V, "Uninit audio decoder.\n"); + d_audio->ad_driver->uninit(d_audio); + d_audio->initialized = 0; + } + talloc_free(d_audio->priv); + d_audio->priv = NULL; +} + +static int init_audio_codec(struct dec_audio *d_audio, const char *decoder) +{ + assert(!d_audio->initialized); + audio_resync_stream(d_audio); + if (!d_audio->ad_driver->preinit(d_audio)) { mp_tmsg(MSGT_DECAUDIO, MSGL_ERR, "Audio decoder preinit failed.\n"); return 0; } - if (!sh_audio->ad_driver->init(sh_audio, decoder)) { + if (!d_audio->ad_driver->init(d_audio, decoder)) { mp_tmsg(MSGT_DECAUDIO, MSGL_V, "Audio decoder init failed.\n"); - uninit_audio(sh_audio); // free buffers + uninit_decoder(d_audio); return 0; } - sh_audio->initialized = 1; + d_audio->initialized = 1; - if (mp_chmap_is_empty(&sh_audio->channels) || !sh_audio->samplerate || - !sh_audio->sample_format) + struct sh_audio *sh = d_audio->header->audio; + if (mp_chmap_is_empty(&sh->channels) || !sh->samplerate || + !sh->sample_format) { mp_tmsg(MSGT_DECAUDIO, MSGL_ERR, "Audio decoder did not specify " "audio format!\n"); - uninit_audio(sh_audio); // free buffers + uninit_decoder(d_audio); return 0; } - sh_audio->decode_buffer = mp_audio_buffer_create(NULL); - reinit_audio_buffer(sh_audio); + d_audio->decode_buffer = mp_audio_buffer_create(NULL); + reinit_audio_buffer(d_audio); return 1; } -struct mp_decoder_list *mp_audio_decoder_list(void) +struct mp_decoder_list *audio_decoder_list(void) { struct mp_decoder_list *list = talloc_zero(NULL, struct mp_decoder_list); for (int i = 0; ad_drivers[i] != NULL; i++) @@ -111,10 +124,10 @@ struct mp_decoder_list *mp_audio_decoder_list(void) return list; } -static struct mp_decoder_list *mp_select_audio_decoders(const char *codec, - char *selection) +static struct mp_decoder_list *audio_select_decoders(const char *codec, + char *selection) { - struct mp_decoder_list *list = mp_audio_decoder_list(); + struct mp_decoder_list *list = audio_decoder_list(); struct mp_decoder_list *new = mp_select_decoders(list, codec, selection); talloc_free(list); return new; @@ -129,13 +142,13 @@ static const struct ad_functions *find_driver(const char *name) return NULL; } -int init_best_audio_codec(sh_audio_t *sh_audio, char *audio_decoders) +int audio_init_best_codec(struct dec_audio *d_audio, char *audio_decoders) { - assert(!sh_audio->initialized); + assert(!d_audio->initialized); struct mp_decoder_entry *decoder = NULL; struct mp_decoder_list *list = - mp_select_audio_decoders(sh_audio->gsh->codec, audio_decoders); + audio_select_decoders(d_audio->header->codec, audio_decoders); mp_print_decoders(MSGT_DECAUDIO, MSGL_V, "Codec list:", list); @@ -146,68 +159,65 @@ int init_best_audio_codec(sh_audio_t *sh_audio, char *audio_decoders) continue; mp_tmsg(MSGT_DECAUDIO, MSGL_V, "Opening audio decoder %s:%s\n", sel->family, sel->decoder); - sh_audio->ad_driver = driver; - if (init_audio_codec(sh_audio, sel->decoder)) { + d_audio->ad_driver = driver; + if (init_audio_codec(d_audio, sel->decoder)) { decoder = sel; break; } - sh_audio->ad_driver = NULL; + d_audio->ad_driver = NULL; mp_tmsg(MSGT_DECAUDIO, MSGL_WARN, "Audio decoder init failed for " "%s:%s\n", sel->family, sel->decoder); } - if (sh_audio->initialized) { - sh_audio->gsh->decoder_desc = - talloc_asprintf(NULL, "%s [%s:%s]", decoder->desc, decoder->family, + if (d_audio->initialized) { + d_audio->decoder_desc = + talloc_asprintf(d_audio, "%s [%s:%s]", decoder->desc, decoder->family, decoder->decoder); mp_msg(MSGT_DECAUDIO, MSGL_INFO, "Selected audio codec: %s\n", - sh_audio->gsh->decoder_desc); + d_audio->decoder_desc); mp_msg(MSGT_DECAUDIO, MSGL_V, "AUDIO: %d Hz, %d ch, %s\n", - sh_audio->samplerate, sh_audio->channels.num, - af_fmt_to_str(sh_audio->sample_format)); + d_audio->header->audio->samplerate, d_audio->header->audio->channels.num, + af_fmt_to_str(d_audio->header->audio->sample_format)); mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_AUDIO_BITRATE=%d\nID_AUDIO_RATE=%d\n" "ID_AUDIO_NCH=%d\n", - sh_audio->i_bps * 8, sh_audio->samplerate, sh_audio->channels.num); + d_audio->i_bps * 8, d_audio->header->audio->samplerate, + d_audio->header->audio->channels.num); } else { mp_msg(MSGT_DECAUDIO, MSGL_ERR, "Failed to initialize an audio decoder for codec '%s'.\n", - sh_audio->gsh->codec ? sh_audio->gsh->codec : "<unknown>"); + d_audio->header->codec ? d_audio->header->codec : "<unknown>"); } talloc_free(list); - return sh_audio->initialized; + return d_audio->initialized; } -void uninit_audio(sh_audio_t *sh_audio) +void audio_uninit(struct dec_audio *d_audio) { - if (sh_audio->afilter) { + if (!d_audio) + return; + if (d_audio->afilter) { mp_msg(MSGT_DECAUDIO, MSGL_V, "Uninit audio filters...\n"); - af_destroy(sh_audio->afilter); - sh_audio->afilter = NULL; - } - if (sh_audio->initialized) { - mp_tmsg(MSGT_DECAUDIO, MSGL_V, "Uninit audio.\n"); - sh_audio->ad_driver->uninit(sh_audio); - sh_audio->initialized = 0; + af_destroy(d_audio->afilter); + d_audio->afilter = NULL; } - talloc_free(sh_audio->gsh->decoder_desc); - sh_audio->gsh->decoder_desc = NULL; - talloc_free(sh_audio->decode_buffer); - sh_audio->decode_buffer = NULL; + uninit_decoder(d_audio); + talloc_free(d_audio->decode_buffer); + talloc_free(d_audio); } -int init_audio_filters(sh_audio_t *sh_audio, int in_samplerate, +int audio_init_filters(struct dec_audio *d_audio, int in_samplerate, int *out_samplerate, struct mp_chmap *out_channels, int *out_format) { - if (!sh_audio->afilter) - sh_audio->afilter = af_new(sh_audio->opts); - struct af_stream *afs = sh_audio->afilter; + if (!d_audio->afilter) + d_audio->afilter = af_new(d_audio->opts); + struct af_stream *afs = d_audio->afilter; // input format: same as codec's output format: - mp_audio_buffer_get_format(sh_audio->decode_buffer, &afs->input); + mp_audio_buffer_get_format(d_audio->decode_buffer, &afs->input); // Sample rate can be different when adjusting playback speed afs->input.rate = in_samplerate; @@ -226,7 +236,7 @@ int init_audio_filters(sh_audio_t *sh_audio, int in_samplerate, // let's autoprobe it! if (af_init(afs) != 0) { af_destroy(afs); - sh_audio->afilter = NULL; + d_audio->afilter = NULL; return 0; // failed :( } @@ -238,34 +248,35 @@ int init_audio_filters(sh_audio_t *sh_audio, int in_samplerate, } // Filter len bytes of input, put result into outbuf. -static int filter_n_bytes(sh_audio_t *sh, struct mp_audio_buffer *outbuf, +static int filter_n_bytes(struct dec_audio *da, struct mp_audio_buffer *outbuf, int len) { int error = 0; struct mp_audio config; - mp_audio_buffer_get_format(sh->decode_buffer, &config); + mp_audio_buffer_get_format(da->decode_buffer, &config); - while (mp_audio_buffer_samples(sh->decode_buffer) < len) { - int maxlen = mp_audio_buffer_get_write_available(sh->decode_buffer); + while (mp_audio_buffer_samples(da->decode_buffer) < len) { + int maxlen = mp_audio_buffer_get_write_available(da->decode_buffer); if (maxlen < DECODE_MAX_UNIT) break; struct mp_audio buffer; - mp_audio_buffer_get_write_buffer(sh->decode_buffer, maxlen, &buffer); + mp_audio_buffer_get_write_buffer(da->decode_buffer, maxlen, &buffer); buffer.samples = 0; - error = sh->ad_driver->decode_audio(sh, &buffer, maxlen); + error = da->ad_driver->decode_audio(da, &buffer, maxlen); if (error < 0) break; // Commit the data just read as valid data - mp_audio_buffer_finish_write(sh->decode_buffer, buffer.samples); + mp_audio_buffer_finish_write(da->decode_buffer, buffer.samples); // Format change + struct sh_audio *sh = da->header->audio; if (sh->samplerate != config.rate || !mp_chmap_equals(&sh->channels, &config.channels) || sh->sample_format != config.format) { // If there are still samples left in the buffer, let them drain // first, and don't signal a format change to the caller yet. - if (mp_audio_buffer_samples(sh->decode_buffer) > 0) + if (mp_audio_buffer_samples(da->decode_buffer) > 0) break; error = -2; break; @@ -274,33 +285,33 @@ static int filter_n_bytes(sh_audio_t *sh, struct mp_audio_buffer *outbuf, // Filter struct mp_audio filter_input; - mp_audio_buffer_peek(sh->decode_buffer, &filter_input); - filter_input.rate = sh->afilter->input.rate; // due to playback speed change + mp_audio_buffer_peek(da->decode_buffer, &filter_input); + filter_input.rate = da->afilter->input.rate; // due to playback speed change len = MPMIN(filter_input.samples, len); filter_input.samples = len; - struct mp_audio *filter_output = af_play(sh->afilter, &filter_input); + struct mp_audio *filter_output = af_play(da->afilter, &filter_input); if (!filter_output) return -1; mp_audio_buffer_append(outbuf, filter_output); // remove processed data from decoder buffer: - mp_audio_buffer_skip(sh->decode_buffer, len); + mp_audio_buffer_skip(da->decode_buffer, len); // Assume the filter chain is drained from old data at this point. // (If not, the remaining old data is discarded.) if (error == -2) - reinit_audio_buffer(sh); + reinit_audio_buffer(da); return error; } /* Try to get at least minsamples decoded+filtered samples in outbuf * (total length including possible existing data). - * Return 0 on success, -1 on error/EOF (not distinguished). + * Return 0 on success, -1 on error/EOF (not distinguidaed). * In the former case outbuf has at least minsamples buffered on return. * In case of EOF/error it might or might not be. */ -int decode_audio(sh_audio_t *sh_audio, struct mp_audio_buffer *outbuf, +int audio_decode(struct dec_audio *d_audio, struct mp_audio_buffer *outbuf, int minsamples) { // Indicates that a filter seems to be buffering large amounts of data @@ -312,7 +323,7 @@ int decode_audio(sh_audio_t *sh_audio, struct mp_audio_buffer *outbuf, /* Filter output size will be about filter_multiplier times input size. * If some filter buffers audio in big blocks this might only hold * as average over time. */ - double filter_multiplier = af_calc_filter_multiplier(sh_audio->afilter); + double filter_multiplier = af_calc_filter_multiplier(d_audio->afilter); int prev_buffered = -1; while (minsamples >= 0) { @@ -341,18 +352,18 @@ int decode_audio(sh_audio_t *sh_audio, struct mp_audio_buffer *outbuf, * of buffering in filters */ huge_filter_buffer = 1; - int res = filter_n_bytes(sh_audio, outbuf, decsamples); + int res = filter_n_bytes(d_audio, outbuf, decsamples); if (res < 0) return res; } return 0; } -void resync_audio_stream(sh_audio_t *sh_audio) +void audio_resync_stream(struct dec_audio *d_audio) |