/** from the stream, a packet packet is detached and delivered to the decoder. * *//***************************************************************************** * Demux:read packet and send them to Decoders ***************************************************************************** * TODO Check for newly Selected track (ie audio UpT-now) **************************************************************************** */Static intDemux (demux_t *P_demux) {demux_sys_t*p_sys = p_demux->P_sys; unsignedintI_track; unsignedinti_track_selected; /*Check for newly selected/unselected track*/ //check each media track to find out which media tracks are available. for(I_track =0, i_track_selected =0; I_track < p_sys->i_tracks; I_track++) {mp4_track_t*TK = &p_sys->track[i_track];//the moral context of the media track. BOOLb; if(!TK->B_OK | | tk->b_chapter | |(TK->b_selected && tk->i_sample >= tk->i_sample_count))//It seems that this track is not quite normal. { Continue; } es_out_control (P_demux- out, Es_out_get_es_state, Tk->p_es, &b);//See if the decoder is normal. if(tk->b_selected &&!)b) {mp4_trackunselect (P_demux, TK); } Else if(!tk->b_selected &&b) {mp4_trackselect (P_demux, TK, mp4_getmoviepts (P_sys)); } if(tk->b_selected) {i_track_selected++; } } if(I_track_selected <=0) {P_sys->i_time + = __max (P_sys->i_timescale/Ten,1 ); if(P_sys->i_timescale >0) {int64_t i_length= Clock_freq *(mtime_t) P_sys->moovfragment.i_duration/(mtime_t) P_sys-I_timescale; if(Mp4_getmoviepts (P_sys) >=i_length)return 0; return 1; } msg_warn (P_demux,"No track selected, exiting ..." ); return 0; } /* */Mp4_updateseekpoint (P_DEMUX); /*First wait for the good time to read a packet*/P_sys->I_PCR =mp4_getmoviepts (P_sys); BOOLB_data_sent =false; /*Find next track matching contiguous data*/mp4_track_t*TK =NULL; uint64_t I_candidate_pos=Uint64_max; mtime_t I_candidate_dts=Int64_max; for(I_track =0; I_track < p_sys->i_tracks; i_track++) {mp4_track_t*tk_tmp = &p_sys->Track[i_track]; if(!TK_TMP->B_OK | | tk_tmp->b_chapter | |!tk_tmp->b_selected | | tk_tmp->i_sample >= tk_tmp->i_sample_count)Continue; if(p_sys->B_seekmode) {mtime_t I_dts=Mp4_trackgetdts (P_demux, tk_tmp); if(I_dts <=I_candidate_dts) {tk=tk_tmp; I_candidate_dts=I_dts; I_candidate_pos=Mp4_trackgetpos (tk_tmp); } } Else { /*Try to avoid seeking on non fastseekable. Would fail with non interleaved content*/uint64_t I_pos=Mp4_trackgetpos (tk_tmp); if(I_pos <=I_candidate_pos) {I_candidate_pos=I_pos; TK=tk_tmp; } } } if( !tk) {msg_dbg (P_demux,"Could not select track by data position" ); Gotoend; } Else if(p_sys->B_seekmode) { if(Stream_seek (p_demux->s, I_candidate_pos)) {Msg_warn (P_demux,"track[0x%x] would be disabled (EOF?)", TK-i_track_id); Mp4_trackunselect (P_demux, TK); Gotoend; } }#if0msg_dbg (P_demux,"tk (%i) =%"PRId64"mv=%"PRId64"pos=%"PRIu64, I_track, Mp4_trackgetdts (P_demux, TK), mp4_getmoviepts (P_sys), i_candidate_pos); /c6>#endifuint32_t i_nb_samples=0; uint32_t i_samplessize= Mp4_trackgetreadsize (tk, &i_nb_samples); if(I_samplessize >0) {block_t*P_block; int64_t I_delta; uint64_t I_current_pos; /*go,go Go!*/ if( ! Mp4_stream_tell (P_demux->s, &I_current_pos)) Gotoend; if(I_current_pos! =I_candidate_pos) { if(Stream_seek (p_demux->s, I_candidate_pos)) {Msg_warn (P_demux,"track[0x%x] would be disabled (EOF?)", TK-i_track_id); Mp4_trackunselect (P_demux, TK); Gotoend; } } /*Now read PES*/ if( ! (P_block = Stream_block (p_demux->s, i_samplessize)) ) {Msg_warn (P_demux,"track[0x%x] would be disabled (EOF?)", TK-i_track_id); Mp4_trackunselect (P_demux, TK); Gotoend; } Else if(Tk->fmt.i_cat = =spu_es) { if(Tk->fmt.i_codec! = vlc_codec_tx3g &&tk->fmt.i_codec! =VLC_CODEC_SPU) P_block->i_buffer =0; } /*DTS*/P_block->i_dts = Vlc_ts_0 +Mp4_trackgetdts (P_demux, TK); /*pts*/I_delta=Mp4_trackgetptsdelta (P_demux, TK); if(I_delta! =-1) P_block->i_pts = P_block->i_dts +I_delta; Else if(Tk->fmt.i_cat! =video_es) P_block->i_pts = p_block->I_dts; ElseP_block->i_pts =Vlc_ts_invalid; if( !b_data_sent) {Es_out_control (P_demux- out, ES_OUT_SET_PCR, Vlc_ts_0 + p_sys->I_PCR); B_data_sent=true; } es_out_send (P_demux- out, tk->P_es, P_block); } /*Next Sample*/ if(I_nb_samples)/*sample size could is 0, need to go fwd. See return*/mp4_tracknextsample (P_demux, TK, i_nb_samples); End:if(b_data_sent) {P_sys->I_PCR =Int64_max; for(I_track =0; I_track < p_sys->i_tracks; i_track++) {mp4_track_t*TK = &p_sys->Track[i_track]; if(!TK->B_OK | |!tk->b_selected | |(TK->fmt.i_cat! = Audio_es && Tk->fmt.i_cat! =video_es)) Continue; mtime_t I_dts=Mp4_trackgetdts (P_demux, TK); P_sys->I_PCR = __min (I_dts, p_sys->I_PCR); if(!p_sys->b_seekmode && I_dts > P_SYS->I_PCR +2*clock_freq) {msg_dbg (P_demux,"that media doesn ' t look interleaved, would need to seek"); P_sys->b_seekmode =true; } P_sys->i_time = P_SYS->I_PCR * P_sys->i_timescale/Clock_freq; } } returnb_data_sent | | (I_samplessize = =0&&i_nb_samples);}
Demux function Analysis of MP4 of VLC