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 <d...@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

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to