From 149a4ce390a78e21309b210f7daba9db5d42afe6 Mon Sep 17 00:00:00 2001 From: Vincent Penquerc'h Date: Wed, 7 Sep 2011 16:04:14 +0100 Subject: [PATCH] theoradec: move the QoS logic to libgstvideo https://bugzilla.gnome.org/show_bug.cgi?id=658241 --- ext/theora/gsttheoradec.c | 76 ++++++--------------------------------- ext/theora/gsttheoradec.h | 8 ++--- 2 files changed, 13 insertions(+), 71 deletions(-) diff --git a/ext/theora/gsttheoradec.c b/ext/theora/gsttheoradec.c index 25d68dbac5..9e417be98d 100644 --- a/ext/theora/gsttheoradec.c +++ b/ext/theora/gsttheoradec.c @@ -231,15 +231,9 @@ gst_theora_dec_reset (GstTheoraDec * dec) dec->discont = TRUE; dec->frame_nr = -1; dec->seqnum = gst_util_seqnum_next (); - dec->dropped = 0; - dec->processed = 0; + gst_video_qos_tracker_reset (&dec->qt); gst_segment_init (&dec->segment, GST_FORMAT_TIME); - GST_OBJECT_LOCK (dec); - dec->proportion = 1.0; - dec->earliest_time = -1; - GST_OBJECT_UNLOCK (dec); - g_list_foreach (dec->queued, (GFunc) gst_mini_object_unref, NULL); g_list_free (dec->queued); dec->queued = NULL; @@ -576,23 +570,12 @@ theora_dec_src_event (GstPad * pad, GstEvent * event) } case GST_EVENT_QOS: { - gdouble proportion; - GstClockTimeDiff diff; - GstClockTime timestamp; - - gst_event_parse_qos (event, &proportion, &diff, ×tamp); - /* we cannot randomly skip frame decoding since we don't have * B frames. we can however use the timestamp and diff to not * push late frames. This would at least save us the time to * crop/memcpy the data. */ - GST_OBJECT_LOCK (dec); - dec->proportion = proportion; - dec->earliest_time = timestamp + diff; - GST_OBJECT_UNLOCK (dec); - - GST_DEBUG_OBJECT (dec, "got QoS %" GST_TIME_FORMAT ", %" G_GINT64_FORMAT, - GST_TIME_ARGS (timestamp), diff); + gst_video_qos_tracker_update (&dec->qt, event, + GST_CLOCK_TIME_NONE, GST_VIDEO_QOS_TRACKER_DIFF); res = gst_pad_push_event (dec->sinkpad, event); break; @@ -1146,50 +1129,11 @@ theora_handle_data_packet (GstTheoraDec * dec, ogg_packet * packet, if (G_UNLIKELY (th_decode_packetin (dec->decoder, packet, &gp) < 0)) goto decode_error; - if (outtime != -1) { - gboolean need_skip; - GstClockTime running_time; - GstClockTime earliest_time; - gdouble proportion; - - /* qos needs to be done on running time */ - running_time = gst_segment_to_running_time (&dec->segment, GST_FORMAT_TIME, - outtime); - - GST_OBJECT_LOCK (dec); - proportion = dec->proportion; - earliest_time = dec->earliest_time; - /* check for QoS, don't perform the last steps of getting and - * pushing the buffers that are known to be late. */ - need_skip = earliest_time != -1 && running_time <= earliest_time; - GST_OBJECT_UNLOCK (dec); - - if (need_skip) { - GstMessage *qos_msg; - guint64 stream_time; - gint64 jitter; - - GST_DEBUG_OBJECT (dec, "skipping decoding: qostime %" - GST_TIME_FORMAT " <= %" GST_TIME_FORMAT, - GST_TIME_ARGS (running_time), GST_TIME_ARGS (earliest_time)); - - dec->dropped++; - - stream_time = - gst_segment_to_stream_time (&dec->segment, GST_FORMAT_TIME, outtime); - jitter = GST_CLOCK_DIFF (running_time, earliest_time); - - qos_msg = - gst_message_new_qos (GST_OBJECT_CAST (dec), FALSE, running_time, - stream_time, outtime, outdur); - gst_message_set_qos_values (qos_msg, jitter, proportion, 1000000); - gst_message_set_qos_stats (qos_msg, GST_FORMAT_BUFFERS, - dec->processed, dec->dropped); - gst_element_post_message (GST_ELEMENT_CAST (dec), qos_msg); - - goto dropping_qos; - } - } + /* check for QoS, don't perform the last steps of getting and + * pushing the buffers that are known to be late. */ + if (gst_video_qos_tracker_process_frame (&dec->qt, &dec->segment, outtime, + outdur)) + goto dropping_qos; /* this does postprocessing and set up the decoded frame * pointers in our yuv variable */ @@ -1212,8 +1156,6 @@ theora_handle_data_packet (GstTheoraDec * dec, ogg_packet * packet, GST_BUFFER_TIMESTAMP (out) = outtime; GST_BUFFER_DURATION (out) = outdur; - dec->processed++; - if (dec->segment.rate >= 0.0) result = theora_dec_push_forward (dec, out); else @@ -1506,6 +1448,7 @@ theora_dec_change_state (GstElement * element, GstStateChange transition) switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: + gst_video_qos_tracker_init (&dec->qt, element); break; case GST_STATE_CHANGE_READY_TO_PAUSED: th_info_clear (&dec->info); @@ -1536,6 +1479,7 @@ theora_dec_change_state (GstElement * element, GstStateChange transition) gst_theora_dec_reset (dec); break; case GST_STATE_CHANGE_READY_TO_NULL: + gst_video_qos_tracker_clear (&dec->qt); break; default: break; diff --git a/ext/theora/gsttheoradec.h b/ext/theora/gsttheoradec.h index f6722119a6..9f10b8dcd2 100644 --- a/ext/theora/gsttheoradec.h +++ b/ext/theora/gsttheoradec.h @@ -25,6 +25,7 @@ #endif #include +#include #include #include @@ -97,11 +98,8 @@ struct _GstTheoraDec gboolean discont; guint32 seqnum; - /* QoS stuff */ /* with LOCK*/ - gdouble proportion; - GstClockTime earliest_time; - guint64 processed; - guint64 dropped; + /* QoS stuff */ + GstVideoQoSTracker qt; gboolean have_par; gint par_num;