diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
commit | 2aa4a82499d4becd2284cdb482213d541b8804dd (patch) | |
tree | b80bf8bf13c3766139fbacc530efd0dd9d54394c /third_party/dav1d/examples/dp_renderer_sdl.c | |
parent | Initial commit. (diff) | |
download | firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.tar.xz firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.zip |
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/dav1d/examples/dp_renderer_sdl.c')
-rw-r--r-- | third_party/dav1d/examples/dp_renderer_sdl.c | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/third_party/dav1d/examples/dp_renderer_sdl.c b/third_party/dav1d/examples/dp_renderer_sdl.c new file mode 100644 index 0000000000..078d613492 --- /dev/null +++ b/third_party/dav1d/examples/dp_renderer_sdl.c @@ -0,0 +1,164 @@ +/* + * Copyright © 2020, VideoLAN and dav1d authors + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "dp_renderer.h" + +#include <assert.h> + +/** + * Renderer context for SDL + */ +typedef struct renderer_priv_ctx +{ + // SDL window + SDL_Window *win; + // SDL renderer + SDL_Renderer *renderer; + // Lock protecting access to the texture + SDL_mutex *lock; + // Texture to render + SDL_Texture *tex; +} Dav1dPlayRendererPrivateContext; + +static void *sdl_renderer_create() +{ + SDL_Window *win = dp_create_sdl_window(0); + if (win == NULL) + return NULL; + + // Alloc + Dav1dPlayRendererPrivateContext *rd_priv_ctx = malloc(sizeof(Dav1dPlayRendererPrivateContext)); + if (rd_priv_ctx == NULL) { + return NULL; + } + rd_priv_ctx->win = win; + + // Create renderer + rd_priv_ctx->renderer = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED); + // Set scale quality + SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear"); + + // Create Mutex + rd_priv_ctx->lock = SDL_CreateMutex(); + if (rd_priv_ctx->lock == NULL) { + fprintf(stderr, "SDL_CreateMutex failed: %s\n", SDL_GetError()); + free(rd_priv_ctx); + return NULL; + } + + rd_priv_ctx->tex = NULL; + + return rd_priv_ctx; +} + +static void sdl_renderer_destroy(void *cookie) +{ + Dav1dPlayRendererPrivateContext *rd_priv_ctx = cookie; + assert(rd_priv_ctx != NULL); + + SDL_DestroyRenderer(rd_priv_ctx->renderer); + SDL_DestroyMutex(rd_priv_ctx->lock); + free(rd_priv_ctx); +} + +static void sdl_render(void *cookie, const Dav1dPlaySettings *settings) +{ + Dav1dPlayRendererPrivateContext *rd_priv_ctx = cookie; + assert(rd_priv_ctx != NULL); + + SDL_LockMutex(rd_priv_ctx->lock); + + if (rd_priv_ctx->tex == NULL) { + SDL_UnlockMutex(rd_priv_ctx->lock); + return; + } + + // Display the frame + SDL_RenderClear(rd_priv_ctx->renderer); + SDL_RenderCopy(rd_priv_ctx->renderer, rd_priv_ctx->tex, NULL, NULL); + SDL_RenderPresent(rd_priv_ctx->renderer); + + SDL_UnlockMutex(rd_priv_ctx->lock); +} + +static int sdl_update_texture(void *cookie, Dav1dPicture *dav1d_pic, + const Dav1dPlaySettings *settings) +{ + Dav1dPlayRendererPrivateContext *rd_priv_ctx = cookie; + assert(rd_priv_ctx != NULL); + + SDL_LockMutex(rd_priv_ctx->lock); + + if (dav1d_pic == NULL) { + rd_priv_ctx->tex = NULL; + SDL_UnlockMutex(rd_priv_ctx->lock); + return 0; + } + + int width = dav1d_pic->p.w; + int height = dav1d_pic->p.h; + int tex_w = width; + int tex_h = height; + + enum Dav1dPixelLayout dav1d_layout = dav1d_pic->p.layout; + + if (DAV1D_PIXEL_LAYOUT_I420 != dav1d_layout || dav1d_pic->p.bpc != 8) { + fprintf(stderr, "Unsupported pixel format, only 8bit 420 supported so far.\n"); + exit(50); + } + + SDL_Texture *texture = rd_priv_ctx->tex; + if (texture != NULL) { + SDL_QueryTexture(texture, NULL, NULL, &tex_w, &tex_h); + if (tex_w != width || tex_h != height) { + SDL_DestroyTexture(texture); + texture = NULL; + } + } + + if (texture == NULL) { + texture = SDL_CreateTexture(rd_priv_ctx->renderer, SDL_PIXELFORMAT_IYUV, + SDL_TEXTUREACCESS_STREAMING, width, height); + } + + SDL_UpdateYUVTexture(texture, NULL, + dav1d_pic->data[0], (int)dav1d_pic->stride[0], // Y + dav1d_pic->data[1], (int)dav1d_pic->stride[1], // U + dav1d_pic->data[2], (int)dav1d_pic->stride[1] // V + ); + + rd_priv_ctx->tex = texture; + SDL_UnlockMutex(rd_priv_ctx->lock); + return 0; +} + +const Dav1dPlayRenderInfo rdr_sdl = { + .name = "sdl", + .create_renderer = sdl_renderer_create, + .destroy_renderer = sdl_renderer_destroy, + .render = sdl_render, + .update_frame = sdl_update_texture +}; |