[Spice-devel] [PATCH spice-gtk 2/3] channel-display-gst: factor out get_decoded_frame
Frediano Ziglio
fziglio at redhat.com
Wed Jan 23 00:08:53 UTC 2019
Separate the code from fetch_pending_sample that extracts the
SpiceGstFrame relative to a give GstBuffer.
This new function will be reused later.
Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
---
src/channel-display-gst.c | 84 ++++++++++++++++++++++++---------------
1 file changed, 53 insertions(+), 31 deletions(-)
diff --git a/src/channel-display-gst.c b/src/channel-display-gst.c
index 1ad06f15..08c9f8fb 100644
--- a/src/channel-display-gst.c
+++ b/src/channel-display-gst.c
@@ -107,6 +107,7 @@ static void free_gst_frame(SpiceGstFrame *gstframe)
static void schedule_frame(SpiceGstDecoder *decoder);
static void fetch_pending_sample(SpiceGstDecoder *decoder);
+static SpiceGstFrame *get_decoded_frame(SpiceGstDecoder *decoder, GstBuffer *buffer);
static int spice_gst_buffer_get_stride(GstBuffer *buffer)
{
@@ -204,6 +205,52 @@ static void schedule_frame(SpiceGstDecoder *decoder)
g_mutex_unlock(&decoder->queues_mutex);
}
+/* Get the decoded frame relative to buffer or NULL if not found.
+ * Dequeue the frame from decoding_queue and return it, caller
+ * is responsible to free the pointer.
+ * queues_mutex must be held.
+ */
+static SpiceGstFrame *get_decoded_frame(SpiceGstDecoder *decoder, GstBuffer *buffer)
+{
+ guint num_frames_dropped = 0;
+
+ /* Gstreamer sometimes returns the same buffer twice
+ * or buffers that have a modified, and thus unrecognizable, PTS.
+ * Blindly removing frames from the decoding_queue until we find a
+ * match would only empty the queue, resulting in later buffers not
+ * finding a match either, etc. So check the buffer has a matching
+ * frame first.
+ */
+ SpiceGstFrame *gstframe = NULL;
+ GList *l = g_queue_peek_head_link(decoder->decoding_queue);
+ while (l) {
+ gstframe = l->data;
+ if (gstframe->timestamp == GST_BUFFER_PTS(buffer)) {
+
+ /* Now that we know there is a match, remove it and the older
+ * frames from the decoding queue.
+ */
+ while ((gstframe = g_queue_pop_head(decoder->decoding_queue))) {
+ if (gstframe->timestamp == GST_BUFFER_PTS(buffer)) {
+ break;
+ }
+ /* The GStreamer pipeline dropped the corresponding
+ * buffer.
+ */
+ num_frames_dropped++;
+ free_gst_frame(gstframe);
+ }
+ break;
+ }
+ gstframe = NULL;
+ l = l->next;
+ }
+ if (num_frames_dropped != 0) {
+ SPICE_DEBUG("the GStreamer pipeline dropped %u frames", num_frames_dropped);
+ }
+ return gstframe;
+}
+
static void fetch_pending_sample(SpiceGstDecoder *decoder)
{
GstSample *sample = gst_app_sink_pull_sample(decoder->appsink);
@@ -212,7 +259,6 @@ static void fetch_pending_sample(SpiceGstDecoder *decoder)
decoder->pending_samples--;
GstBuffer *buffer = gst_sample_get_buffer(sample);
- guint num_frames_dropped = 0;
/* gst_app_sink_pull_sample() sometimes returns the same buffer twice
* or buffers that have a modified, and thus unrecognizable, PTS.
@@ -221,36 +267,12 @@ static void fetch_pending_sample(SpiceGstDecoder *decoder)
* finding a match either, etc. So check the buffer has a matching
* frame first.
*/
- SpiceGstFrame *gstframe;
- GList *l = g_queue_peek_head_link(decoder->decoding_queue);
- while (l) {
- gstframe = l->data;
- if (gstframe->timestamp == GST_BUFFER_PTS(buffer)) {
- /* The frame is now ready for display */
- gstframe->decoded_sample = sample;
- decoder->display_frame = gstframe;
-
- /* Now that we know there is a match, remove it and the older
- * frames from the decoding queue.
- */
- while ((gstframe = g_queue_pop_head(decoder->decoding_queue))) {
- if (gstframe->timestamp == GST_BUFFER_PTS(buffer)) {
- break;
- }
- /* The GStreamer pipeline dropped the corresponding
- * buffer.
- */
- num_frames_dropped++;
- free_gst_frame(gstframe);
- }
- break;
- }
- l = l->next;
- }
- if (num_frames_dropped != 0) {
- SPICE_DEBUG("the GStreamer pipeline dropped %u frames", num_frames_dropped);
- }
- if (!l) {
+ SpiceGstFrame *gstframe = get_decoded_frame(decoder, buffer);
+ if (gstframe) {
+ /* The frame is now ready for display */
+ gstframe->decoded_sample = sample;
+ decoder->display_frame = gstframe;
+ } else {
spice_warning("got an unexpected decoded buffer!");
gst_sample_unref(sample);
}
--
2.20.1
More information about the Spice-devel
mailing list