[Mesa-dev] [PATCH v3 12/12] cube-video: Add switch for enabling synced playback

Carlos Rafael Giani dv at pseudoterminal.org
Wed Apr 26 18:56:24 UTC 2017


With synced playback, frames may be dropped if the OpenGL ES code does
not output the decoded frames in time, thereby making sure the timestamps
in the video aren't missed

Signed-off-by: Carlos Rafael Giani <dv at pseudoterminal.org>
---
 common.h      |  8 ++++----
 cube-video.c  |  9 ++++++---
 gst-decoder.c |  5 +++--
 kmscube.c     | 16 ++++++++++++----
 4 files changed, 25 insertions(+), 13 deletions(-)

diff --git a/common.h b/common.h
index 639bd87..e10930e 100644
--- a/common.h
+++ b/common.h
@@ -102,17 +102,17 @@ const struct egl * init_cube_tex(const struct gbm *gbm, enum mode mode);
 #ifdef HAVE_GST
 
 struct decoder;
-struct decoder * video_init(const struct egl *egl, const struct gbm *gbm, const char *filename);
+struct decoder * video_init(const struct egl *egl, const struct gbm *gbm, const char *filename, int synced_playback);
 EGLImage video_frame(struct decoder *dec);
 void video_deinit(struct decoder *dec);
 
-const struct egl * init_cube_video(const struct gbm *gbm, const char *video);
+const struct egl * init_cube_video(const struct gbm *gbm, const char *video, int synced_playback);
 
 #else
 static inline const struct egl *
-init_cube_video(const struct gbm *gbm, const char *video)
+init_cube_video(const struct gbm *gbm, const char *video, int synced_playback)
 {
-	(void)gbm; (void)video;
+	(void)gbm; (void)video; (void)synced_playback;
 	printf("no GStreamer support!\n");
 	return NULL;
 }
diff --git a/cube-video.c b/cube-video.c
index 6ce20da..32cce0a 100644
--- a/cube-video.c
+++ b/cube-video.c
@@ -49,6 +49,7 @@ struct {
 	struct decoder *decoder;
 	int filenames_count, idx;
 	const char *filenames[32];
+	int synced_playback;
 } gl;
 
 static const struct egl *egl = &gl.egl;
@@ -230,7 +231,7 @@ static void draw_cube_video(unsigned i)
 		glGenTextures(1, &gl.tex);
 		video_deinit(gl.decoder);
 		gl.idx = (gl.idx + 1) % gl.filenames_count;
-		gl.decoder = video_init(&gl.egl, gl.gbm, gl.filenames[gl.idx]);
+		gl.decoder = video_init(&gl.egl, gl.gbm, gl.filenames[gl.idx], gl.synced_playback);
 	}
 
 	glUseProgram(gl.blit_program);
@@ -291,7 +292,7 @@ static void draw_cube_video(unsigned i)
 	glDrawArrays(GL_TRIANGLE_STRIP, 20, 4);
 }
 
-const struct egl * init_cube_video(const struct gbm *gbm, const char *filenames)
+const struct egl * init_cube_video(const struct gbm *gbm, const char *filenames, int synced_playback)
 {
 	char *fnames, *s;
 	int ret, i = 0;
@@ -305,6 +306,8 @@ const struct egl * init_cube_video(const struct gbm *gbm, const char *filenames)
 		return NULL;
 	}
 
