uint64_t pulse; /*< Pulses counter */
mtime_t tick; /*< Last tick timestamp */
+ mtime_t duration; /*< Total duration */
unsigned ppqn; /*< Pulses Per Quarter Note */
/* by the way, "quarter note" is "noire" in French */
}
static
-int HandleMessage (demux_t *p_demux, mtrk_t *tr)
+int HandleMessage (demux_t *p_demux, mtrk_t *tr, es_out_t *out)
{
stream_t *s = p_demux->s;
block_t *block;
send:
block->i_dts = block->i_pts = date_Get (&p_demux->p_sys->pts);
- es_out_Send (p_demux->out, p_demux->p_sys->es, block);
+ if (out != NULL)
+ es_out_Send (out, p_demux->p_sys->es, block);
+ else
+ block_Release (block);
skip:
if (event < 0xF8)
return 0;
}
-static int ReadEvents (demux_t *demux, uint64_t *restrict pulse)
+static int ReadEvents (demux_t *demux, uint64_t *restrict pulse,
+ es_out_t *out)
{
uint64_t cur_pulse = *pulse, next_pulse = UINT64_MAX;
demux_sys_t *sys = demux->p_sys;
while (track->next <= cur_pulse)
{
- if (HandleMessage (demux, track)
+ if (HandleMessage (demux, track, out)
|| ReadDeltaTime (demux->s, track))
{
msg_Err (demux, "fatal parsing error");
/* MIDI events in chronological order across all tracks */
uint64_t pulse = sys->pulse;
- if (ReadEvents (demux, &pulse))
+ if (ReadEvents (demux, &pulse, demux->out))
return VLC_EGENERIC;
if (pulse == UINT64_MAX)
switch (i_query)
{
- case DEMUX_GET_TIME:
- *va_arg (args, int64_t *) = sys->tick - VLC_TS_0;
- return 0;
-#if 0
- /* TODO: */
- case DEMUX_SET_TIME:
case DEMUX_GET_POSITION:
- case DEMUX_SET_POSITION:
+ if (!sys->duration)
+ return VLC_EGENERIC;
+ *va_arg (args, double *) = (sys->tick - (double)VLC_TS_0)
+ / sys->duration;
+ break;
+ //case DEMUX_SET_POSITION:
case DEMUX_GET_LENGTH:
-#endif
+ *va_arg (args, int64_t *) = sys->duration;
+ break;
+ case DEMUX_GET_TIME:
+ *va_arg (args, int64_t *) = sys->tick - VLC_TS_0;
+ break;
+ //case DEMUX_SET_TIME:
+ default:
+ return VLC_EGENERIC;
}
- return VLC_EGENERIC;
+ return VLC_SUCCESS;
}
/**
goto error;
demux->p_sys = sys;
+ sys->duration = 0;
sys->ppqn = ppqn;
sys->trackc = tracks;
tr->length = GetDWBE (head + 4);
}
+ bool b;
+ if (stream_Control (stream, STREAM_CAN_FASTSEEK, &b) == 0 && b)
+ {
+ if (SeekSet0 (demux))
+ goto error;
+
+ for (uint64_t pulse = 0; pulse != UINT64_MAX;)
+ if (ReadEvents (demux, &pulse, NULL))
+ break;
+
+ sys->duration = date_Get (&sys->pts);
+ }
+
if (SeekSet0 (demux))
goto error;