audiodecoder: Handle instant-rate-change event

When receiving an instant-rate-change event, store the updated
seek flags and replace the flags in any input segments with them
to allow for instant switching between trickmodes and not.
This commit is contained in:
Jan Schmidt 2018-11-30 23:10:55 +11:00 committed by Sebastian Dröge
parent 8cb14728a7
commit fd3942d06b

View file

@ -214,6 +214,10 @@ struct _GstAudioDecoderPrivate
gboolean force; gboolean force;
/* input_segment are output_segment identical */ /* input_segment are output_segment identical */
gboolean in_out_segment_sync; gboolean in_out_segment_sync;
/* TRUE if we have an active set of instant rate flags */
gboolean decode_flags_override;
GstSegmentFlags decode_flags;
/* expecting the buffer with DISCONT flag */ /* expecting the buffer with DISCONT flag */
gboolean expecting_discont_buf; gboolean expecting_discont_buf;
@ -519,6 +523,7 @@ gst_audio_decoder_reset (GstAudioDecoder * dec, gboolean full)
gst_object_unref (dec->priv->ctx.allocator); gst_object_unref (dec->priv->ctx.allocator);
GST_OBJECT_LOCK (dec); GST_OBJECT_LOCK (dec);
dec->priv->decode_flags_override = FALSE;
gst_caps_replace (&dec->priv->ctx.input_caps, NULL); gst_caps_replace (&dec->priv->ctx.input_caps, NULL);
gst_caps_replace (&dec->priv->ctx.caps, NULL); gst_caps_replace (&dec->priv->ctx.caps, NULL);
gst_caps_replace (&dec->priv->ctx.allocation_caps, NULL); gst_caps_replace (&dec->priv->ctx.allocation_caps, NULL);
@ -2373,9 +2378,19 @@ gst_audio_decoder_sink_eventfunc (GstAudioDecoder * dec, GstEvent * event)
dec->priv->samples = 0; dec->priv->samples = 0;
} }
/* Update the decode flags in the segment if we have an instant-rate
* override active */
GST_OBJECT_LOCK (dec);
if (dec->priv->decode_flags_override) {
seg.flags &= ~GST_SEGMENT_INSTANT_FLAGS;
seg.flags |= dec->priv->decode_flags & GST_SEGMENT_INSTANT_FLAGS;
}
/* and follow along with segment */ /* and follow along with segment */
dec->priv->in_out_segment_sync = FALSE; dec->priv->in_out_segment_sync = FALSE;
dec->input_segment = seg; dec->input_segment = seg;
GST_OBJECT_UNLOCK (dec);
dec->priv->pending_events = dec->priv->pending_events =
g_list_append (dec->priv->pending_events, event); g_list_append (dec->priv->pending_events, event);
GST_AUDIO_DECODER_STREAM_UNLOCK (dec); GST_AUDIO_DECODER_STREAM_UNLOCK (dec);
@ -2383,6 +2398,27 @@ gst_audio_decoder_sink_eventfunc (GstAudioDecoder * dec, GstEvent * event)
ret = TRUE; ret = TRUE;
break; break;
} }
case GST_EVENT_INSTANT_RATE_CHANGE:
{
GstSegmentFlags flags;
GstSegment *seg;
gst_event_parse_instant_rate_change (event, NULL, &flags);
GST_OBJECT_LOCK (dec);
dec->priv->decode_flags_override = TRUE;
dec->priv->decode_flags = flags;
/* Update the input segment flags */
seg = &dec->input_segment;
seg->flags &= ~GST_SEGMENT_INSTANT_FLAGS;
seg->flags |= dec->priv->decode_flags & GST_SEGMENT_INSTANT_FLAGS;
GST_OBJECT_UNLOCK (dec);
/* Forward downstream */
ret = gst_pad_event_default (dec->sinkpad, GST_OBJECT_CAST (dec), event);
break;
}
case GST_EVENT_GAP: case GST_EVENT_GAP:
ret = gst_audio_decoder_handle_gap (dec, event); ret = gst_audio_decoder_handle_gap (dec, event);
break; break;