diff options
author | Martin Herkt <lachs0r@srsfckn.biz> | 2016-02-28 23:31:51 +0100 |
---|---|---|
committer | Martin Herkt <lachs0r@srsfckn.biz> | 2016-02-28 23:31:51 +0100 |
commit | 21cd4ff05bb46b375a9ad38c9f0b7f8e71a5d979 (patch) | |
tree | b9679cc1d2c7c3cab0f88c370015f34f6d0b27ca /audio | |
parent | d1d6257731866934717353fce484f5f472f845d1 (diff) | |
parent | 1f436f65f2ee4df6419ca68bd6426b8283db6d22 (diff) | |
download | mpv-21cd4ff05bb46b375a9ad38c9f0b7f8e71a5d979.tar.bz2 mpv-21cd4ff05bb46b375a9ad38c9f0b7f8e71a5d979.tar.xz |
Merge branch 'master' into release/current
Diffstat (limited to 'audio')
31 files changed, 969 insertions, 625 deletions
diff --git a/audio/audio.c b/audio/audio.c index 157649c3f8..ae85a4bf08 100644 --- a/audio/audio.c +++ b/audio/audio.c @@ -22,6 +22,7 @@ #include <libavutil/buffer.h> #include <libavutil/frame.h> +#include <libavutil/mem.h> #include <libavutil/version.h> #include "mpv_talloc.h" @@ -251,8 +252,43 @@ void mp_audio_skip_samples(struct mp_audio *data, int samples) data->planes[n] = (uint8_t *)data->planes[n] + samples * data->sstride; data->samples -= samples; + + if (data->pts != MP_NOPTS_VALUE) + data->pts += samples / (double)data->rate; } +// Clip the given frame to the given timestamp range. Adjusts the frame size +// and timestamp. +void mp_audio_clip_timestamps(struct mp_audio *f, double start, double end) +{ + if (f->pts == MP_NOPTS_VALUE || f->rate < 1) + return; + double f_end = f->pts + f->samples / (double)f->rate; + if (end != MP_NOPTS_VALUE) { + if (f_end >= end) { + if (f->pts >= end) { + f->samples = 0; + } else { + int new = (end - f->pts) * f->rate; + f->samples = MPCLAMP(new, 0, f->samples); + } + } + } + if (start != MP_NOPTS_VALUE) { + if (f->pts < start) { + if (f_end <= start) { + f->samples = 0; + f->pts = f_end; + } else { + int skip = (start - f->pts) * f->rate; + skip = MPCLAMP(skip, 0, f->samples); + mp_audio_skip_samples(f, skip); + } + } + } +} + + // Return false if the frame data is shared, true otherwise. // Will return true for non-refcounted frames. bool mp_audio_is_writeable(struct mp_audio *data) @@ -350,6 +386,78 @@ fail: return NULL; } +// Returns NULL on failure. The input is always unreffed. +struct AVFrame *mp_audio_to_avframe_and_unref(struct mp_audio *frame) +{ + struct AVFrame *avframe = av_frame_alloc(); + if (!avframe) + goto fail; + + avframe->nb_samples = frame->samples; + avframe->format = af_to_avformat(frame->format); + if (avframe->format == AV_SAMPLE_FMT_NONE) + goto fail; + + avframe->channel_layout = mp_chmap_to_lavc(&frame->channels); + if (!avframe->channel_layout) + goto fail; +#if LIBAVUTIL_VERSION_MICRO >= 100 + // FFmpeg being a stupid POS (but I respect it) + avframe->channels = frame->channels.num; +#endif + avframe->sample_rate = frame->rate; + + if (frame->num_planes > AV_NUM_DATA_POINTERS) { + avframe->extended_data = + av_mallocz_array(frame->num_planes, sizeof(avframe->extended_data[0])); + int extbufs = frame->num_planes - AV_NUM_DATA_POINTERS; + avframe->extended_buf = + av_mallocz_array(extbufs, sizeof(avframe->extended_buf[0])); + if (!avframe->extended_data || !avframe->extended_buf) + goto fail; + avframe->nb_extended_buf = extbufs; + } + + for (int p = 0; p < frame->num_planes; p++) + avframe->extended_data[p] = frame->planes[p]; + avframe->linesize[0] = frame->samples * frame->sstride; + + for (int p = 0; p < AV_NUM_DATA_POINTERS; p++) + avframe->data[p] = avframe->extended_data[p]; + + for (int p = 0; p < frame->num_planes; p++) { + if (!frame->allocated[p]) + break; + AVBufferRef *nref = av_buffer_ref(frame->allocated[p]); + if (!nref) + goto fail; + if (p < AV_NUM_DATA_POINTERS) { + avframe->buf[p] = nref; + } else { + avframe->extended_buf[p - AV_NUM_DATA_POINTERS] = nref; + } + } + + // Force refcounted frame. + if (!avframe->buf[0]) { + AVFrame *tmp = av_frame_alloc(); + if (!tmp) + goto fail; + if (av_frame_ref(tmp, avframe) < 0) + goto fail; + av_frame_free(&avframe); + avframe = tmp; + } + + talloc_free(frame); + return avframe; + +fail: + av_frame_free(&avframe); + talloc_free(frame); + return NULL; +} + struct mp_audio_pool { AVBufferPool *avpool; int element_size; diff --git a/audio/audio.h b/audio/audio.h index c74d0f778c..c469f7a21e 100644 --- a/audio/audio.h +++ b/audio/audio.h @@ -72,12 +72,14 @@ void mp_audio_copy(struct mp_audio *dst, int dst_offset, struct mp_audio *src, int src_offset, int length); void mp_audio_copy_attributes(struct mp_audio *dst, struct mp_audio *src); void mp_audio_skip_samples(struct mp_audio *data, int samples); +void mp_audio_clip_timestamps(struct mp_audio *f, double start, double end); bool mp_audio_is_writeable(struct mp_audio *data); int mp_audio_make_writeable(struct mp_audio *data); struct AVFrame; struct mp_audio *mp_audio_from_avframe(struct AVFrame *avframe); +struct AVFrame *mp_audio_to_avframe_and_unref(struct mp_audio *frame); struct mp_audio_pool; struct mp_audio_pool *mp_audio_pool_create(void *ta_parent); diff --git a/audio/audio_buffer.c b/audio/audio_buffer.c index c0f1341afe..a443a2185a 100644 --- a/audio/audio_buffer.c +++ b/audio/audio_buffer.c @@ -1,18 +1,18 @@ /* * This file is part of mpv. * - * mpv 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. + * mpv is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. * * mpv 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. + * GNU Lesser General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with mpv. If not, see <http://www.gnu.org/licenses/>. + * You should have received a copy of the GNU Lesser General Public + * License along with mpv. If not, see <http://www.gnu.org/licenses/>. */ #include <stddef.h> diff --git a/audio/audio_buffer.h b/audio/audio_buffer.h index f517542ef5..212d187572 100644 --- a/audio/audio_buffer.h +++ b/audio/audio_buffer.h @@ -1,18 +1,18 @@ /* * This file is part of mpv. * - * mpv 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. + * mpv is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. * * mpv 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. + * GNU Lesser General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with mpv. If not, see <http://www.gnu.org/licenses/>. + * You should have received a copy of the GNU Lesser General Public + * License along with mpv. If not, see <http://www.gnu.org/licenses/>. */ #ifndef MP_AUDIO_BUFFER_H diff --git a/audio/chmap.c b/audio/chmap.c index e0f485c4dc..1d4970da6c 100644 --- a/audio/chmap.c +++ b/audio/chmap.c @@ -1,18 +1,18 @@ /* * This file is part of mpv. * - * mpv 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. + * mpv is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. * * mpv 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. + * GNU Lesser General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with mpv. If not, see <http://www.gnu.org/licenses/>. + * You should have received a copy of the GNU Lesser General Public + * License along with mpv. If not, see <http://www.gnu.org/licenses/>. */ #include <stdlib.h> diff --git a/audio/chmap.h b/audio/chmap.h index b32c63b6fc..aa9b1c5a10 100644 --- a/audio/chmap.h +++ b/audio/chmap.h @@ -1,18 +1,18 @@ /* * This file is part of mpv. * - * mpv 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. + * mpv is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. * * mpv 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. + * GNU Lesser General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with mpv. If not, see <http://www.gnu.org/licenses/>. + * You should have received a copy of the GNU Lesser General Public + * License along with mpv. If not, see <http://www.gnu.org/licenses/>. */ #ifndef MP_CHMAP_H diff --git a/audio/chmap_sel.c b/audio/chmap_sel.c index fa1941e6f6..45b696c924 100644 --- a/audio/chmap_sel.c +++ b/audio/chmap_sel.c @@ -1,18 +1,18 @@ /* * This file is part of mpv. * - * mpv 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. + * mpv is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. * * mpv 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. + * GNU Lesser General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with mpv. If not, see <http://www.gnu.org/licenses/>. + * You should have received a copy of the GNU Lesser General Public + * License along with mpv. If not, see <http://www.gnu.org/licenses/>. */ #include <stdlib.h> diff --git a/audio/chmap_sel.h b/audio/chmap_sel.h index 12ded3b466..5bd8783b83 100644 --- a/audio/chmap_sel.h +++ b/audio/chmap_sel.h @@ -1,18 +1,18 @@ /* * This file is part of mpv. * - * mpv 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. + * mpv is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. * * mpv 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. + * GNU Lesser General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with mpv. If not, see <http://www.gnu.org/licenses/>. + * You should have received a copy of the GNU Lesser General Public + * License along with mpv. If not, see <http://www.gnu.org/licenses/>. */ #ifndef MP_CHMAP_SEL_H diff --git a/audio/decode/ad.h b/audio/decode/ad.h index 05139549b1..771ceb7e88 100644 --- a/audio/decode/ad.h +++ b/audio/decode/ad.h @@ -35,7 +35,8 @@ struct ad_functions { 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_packet)(struct dec_audio *da, struct mp_audio **out); + int (*decode_packet)(struct dec_audio *da, struct demux_packet *pkt, + struct mp_audio **out); }; enum ad_ctrl { diff --git a/audio/decode/ad_lavc.c b/audio/decode/ad_lavc.c index 7e5c8d5aa5..c30aff7fd5 100644 --- a/audio/decode/ad_lavc.c +++ b/audio/decode/ad_lavc.c @@ -42,8 +42,9 @@ struct priv { AVFrame *avframe; struct mp_audio frame; bool force_channel_map; - struct demux_packet *packet; - uint32_t skip_samples; + uint32_t skip_samples, trim_samples; + bool preroll_done; + double next_pts; }; static void uninit(struct dec_audio *da); @@ -60,7 +61,7 @@ const struct m_sub_options ad_lavc_conf = { .opts = (const m_option_t[]) { OPT_FLOATRANGE("ac3drc", ac3drc, 0, 0, 6), OPT_FLAG("downmix", downmix, 0), - OPT_INTRANGE("threads", threads, 0, 1, 16), + OPT_INTRANGE("threads", threads, 0, 0, 16), OPT_KEYVALUELIST("o", avopts, 0), {0} }, @@ -78,8 +79,7 @@ static int init(struct dec_audio *da, const char *decoder) struct ad_lavc_params *opts = mpopts->ad_lavc_params; AVCodecContext *lavc_context; AVCodec *lavc_codec; - struct sh_stream *sh = da->header; - struct mp_codec_params *c = sh->codec; + struct mp_codec_params *c = da->codec; struct priv *ctx = talloc_zero(NULL, struct priv); da->priv = ctx; @@ -140,6 +140,8 @@ static int init(struct dec_audio *da, const char *decoder) return 0; } + ctx->next_pts = MP_NOPTS_VALUE; + return 1; } @@ -165,27 +167,21 @@ static int control(struct dec_audio *da, int cmd, void *arg) switch (cmd) { case ADCTRL_RESET: avcodec_flush_buffers(ctx->avctx); - talloc_free(ctx->packet); - ctx->packet = NULL; ctx->skip_samples = 0; + ctx->trim_samples = 0; + ctx->preroll_done = false; + ctx->next_pts = MP_NOPTS_VALUE; return CONTROL_TRUE; } return CONTROL_UNKNOWN; } -static int decode_packet(struct dec_audio *da, struct mp_audio **out) +static int decode_packet(struct dec_audio *da, struct demux_packet *mpkt, + struct mp_audio **out) { struct priv *priv = da->priv; AVCodecContext *avctx = priv->avctx; - struct demux_packet *mpkt = priv->packet; - if (!mpkt) { - if (demux_read_packet_async(da->header, &mpkt) == 0) - return AD_WAIT; - } - - priv->packet = talloc_steal(priv, mpkt); - int in_len = mpkt ? mpkt->len : 0; AVPacket pkt; @@ -203,57 +199,69 @@ static int decode_packet(struct dec_audio *da, struct mp_audio **out) mpkt->len -= ret; mpkt->pts = MP_NOPTS_VALUE; // don't reset PTS next time } - if (mpkt->len == 0 || ret < 0) { - talloc_free(mpkt); - priv->packet = NULL; - } // LATM may need many packets to find mux info - if (ret == AVERROR(EAGAIN)) - return AD_OK; + if (ret == AVERROR(EAGAIN)) { + mpkt->len = 0; + return 0; + } } if (ret < 0) { MP_ERR(da, "Error decoding audio.\n"); - return AD_ERR; + return -1; } if (!got_frame) - return mpkt ? AD_OK : AD_EOF; + return 0; double out_pts = mp_pts_from_av(priv->avframe->pkt_pts, NULL); struct mp_audio *mpframe = mp_audio_from_avframe(priv->avframe); if (!mpframe) - return AD_ERR; + return -1; struct mp_chmap lavc_chmap = mpframe->channels; if (lavc_chmap.num != avctx->channels) mp_chmap_from_channels(&lavc_chmap, avctx->channels); if (priv->force_channel_map) { - if (lavc_chmap.num == da->header->codec->channels.num) - lavc_chmap = da->header->codec->channels; + if (lavc_chmap.num == da->codec->channels.num) + lavc_chmap = da->codec->channels; } mp_audio_set_channels(mpframe, &lavc_chmap); mpframe->pts = out_pts; + if (mpframe->pts == MP_NOPTS_VALUE) + mpframe->pts = priv->next_pts; + if (mpframe->pts != MP_NOPTS_VALUE) + priv->next_pts = mpframe->pts + mpframe->samples / (double)mpframe->rate; + #if HAVE_AVFRAME_SKIP_SAMPLES AVFrameSideData *sd = av_frame_get_side_data(priv->avframe, AV_FRAME_DATA_SKIP_SAMPLES); if (sd && sd->size >= 10) { char *d = sd->data; priv->skip_samples += AV_RL32(d + 0); - uint32_t pad = AV_RL32(d + 4); - uint32_t skip = MPMIN(priv->skip_samples, mpframe->samples); - if (skip) { - mp_audio_skip_samples(mpframe, skip); - if (mpframe->pts != MP_NOPTS_VALUE) - mpframe->pts += skip / (double)mpframe->rate; - priv->skip_samples -= skip; - } - if (pad <= mpframe->samples) - mpframe->samples -= pad; + priv->trim_samples += AV_RL32(d + 4); } #endif + if (!priv->preroll_done) { + // Skip only if this isn't already handled by AV_FRAME_DATA_SKIP_SAMPLES. + if (!priv->skip_samples) + priv->skip_samples = avctx->delay; + priv->preroll_done = true; + } + + uint32_t skip = MPMIN(priv->skip_samples, mpframe->samples); + if (skip) { + mp_audio_skip_samples(mpframe, skip); + priv->skip_samples -= skip; + } + uint32_t trim = MPMIN(priv->trim_samples, mpframe->samples); + if (trim) { + mpframe->samples -= trim; + priv->trim_samples -= trim; + } + *out = mpframe; av_frame_unref(priv->avframe); diff --git a/audio/decode/ad_spdif.c b/audio/decode/ad_spdif.c index 5e9dcf1c4f..7298d9e7d7 100644 --- a/audio/decode/ad_spdif.c +++ b/audio/decode/ad_spdif.c @@ -41,6 +41,7 @@ struct spdifContext { bool need_close; bool use_dts_hd; struct mp_audio fmt; + struct mp_audio_pool *pool; }; static int write_packet(void *p, uint8_t *buf, int buf_size) @@ -79,6 +80,7 @@ static int init(struct dec_audio *da, const char *decoder) da->priv = spdif_ctx; spdif_ctx->log = da->log; spdif_ctx->use_dts_hd = da->opts->dtshd; + spdif_ctx->pool = mp_audio_pool_create(spdif_ctx); if (strcmp(decoder, "dts-hd") == 0) { decoder = "dts"; @@ -189,7 +191,8 @@ static int init_filter(struct dec_audio *da, AVPacket *pkt) break; case AV_CODEC_ID_DTS: { bool is_hd = profile == FF_PROFILE_DTS_HD_HRA || - profile == FF_PROFILE_DTS_HD_MA; + profile == FF_PROFILE_DTS_HD_MA || + profile == FF_PROFILE_UNKNOWN; if (spdif_ctx->use_dts_hd && is_hd) { av_dict_set(&format_opts, "dtshd_rate", "768000", 0); // 4*192000 sample_format = AF_FORMAT_S_DTSHD; @@ -240,38 +243,35 @@ fail: return -1; } -static int decode_packet(struct dec_audio *da, struct mp_audio **out) +static int decode_packet(struct dec_audio *da, struct demux_packet *mpkt, + struct mp_audio **out) { struct spdifContext *spdif_ctx = da->priv; spdif_ctx->out_buffer_len = 0; - struct demux_packet *mpkt; - if (demux_read_packet_async(da->header, &mpkt) == 0) - return AD_WAIT; - if (!mpkt) - return AD_EOF; + return 0; double pts = mpkt->pts; AVPacket pkt; mp_set_av_packet(&pkt, mpkt, NULL); + mpkt->len = 0; // will be fully consumed pkt.pts = pkt.dts = 0; if (!spdif_ctx->lavf_ctx) { if (init_filter(da, &pkt) < 0) - return AD_ERR; + return -1; } int ret = av_write_frame(spdif_ctx->lavf_ctx, &pkt); - talloc_free(mpkt); avio_flush(spdif_ctx->lavf_ctx->pb); if (ret < 0) - return AD_ERR; + return -1; int samples = spdif_ctx->out_buffer_len / spdif_ctx->fmt.sstride; - *out = mp_audio_pool_get(da->pool, &spdif_ctx->fmt, samples); + *out = mp_audio_pool_get(spdif_ctx->pool, &spdif_ctx->fmt, samples); if (!*out) - return AD_ERR; + return -1; memcpy((*out)->planes[0], spdif_ctx->out_buffer, spdif_ctx->out_buffer_len); (*out)->pts = pts; diff --git a/audio/decode/dec_audio.c b/audio/decode/dec_audio.c index f774ed1abd..e60ebe370f 100644 --- a/audio/decode/dec_audio.c +++ b/audio/decode/dec_audio.c @@ -61,8 +61,6 @@ static void uninit_decoder(struct dec_audio *d_audio) d_audio->ad_driver = NULL; talloc_free(d_audio->priv); d_audio->priv = NULL; - d_audio->afilter->initialized = -1; - d_audio->decode_format = (struct mp_audio){0}; } static int init_audio_codec(struct dec_audio *d_audio, const char *decoder) @@ -88,12 +86,12 @@ struct mp_decoder_list *audio_decoder_list(void) static struct mp_decoder_list *audio_select_decoders(struct dec_audio *d_audio) { struct MPOpts *opts = d_audio->opts; - const char *codec = d_audio->header->codec->codec; + const char *codec = d_audio->codec->codec; struct mp_decoder_list *list = audio_decoder_list(); struct mp_decoder_list *new = mp_select_decoders(list, codec, opts->audio_decoders); - if (d_audio->spdif_passthrough) { + if (d_audio->try_spdif) { struct mp_decoder_list *spdif = mp_select_decoder_list(list, codec, "spdif", opts->audio_spdif); mp_append_decoders(spdif, new); @@ -146,7 +144,7 @@ int audio_init_best_codec(struct dec_audio *d_audio) MP_VERBOSE(d_audio, "Selected audio codec: %s\n", d_audio->decoder_desc); } else { MP_ERR(d_audio, "Failed to initialize an audio decoder for codec '%s'.\n", - d_audio->header->codec->codec); + d_audio->codec->codec); } talloc_free(list); @@ -157,136 +155,132 @@ void audio_uninit(struct dec_audio *d_audio) { if (!d_audio) return; - MP_VERBOSE(d_audio, "Uninit audio filters...\n"); uninit_decoder(d_audio); - af_destroy(d_audio->afilter); - talloc_free(d_audio->waiting); talloc_free(d_audio); } -static int decode_new_frame(struct dec_audio *da) +void audio_reset_decoding(struct dec_audio *d_audio) { - while (!da->waiting) { - int ret = da->ad_driver->decode_packet(da, &da->waiting); - if (ret < 0) - return ret; - - if (da->waiting) { - if (da->waiting->pts != MP_NOPTS_VALUE) { - if (da->pts != MP_NOPTS_VALUE) { - da->pts += da->pts_offset / (double)da->waiting->rate; - da->pts_offset = 0; - } - double newpts = da->waiting->pts; - // Keep the interpolated timestamp if it doesn't deviate more - // than 1 ms from the real one. (MKV rounded timestamps.) - if (da->pts == MP_NOPTS_VALUE || da->pts_offset != 0 || - fabs(da->pts - newpts) > 0.001) - { - // Attempt to detect jumps in PTS. Even for the lowest - // sample rates and with worst container rounded timestamp, - // this should be a margin more than enough. - if (da->pts != MP_NOPTS_VALUE && fabs(newpts - da->pts) > 0.1) - { - MP_WARN(da, "Invalid audio PTS: %f -> %f\n", - da->pts, newpts); - da->pts_reset = true; - } - da->pts = da->waiting->pts; - da->pts_offset = 0; - } - } - da->pts_offset += da->waiting->samples; - da->decode_format = *da->waiting; - mp_audio_set_null_data(&da->decode_format); - } - - if (da->pts == MP_NOPTS_VALUE && da->header->missing_timestamps) - da->pts = 0; - } - return mp_audio_config_valid(da->waiting) ? AD_OK : AD_ERR; + if (d_audio->ad_driver) + d_audio->ad_driver->control(d_audio, ADCTRL_RESET, NULL); + d_audio->pts = MP_NOPTS_VALUE; + talloc_free(d_audio->current_frame); + d_audio->current_frame = NULL; + talloc_free(d_audio->packet); + d_audio->packet = NULL; + talloc_free(d_audio->new_segment); + d_audio->new_segment = NULL; + d_audio->start = d_audio->end = MP_NOPTS_VALUE; } -/* Decode packets until we know the audio format. Then reinit the buffer. - * Returns AD_OK on success, negative AD_* code otherwise. - * Also returns AD_OK if already initialized (and does nothing). - */ -int initial_audio_decode(struct dec_audio *da) +static void fix_audio_pts(struct dec_audio *da) { - return decode_new_frame(da); -} + if (!da->current_frame) + return; -static bool copy_output(struct af_stream *afs, struct mp_audio_buffer *outbuf, - |