decklink: fixup internal time tracking over buffering pauses

Instead of relying on buffers after a state change to PLAYING to always start
from 0, track the amount of time we have spent outside playing but not changed
state to PAUSED.
This commit is contained in:
Matthew Waters 2018-11-21 08:43:56 -06:00
parent 65c9c4b406
commit d67d866eb9
2 changed files with 16 additions and 12 deletions

View file

@ -640,20 +640,21 @@ gst_decklink_video_sink_convert_to_internal_clock (GstDecklinkVideoSink * self,
GST_TIME_FORMAT, GST_TIME_ARGS (*timestamp)); GST_TIME_FORMAT, GST_TIME_ARGS (*timestamp));
} }
if (GST_CLOCK_TIME_IS_VALID (self->paused_start_time)) { if (GST_CLOCK_TIME_IS_VALID (self->paused_start_time) &&
GST_CLOCK_TIME_IS_VALID (self->playing_base_time)) {
/* add the time since we were last playing. */
*timestamp += self->paused_start_time + self->playing_base_time;
} else {
/* only valid whil we're in PAUSED and most likely without a set clock, /* only valid whil we're in PAUSED and most likely without a set clock,
* we update based on our internal clock */ * we update based on our internal clock */
*timestamp += gst_clock_get_internal_time (self->output->clock); *timestamp += gst_clock_get_internal_time (self->output->clock);
} else {
/* add the time since we were last playing. */
*timestamp += self->playing_start_time;
} }
GST_LOG_OBJECT (self, "Output timestamp %" GST_TIME_FORMAT GST_LOG_OBJECT (self, "Output timestamp %" GST_TIME_FORMAT
" using paused start at %" GST_TIME_FORMAT " playing start at %" " using paused start at %" GST_TIME_FORMAT " playing start at %"
GST_TIME_FORMAT, GST_TIME_ARGS (*timestamp), GST_TIME_FORMAT, GST_TIME_ARGS (*timestamp),
GST_TIME_ARGS (self->paused_start_time), GST_TIME_ARGS (self->paused_start_time),
GST_TIME_ARGS (self->playing_start_time)); GST_TIME_ARGS (self->playing_base_time));
} }
static GstFlowReturn static GstFlowReturn
@ -1211,6 +1212,9 @@ gst_decklink_video_sink_change_state (GstElement * element,
GST_STATE_CHANGE_FAILURE) GST_STATE_CHANGE_FAILURE)
ret = GST_STATE_CHANGE_FAILURE; ret = GST_STATE_CHANGE_FAILURE;
break; break;
case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
self->playing_exit_time = gst_clock_get_internal_time (self->output->clock);
break;
default: default:
break; break;
} }
@ -1259,12 +1263,11 @@ gst_decklink_video_sink_state_changed (GstElement * element,
GstDecklinkVideoSink *self = GST_DECKLINK_VIDEO_SINK_CAST (element); GstDecklinkVideoSink *self = GST_DECKLINK_VIDEO_SINK_CAST (element);
if (new_state == GST_STATE_PLAYING) { if (new_state == GST_STATE_PLAYING) {
self->paused_start_time = GST_CLOCK_TIME_NONE; self->playing_base_time = gst_clock_get_internal_time (self->output->clock) - self->playing_exit_time;
self->playing_start_time = GST_DEBUG_OBJECT (self, "playing entered paused start time %"
gst_clock_get_internal_time (self->output->clock); GST_TIME_FORMAT "playing base time %" GST_TIME_FORMAT,
GST_DEBUG_OBJECT (self, GST_TIME_ARGS (self->paused_start_time),
"playing entered, new playing start time %" GST_TIME_FORMAT, GST_TIME_ARGS (self->playing_base_time));
GST_TIME_ARGS (self->playing_start_time));
} }
if (new_state == GST_STATE_PAUSED) { if (new_state == GST_STATE_PAUSED) {

View file

@ -63,9 +63,10 @@ struct _GstDecklinkVideoSink
/* all in internal time of the decklink clock */ /* all in internal time of the decklink clock */
/* really an internal base time */ /* really an internal base time */
GstClockTime playing_start_time; /* time that we entered playing */ GstClockTime playing_base_time; /* time that we entered playing */
/* really an internal start time */ /* really an internal start time */
GstClockTime paused_start_time; /* time we entered paused, used to track how long we are in paused while the clock is running */ GstClockTime paused_start_time; /* time we entered paused, used to track how long we are in paused while the clock is running */
GstClockTime playing_exit_time; /* time that we exit playing */
GstDecklinkOutput *output; GstDecklinkOutput *output;