[daala] [PATCH] Switch player_example to SDL2, add fullscreen

Ralph Giles giles at thaumas.net
Wed Apr 29 11:05:16 PDT 2015


Patch set to add 'f' for fullscreen in the example player. Getting this
to work adequately requires porting to SDL2.

 -r
-------------- next part --------------
From 36d590e9f9fc5d3e746897cc32f62bfeb9b056da Mon Sep 17 00:00:00 2001
From: Ralph Giles <giles at mozilla.com>
Date: Wed, 29 Apr 2015 10:16:59 -0700
Subject: [PATCH 2/4] Port player_example to SDL2.

The newer versions integrates better with newer desktop environments.

The documenation suggests the streaming texture update might be
faster but I didn't benchmark it. We do seem to need to switch
to 32-bit RGB which increases bandwidth by 33%, but may avoid
a conversion in the blit.
---
 configure.ac              |  2 +-
 examples/player_example.c | 52 +++++++++++++++++++++++++++++------------------
 2 files changed, 33 insertions(+), 21 deletions(-)

diff --git a/configure.ac b/configure.ac
index 68401b6..0b159b8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -93,7 +93,7 @@ LT_LIB_M
 AC_CHECK_FUNCS([gettimeofday ftime],[break])
 
 AS_IF([test "$enable_player" = "yes"], [
-  PKG_CHECK_MODULES([SDL], [sdl])
+  PKG_CHECK_MODULES([SDL], [sdl2])
 ])
 AM_CONDITIONAL([ENABLE_PLAYER_EXAMPLE], [test "$enable_player" = "yes"])
 
