summaryrefslogtreecommitdiffstats
path: root/audio/decode/ad_lavc.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-07-21 19:29:37 +0200
committerwm4 <wm4@nowhere>2014-07-21 19:29:58 +0200
commitb6af44d31e5c00b512e4c64b7075b771286e7c74 (patch)
tree0590b1095d13c61a538d622c1383f96554f27c85 /audio/decode/ad_lavc.c
parent1f9e0a15a13f9b1efece10515c57e5ed4683e9f3 (diff)
downloadmpv-b6af44d31e5c00b512e4c64b7075b771286e7c74.tar.bz2
mpv-b6af44d31e5c00b512e4c64b7075b771286e7c74.tar.xz
audio: move initial decode to generic code
This commit mainly moves the initial decoding of data (done to probe the audio format) to generic code. This will make it easier to make audio decoding non-blocking in a later commit. This commit also changes how decoders return data: instead of having them write the data into a prepared buffer, they return a reference to an internal buffer (by setting dec_audio.decoded). This makes it significantly easier to handle audio format changes, since the decoders don't really need to care anymore.
Diffstat (limited to 'audio/decode/ad_lavc.c')
-rw-r--r--audio/decode/ad_lavc.c69
1 files changed, 14 insertions, 55 deletions
diff --git a/audio/decode/ad_lavc.c b/audio/decode/ad_lavc.c
index 4d892da32b..cb8cfa8c82 100644
--- a/audio/decode/ad_lavc.c
+++ b/audio/decode/ad_lavc.c
@@ -49,7 +49,6 @@ struct priv {
};
static void uninit(struct dec_audio *da);
-static int decode_new_packet(struct dec_audio *da);
#define OPT_BASE_STRUCT struct ad_lavc_params
struct ad_lavc_params {
@@ -143,11 +142,10 @@ static const char *find_pcm_decoder(const struct pcm_map *map, int format,
return NULL;
}
-static int setup_format(struct dec_audio *da)
+static void set_data_from_avframe(struct dec_audio *da)
{
struct priv *priv = da->priv;
AVCodecContext *lavc_context = priv->avctx;
- struct sh_audio *sh_audio = da->header->audio;
// Note: invalid parameters are rejected by dec_audio.c
@@ -164,12 +162,15 @@ static int setup_format(struct dec_audio *da)
if (lavc_chmap.num != lavc_context->channels)
mp_chmap_from_channels(&lavc_chmap, lavc_context->channels);
if (priv->force_channel_map) {
+ struct sh_audio *sh_audio = da->header->audio;
if (lavc_chmap.num == sh_audio->channels.num)
lavc_chmap = sh_audio->channels;
}
mp_audio_set_channels(&da->decoded, &lavc_chmap);
- return 0;
+ da->decoded.samples = priv->avframe->nb_samples;
+ for (int n = 0; n < da->decoded.num_planes; n++)
+ da->decoded.planes[n] = priv->avframe->data[n];
}
static void set_from_wf(AVCodecContext *avctx, MP_WAVEFORMATEX *wf)
@@ -261,22 +262,6 @@ static int init(struct dec_audio *da, const char *decoder)
uninit(da);
return 0;
}
- MP_VERBOSE(da, "INFO: libavcodec \"%s\" init OK!\n",
- lavc_codec->name);
-
- // Decode at least 1 sample: (to get header filled)
- for (int tries = 1; ; tries++) {
- int x = decode_new_packet(da);
- if (x >= 0 && ctx->frame.samples > 0) {
- MP_VERBOSE(da, "Initial decode succeeded after %d packets.\n", tries);
- break;
- }
- if (tries >= 50) {
- MP_ERR(da, "initial decode failed\n");
- uninit(da);
- return 0;
- }
- }
if (lavc_context->bit_rate != 0)
da->bitrate = lavc_context->bit_rate;
@@ -308,7 +293,7 @@ static int control(struct dec_audio *da, int cmd, void *arg)
switch (cmd) {
case ADCTRL_RESET:
avcodec_flush_buffers(ctx->avctx);
- ctx->frame.samples = 0;
+ mp_audio_set_null_data(&da->decoded);
talloc_free(ctx->packet);
ctx->packet = NULL;
return CONTROL_TRUE;
@@ -316,12 +301,12 @@ static int control(struct dec_audio *da, int cmd, void *arg)
return CONTROL_UNKNOWN;
}
-static int decode_new_packet(struct dec_audio *da)
+static int decode_packet(struct dec_audio *da)
{
struct priv *priv = da->priv;
AVCodecContext *avctx = priv->avctx;
- priv->frame.samples = 0;
+ mp_audio_set_null_data(&da->decoded);
struct demux_packet *mpkt = priv->packet;
if (!mpkt)
@@ -361,19 +346,13 @@ static int decode_new_packet(struct dec_audio *da)
return 0;
}
if (ret < 0) {
- MP_VERBOSE(da, "lavc_audio: error\n");
- return -1;
+ MP_ERR(da, "Error decoding audio.\n");
+ return AD_ERR;
}
if (!got_frame)
- return mpkt ? 0 : -1; // -1: eof
-
- if (setup_format(da) < 0)
- return -1;
+ return mpkt ? AD_OK : AD_EOF;
- priv->frame.samples = priv->avframe->nb_samples;
- mp_audio_copy_config(&priv->frame, &da->decoded);
- for (int n = 0; n < priv->frame.num_planes; n++)
- priv->frame.planes[n] = priv->avframe->data[n];
+ set_data_from_avframe(da);
double out_pts = mp_pts_from_av(priv->avframe->pkt_pts, NULL);
if (out_pts != MP_NOPTS_VALUE) {
@@ -381,27 +360,7 @@ static int decode_new_packet(struct dec_audio *da)
da->pts_offset = 0;
}
- MP_DBG(da, "Decoded %d -> %d samples\n", in_len,
- priv->frame.samples);
- return 0;
-}
-
-static int decode_audio(struct dec_audio *da, struct mp_audio *buffer, int maxlen)
-{
- struct priv *priv = da->priv;
-
- if (!priv->frame.samples) {
- if (decode_new_packet(da) < 0)
- return AD_ERR;
- }
-
- if (!mp_audio_config_equals(buffer, &priv->frame))
- return 0;
-
- 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);
- da->pts_offset += buffer->samples;
+ MP_DBG(da, "Decoded %d -> %d samples\n", in_len, da->decoded.samples);
return 0;
}
@@ -418,5 +377,5 @@ const struct ad_functions ad_lavc = {
.init = init,
.uninit = uninit,
.control = control,
- .decode_audio = decode_audio,
+ .decode_packet = decode_packet,
};