+	gl.synced_playback = synced_playback;
+
 	fnames = strdup(filenames);
 	while ((s = strstr(fnames, ","))) {
 		gl.filenames[i] = fnames;
@@ -315,7 +318,7 @@ const struct egl * init_cube_video(const struct gbm *gbm, const char *filenames)
 	gl.filenames[i] = fnames;
 	gl.filenames_count = ++i;
 
-	gl.decoder = video_init(&gl.egl, gbm, gl.filenames[gl.idx]);
+	gl.decoder = video_init(&gl.egl, gbm, gl.filenames[gl.idx], synced_playback);
 	if (!gl.decoder) {
 		printf("cannot create video decoder\n");
 		return NULL;
diff --git a/gst-decoder.c b/gst-decoder.c
index deffad5..6cdf9c4 100644
--- a/gst-decoder.c
+++ b/gst-decoder.c
@@ -253,7 +253,7 @@ appsink_query_cb(GstPad *pad G_GNUC_UNUSED, GstPadProbeInfo *info,
 }
 
 struct decoder *
-video_init(const struct egl *egl, const struct gbm *gbm, const char *filename)
+video_init(const struct egl *egl, const struct gbm *gbm, const char *filename, int synced_playback)
 {
 	struct decoder *dec;
 	GstElement *src, *decodebin;
@@ -267,7 +267,7 @@ video_init(const struct egl *egl, const struct gbm *gbm, const char *filename)
 
 	/* Setup pipeline: */
 	static const char *pipeline =
-		"filesrc name=\"src\" ! decodebin name=\"decode\" ! video/x-raw ! appsink sync=false name=\"sink\"";
+		"filesrc name=\"src\" ! decodebin name=\"decode\" ! video/x-raw ! appsink name=\"sink\"";
 	dec->pipeline = gst_parse_launch(pipeline, NULL);
 
 	dec->sink = gst_bin_get_by_name(GST_BIN(dec->pipeline), "sink");
@@ -294,6 +294,7 @@ video_init(const struct egl *egl, const struct gbm *gbm, const char *filename)
 	 * vsync and quickly chew up 100's of MB of buffers:
 	 */
 	g_object_set(G_OBJECT(dec->sink), "max-buffers", 2, NULL);
+	g_object_set(G_OBJECT(dec->sink), "sync", (gboolean)(!!synced_playback), NULL);
 
 	gst_pad_add_probe(gst_element_get_static_pad(dec->sink, "sink"),
 			GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM,
diff --git a/kmscube.c b/kmscube.c
index 3a2c4dd..486a558 100644
--- a/kmscube.c
+++ b/kmscube.c
@@ -43,7 +43,7 @@ static const struct egl *egl;
 static const struct gbm *gbm;
 static const struct drm *drm;
 
-static const char *shortopts = "AD:M:m:V:";
+static const char *shortopts = "AD:M:m:V:S";
 
 static const struct option longopts[] = {
 	{"atomic", no_argument,       0, 'A'},
@@ -51,12 +51,13 @@ static const struct option longopts[] = {
 	{"mode",   required_argument, 0, 'M'},
 	{"modifier", required_argument, 0, 'm'},
 	{"video",  required_argument, 0, 'V'},
+	{"synced-playback", no_argument, 0, 'S'},
 	{0, 0, 0, 0}
 };
 
 static void usage(const char *name)
 {
-	printf("Usage: %s [-ADMmV]\n"
+	printf("Usage: %s [-ADMmVS]\n"
 			"\n"
 			"options:\n"
 			"    -A, --atomic             use atomic modesetting and fencing\n"
@@ -67,7 +68,10 @@ static void usage(const char *name)
 			"        nv12-2img -  yuv textured (color conversion in shader)\n"
 			"        nv12-1img -  yuv textured (single nv12 texture)\n"
 			"    -m, --modifier=MODIFIER  hardcode the selected modifier\n"
-			"    -V, --video=FILE         video textured cube\n",
+			"    -V, --video=FILE         video textured cube\n"
+			"    -S, --synced-playback    make sure playback stays in sync\n"
+			"                             with the timestamps in the video;\n"
+			"                             this drops frames if necessary\n",
 			name);
 }
 
@@ -78,6 +82,7 @@ int main(int argc, char *argv[])
 	enum mode mode = SMOOTH;
 	uint64_t modifier = DRM_FORMAT_MOD_INVALID;
 	int atomic = 0;
+	int synced_playback = 0;
 	int opt;
 
 #ifdef HAVE_GST
@@ -115,6 +120,9 @@ int main(int argc, char *argv[])
 			mode = VIDEO;
 			video = optarg;
 			break;
+		case 'S':
+			synced_playback = 1;
+			break;
 		default:
 			usage(argv[0]);
 			return -1;
@@ -140,7 +148,7 @@ int main(int argc, char *argv[])
 	if (mode == SMOOTH)
 		egl = init_cube_smooth(gbm);
 	else if (mode == VIDEO)
-		egl = init_cube_video(gbm, video);
+		egl = init_cube_video(gbm, video, synced_playback);
 	else
 		egl = init_cube_tex(gbm, mode);
 
-- 
2.7.4



More information about the mesa-dev mailing list