From 055e3dff56b39b973774605b49c787c03d6a6d78 Mon Sep 17 00:00:00 2001 From: "Alfred E. Heggestad" Date: Sun, 15 Jan 2017 21:07:26 +0100 Subject: sdl2: add more pixelformats (ref #202) --- modules/sdl2/sdl.c | 72 +++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 58 insertions(+), 14 deletions(-) (limited to 'modules') diff --git a/modules/sdl2/sdl.c b/modules/sdl2/sdl.c index 7199cdf..938039d 100644 --- a/modules/sdl2/sdl.c +++ b/modules/sdl2/sdl.c @@ -23,6 +23,7 @@ struct vidisp_st { SDL_Renderer *renderer; /**< SDL Renderer */ SDL_Texture *texture; /**< Texture for pixels */ struct vidsz size; /**< Current size */ + enum vidfmt fmt; /**< Current pixel format */ bool fullscreen; /**< Fullscreen flag */ }; @@ -30,6 +31,30 @@ struct vidisp_st { static struct vidisp *vid; +static uint32_t match_fmt(enum vidfmt fmt) +{ + switch (fmt) { + + case VID_FMT_YUV420P: return SDL_PIXELFORMAT_IYUV; + case VID_FMT_NV12: return SDL_PIXELFORMAT_NV12; + case VID_FMT_RGB32: return SDL_PIXELFORMAT_BGRA32; + default: return SDL_PIXELFORMAT_UNKNOWN; + } +} + + +static uint32_t chroma_step(enum vidfmt fmt) +{ + switch (fmt) { + + case VID_FMT_YUV420P: return 2; + case VID_FMT_NV12: return 1; + case VID_FMT_RGB32: return 0; + default: return 0; + } +} + + static void sdl_reset(struct vidisp_st *st) { if (st->texture) { @@ -92,17 +117,27 @@ static int display(struct vidisp_st *st, const char *title, const struct vidframe *frame) { void *pixels; - uint8_t *p; - int pitch, ret; + uint8_t *d; + int dpitch, ret; unsigned i, h; + uint32_t format; if (!st || !frame) return EINVAL; - if (!vidsz_cmp(&st->size, &frame->size)) { + format = match_fmt(frame->fmt); + if (format == SDL_PIXELFORMAT_UNKNOWN) { + warning("sdl2: pixel format not supported (%s)\n", + vidfmt_name(frame->fmt)); + return ENOTSUP; + } + + if (!vidsz_cmp(&st->size, &frame->size) || frame->fmt != st->fmt) { if (st->size.w && st->size.h) { - info("sdl: reset size: %u x %u ---> %u x %u\n", - st->size.w, st->size.h, + info("sdl: reset size:" + " %s %u x %u ---> %s %u x %u\n", + vidfmt_name(st->fmt), st->size.w, st->size.h, + vidfmt_name(frame->fmt), frame->size.w, frame->size.h); } sdl_reset(st); @@ -136,6 +171,7 @@ static int display(struct vidisp_st *st, const char *title, } st->size = frame->size; + st->fmt = frame->fmt; SDL_RaiseWindow(st->window); SDL_SetWindowBordered(st->window, true); @@ -160,7 +196,7 @@ static int display(struct vidisp_st *st, const char *title, if (!st->texture) { st->texture = SDL_CreateTexture(st->renderer, - SDL_PIXELFORMAT_IYUV, + format, SDL_TEXTUREACCESS_STREAMING, frame->size.w, frame->size.h); if (!st->texture) { @@ -170,25 +206,33 @@ static int display(struct vidisp_st *st, const char *title, } } - ret = SDL_LockTexture(st->texture, NULL, &pixels, &pitch); + ret = SDL_LockTexture(st->texture, NULL, &pixels, &dpitch); if (ret != 0) { warning("sdl: unable to lock texture (ret=%d)\n", ret); return ENODEV; } - p = pixels; + d = pixels; for (i=0; i<3; i++) { - const uint8_t *s = frame->data[i]; - const unsigned stp = frame->linesize[0] / frame->linesize[i]; - const unsigned sz = frame->size.w / stp; + const uint8_t *s = frame->data[i]; + unsigned sz, dsz, hstep, wstep; + + if (!frame->data[i] || !frame->linesize[i]) + break; + + hstep = i==0 ? 1 : 2; + wstep = i==0 ? 1 : chroma_step(frame->fmt); + + dsz = dpitch / wstep; + sz = min(frame->linesize[i], dsz); - for (h = 0; h < frame->size.h; h += stp) { + for (h = 0; h < frame->size.h; h += hstep) { - memcpy(p, s, sz); + memcpy(d, s, sz); s += frame->linesize[i]; - p += (pitch / stp); + d += dsz; } } -- cgit v1.2.3