mxfdemux: fix seeking, send data starting from a key unit

Fixes multiple seeking issues. When doing ACCURATE or normal
non-KEYUNIT seeks, mxfdemux would just send data from the
edit unit that covered the seek position, whether that's
a keyframe or not. Decoders would only output things from
the next keyframe then, which means there's a gap between
the start of the segment and the first decoded data in
some cases. In combination with gst-editing-services this
might result in a frozen picture for the duration of that
gap at the beginning (if videorate fixes up the first
buffer's start timestamp to cover the entire gap), or
a black frame (if no videorate is used and videomixer
fills the gap). Also fixes A/V sync issue when requesting
a KEYUNIT seek.
This commit is contained in:
Tim-Philipp Müller 2014-04-08 13:26:49 +01:00
parent 57a138df86
commit 4898a51afe

View file

@ -3400,10 +3400,11 @@ gst_mxf_demux_seek_pull (GstMXFDemux * demux, GstEvent * event)
p->last_flow = GST_FLOW_OK; p->last_flow = GST_FLOW_OK;
gst_mxf_demux_pad_set_position (demux, p, start); gst_mxf_demux_pad_set_position (demux, p, start);
/* we always want to send data starting with a key unit */
position = p->current_essence_track_position; position = p->current_essence_track_position;
off = off =
gst_mxf_demux_find_essence_element (demux, p->current_essence_track, gst_mxf_demux_find_essence_element (demux, p->current_essence_track,
&position, keyframe); &position, TRUE);
if (off == -1) { if (off == -1) {
GST_DEBUG_OBJECT (demux, "Unable to find offset for pad %s", GST_DEBUG_OBJECT (demux, "Unable to find offset for pad %s",
GST_PAD_NAME (p)); GST_PAD_NAME (p));
@ -3411,11 +3412,11 @@ gst_mxf_demux_seek_pull (GstMXFDemux * demux, GstEvent * event)
} else { } else {
new_offset = MIN (off, new_offset); new_offset = MIN (off, new_offset);
if (position != p->current_essence_track_position) { if (position != p->current_essence_track_position) {
p->last_flow -= p->position -=
gst_util_uint64_scale (p->current_essence_track_position - gst_util_uint64_scale (p->current_essence_track_position -
position, position,
GST_SECOND * p->current_essence_track->source_track->edit_rate.d, GST_SECOND * p->current_essence_track->source_track->edit_rate.d,
p->current_essence_track->source_track->edit_rate.d); p->current_essence_track->source_track->edit_rate.n);
} }
p->current_essence_track_position = position; p->current_essence_track_position = position;
} }
@ -3451,6 +3452,10 @@ gst_mxf_demux_seek_pull (GstMXFDemux * demux, GstEvent * event)
gst_event_set_seqnum (demux->close_seg_event, demux->seqnum); gst_event_set_seqnum (demux->close_seg_event, demux->seqnum);
} }
if (keyframe) {
/* FIXME: fix up segment start to position of key unit */
}
/* Ok seek succeeded, take the newly configured segment */ /* Ok seek succeeded, take the newly configured segment */
memcpy (&demux->segment, &seeksegment, sizeof (GstSegment)); memcpy (&demux->segment, &seeksegment, sizeof (GstSegment));