From 0d30fa6cc736ee91217d7a47a2efd2a07258720c Mon Sep 17 00:00:00 2001 From: Joachim Bauch Date: Mon, 8 Jul 2024 10:17:52 +0200 Subject: [PATCH] dec265: Resize window if image resolution changes mid-stream. --- dec265/dec265.cc | 18 +++++++++-------- dec265/sdl.cc | 52 ++++++++++++++++++++++++++++++++++++++++++++++++ dec265/sdl.hh | 1 + 3 files changed, 63 insertions(+), 8 deletions(-) diff --git a/dec265/dec265.cc b/dec265/dec265.cc index 79f67cd3..5ccd2c1d 100644 --- a/dec265/dec265.cc +++ b/dec265/dec265.cc @@ -266,17 +266,19 @@ bool display_sdl(const struct de265_image* img) de265_chroma chroma = de265_get_chroma_format(img); + enum SDL_YUV_Display::SDL_Chroma sdlChroma; + switch (chroma) { + case de265_chroma_420: sdlChroma = SDL_YUV_Display::SDL_CHROMA_420; break; + case de265_chroma_422: sdlChroma = SDL_YUV_Display::SDL_CHROMA_422; break; + case de265_chroma_444: sdlChroma = SDL_YUV_Display::SDL_CHROMA_444; break; + case de265_chroma_mono: sdlChroma = SDL_YUV_Display::SDL_CHROMA_MONO; break; + } + if (!sdl_active) { sdl_active=true; - enum SDL_YUV_Display::SDL_Chroma sdlChroma; - switch (chroma) { - case de265_chroma_420: sdlChroma = SDL_YUV_Display::SDL_CHROMA_420; break; - case de265_chroma_422: sdlChroma = SDL_YUV_Display::SDL_CHROMA_422; break; - case de265_chroma_444: sdlChroma = SDL_YUV_Display::SDL_CHROMA_444; break; - case de265_chroma_mono: sdlChroma = SDL_YUV_Display::SDL_CHROMA_MONO; break; - } - sdlWin.init(width,height, sdlChroma); + } else { + sdlWin.resize(width,height, sdlChroma); } int stride,chroma_stride; diff --git a/dec265/sdl.cc b/dec265/sdl.cc index eab1f8f1..b91278eb 100644 --- a/dec265/sdl.cc +++ b/dec265/sdl.cc @@ -94,6 +94,58 @@ bool SDL_YUV_Display::init(int frame_width, int frame_height, enum SDL_Chroma ch return true; } +bool SDL_YUV_Display::resize(int frame_width, int frame_height, enum SDL_Chroma chroma) +{ + // reduce image size to a multiple of 8 (apparently required by YUV overlay) + + frame_width &= ~7; + frame_height &= ~7; + + if (frame_width == rect.w && frame_height == rect.h && mChroma == chroma) { + return true; + } + + SDL_SetWindowSize(mWindow, frame_width, frame_height); + SDL_DestroyTexture(mTexture); + SDL_DestroyRenderer(mRenderer); + + Uint32 flags = 0; // Empty flags prioritize SDL_RENDERER_ACCELERATED. + mRenderer = SDL_CreateRenderer(mWindow, -1, flags); + if (!mRenderer) { + printf("SDL: Couldn't create renderer: %s\n", SDL_GetError()); + SDL_Quit(); + return false; + } + + Uint32 pixelFormat = 0; + switch (mChroma) { + case SDL_CHROMA_MONO: pixelFormat = SDL_PIXELFORMAT_YV12; break; + case SDL_CHROMA_420: pixelFormat = SDL_PIXELFORMAT_YV12; break; + case SDL_CHROMA_422: pixelFormat = SDL_PIXELFORMAT_YV12; break; + case SDL_CHROMA_444: pixelFormat = SDL_PIXELFORMAT_YV12; break; + //case SDL_CHROMA_444: pixelFormat = SDL_PIXELFORMAT_YV12; break; + default: + printf("Unsupported chroma: %d\n", mChroma); + SDL_Quit(); + return false; + } + + mTexture = SDL_CreateTexture(mRenderer, pixelFormat, + SDL_TEXTUREACCESS_STREAMING, frame_width, frame_height); + if (!mTexture ) { + printf("SDL: Couldn't create SDL texture: %s\n", SDL_GetError()); + SDL_Quit(); + return false; + } + + mChroma = chroma; + + rect.w = frame_width; + rect.h = frame_height; + + return true; +} + void SDL_YUV_Display::display(const unsigned char *Y, const unsigned char *U, const unsigned char *V, diff --git a/dec265/sdl.hh b/dec265/sdl.hh index f94aad66..1d020b65 100644 --- a/dec265/sdl.hh +++ b/dec265/sdl.hh @@ -39,6 +39,7 @@ public: }; bool init(int frame_width, int frame_height, enum SDL_Chroma chroma = SDL_CHROMA_420); + bool resize(int frame_width, int frame_height, enum SDL_Chroma chroma = SDL_CHROMA_420); void display(const unsigned char *Y, const unsigned char *U, const unsigned char *V, int stride, int chroma_stride); void close();