From 62e38774173972acab91e116f01050ef5cc0149f Mon Sep 17 00:00:00 2001 From: Uoti Urpala Date: Thu, 22 Dec 2011 05:54:48 +0200 Subject: [PATCH] ad_ffmpeg: pass packet side data from libavformat Pass avpacket->side_data when using a libavcodec audio decoder together with libavformat demuxer (this was already done for video). --- libmpcodecs/ad_ffmpeg.c | 39 ++++++++++++++++++++++++++------------- libmpdemux/demuxer.c | 7 ++++--- libmpdemux/demuxer.h | 2 +- mplayer.c | 2 +- 4 files changed, 32 insertions(+), 18 deletions(-) diff --git a/libmpcodecs/ad_ffmpeg.c b/libmpcodecs/ad_ffmpeg.c index e76c536957..cd742cf8f8 100644 --- a/libmpcodecs/ad_ffmpeg.c +++ b/libmpcodecs/ad_ffmpeg.c @@ -20,6 +20,7 @@ #include #include #include +#include #include @@ -47,7 +48,7 @@ LIBAD_EXTERN(ffmpeg) struct priv { AVCodecContext *avctx; - bool old_packet; + int previous_data_left; }; static int preinit(sh_audio_t *sh) @@ -230,7 +231,7 @@ static int control(sh_audio_t *sh, int cmd, void *arg, ...) case ADCTRL_RESYNC_STREAM: avcodec_flush_buffers(ctx->avctx); ds_clear_parser(sh->ds); - ctx->old_packet = false; + ctx->previous_data_left = 0; return CONTROL_TRUE; } return CONTROL_UNKNOWN; @@ -247,23 +248,37 @@ static int decode_audio(sh_audio_t *sh_audio, unsigned char *buf, int minlen, while (len < minlen) { AVPacket pkt; int len2 = maxlen; - double pts; - int x = ds_get_packet_pts(sh_audio->ds, &start, &pts); - if (x <= 0) { + double pts = MP_NOPTS_VALUE; + int x; + bool packet_already_used = ctx->previous_data_left; + struct demux_packet *mpkt = ds_get_packet2(sh_audio->ds, + ctx->previous_data_left); + if (!mpkt) { + assert(!ctx->previous_data_left); start = NULL; x = 0; - ds_parse(sh_audio->ds, &start, &x, MP_NOPTS_VALUE, 0); + ds_parse(sh_audio->ds, &start, &x, pts, 0); if (x <= 0) break; // error } else { - int in_size = x; + assert(mpkt->len >= ctx->previous_data_left); + if (!ctx->previous_data_left) { + ctx->previous_data_left = mpkt->len; + pts = mpkt->pts; + } + x = ctx->previous_data_left; + start = mpkt->buffer + mpkt->len - ctx->previous_data_left; int consumed = ds_parse(sh_audio->ds, &start, &x, pts, 0); - sh_audio->ds->buffer_pos -= in_size - consumed; + ctx->previous_data_left -= consumed; } av_init_packet(&pkt); pkt.data = start; pkt.size = x; - if (pts != MP_NOPTS_VALUE && !ctx->old_packet) { + if (mpkt && mpkt->avpacket) { + pkt.side_data = mpkt->avpacket->side_data; + pkt.side_data_elems = mpkt->avpacket->side_data_elems; + } + if (pts != MP_NOPTS_VALUE && !packet_already_used) { sh_audio->pts = pts; sh_audio->pts_bytes = 0; } @@ -275,10 +290,8 @@ static int decode_audio(sh_audio_t *sh_audio, unsigned char *buf, int minlen, mp_msg(MSGT_DECAUDIO, MSGL_V, "lavc_audio: error\n"); break; } - if (!sh_audio->parser && y < x) { - sh_audio->ds->buffer_pos += y - x; // put back data (HACK!) - ctx->old_packet = true; - } + if (!sh_audio->parser) + ctx->previous_data_left += x - y; if (len2 > 0) { if (avctx->channels >= 5) { int samplesize = av_get_bytes_per_sample(avctx->sample_fmt); diff --git a/libmpdemux/demuxer.c b/libmpdemux/demuxer.c index 199558c2ae..b3a1998d0c 100644 --- a/libmpdemux/demuxer.c +++ b/libmpdemux/demuxer.c @@ -831,11 +831,12 @@ int ds_get_packet_sub(demux_stream_t *ds, unsigned char **start) return len; } -struct demux_packet *ds_get_packet2(struct demux_stream *ds) +struct demux_packet *ds_get_packet2(struct demux_stream *ds, bool repeat_last) { // This shouldn't get used together with partial reads - assert(ds->buffer_pos >= ds->buffer_size); - ds_fill_buffer(ds); + assert(ds->buffer_pos == 0 || ds->buffer_pos >= ds->buffer_size); + if (!repeat_last) + ds_fill_buffer(ds); ds->buffer_pos = ds->buffer_size; return ds->current; } diff --git a/libmpdemux/demuxer.h b/libmpdemux/demuxer.h index 55fda059fe..cdea5baa61 100644 --- a/libmpdemux/demuxer.h +++ b/libmpdemux/demuxer.h @@ -346,7 +346,7 @@ int ds_get_packet(struct demux_stream *ds, unsigned char **start); int ds_get_packet_pts(struct demux_stream *ds, unsigned char **start, double *pts); int ds_get_packet_sub(struct demux_stream *ds, unsigned char **start); -struct demux_packet *ds_get_packet2(struct demux_stream *ds); +struct demux_packet *ds_get_packet2(struct demux_stream *ds, bool repeat_last); double ds_get_next_pts(struct demux_stream *ds); int ds_parse(struct demux_stream *sh, uint8_t **buffer, int *len, double pts, off_t pos); diff --git a/mplayer.c b/mplayer.c index d79d45f057..78199499e8 100644 --- a/mplayer.c +++ b/mplayer.c @@ -2933,7 +2933,7 @@ static double update_video(struct MPContext *mpctx) int in_size = 0; unsigned char *buf = NULL; pts = MP_NOPTS_VALUE; - struct demux_packet *pkt = ds_get_packet2(mpctx->d_video); + struct demux_packet *pkt = ds_get_packet2(mpctx->d_video, false); if (pkt) { in_size = pkt->len; buf = pkt->buffer;