diff --git a/examples/player_example.c b/examples/player_example.c
index 2063a2c..bc2c0c5 100644
--- a/examples/player_example.c
+++ b/examples/player_example.c
@@ -39,7 +39,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.*/
 #define ODS_DATA 2
 
 typedef struct {
-  SDL_Surface *screen;
+  SDL_Window *screen;
+  SDL_Renderer *renderer;
   daala_info di;
   daala_comment dc;
   ogg_sync_state oy;
@@ -47,7 +48,7 @@ typedef struct {
   const char *input_path;
   ogg_stream_state os;
   daala_dec_ctx *dctx;
-  SDL_Surface *surf;
+  SDL_Texture *texture;
   od_img img;
   int width;
   int height;
@@ -69,7 +70,7 @@ enum {
   OD_ALL_MASK = OD_LUMA_MASK | OD_CB_MASK | OD_CR_MASK
 };
 
-static void img_to_rgb(SDL_Surface *surf, const od_img *img, int plane_mask);
+static void img_to_rgb(SDL_Texture *tex, const od_img *img, int plane_mask);
 static int next_plane(int plane_mask);
 static void wait_to_refresh(uint32_t *previous_ticks, uint32_t ms_per_frame);
 
@@ -109,7 +110,8 @@ int player_example_daala_stream_clear(player_example *player) {
 int player_example_init(player_example *player) {
   if (player == NULL) return -1;
   player->screen = NULL;
-  player->surf = NULL;
+  player->renderer = NULL;
+  player->texture = NULL;
   player->width = 0;
   player->height = 0;
   player->paused = 0;
@@ -358,12 +360,18 @@ int player_example_play(player_example *player) {
            || (player->height != player->di.pic_height)) {
             player->width = player->di.pic_width;
             player->height = player->di.pic_height;
-            player->screen = SDL_SetVideoMode(player->width, player->height,
-             24,
-             SDL_HWSURFACE | SDL_DOUBLEBUF);
+            player->screen = SDL_CreateWindow("Daala example player",
+                SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
+                player->width, player->height,
+                SDL_WINDOW_ALLOW_HIGHDPI);
             if (player->screen == NULL) return -1;
-            player->surf = SDL_GetVideoSurface();
-            if (player->surf == NULL) return -1;
+            player->renderer = SDL_CreateRenderer(player->screen, -1, 0);
+            if (player->renderer == NULL) return -1;
+            player->texture = SDL_CreateTexture(player->renderer,
+                SDL_PIXELFORMAT_ARGB8888,
+                SDL_TEXTUREACCESS_STREAMING,
+                player->width, player->height);
+            if (player->texture == NULL) return -1;
           }
           ret = daala_decode_packet_in(player->dctx, &player->img, &packet);
           if (ret != 0) return -1;
@@ -384,10 +392,10 @@ int player_example_play(player_example *player) {
           }
           if ((!player->restart) && (!player->done)) {
             wait_to_refresh(&ticks, ms_per_frame);
-            SDL_LockSurface(player->surf);
-            img_to_rgb(player->surf, &player->img, player->plane_mask);
-            SDL_UnlockSurface(player->surf);
-            SDL_Flip(player->screen);
+            img_to_rgb(player->texture, &player->img, player->plane_mask);
+            SDL_RenderClear(player->renderer);
+            SDL_RenderCopy(player->renderer, player->texture, NULL, NULL);
+            SDL_RenderPresent(player->renderer);
           }
           break;
         }
@@ -439,7 +447,6 @@ int main(int argc, char *argv[]) {
     exit(1);
   }
   atexit(SDL_Quit);
-  SDL_EnableKeyRepeat(222, 100);
 
   player = player_example_create();
   if (player == NULL) {
@@ -475,7 +482,7 @@ int main(int argc, char *argv[]) {
 #define OD_CLAMP255(x) \
   ((unsigned char)((((x) < 0) - 1) & ((x) | -((x) > 255))))
 
-void img_to_rgb(SDL_Surface *surf, const od_img *img, int plane_mask) {
+void img_to_rgb(SDL_Texture *texture, const od_img *img, int plane_mask) {
   unsigned char *y_row;
   unsigned char *cb_row;
   unsigned char *cr_row;
@@ -493,10 +500,6 @@ void img_to_rgb(SDL_Surface *surf, const od_img *img, int plane_mask) {
   int j;
   unsigned char *pixels;
   int pitch;
-  pixels = (unsigned char *)surf->pixels;
-  pitch = surf->pitch;
-  width = img->width;
-  height = img->height;
   /*Assume both C planes are decimated.*/
   xdec = img->planes[1].xdec;
   ydec = img->planes[1].ydec;
@@ -506,6 +509,13 @@ void img_to_rgb(SDL_Surface *surf, const od_img *img, int plane_mask) {
   y_row = img->planes[0].data;
   cb_row = img->planes[1].data;
   cr_row = img->planes[2].data;
+  /*Lock the texture in video memory for update.*/
+  if (SDL_LockTexture(texture, NULL, (void**)&pixels, &pitch)) {
+    fprintf(stderr, "Couldn't lock video texture!");
+    exit(1);
+  }
+  width = img->width;
+  height = img->height;
   /*Chroma up-sampling is just done with a box filter.
     This is very likely what will actually be used in practice on a real
      display, and also removes one more layer to search in for the source of
@@ -516,7 +526,7 @@ void img_to_rgb(SDL_Surface *surf, const od_img *img, int plane_mask) {
     y = y_row;
     cb = cb_row;
     cr = cr_row;
-    for (i = 0; i < 3 * width;) {
+    for (i = 0; i < 4 * width;) {
       int64_t yval;
       int64_t cbval;
       int64_t crval;
@@ -538,6 +548,7 @@ void img_to_rgb(SDL_Surface *surf, const od_img *img, int plane_mask) {
       *(pixels + pitch*j + i++) = (unsigned char)(bval >> 8);
       *(pixels + pitch*j + i++) = (unsigned char)(gval >> 8);
       *(pixels + pitch*j + i++) = (unsigned char)(rval >> 8);
+      *(pixels + pitch*j + i++) = 0;
       dc = ((y - y_row) & 1) | (1 - xdec);
       y++;
       cb += dc;
@@ -548,6 +559,7 @@ void img_to_rgb(SDL_Surface *surf, const od_img *img, int plane_mask) {
     cb_row += dc & cb_stride;
     cr_row += dc & cr_stride;
   }
+  SDL_UnlockTexture(texture);
 }
 
 int next_plane(int plane_mask) {
-- 
2.3.6
-------------- next part --------------
From 68d15e0d51185893af0d56fdc0ead90280fb00f6 Mon Sep 17 00:00:00 2001
From: Ralph Giles <giles at mozilla.com>
Date: Wed, 29 Apr 2015 10:19:48 -0700
Subject: [PATCH 3/4] Add 'f' for fullscreen to player_example.

SDL will scale the image in the gpu, so this isn't ideal for
diagnostic interpretation, but is nice for display, especially
for higher resolution videos which may not fit on a single screen
in a decorated window.

This works better than SDL_WM_ToggleFullScreen() in SDL 1.2,
which tries to change the output video resolution. However
there are still some issues, e.g. gnome-shell minimizes
the window if it loses focus.
---
 examples/player_example.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/examples/player_example.c b/examples/player_example.c
index bc2c0c5..73db347 100644
--- a/examples/player_example.c
+++ b/examples/player_example.c
@@ -59,6 +59,7 @@ typedef struct {
   int slow;
   int loop;
   int step;
+  int fullscreen;
   int valid;
   int plane_mask;
 } player_example;
@@ -120,6 +121,7 @@ int player_example_init(player_example *player) {
   player->loop = 0;
   player->done = 0;
   player->step = 0;
+  player->fullscreen = 0;
   player->valid = 0;
   player->od_state = ODS_NONE;
   player->plane_mask = OD_ALL_MASK;
@@ -251,6 +253,12 @@ void player_example_handle_event(player_example *player, SDL_Event *event) {
           }
           break;
         }
+        case SDLK_f: {
+          player->fullscreen = !player->fullscreen;
+          SDL_SetWindowFullscreen(player->screen,
+              player->fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
+          break;
+        }
         default: break;
       }
       break;
-- 
2.3.6
-------------- next part --------------
From 21b71ef9f90fd53e572fa460e1a343014270bc2a Mon Sep 17 00:00:00 2001
From: Ralph Giles <giles at mozilla.com>
Date: Wed, 29 Apr 2015 10:42:46 -0700
Subject: [PATCH 4/4] Update unix makefile to use SDL2.

---
 unix/Makefile | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/unix/Makefile b/unix/Makefile
index 4eee763..2a7af0c 100644
--- a/unix/Makefile
+++ b/unix/Makefile
@@ -50,7 +50,7 @@ MAKEDEPEND = $(CC) -MM
 # The location of include files.
 # Modify these to point to your Ogg and Vorbis include directories if they are
 #  not installed in a standard location.
-CINCLUDE = `sdl-config --cflags` `pkg-config ogg --cflags`
+CINCLUDE = `pkg-config sdl2 ogg --cflags`
 # These are gcc-only, but not actually critical.
 # Extra compilation flags.
 # You may get speed increases by including flags such as -O2 or -O3 or
@@ -83,7 +83,7 @@ endif
 
 # Libraries to link with, and the location of library files.
 # Add -lpng -lz if you want to use -DOD_DUMP_IMAGES.
-LIBS = `pkg-config ogg --libs` `sdl-config --libs` -lm
+LIBS = `pkg-config ogg sdl2 --libs` -lm
 ifeq ($(findstring -DOD_DUMP_IMAGES,${CFLAGS}),-DOD_DUMP_IMAGES)
     LIBS += -lpng -lz
 endif
-- 
2.3.6


More information about the daala mailing list