summaryrefslogtreecommitdiffstats
path: root/audio
diff options
context:
space:
mode:
Diffstat (limited to 'audio')
-rw-r--r--audio/decode/ad.h49
-rw-r--r--audio/decode/ad_lavc.c130
-rw-r--r--audio/decode/ad_spdif.c158
-rw-r--r--audio/decode/dec_audio.c309
-rw-r--r--audio/decode/dec_audio.h66
5 files changed, 163 insertions, 549 deletions
diff --git a/audio/decode/ad.h b/audio/decode/ad.h
deleted file mode 100644
index a8384c277f..0000000000
--- a/audio/decode/ad.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * This file is part of mpv.
- *
- * 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 Lesser General Public License for more details.
- *
- * 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 MPLAYER_AD_H
-#define MPLAYER_AD_H
-
-#include "common/codecs.h"
-#include "demux/stheader.h"
-#include "demux/demux.h"
-
-#include "audio/format.h"
-#include "audio/aframe.h"
-#include "dec_audio.h"
-
-struct mp_decoder_list;
-
-/* interface of audio decoder drivers */
-struct ad_functions {
- const char *name;
- void (*add_decoders)(struct mp_decoder_list *list);
- 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);
- // Return whether or not the packet has been consumed.
- bool (*send_packet)(struct dec_audio *da, struct demux_packet *pkt);
- // Return whether decoding is still going on (false if EOF was reached).
- // Never returns false & *out set, but can return true with !*out.
- bool (*receive_frame)(struct dec_audio *da, struct mp_aframe **out);
-};
-
-enum ad_ctrl {
- ADCTRL_RESET = 1, // flush and reset state, e.g. after seeking
-};
-
-#endif /* MPLAYER_AD_H */
diff --git a/audio/decode/ad_lavc.c b/audio/decode/ad_lavc.c
index fb429d567b..7713a506a6 100644
--- a/audio/decode/ad_lavc.c
+++ b/audio/decode/ad_lavc.c
@@ -27,27 +27,30 @@
#include <libavutil/intreadwrite.h>
#include "mpv_talloc.h"
-
-#include "config.h"
+#include "audio/aframe.h"
+#include "audio/fmt-conversion.h"
#include "common/av_common.h"
#include "common/codecs.h"
+#include "common/global.h"
#include "common/msg.h"
+#include "demux/packet.h"
+#include "demux/stheader.h"
+#include "filters/f_decoder_wrapper.h"
+#include "filters/filter_internal.h"
#include "options/options.h"
-#include "ad.h"
-#include "audio/fmt-conversion.h"
-
struct priv {
AVCodecContext *avctx;
AVFrame *avframe;
- bool force_channel_map;
+ struct mp_chmap force_channel_map;
uint32_t skip_samples, trim_samples;
bool preroll_done;
double next_pts;
AVRational codec_timebase;
-};
+ bool eof_returned;
-static void uninit(struct dec_audio *da);
+ struct mp_decoder public;
+};
#define OPT_BASE_STRUCT struct ad_lavc_params
struct ad_lavc_params {
@@ -73,26 +76,24 @@ const struct m_sub_options ad_lavc_conf = {
},
};
-static int init(struct dec_audio *da, const char *decoder)
+static bool init(struct mp_filter *da, struct mp_codec_params *codec,
+ const char *decoder)
{
- struct MPOpts *mpopts = da->opts;
+ struct priv *ctx = da->priv;
+ struct MPOpts *mpopts = da->global->opts;
struct ad_lavc_params *opts = mpopts->ad_lavc_params;
AVCodecContext *lavc_context;
AVCodec *lavc_codec;
- struct mp_codec_params *c = da->codec;
-
- struct priv *ctx = talloc_zero(NULL, struct priv);
- da->priv = ctx;
- ctx->codec_timebase = mp_get_codec_timebase(da->codec);
+ ctx->codec_timebase = mp_get_codec_timebase(codec);
- ctx->force_channel_map = c->force_channels;
+ if (codec->force_channels)
+ ctx->force_channel_map = codec->channels;
lavc_codec = avcodec_find_decoder_by_name(decoder);
if (!lavc_codec) {
MP_ERR(da, "Cannot find codec '%s' in libavcodec...\n", decoder);
- uninit(da);
- return 0;
+ return false;
}
lavc_context = avcodec_alloc_context3(lavc_codec);
@@ -121,10 +122,9 @@ static int init(struct dec_audio *da, const char *decoder)
mp_set_avopts(da->log, lavc_context, opts->avopts);
- if (mp_set_avctx_codec_headers(lavc_context, c) < 0) {
+ if (mp_set_avctx_codec_headers(lavc_context, codec) < 0) {
MP_ERR(da, "Could not set decoder parameters.\n");
- uninit(da);
- return 0;
+ return false;
}
mp_set_avcodec_threads(da->log, lavc_context, opts->threads);
@@ -132,41 +132,35 @@ static int init(struct dec_audio *da, const char *decoder)
/* open it */
if (avcodec_open2(lavc_context, lavc_codec, NULL) < 0) {
MP_ERR(da, "Could not open codec.\n");
- uninit(da);
- return 0;
+ return false;
}
ctx->next_pts = MP_NOPTS_VALUE;
- return 1;
+ return true;
}
-static void uninit(struct dec_audio *da)
+static void destroy(struct mp_filter *da)
{
struct priv *ctx = da->priv;
- if (!ctx)
- return;
avcodec_free_context(&ctx->avctx);
av_frame_free(&ctx->avframe);
}
-static int control(struct dec_audio *da, int cmd, void *arg)
+static void reset(struct mp_filter *da)
{
struct priv *ctx = da->priv;
- switch (cmd) {
- case ADCTRL_RESET:
- avcodec_flush_buffers(ctx->avctx);
- ctx->skip_samples = 0;
- ctx->trim_samples = 0;
- ctx->preroll_done = false;
- ctx->next_pts = MP_NOPTS_VALUE;
- return CONTROL_TRUE;
- }
- return CONTROL_UNKNOWN;
+
+ avcodec_flush_buffers(ctx->avctx);
+ ctx->skip_samples = 0;
+ ctx->trim_samples = 0;
+ ctx->preroll_done = false;
+ ctx->next_pts = MP_NOPTS_VALUE;
+ ctx->eof_returned = false;
}
-static bool send_packet(struct dec_audio *da, struct demux_packet *mpkt)
+static bool send_packet(struct mp_filter *da, struct demux_packet *mpkt)
{
struct priv *priv = da->priv;
AVCodecContext *avctx = priv->avctx;
@@ -190,7 +184,7 @@ static bool send_packet(struct dec_audio *da, struct demux_packet *mpkt)
return true;
}
-static bool receive_frame(struct dec_audio *da, struct mp_aframe **out)
+static bool receive_frame(struct mp_filter *da, struct mp_frame *out)
{
struct priv *priv = da->priv;
AVCodecContext *avctx = priv->avctx;
@@ -200,7 +194,8 @@ static bool receive_frame(struct dec_audio *da, struct mp_aframe **out)
if (ret == AVERROR_EOF) {
// If flushing was initialized earlier and has ended now, make it start
// over in case we get new packets at some point in the future.
- control(da, ADCTRL_RESET, NULL);
+ // (Dont' reset the filter itself, we want to keep other state.)
+ avcodec_flush_buffers(priv->avctx);
return false;
} else if (ret < 0 && ret != AVERROR(EAGAIN)) {
MP_ERR(da, "Error decoding audio.\n");
@@ -220,8 +215,8 @@ static bool receive_frame(struct dec_audio *da, struct mp_aframe **out)
if (!mpframe)
return true;
- if (priv->force_channel_map)
- mp_aframe_set_chmap(mpframe, &da->codec->channels);
+ if (priv->force_channel_map.num)
+ mp_aframe_set_chmap(mpframe, &priv->force_channel_map);
if (out_pts == MP_NOPTS_VALUE)
out_pts = priv->next_pts;
@@ -257,24 +252,57 @@ static bool receive_frame(struct dec_audio *da, struct mp_aframe **out)
priv->trim_samples -= trim;
}
- *out = mpframe;
+ *out = MAKE_FRAME(MP_FRAME_AUDIO, mpframe);
av_frame_unref(priv->avframe);
return true;
}
+static void process(struct mp_filter *ad)
+{
+ struct priv *priv = ad->priv;
+
+ lavc_process(ad, &priv->eof_returned, send_packet, receive_frame);
+}
+
+static const struct mp_filter_info ad_lavc_filter = {
+ .name = "ad_lavc",
+ .priv_size = sizeof(struct priv),
+ .process = process,
+ .reset = reset,
+ .destroy = destroy,
+};
+
+static struct mp_decoder *create(struct mp_filter *parent,
+ struct mp_codec_params *codec,
+ const char *decoder)
+{
+ struct mp_filter *da = mp_filter_create(parent, &ad_lavc_filter);
+ if (!da)
+ return NULL;
+
+ mp_filter_add_pin(da, MP_PIN_IN, "in");
+ mp_filter_add_pin(da, MP_PIN_OUT, "out");
+
+ da->log = mp_log_new(da, parent->log, NULL);
+
+ struct priv *priv = da->priv;
+ priv->public.f = da;
+
+ if (!init(da, codec, decoder)) {
+ talloc_free(da);
+ return NULL;
+ }
+ return &priv->public;
+}
+
static void add_decoders(struct mp_decoder_list *list)
{
mp_add_lavc_decoders(list, AVMEDIA_TYPE_AUDIO);
}
-const struct ad_functions ad_lavc = {
- .name = "lavc",
+const struct mp_decoder_fns ad_lavc = {
+ .create = create,
.add_decoders = add_decoders,
- .init = init,
- .uninit = uninit,
- .control = control,
- .send_packet = send_packet,
- .receive_frame = receive_frame,
};
diff --git a/audio/decode/ad_spdif.c b/audio/decode/ad_spdif.c
index cc800224e9..c97c62ddaa 100644
--- a/audio/decode/ad_spdif.c
+++ b/audio/decode/ad_spdif.c
@@ -24,11 +24,16 @@
#include <libavcodec/avcodec.h>
#include <libavutil/opt.h>
-#include "config.h"
-#include "common/msg.h"
+#include "audio/aframe.h"
+#include "audio/format.h"
#include "common/av_common.h"
+#include "common/codecs.h"
+#include "common/msg.h"
+#include "demux/packet.h"
+#include "demux/stheader.h"
+#include "filters/f_decoder_wrapper.h"
+#include "filters/filter_internal.h"
#include "options/options.h"
-#include "ad.h"
#define OUTBUF_SIZE 65536
@@ -43,8 +48,8 @@ struct spdifContext {
struct mp_aframe *fmt;
int sstride;
struct mp_aframe_pool *pool;
- bool got_eof;
- struct demux_packet *queued_packet;
+
+ struct mp_decoder public;
};
static int write_packet(void *p, uint8_t *buf, int buf_size)
@@ -62,7 +67,8 @@ static int write_packet(void *p, uint8_t *buf, int buf_size)
return buf_size;
}
-static void uninit(struct dec_audio *da)
+// (called on both filter destruction _and_ if lavf fails to init)
+static void destroy(struct mp_filter *da)
{
struct spdifContext *spdif_ctx = da->priv;
AVFormatContext *lavf_ctx = spdif_ctx->lavf_ctx;
@@ -74,26 +80,11 @@ static void uninit(struct dec_audio *da)
av_freep(&lavf_ctx->pb->buffer);
av_freep(&lavf_ctx->pb);
avformat_free_context(lavf_ctx);
- talloc_free(spdif_ctx->queued_packet);
spdif_ctx->lavf_ctx = NULL;
}
}
-static int init(struct dec_audio *da, const char *decoder)
-{
- struct spdifContext *spdif_ctx = talloc_zero(NULL, struct spdifContext);
- da->priv = spdif_ctx;
- spdif_ctx->log = da->log;
- spdif_ctx->pool = mp_aframe_pool_create(spdif_ctx);
-
- if (strcmp(decoder, "spdif_dts_hd") == 0)
- spdif_ctx->use_dts_hd = true;
-
- spdif_ctx->codec_id = mp_codec_to_av_codec_id(da->codec->codec);
- return spdif_ctx->codec_id != AV_CODEC_ID_NONE;
-}
-
-static void determine_codec_params(struct dec_audio *da, AVPacket *pkt,
+static void determine_codec_params(struct mp_filter *da, AVPacket *pkt,
int *out_profile, int *out_rate)
{
struct spdifContext *spdif_ctx = da->priv;
@@ -156,7 +147,7 @@ done:
MP_WARN(da, "Failed to parse codec profile.\n");
}
-static int init_filter(struct dec_audio *da, AVPacket *pkt)
+static int init_filter(struct mp_filter *da, AVPacket *pkt)
{
struct spdifContext *spdif_ctx = da->priv;
@@ -270,39 +261,36 @@ static int init_filter(struct dec_audio *da, AVPacket *pkt)
return 0;
fail:
- uninit(da);
+ destroy(da);
+ mp_filter_internal_mark_failed(da);
return -1;
}
-
-static bool send_packet(struct dec_audio *da, struct demux_packet *mpkt)
+static void process(struct mp_filter *da)
{
struct spdifContext *spdif_ctx = da->priv;
- if (spdif_ctx->queued_packet || spdif_ctx->got_eof)
- return false;
-
- spdif_ctx->queued_packet = mpkt ? demux_copy_packet(mpkt) : NULL;
- spdif_ctx->got_eof = !mpkt;
- return true;
-}
-
-static bool receive_frame(struct dec_audio *da, struct mp_aframe **out)
-{
- struct spdifContext *spdif_ctx = da->priv;
+ if (!mp_pin_can_transfer_data(da->ppins[1], da->ppins[0]))
+ return;
- if (spdif_ctx->got_eof) {
- spdif_ctx->got_eof = false;
- return false;
+ struct mp_frame inframe = mp_pin_out_read(da->ppins[0]);
+ if (inframe.type == MP_FRAME_EOF) {
+ mp_pin_in_write(da->ppins[1], inframe);
+ return;
+ } else if (inframe.type != MP_FRAME_PACKET) {
+ if (inframe.type) {
+ MP_ERR(da, "unknown frame type\n");
+ mp_filter_internal_mark_failed(da);
+ }
+ return;
}
- if (!spdif_ctx->queued_packet)
- return true;
-
- double pts = spdif_ctx->queued_packet->pts;
+ struct demux_packet *mpkt = inframe.data;
+ struct mp_aframe *out = NULL;
+ double pts = mpkt->pts;
AVPacket pkt;
- mp_set_av_packet(&pkt, spdif_ctx->queued_packet, NULL);
+ mp_set_av_packet(&pkt, mpkt, NULL);
pkt.pts = pkt.dts = 0;
if (!spdif_ctx->lavf_ctx) {
if (init_filter(da, &pkt) < 0)
@@ -316,39 +304,29 @@ static bool receive_frame(struct dec_audio *da, struct mp_aframe **out)
goto done;
}
- *out = mp_aframe_new_ref(spdif_ctx->fmt);
+ out = mp_aframe_new_ref(spdif_ctx->fmt);
int samples = spdif_ctx->out_buffer_len / spdif_ctx->sstride;
- if (mp_aframe_pool_allocate(spdif_ctx->pool, *out, samples) < 0) {
- TA_FREEP(out);
+ if (mp_aframe_pool_allocate(spdif_ctx->pool, out, samples) < 0) {
+ TA_FREEP(&out);
goto done;
}
- uint8_t **data = mp_aframe_get_data_rw(*out);
+ uint8_t **data = mp_aframe_get_data_rw(out);
if (!data) {
- TA_FREEP(out);
+ TA_FREEP(&out);
goto done;
}
memcpy(data[0], spdif_ctx->out_buffer, spdif_ctx->out_buffer_len);
- mp_aframe_set_pts(*out, pts);
+ mp_aframe_set_pts(out, pts);
done:
- talloc_free(spdif_ctx->queued_packet);
- spdif_ctx->queued_packet = NULL;
- return true;
-}
-
-static int control(struct dec_audio *da, int cmd, void *arg)
-{
- struct spdifContext *spdif_ctx = da->priv;
- switch (cmd) {
- case ADCTRL_RESET:
- talloc_free(spdif_ctx->queued_packet);
- spdif_ctx->queued_packet = NULL;
- spdif_ctx->got_eof = false;
- return CONTROL_TRUE;
+ talloc_free(mpkt);
+ if (out) {
+ mp_pin_in_write(da->ppins[1], MAKE_FRAME(MP_FRAME_AUDIO, out));
+ } else {
+ mp_filter_internal_mark_failed(da);
}
- return CONTROL_UNKNOWN;
}
static const int codecs[] = {
@@ -405,12 +383,44 @@ struct mp_decoder_list *select_spdif_codec(const char *codec, const char *pref)
return list;
}
-const struct ad_functions ad_spdif = {
- .name = "spdif",
- .add_decoders = NULL,
- .init = init,
- .uninit = uninit,
- .control = control,
- .send_packet = send_packet,
- .receive_frame = receive_frame,
+static const struct mp_filter_info ad_spdif_filter = {
+ .name = "ad_spdif",
+ .priv_size = sizeof(struct spdifContext),
+ .process = process,
+ .destroy = destroy,
+};
+
+static struct mp_decoder *create(struct mp_filter *parent,
+ struct mp_codec_params *codec,
+ const char *decoder)
+{
+ struct mp_filter *da = mp_filter_create(parent, &ad_spdif_filter);
+ if (!da)
+ return NULL;
+
+ mp_filter_add_pin(da, MP_PIN_IN, "in");
+ mp_filter_add_pin(da, MP_PIN_OUT, "out");
+
+ da->log = mp_log_new(da, parent->log, NULL);
+
+ struct spdifContext *spdif_ctx = da->priv;
+ spdif_ctx->log = da->log;
+ spdif_ctx->pool = mp_aframe_pool_create(spdif_ctx);
+ spdif_ctx->public.f = da;
+
+ if (strcmp(decoder, "spdif_dts_hd") == 0)
+ spdif_ctx->use_dts_hd = true;
+
+ spdif_ctx->codec_id = mp_codec_to_av_codec_id(codec->codec);
+
+
+ if (spdif_ctx->codec_id == AV_CODEC_ID_NONE) {
+ talloc_free(da);
+ return NULL;
+ }
+ return &spdif_ctx->public;
+}
+
+const struct mp_decoder_fns ad_spdif = {
+ .create = create,
};
diff --git a/audio/decode/dec_audio.c b/audio/decode/dec_audio.c
deleted file mode 100644
index 111f981690..0000000000
--- a/audio/decode/dec_audio.c
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- * This file is part of mpv.
- *
- * 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 Lesser General Public License for more details.
- *
- * 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 <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <math.h>
-#include <assert.h>
-
-#include <libavutil/mem.h>
-
-#include "demux/codec_tags.h"
-
-#include "common/codecs.h"
-#include "common/msg.h"
-#include "common/recorder.h"
-#include "misc/bstr.h"
-#include "options/options.h"
-
-#include "stream/stream.h"
-#include "demux/demux.h"
-
-#include "demux/stheader.h"
-
-#include "dec_audio.h"
-#include "ad.h"
-#include "audio/format.h"
-
-extern const struct ad_functions ad_lavc;
-
-// Not a real codec - specially treated.
-extern const struct ad_functions ad_spdif;
-
-static const struct ad_functions * const ad_drivers[] = {
- &ad_lavc,
- NULL
-};
-
-static void uninit_decoder(struct dec_audio *d_audio)
-{
- audio_reset_decoding(d_audio);
- if (d_audio->ad_driver) {
- MP_VERBOSE(d_audio, "Uninit audio decoder.\n");
- d_audio->ad_driver->uninit(d_audio);
- }
- d_audio->ad_driver = NULL;
- talloc_free(d_audio->priv);
- d_audio->priv = NULL;
-}
-
-static int init_audio_codec(struct dec_audio *d_audio, const char *decoder)
-{
- if (!d_audio->ad_driver->init(d_audio, decoder)) {
- MP_VERBOSE(d_audio, "Audio decoder init failed.\n");
- d_audio->ad_driver = NULL;
- uninit_decoder(d_audio);
- return 0;
- }
-
- return 1;
-}
-
-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++)
- ad_drivers[i]->add_decoders(list);
- return list;
-}
-
-static struct mp_decoder_list *audio_select_decoders(struct dec_audio *d_audio)
-{
- struct MPOpts *opts = d_audio->opts;
- const char *codec = d_audio->codec->codec;
-
- struct mp_decoder_list *list = audio_decoder_list();
- struct mp_decoder_list *new =
- mp_select_decoders(d_audio->log, list, codec, opts->audio_decoders);
- if (d_audio->try_spdif && codec) {
- struct mp_decoder_list *spdif =
- select_spdif_codec(codec, opts->audio_spdif);
- mp_append_decoders(spdif, new);
- talloc_free(new);
- new = spdif;
- }
- talloc_free(list);
- return new;
-}
-
-static const struct ad_functions *find_driver(const char *name)
-{
- for (int i = 0; ad_drivers[i] != NULL; i++) {
- if (strcmp(ad_drivers[i]->name, name) == 0)
- return ad_drivers[i];
- }
- if (strcmp(name, "spdif") == 0)
- return &ad_spdif;
- return NULL;
-}
-
-int audio_init_best_codec(struct dec_audio *d_audio)
-{
- uninit_decoder(d_audio);
- assert(!d_audio->ad_driver);
-
- struct mp_decoder_entry *decoder = NULL;
- struct mp_decoder_list *list = audio_select_decoders(d_audio);
-
- mp_print_decoders(d_audio->log, MSGL_V, "Codec list:", list);
-
- for (int n = 0; n < list->num_entries; n++) {
- struct mp_decoder_entry *sel = &list->entries[n];
- const struct ad_functions *driver = find_driver(sel->family);
- if (!driver)
- continue;
- MP_VERBOSE(d_audio, "Opening audio decoder %s\n", sel->decoder);
- d_audio->ad_driver = driver;
- if (init_audio_codec(d_audio, sel->decoder)) {
- decoder = sel;
- break;
- }
- MP_WARN(d_audio, "Audio decoder init failed for %s\n", sel->decoder);
- }
-
- if (d_audio->ad_driver) {
- d_audio->decoder_desc =
- talloc_asprintf(d_audio, "%s (%s)", decoder->decoder, decoder->desc);
- 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->codec->codec);
- }
-
- talloc_free(list);
- return !!d_audio->ad_driver;
-}
-
-void audio_uninit(struct dec_audio *d_audio)
-{
- if (!d_audio)
- return;
- uninit_decoder(d_audio);
- talloc_free(d_audio);
-}
-
-void audio_reset_decoding(struct dec_audio *d_audio)
-{
- 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;
-}
-
-static void fix_audio_pts(struct dec_audio *da)
-{
- if (!da->current_frame)
- return;
-
- double frame_pts = mp_aframe_get_pts(da->current_frame);
- if (frame_pts != MP_NOPTS_VALUE) {
- if (da->pts != MP_NOPTS_VALUE)
- MP_STATS(da, "value %f audio-pts-err", da->pts - frame_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 || fabs(da->pts - frame_pts) > 0.001)
- da->pts = frame_pts;
- }
-
- if (da->pts == MP_NOPTS_VALUE && da->header->missing_timestamps)
- da->pts = 0;
-
- mp_aframe_set_pts(da->current_frame, da->pts);
-
- if (da->pts != MP_NOPTS_VALUE)
- da->pts += mp_aframe_duration(da->current_frame);
-}
-
-static bool is_new_segment(struct dec_audio *da, struct demux_packet *p)
-{
- return p->segmented &&
- (p->start != da->start || p->end != da->end || p->codec != da->codec);
-}
-
-static void feed_packet(struct dec_audio *da)
-{
- if (da->current_frame || !da->ad_driver)
- return;
-
- if (!da->packet && !da->new_segment &&
- demux_read_packet_async(da->header, &da->packet) == 0)
- {
- da->current_state = DATA_WAIT;
- return;
- }
-
- if (da->packet && is_new_segment(da, da->packet)) {
- assert(!da->new_segment);
- da->new_segment = da->packet;
- da->packet = NULL;
- }
-
- if (da->ad_driver->send_packet(da, da->packet)) {
- if (da->recorder_sink)
- mp_recorder_feed_packet(da->recorder_sink, da->packet);
-
- talloc_free(da->packet);
- da->packet = NULL;
- }
-
- da->current_state = DATA_AGAIN;
-}
-
-static void read_frame(struct dec_audio *da)
-{
- if (da->current_frame || !da->ad_driver)
- return;
-
- bool progress = da->ad_driver->receive_frame(da, &da->current_frame);
-
- da->current_state = da->current_frame ? DATA_OK : DATA_AGAIN;
- if (!progress)
- da->current_state = DATA_EOF;
-
- fix_audio_pts(da);
-
- bool segment_end = da->current_state == DATA_EOF;
-
- if (da->current_frame) {
- mp_aframe_clip_timestamps(da->current_frame, da->start, da->end);
- double frame_pts = mp_aframe_get_pts(da->current_frame);
- if (frame_pts != MP_NOPTS_VALUE && da->start != MP_NOPTS_VALUE)
- segment_end = frame_pts >= da->end;
- if (mp_aframe_get_size(da->current_frame) == 0) {
- talloc_free(da->current_frame);
- da->current_frame = NULL;
- }
- }
-
- // If there's a new segment, start it as soon as we're drained/finished.
- if (segment_end && da->new_segment) {
- struct demux_packet *new_segment = da->new_segment;
- da->new_segment = NULL;
-
- if (da->codec == new_segment->codec) {
- audio_reset_decoding(da);
- } else {
- da->codec = new_segment->codec;
- da->ad_driver->uninit(da);
- da->ad_driver = NULL;
- audio_init_best_codec(da);
- }
-
- da->start = new_segment->start;
- da->end = new_segment->end;
-
- da->packet = new_segment;
- da->current_state = DATA_AGAIN;
- }
-}
-
-void audio_work(struct dec_audio *da)
-{
- read_frame(da);
- if (!da->current_frame) {
- feed_packet(da);
- if (da->current_state == DATA_WAIT)
- return;
- read_frame(da); // retry, to avoid redundant iterations
- }
-}
-
-// Fetch an audio frame decoded with audio_work(). Returns one of:
-// DATA_OK: *out_frame is set to a new image
-// DATA_WAIT: waiting for demuxer; will receive a wakeup signal
-// DATA_EOF: end of file, no more frames to be expected
-// DATA_AGAIN: dropped frame or something similar
-int audio_get_frame(struct dec_audio *da, struct mp_aframe **out_frame)
-{
- *out_frame = NULL;
- if (da->current_frame) {
- *out_frame = da->current_frame;
- da->current_frame = NULL;
- return DATA_OK;
- }
- if (da->current_state == DATA_OK)
- return DATA_AGAIN;
- return da->current_state;
-}
diff --git a/audio/decode/dec_audio.h b/audio/decode/dec_audio.h
deleted file mode 100644
index ea504328df..0000000000
--- a/audio/decode/dec_audio.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * This file is part of mpv.
- *
- * 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 Lesser General Public License for more details.
- *
- * 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 MPLAYER_DEC_AUDIO_H
-#define MPLAYER_DEC_AUDIO_H
-
-#include "audio/chmap.h"
-#include "audio/aframe.h"
-#include "demux/demux.h"
-#include "demux/stheader.h"
-
-struct mp_decoder_list;
-
-struct dec_audio {
- struct mp_log *log;
- struct MPOpts *opts;
- struct mpv_global *global;
- const struct ad_functions *ad_driver;
- struct sh_stream *header;
- struct mp_codec_params *codec;
- char *decoder_desc;
-
- bool try_spdif;
-
- struct mp_recorder_sink *recorder_sink;
-
- // For free use by the ad_driver
- void *priv;
-
- // Strictly internal (dec_audio.c).
-
- double pts; // endpts of previous frame
- double start, end;
- struct demux_packet *packet;
- struct demux_packet *new_segment;
- struct mp_aframe *current_frame;
- int current_state;
-};
-
-struct mp_decoder_list *audio_decoder_list(void);
-int audio_init_best_codec(struct dec_audio *d_audio);
-void audio_uninit(struct dec_audio *d_audio);
-
-void audio_work(struct dec_audio *d_audio);
-int audio_get_frame(struct dec_audio *d_audio, struct mp_aframe **out_frame);
-
-void audio_reset_decoding(struct dec_audio *d_audio);
-
-// ad_spdif.c
-struct mp_decoder_list *select_spdif_codec(const char *codec, const char *pref);
-
-#endif /* MPLAYER_DEC_AUDIO_H */