summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--audio/decode/ad.h11
-rw-r--r--audio/decode/ad_lavc.c68
-rw-r--r--audio/decode/ad_mpg123.c110
-rw-r--r--audio/decode/ad_spdif.c30
-rw-r--r--audio/decode/dec_audio.c161
-rw-r--r--audio/decode/dec_audio.h30
-rw-r--r--demux/stheader.h5
-rw-r--r--mpvcore/player/audio.c85
-rw-r--r--mpvcore/player/command.c32
-rw-r--r--mpvcore/player/loadfile.c30
-rw-r--r--mpvcore/player/main.c2
-rw-r--r--mpvcore/player/mp_core.h6
-rw-r--r--mpvcore/player/osd.c4
-rw-r--r--mpvcore/player/playloop.c36
-rw-r--r--mpvcore/player/video.c8
15 files changed, 327 insertions, 291 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);
<