summaryrefslogtreecommitdiffstats
path: root/audio/decode/ad_lavc.c
diff options
context:
space:
mode:
Diffstat (limited to 'audio/decode/ad_lavc.c')
-rw-r--r--audio/decode/ad_lavc.c62
1 files changed, 26 insertions, 36 deletions
diff --git a/audio/decode/ad_lavc.c b/audio/decode/ad_lavc.c
index b5a4ee1ef8..e78e26f208 100644
--- a/audio/decode/ad_lavc.c
+++ b/audio/decode/ad_lavc.c
@@ -24,6 +24,7 @@
#include <libavcodec/avcodec.h>
#include <libavutil/opt.h>
+#include <libavutil/common.h>
#include "talloc.h"
@@ -50,8 +51,8 @@ struct priv {
uint8_t *output_packed; // used by deplanarize to store packed audio samples
int output_left;
int unitsize;
- int previous_data_left; // input demuxer packet data
bool force_channel_map;
+ struct demux_packet *packet;
};
#define OPT_BASE_STRUCT struct MPOpts
@@ -344,9 +345,9 @@ static int control(sh_audio_t *sh, int cmd, void *arg)
switch (cmd) {
case ADCTRL_RESYNC_STREAM:
avcodec_flush_buffers(ctx->avctx);
- ds_clear_parser(sh->ds);
- ctx->previous_data_left = 0;
ctx->output_left = 0;
+ talloc_free(ctx->packet);
+ ctx->packet = NULL;
return CONTROL_TRUE;
}
return CONTROL_UNKNOWN;
@@ -375,43 +376,35 @@ static int decode_new_packet(struct sh_audio *sh)
{
struct priv *priv = sh->context;
AVCodecContext *avctx = priv->avctx;
- double pts = MP_NOPTS_VALUE;
- int insize;
- bool packet_already_used = priv->previous_data_left;
- struct demux_packet *mpkt = ds_get_packet2(sh->ds,
- priv->previous_data_left);
- unsigned char *start;
- if (!mpkt) {
- assert(!priv->previous_data_left);
- start = NULL;
- insize = 0;
- ds_parse(sh->ds, &start, &insize, pts, 0);
- if (insize <= 0)
- return -1; // error or EOF
- } else {
- assert(mpkt->len >= priv->previous_data_left);
- if (!priv->previous_data_left) {
- priv->previous_data_left = mpkt->len;
- pts = mpkt->pts;
- }
- insize = priv->previous_data_left;
- start = mpkt->buffer + mpkt->len - priv->previous_data_left;
- int consumed = ds_parse(sh->ds, &start, &insize, pts, 0);
- priv->previous_data_left -= consumed;
- priv->previous_data_left = FFMAX(priv->previous_data_left, 0);
- }
+ struct demux_packet *mpkt = priv->packet;
+ if (!mpkt)
+ mpkt = demux_read_packet(sh->gsh);
+ if (!mpkt)
+ return -1; // error or EOF
+
+ priv->packet = talloc_steal(priv, mpkt);
+
+ int in_len = mpkt->len;
AVPacket pkt;
mp_set_av_packet(&pkt, mpkt);
- pkt.data = start;
- pkt.size = insize;
- if (pts != MP_NOPTS_VALUE && !packet_already_used) {
- sh->pts = pts;
+ if (mpkt->pts != MP_NOPTS_VALUE) {
+ sh->pts = mpkt->pts;
sh->pts_bytes = 0;
}
int got_frame = 0;
int ret = avcodec_decode_audio4(avctx, priv->avframe, &got_frame, &pkt);
+ if (ret > 0) {
+ ret = FFMIN(ret, mpkt->len); // sanity check against decoder overreads
+ mpkt->buffer += ret;
+ 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 0;
@@ -419,9 +412,6 @@ static int decode_new_packet(struct sh_audio *sh)
mp_msg(MSGT_DECAUDIO, MSGL_V, "lavc_audio: error\n");
return -1;
}
- // The "insize >= ret" test is sanity check against decoder overreads
- if (!sh->parser && insize >= ret)
- priv->previous_data_left = insize - ret;
if (!got_frame)
return 0;
uint64_t unitsize = (uint64_t)av_get_bytes_per_sample(avctx->sample_fmt) *
@@ -438,7 +428,7 @@ static int decode_new_packet(struct sh_audio *sh)
} else {
priv->output = priv->avframe->data[0];
}
- mp_dbg(MSGT_DECAUDIO, MSGL_DBG2, "Decoded %d -> %d \n", insize,
+ mp_dbg(MSGT_DECAUDIO, MSGL_DBG2, "Decoded %d -> %d \n", in_len,
priv->output_left);
return 0;
}