vlc | branch: master | Rémi Denis-Courmont <r...@remlab.net> | Wed Jul 9 23:18:22 2014 +0300| [04c2e2360c113d0fd36548589baa2d723f4aaec4] | committer: Jean-Baptiste Kempf
smf: avoid arbitrarily long (PCR wise) Demux calls Always return after one tick or one events timestamp. > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=04c2e2360c113d0fd36548589baa2d723f4aaec4 --- modules/demux/smf.c | 82 +++++++++++++++++++++++++-------------------------- 1 file changed, 40 insertions(+), 42 deletions(-) diff --git a/modules/demux/smf.c b/modules/demux/smf.c index 48407c2..b55f9fc 100644 --- a/modules/demux/smf.c +++ b/modules/demux/smf.c @@ -93,14 +93,15 @@ static int ReadDeltaTime (stream_t *s, mtrk_t *track) struct demux_sys_t { es_out_id_t *es; - date_t pts; - uint64_t pulse; /* Pulses counter */ + date_t pts; /*< Play timestamp */ + uint64_t pulse; /*< Pulses counter */ + mtime_t tick; /*< Last tick timestamp */ - unsigned ppqn; /* Pulses Per Quarter Note */ + unsigned ppqn; /*< Pulses Per Quarter Note */ /* by the way, "quarter note" is "noire" in French */ - unsigned trackc; /* Number of tracks */ - mtrk_t trackv[]; /* Track states */ + unsigned trackc; /*< Number of tracks */ + mtrk_t trackv[]; /*< Track states */ }; /** @@ -359,55 +360,53 @@ skip: ***************************************************************************** * Returns -1 in case of error, 0 in case of EOF, 1 otherwise *****************************************************************************/ -static int Demux (demux_t *p_demux) +static int Demux (demux_t *demux) { - stream_t *s = p_demux->s; - demux_sys_t *p_sys = p_demux->p_sys; - uint64_t pulse = p_sys->pulse, next_pulse = UINT64_MAX; + demux_sys_t *sys = demux->p_sys; - if (pulse == UINT64_MAX) - return 0; /* all tracks are done */ + /* MIDI Tick emulation (ping the decoder every 10ms) */ + if (sys->tick <= date_Get (&sys->pts)) + { + block_t *tick = block_Alloc (1); + if (unlikely(tick == NULL)) + return VLC_ENOMEM; - es_out_Control (p_demux->out, ES_OUT_SET_PCR, date_Get (&p_sys->pts)); + tick->p_buffer[0] = 0xF9; + tick->i_dts = tick->i_pts = sys->tick; - for (unsigned i = 0; i < p_sys->trackc; i++) + es_out_Send (demux->out, sys->es, tick); + es_out_Control (demux->out, ES_OUT_SET_PCR, sys->tick); + + sys->tick += CLOCK_FREQ / 100; + return 1; + } + + /* MIDI events in chronological order across all tracks */ + uint64_t cur_pulse = sys->pulse, next_pulse = UINT64_MAX; + + for (unsigned i = 0; i < sys->trackc; i++) { - mtrk_t *track = p_sys->trackv + i; + mtrk_t *track = sys->trackv + i; - while (track->next == pulse) + while (track->next == cur_pulse) { - if (HandleMessage (p_demux, track) - || ReadDeltaTime (s, track)) + if (HandleMessage (demux, track) + || ReadDeltaTime (demux->s, track)) { - msg_Err (p_demux, "fatal parsing error"); + msg_Err (demux, "fatal parsing error"); return VLC_EGENERIC; } } - if (track->next < next_pulse) + if (next_pulse > track->next) next_pulse = track->next; } - mtime_t cur_tick = (date_Get (&p_sys->pts) + 9999) / 10000, last_tick; - if (next_pulse != UINT64_MAX) - last_tick = date_Increment (&p_sys->pts, next_pulse - pulse) / 10000; - else - last_tick = cur_tick + 1; - - /* MIDI Tick emulation (ping the decoder every 10ms) */ - while (cur_tick < last_tick) - { - block_t *tick = block_Alloc (1); - if (tick == NULL) - break; - - tick->p_buffer[0] = 0xF9; - tick->i_dts = tick->i_pts = VLC_TS_0 + cur_tick++ * 10000; - es_out_Send (p_demux->out, p_sys->es, tick); - } - - p_sys->pulse = next_pulse; + if (next_pulse == UINT64_MAX) + return 0; /* all tracks are done */ + date_Increment (&sys->pts, next_pulse - cur_pulse); + sys->pulse = next_pulse; return 1; } @@ -416,15 +415,13 @@ static int Demux (demux_t *p_demux) *****************************************************************************/ static int Control (demux_t *p_demux, int i_query, va_list args) { - demux_sys_t *p_sys = p_demux->p_sys; + demux_sys_t *sys = p_demux->p_sys; switch (i_query) { case DEMUX_GET_TIME: - { - *(va_arg (args, int64_t *)) = date_Get (&p_sys->pts); + *va_arg (args, int64_t *) = sys->tick - VLC_TS_0; return 0; - } #if 0 /* TODO: */ case DEMUX_SET_TIME: @@ -544,6 +541,7 @@ static int Open (vlc_object_t *obj) date_Init (&sys->pts, ppqn * 2, 1); date_Set (&sys->pts, VLC_TS_0); sys->pulse = 0; + sys->tick = VLC_TS_0; sys->ppqn = ppqn; sys->trackc = tracks; _______________________________________________ vlc-commits mailing list vlc-commits@videolan.org https://mailman.videolan.org/listinfo/vlc-commits