static void demux_demuxers_seek(demuxer_t *demuxer,float rel_seek_secs,float audio_delay,int flags) { dd_priv_t* priv; float pos; priv=demuxer->priv; priv->ad->stream->eof = 0; priv->sd->stream->eof = 0; // Seek video demux_seek(priv->vd,rel_seek_secs,audio_delay,flags); // Get the new pos pos = demuxer->video->pts; if (!pos) { demux_fill_buffer(priv->vd, demuxer->video); if (demuxer->video->first) pos = demuxer->video->first->pts; } if(priv->ad != priv->vd && demuxer->audio->sh) { sh_audio_t* sh = demuxer->audio->sh; demux_seek(priv->ad,pos,audio_delay,1); // In case the demuxer don't set pts if(!demuxer->audio->pts) demuxer->audio->pts = pos-((ds_tell_pts(demuxer->audio)-sh->a_in_buffer_len)/(float)sh->i_bps); } if(priv->sd != priv->vd) demux_seek(priv->sd,pos,audio_delay,1); }
/// Returns a_pts double calc_a_pts(sh_audio_t *sh_audio, demux_stream_t *d_audio) { double a_pts; if(!sh_audio || !d_audio) return MP_NOPTS_VALUE; // first calculate the end pts of audio that has been output by decoder a_pts = sh_audio->pts; // If we cannot get any useful information at all from the demuxer layer // just count the decoded bytes. This is still better than constantly // resetting to 0. if (sh_audio->pts_bytes && a_pts == MP_NOPTS_VALUE && !d_audio->pts && !sh_audio->i_bps) a_pts = 0; if (a_pts != MP_NOPTS_VALUE) // Good, decoder supports new way of calculating audio pts. // sh_audio->pts is the timestamp of the latest input packet with // known pts that the decoder has decoded. sh_audio->pts_bytes is // the amount of bytes the decoder has written after that timestamp. a_pts += sh_audio->pts_bytes / (double) sh_audio->o_bps; else { // Decoder doesn't support new way of calculating pts (or we're // being called before it has decoded anything with known timestamp). // Use the old method of audio pts calculation: take the timestamp // of last packet with known pts the decoder has read data from, // and add amount of bytes read after the beginning of that packet // divided by input bps. This will be inaccurate if the input/output // ratio is not constant for every audio packet or if it is constant // but not accurately known in sh_audio->i_bps. a_pts = d_audio->pts; // ds_tell_pts returns bytes read after last timestamp from // demuxing layer, decoder might use sh_audio->a_in_buffer for bytes // it has read but not decoded if (sh_audio->i_bps) a_pts += (ds_tell_pts(d_audio) - sh_audio->a_in_buffer_len) / (double)sh_audio->i_bps; } return a_pts; }
static void demux_demuxers_seek(demuxer_t *demuxer,float rel_seek_secs,float audio_delay,int flags) { dd_priv_t* priv; float pos; priv=demuxer->priv; priv->ad->stream->eof = 0; priv->sd->stream->eof = 0; // Seek video demux_seek(priv->vd,rel_seek_secs,audio_delay,flags); // Get the new pos pos = demuxer->video->pts; if (!pos) { // since the video demuxer might provide multiple // streams (e.g. subs) we might have to call // demux_fill_buffer multiple times. int limit = 10; do { demux_fill_buffer(priv->vd, demuxer->video); } while (--limit && !demuxer->video->first); if (demuxer->video->first) pos = demuxer->video->first->pts; } if(priv->ad != priv->vd && demuxer->audio->sh) { sh_audio_t* sh = demuxer->audio->sh; demux_seek(priv->ad,pos,audio_delay,1); // In case the demuxer don't set pts if(!demuxer->audio->pts) demuxer->audio->pts = pos-((ds_tell_pts(demuxer->audio)-sh->a_in_buffer_len)/(float)sh->i_bps); } if(priv->sd != priv->vd) demux_seek(priv->sd,pos,audio_delay,1); }
static int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen) { DMO_AudioDecoder* ds_adec = sh_audio->context; // int len=-1; int size_in=0; int size_out=0; int srcsize=DMO_AudioDecoder_GetSrcSize(ds_adec, maxlen); mp_msg(MSGT_DECAUDIO,MSGL_DBG3,"DMO says: srcsize=%d (buffsize=%d) out_size=%d\n",srcsize,sh_audio->a_in_buffer_size,maxlen); if(srcsize>sh_audio->a_in_buffer_size) srcsize=sh_audio->a_in_buffer_size; // !!!!!! if(sh_audio->a_in_buffer_len<srcsize){ sh_audio->a_in_buffer_len+= demux_read_data(sh_audio->ds,&sh_audio->a_in_buffer[sh_audio->a_in_buffer_len], srcsize-sh_audio->a_in_buffer_len); } DMO_AudioDecoder_Convert(ds_adec, sh_audio->a_in_buffer,sh_audio->a_in_buffer_len, buf,maxlen, &size_in,&size_out); mp_dbg(MSGT_DECAUDIO,MSGL_DBG2,"DMO: audio %d -> %d converted (in_buf_len=%d of %d) %d\n",size_in,size_out,sh_audio->a_in_buffer_len,sh_audio->a_in_buffer_size,ds_tell_pts(sh_audio->ds)); if(size_in>=sh_audio->a_in_buffer_len){ sh_audio->a_in_buffer_len=0; } else { sh_audio->a_in_buffer_len-=size_in; memmove(sh_audio->a_in_buffer,&sh_audio->a_in_buffer[size_in],sh_audio->a_in_buffer_len); } // len=size_out; return size_out; }