gboolean output_state_changed;
/* QoS properties */
- gdouble proportion;
- GstClockTime earliest_time;
+ gdouble proportion; /* OBJECT_LOCK */
+ GstClockTime earliest_time; /* OBJECT_LOCK */
+ GstClockTime qos_frame_duration; /* OBJECT_LOCK */
gboolean discont;
/* qos messages: frames dropped/processed */
guint dropped;
gdouble proportion;
GstClockTimeDiff diff;
GstClockTime timestamp;
- GstClockTime duration;
gst_event_parse_qos (event, &type, &proportion, &diff, ×tamp);
priv->proportion = proportion;
if (G_LIKELY (GST_CLOCK_TIME_IS_VALID (timestamp))) {
if (G_UNLIKELY (diff > 0)) {
- GST_VIDEO_DECODER_STREAM_LOCK (decoder);
- if (priv->output_state != NULL && priv->output_state->info.fps_n > 0)
- duration =
- gst_util_uint64_scale (GST_SECOND,
- priv->output_state->info.fps_d, priv->output_state->info.fps_n);
- else
- duration = 0;
- GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
- priv->earliest_time = timestamp + 2 * diff + duration;
+ priv->earliest_time = timestamp + 2 * diff + priv->qos_frame_duration;
} else {
priv->earliest_time = timestamp + diff;
}
if (priv->output_state)
gst_video_codec_state_unref (priv->output_state);
priv->output_state = NULL;
+
+ GST_OBJECT_LOCK (decoder);
+ priv->qos_frame_duration = 0;
+ GST_OBJECT_UNLOCK (decoder);
+
priv->min_latency = 0;
priv->max_latency = 0;
priv->bytes_out = 0;
priv->time = 0;
+ GST_OBJECT_LOCK (decoder);
priv->earliest_time = GST_CLOCK_TIME_NONE;
priv->proportion = 0.5;
+ GST_OBJECT_UNLOCK (decoder);
GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
}
dec->priv->dropped++;
/* post QoS message */
- timestamp = frame->pts;
+ GST_OBJECT_LOCK (dec);
proportion = dec->priv->proportion;
+ earliest_time = dec->priv->earliest_time;
+ GST_OBJECT_UNLOCK (dec);
+
+ timestamp = frame->pts;
segment = &dec->output_segment;
stream_time =
gst_segment_to_stream_time (segment, GST_FORMAT_TIME, timestamp);
qostime = gst_segment_to_running_time (segment, GST_FORMAT_TIME, timestamp);
- earliest_time = dec->priv->earliest_time;
jitter = GST_CLOCK_DIFF (qostime, earliest_time);
qos_msg =
gst_message_new_qos (GST_OBJECT_CAST (dec), FALSE, qostime, stream_time,
{
GstVideoDecoderPrivate *priv = decoder->priv;
GstVideoCodecState *state;
+ GstClockTime qos_frame_duration;
GST_DEBUG_OBJECT (decoder, "fmt:%d, width:%d, height:%d, reference:%p",
fmt, width, height, reference);
gst_video_codec_state_unref (priv->output_state);
priv->output_state = gst_video_codec_state_ref (state);
+ if (priv->output_state != NULL && priv->output_state->info.fps_n > 0) {
+ qos_frame_duration =
+ gst_util_uint64_scale (GST_SECOND, priv->output_state->info.fps_d,
+ priv->output_state->info.fps_n);
+ } else {
+ qos_frame_duration = 0;
+ }
priv->output_state_changed = TRUE;
GST_VIDEO_DECODER_STREAM_UNLOCK (decoder);
+ GST_OBJECT_LOCK (decoder);
+ priv->qos_frame_duration = qos_frame_duration;
+ GST_OBJECT_UNLOCK (decoder);
+
return state;
}