Skip to content

oggdemux: fix a race in push mode when performing the duration seek

There may be two or more threads involved here however the important interaction is the use of ogg->seeK_event_drop_till value that was only set in the push-mode seek-event thread and could race with upstream sending e.g. and EOS (or data).

Scenario is this:

  1. oggdemux performs a seek to near the end of the file to try and find the duration. ogg->push_state is set to PUSH_DURATION.
  2. Seek is picked up by the dedicated seek event thread and sets ogg->seek_event_drop_till to the seek event's seqnum.
  3. Most operations are blocked or dropped waiting on the duration to be determined and processing continues until a duration is found.
  4. Two branching options for how this ultimately plays out 4a. The source is too fast and we receive an EOS event which is dropped because ogg->push_state == PUSH_DURATION. In this case everything works. 4b. We hit our 'almost at the end' check in gst_ogg_pad_handle_push_mode_state() and attempt to seek back to the beginning (or to a user-provided seek). This seek is marshalled to the seek event thread without setting ogg->seek_event_drop_till but with change ogg->push_state = PUSH_PLAYING. If an EOS event or e.g. buffers arrive from upstream before the seek event thread has picked up the seek event, then the EOS/data is processed as if it came as a result of the seek event. This is the case that fails.

The fix is two-fold:

  1. Preemptively set ogg->seek_event_drop_till when setting the seek event so that data and other events can be dropped correctly.
  2. In addition to dropping and EOS events while ogg->push_state == PUSH_DURATION, also drop any EOS events that are received before the seek event has been processed by also tracking the seqnum of the seek.

Merge request reports