summaryrefslogtreecommitdiffstats
path: root/audio
diff options
context:
space:
mode:
authorMartin Herkt <lachs0r@srsfckn.biz>2016-02-28 23:31:51 +0100
committerMartin Herkt <lachs0r@srsfckn.biz>2016-02-28 23:31:51 +0100
commit21cd4ff05bb46b375a9ad38c9f0b7f8e71a5d979 (patch)
treeb9679cc1d2c7c3cab0f88c370015f34f6d0b27ca /audio
parentd1d6257731866934717353fce484f5f472f845d1 (diff)
parent1f436f65f2ee4df6419ca68bd6426b8283db6d22 (diff)
downloadmpv-21cd4ff05bb46b375a9ad38c9f0b7f8e71a5d979.tar.bz2
mpv-21cd4ff05bb46b375a9ad38c9f0b7f8e71a5d979.tar.xz
Merge branch 'master' into release/current
Diffstat (limited to 'audio')
-rw-r--r--audio/audio.c108
-rw-r--r--audio/audio.h2
-rw-r--r--audio/audio_buffer.c14
-rw-r--r--audio/audio_buffer.h14
-rw-r--r--audio/chmap.c14
-rw-r--r--audio/chmap.h14
-rw-r--r--audio/chmap_sel.c14
-rw-r--r--audio/chmap_sel.h14
-rw-r--r--audio/decode/ad.h3
-rw-r--r--audio/decode/ad_lavc.c82
-rw-r--r--audio/decode/ad_spdif.c24
-rw-r--r--audio/decode/dec_audio.c216
-rw-r--r--audio/decode/dec_audio.h42
-rw-r--r--audio/filter/af.c14
-rw-r--r--audio/filter/af.h3
-rw-r--r--audio/filter/af_lavfi.c46
-rw-r--r--audio/filter/af_lavrresample.c45
-rw-r--r--audio/filter/af_rubberband.c14
-rw-r--r--audio/mixer.c1
-rw-r--r--audio/out/ao.c4
-rw-r--r--audio/out/ao_coreaudio_chmap.c41
-rw-r--r--audio/out/ao_coreaudio_chmap.h14
-rw-r--r--audio/out/ao_openal.c1
-rw-r--r--audio/out/ao_opensles.c250
-rw-r--r--audio/out/ao_sdl.c14
-rw-r--r--audio/out/ao_wasapi.c348
-rw-r--r--audio/out/ao_wasapi.h33
-rw-r--r--audio/out/ao_wasapi_changenotify.c20
-rw-r--r--audio/out/ao_wasapi_utils.c157
-rw-r--r--audio/out/pull.c14
-rw-r--r--audio/out/push.c14
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,
-