Index: libmpcodecs/ad_pcm.c =================================================================== --- libmpcodecs/ad_pcm.c (revision 27776) +++ libmpcodecs/ad_pcm.c (working copy) @@ -16,6 +16,11 @@ "" }; +struct ad_pcm_context { + unsigned char *packet_ptr; + int packet_len; +}; + LIBAD_EXTERN(pcm) static int init(sh_audio_t *sh_audio) @@ -91,6 +96,7 @@ } if (!sh_audio->samplesize) // this would cause MPlayer to hang later sh_audio->samplesize = 2; + sh_audio->context = av_mallocz(sizeof(struct ad_pcm_context)); return 1; } @@ -102,6 +108,7 @@ static void uninit(sh_audio_t *sh) { + av_freep(&sh->context); } static int control(sh_audio_t *sh,int cmd,void* arg, ...) @@ -120,14 +127,40 @@ static int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen) { - unsigned len = sh_audio->channels*sh_audio->samplesize; - len = (minlen + len - 1) / len * len; - if (len > maxlen) + int len = sh_audio->channels*sh_audio->samplesize; + struct ad_pcm_context *ctx = sh_audio->context; + minlen = (minlen + len - 1) / len * len; + if (minlen > maxlen) // if someone needs hundreds of channels adjust audio_out_minsize // based on channels in preinit() return -1; - len=demux_read_data(sh_audio->ds,buf,len); - if (len > 0 && sh_audio->channels >= 5) { + + len = 0; + while (len < minlen) { + int plen = ctx->packet_len; + if (plen == 0) { + double pts; + plen = ds_get_packet_pts(sh_audio->ds, &ctx->packet_ptr, &pts); + if (plen <= 0) + break; + ctx->packet_len = plen; + if (pts != MP_NOPTS_VALUE) { + sh_audio->pts = pts; + sh_audio->pts_bytes = 0; + } + } + if (plen > minlen - len) + plen = minlen - len; + memcpy(buf, ctx->packet_ptr, plen); + ctx->packet_len -= plen; + ctx->packet_ptr += plen; + sh_audio->pts_bytes += plen; + len += plen; + buf += plen; + } + if (len <= 0) + return -1; // The loop above only exits at error/EOF + if (sh_audio->channels >= 5) { reorder_channel_nch(buf, AF_CHANNEL_LAYOUT_WAVEEX_DEFAULT, AF_CHANNEL_LAYOUT_MPLAYER_DEFAULT, sh_audio->channels,