summaryrefslogtreecommitdiffstats
path: root/tools/guest-diag/sdl_cap.c
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-11-15 16:00:06 -0500
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-11-15 16:00:06 -0500
commit43bbf490dca972cb96fcf1d69dd0b6859377e452 (patch)
treeac836f0dfcd50b3302d29a88402b1753127f7cf2 /tools/guest-diag/sdl_cap.c
parentf37f1f6a92939a8c147da1ed5a9032d9e8604ddc (diff)
downloadopen-iov-43bbf490dca972cb96fcf1d69dd0b6859377e452.tar.gz
open-iov-43bbf490dca972cb96fcf1d69dd0b6859377e452.zip
tools/guest-diag: tag BGRA capture records as GZF2 fmt 33
sdl_cap.c wrote the same 32 in the GZF2 record format field for every capture path, so gzf2_video.py's auto mode decoded ARGB8888/X-surface frames (BGRA byte order on little-endian) as RGBA and swapped red and blue. Make the field the documented pixel-order tag: 32 = RGBA8 from the GL swap path (glReadPixels GL_RGBA), 33 = BGRA8 from SDL_RenderReadPixels(ARGB8888) and X window surfaces; xgrab.c tags its ZPixmap BGRA records 33 as well. gzf2_video.py continues to accept both tags (and old all-32 captures via --pix-fmt bgra), checks ffmpeg/ffprobe before indexing, and keeps the final resampled endpoint so a 90-frame 60 fps capture encodes as 90 frames instead of 88.
Diffstat (limited to 'tools/guest-diag/sdl_cap.c')
-rw-r--r--tools/guest-diag/sdl_cap.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/tools/guest-diag/sdl_cap.c b/tools/guest-diag/sdl_cap.c
index 5b9c096..f875ed0 100644
--- a/tools/guest-diag/sdl_cap.c
+++ b/tools/guest-diag/sdl_cap.c
@@ -11,9 +11,12 @@
// File layout (little endian):
// [0] 8B magic "GZCAPV01" (+ 4088 B reserved zero)
// [4096] frame records:
-// 4B "GZF2" | u32 w | u32 h | u32 stride | u32 bpp
+// 4B "GZF2" | u32 w | u32 h | u32 stride | u32 fmt
// u64 ts_ns (CLOCK_MONOTONIC) | u64 seq | stride*h bytes (top-down)
-// A trailing record with seq = 0xFFFFFFFFFFFFFFFF marks clean stop.
+// fmt is a pixel-order tag (not bits per pixel): 32 = RGBA8 from the GL
+// swap path (glReadPixels GL_RGBA), 33 = BGRA8 from SDL_RenderReadPixels
+// ARGB8888 or an X window surface. A trailing record with
+// seq = 0xFFFFFFFFFFFFFFFF marks clean stop.
//
// Env: GZCAP (path, default /dev/shm/gzframes.bin), GZCAP_MAXF (0=unlimited)
#define _GNU_SOURCE
@@ -26,6 +29,8 @@
#include <unistd.h>
#define ARGB8888 0x16362004u
+#define GZF2_FMT_RGBA 32
+#define GZF2_FMT_BGRA 33
typedef struct SDL_Renderer SDL_Renderer;
typedef struct SDL_Window SDL_Window;
@@ -87,7 +92,7 @@ __attribute__((constructor)) static void cap_init(void)
if (h)
real_glReadPixels = dlsym(h, "glReadPixels");
}
- fprintf(stderr, "[gzcap] init pid=%d path=%s present=%p updwin=%p swap=%p read=%p gros=%p\n",
+ fprintf(stderr, "[gzcap] init pid=%d path=%s present=%p updwin=%p swap=%p read=%p gros=%p readpix=%p\n",
(int)getpid(), p, (void *)real_RenderPresent, (void *)real_UpdateWindowSurface,
(void *)real_GL_SwapWindow, (void *)real_RenderReadPixels,
(void *)real_GetRendererOutputSize, (void *)real_glReadPixels);
@@ -102,7 +107,7 @@ __attribute__((constructor)) static void cap_init(void)
fflush(cap_fp);
}
-static void cap_record(const void *px, int w, int h, int stride, int bpp)
+static void cap_record(const void *px, int w, int h, int stride, int fmt)
{
struct timespec ts;
uint64_t tns, seq;
@@ -126,7 +131,7 @@ static void cap_record(const void *px, int w, int h, int stride, int bpp)
rh[0] = (uint32_t)w;
rh[1] = (uint32_t)h;
rh[2] = (uint32_t)stride;
- rh[3] = (uint32_t)bpp;
+ rh[3] = (uint32_t)fmt;
fwrite(m, 1, 4, cap_fp);
fwrite(rh, 4, 4, cap_fp);
fwrite(&tns, 8, 1, cap_fp);
@@ -161,7 +166,7 @@ int SDL_RenderPresent(SDL_Renderer *r)
}
if (buf && real_RenderReadPixels(r, NULL, ARGB8888, buf,
w * 4) == 0)
- cap_record(buf, w, h, w * 4, 32);
+ cap_record(buf, w, h, w * 4, GZF2_FMT_BGRA);
}
}
if (real_RenderPresent)
@@ -180,7 +185,7 @@ int SDL_UpdateWindowSurface(SDL_Window *win)
if (s && s->pixels && s->w > 0 && s->h > 0 && s->pitch > 0 &&
s->w <= 4096 && s->h <= 4096)
- cap_record(s->pixels, s->w, s->h, s->pitch, 32);
+ cap_record(s->pixels, s->w, s->h, s->pitch, GZF2_FMT_BGRA);
}
if (real_UpdateWindowSurface)
return real_UpdateWindowSurface(win);
@@ -221,7 +226,7 @@ void SDL_GL_SwapWindow(SDL_Window *win)
memcpy(tmp + (size_t)y * w * 4,
gbuf + (size_t)(h - 1 - y) * w * 4,
(size_t)w * 4);
- cap_record(tmp, w, h, w * 4, 32);
+ cap_record(tmp, w, h, w * 4, GZF2_FMT_RGBA);
free(tmp);
}
}