From 9a9589e8e11696a8afdbafbb16c687a4d295c23b Mon Sep 17 00:00:00 2001
From: Joshua Colp <jcolp@digium.com>
Date: Thu, 24 Aug 2017 13:45:08 -0300
Subject: [PATCH] core: Reduce video update queueing.

A video update frame is used to indicate that a channel
with video negotiated should provide a full frame so the
decoder decoding the stream is able to do so. In situations
where a queue is used to store frames it makes no sense
for the queue to contain multiple video update frames. One
is sufficient to have a full frame be sent.

ASTERISK-27222

Change-Id: Id3f40a6f51b740ae4704003a1800185c0c658ee7
---
 main/autoservice.c | 12 ++++++++++++
 main/core_unreal.c |  3 ++-
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/main/autoservice.c b/main/autoservice.c
index d1a0156ab4..cd7388b7dd 100644
--- a/main/autoservice.c
+++ b/main/autoservice.c
@@ -58,6 +58,7 @@ struct asent {
 	 *  it gets stopped for the last time. */
 	unsigned int use_count;
 	unsigned int orig_end_dtmf_flag:1;
+	unsigned int video_update:1;
 	unsigned int ignore_frame_types;
 	/*! Frames go on at the head of deferred_frames, so we have the frames
 	 *  from newest to oldest.  As we put them at the head of the readq, we'll
@@ -161,6 +162,17 @@ static void *autoservice_run(void *ign)
 					AST_LIST_INSERT_HEAD(&ents[i]->deferred_frames, dup_f, frame_list);
 				}
 			} else {
+				if (defer_frame->frametype == AST_FRAME_CONTROL &&
+					defer_frame->subclass.integer == AST_CONTROL_VIDUPDATE) {
+
+					/* If a video update is already queued don't needlessly queue another */
+					if (ents[i]->video_update) {
+						ast_frfree(defer_frame);
+						break;
+					}
+
+					ents[i]->video_update = 1;
+				}
 				if ((dup_f = ast_frisolate(defer_frame))) {
 					AST_LIST_INSERT_HEAD(&ents[i]->deferred_frames, dup_f, frame_list);
 				}
diff --git a/main/core_unreal.c b/main/core_unreal.c
index 3db6a4dbdd..763be4f0ca 100644
--- a/main/core_unreal.c
+++ b/main/core_unreal.c
@@ -330,7 +330,8 @@ int ast_unreal_write(struct ast_channel *ast, struct ast_frame *f)
 		if (!ast_channel_get_default_stream(ast, AST_MEDIA_TYPE_AUDIO)) {
 			return 0;
 		}
-	} else if (f->frametype == AST_FRAME_VIDEO) {
+	} else if (f->frametype == AST_FRAME_VIDEO ||
+		(f->frametype == AST_FRAME_CONTROL && f->subclass.integer == AST_CONTROL_VIDUPDATE)) {
 		if (!ast_channel_get_default_stream(ast, AST_MEDIA_TYPE_VIDEO)) {
 			return 0;
 		}
-- 
GitLab