[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