diff options
author | Marvin Scholz <epirat07@gmail.com> | 2020-05-15 11:13:31 +0300 |
---|---|---|
committer | Marvin Scholz <epirat07@gmail.com> | 2020-05-15 11:49:14 +0300 |
commit | c1c41ff09814cb45dc79f1b9d326bb82b3b287b8 (patch) | |
tree | bf8a28b041e16cd3594fa92a037e963767442d1a /examples | |
parent | 7f5cf34d06e4b8e7ff83e653c67532e92f4b462b (diff) |
Dav1dPlay: Allow runtime renderer selection
Diffstat (limited to 'examples')
-rw-r--r-- | examples/dav1dplay.c | 110 | ||||
-rw-r--r-- | examples/dp_renderer.h | 73 | ||||
-rw-r--r-- | examples/dp_renderer_placebo.c (renamed from examples/dp_renderer_placebo.h) | 14 | ||||
-rw-r--r-- | examples/dp_renderer_sdl.c (renamed from examples/dp_renderer_sdl.h) | 9 | ||||
-rw-r--r-- | examples/meson.build | 2 |
5 files changed, 128 insertions, 80 deletions
diff --git a/examples/dav1dplay.c b/examples/dav1dplay.c index ef39d41..7c7d63a 100644 --- a/examples/dav1dplay.c +++ b/examples/dav1dplay.c @@ -29,71 +29,19 @@ #include <getopt.h> #include <stdbool.h> -#include <stdint.h> -#include <stdio.h> -#include <string.h> #include <SDL.h> -#include "common/attributes.h" - #include "dav1d/dav1d.h" +#include "common/attributes.h" #include "tools/input/input.h" #include "dp_fifo.h" - -// Determine which renderer we are going to compile: -// Selection order by preference: -// - libplacebo Vulkan renderer -// - libplacebo OpenGL renderer -// - SDL2 renderer -#ifdef HAVE_PLACEBO -# include <libplacebo/config.h> -#endif - -// Check libplacebo Vulkan rendering -#if defined(HAVE_VULKAN) && defined(SDL_VIDEO_VULKAN) -# if defined(PL_HAVE_VULKAN) && PL_HAVE_VULKAN -# define HAVE_RENDERER_PLACEBO -# define HAVE_PLACEBO_VULKAN -# endif -#endif - -// Check libplacebo OpenGL rendering -#ifndef HAVE_RENDERER_PLACEBO -# if defined(PL_HAVE_OPENGL) && PL_HAVE_OPENGL -# define HAVE_RENDERER_PLACEBO -# define HAVE_PLACEBO_OPENGL -# endif -#endif - -// Fallback to SDL if we can't use placebo -#ifndef HAVE_RENDERER_PLACEBO -# define HAVE_RENDERER_SDL -#endif - - -/** - * Settings structure - * Hold all settings available for the player, - * this is usually filled by parsing arguments - * from the console. - */ -typedef struct { - const char *inputfile; - int highquality; - int untimed; - int zerocopy; -} Dav1dPlaySettings; - -#define WINDOW_WIDTH 910 -#define WINDOW_HEIGHT 512 - -#define DAV1D_EVENT_NEW_FRAME 1 -#define DAV1D_EVENT_DEC_QUIT 2 - #include "dp_renderer.h" +// Selected renderer callbacks and cookie +static const Dav1dPlayRenderInfo *renderer_info = { NULL }; + /** * Render context structure * This structure contains informations necessary @@ -151,7 +99,8 @@ static void dp_settings_print_usage(const char *const app, " --tilethreads $num: number of tile threads (default: 1)\n" " --highquality: enable high quality rendering\n" " --zerocopy/-z: enable zero copy upload path\n" - " --version/-v: print version and exit\n"); + " --version/-v: print version and exit\n" + " --renderer/-r: select renderer backend (default: auto)\n"); exit(1); } @@ -174,7 +123,7 @@ static void dp_rd_ctx_parse_args(Dav1dPlayRenderContext *rd_ctx, Dav1dSettings *lib_settings = &rd_ctx->lib_settings; // Short options - static const char short_opts[] = "i:vuz"; + static const char short_opts[] = "i:vuzr:"; enum { ARG_FRAME_THREADS = 256, @@ -191,6 +140,7 @@ static void dp_rd_ctx_parse_args(Dav1dPlayRenderContext *rd_ctx, { "tilethreads", 1, NULL, ARG_TILE_THREADS }, { "highquality", 0, NULL, ARG_HIGH_QUALITY }, { "zerocopy", 0, NULL, 'z' }, + { "renderer", 0, NULL, 'r'}, { NULL, 0, NULL, 0 }, }; @@ -217,6 +167,9 @@ static void dp_rd_ctx_parse_args(Dav1dPlayRenderContext *rd_ctx, fprintf(stderr, "warning: --zerocopy requires libplacebo\n"); #endif break; + case 'r': + settings->renderer_name = optarg; + break; case ARG_FRAME_THREADS: lib_settings->n_frame_threads = parse_unsigned(optarg, ARG_FRAME_THREADS, argv[0]); @@ -235,6 +188,8 @@ static void dp_rd_ctx_parse_args(Dav1dPlayRenderContext *rd_ctx, "Extra/unused arguments found, e.g. '%s'\n", argv[optind]); if (!settings->inputfile) dp_settings_print_usage(argv[0], "Input file (-i/--input) is required"); + if (settings->renderer_name && strcmp(settings->renderer_name, "auto") == 0) + settings->renderer_name = NULL; } /** @@ -244,7 +199,7 @@ static void dp_rd_ctx_destroy(Dav1dPlayRenderContext *rd_ctx) { assert(rd_ctx != NULL); - renderer_info.destroy_renderer(rd_ctx->rd_priv); + renderer_info->destroy_renderer(rd_ctx->rd_priv); dp_fifo_destroy(rd_ctx->fifo); SDL_DestroyMutex(rd_ctx->lock); free(rd_ctx); @@ -256,7 +211,7 @@ static void dp_rd_ctx_destroy(Dav1dPlayRenderContext *rd_ctx) * \note The Dav1dPlayRenderContext must be destroyed * again by using dp_rd_ctx_destroy. */ -static Dav1dPlayRenderContext *dp_rd_ctx_create(void *rd_data) +static Dav1dPlayRenderContext *dp_rd_ctx_create(void *rd_data, int argc, char **argv) { Dav1dPlayRenderContext *rd_ctx; @@ -290,7 +245,22 @@ static Dav1dPlayRenderContext *dp_rd_ctx_create(void *rd_data) return NULL; } - rd_ctx->rd_priv = renderer_info.create_renderer(rd_data); + // Parse and validate arguments + dav1d_default_settings(&rd_ctx->lib_settings); + memset(&rd_ctx->settings, 0, sizeof(rd_ctx->settings)); + dp_rd_ctx_parse_args(rd_ctx, argc, argv); + + // Select renderer + renderer_info = dp_get_renderer(rd_ctx->settings.renderer_name); + + if (renderer_info == NULL) { + printf("No suitable rendered matching %s found.\n", + (rd_ctx->settings.renderer_name) ? rd_ctx->settings.renderer_name : "auto"); + } else { + printf("Using %s renderer\n", renderer_info->name); + } + + rd_ctx->rd_priv = (renderer_info) ? renderer_info->create_renderer(rd_data) : NULL; if (rd_ctx->rd_priv == NULL) { SDL_DestroyMutex(rd_ctx->lock); dp_fifo_destroy(rd_ctx->fifo); @@ -298,9 +268,6 @@ static Dav1dPlayRenderContext *dp_rd_ctx_create(void *rd_data) return NULL; } - dav1d_default_settings(&rd_ctx->lib_settings); - memset(&rd_ctx->settings, 0, sizeof(rd_ctx->settings)); - rd_ctx->last_pts = 0; rd_ctx->last_ticks = 0; rd_ctx->current_pts = 0; @@ -332,7 +299,7 @@ static void dp_rd_ctx_post_event(Dav1dPlayRenderContext *rd_ctx, uint32_t code) static void dp_rd_ctx_update_with_dav1d_picture(Dav1dPlayRenderContext *rd_ctx, Dav1dPicture *dav1d_pic) { - renderer_info.update_frame(rd_ctx->rd_priv, dav1d_pic, &rd_ctx->settings); + renderer_info->update_frame(rd_ctx->rd_priv, dav1d_pic, &rd_ctx->settings); rd_ctx->current_pts = dav1d_pic->m.timestamp; } @@ -387,7 +354,7 @@ static void dp_rd_ctx_render(Dav1dPlayRenderContext *rd_ctx) fprintf(stderr, "Frame displayed %f seconds too late\n", wait_time/(float)1000); } - renderer_info.render(rd_ctx->rd_priv, &rd_ctx->settings); + renderer_info->render(rd_ctx->rd_priv, &rd_ctx->settings); rd_ctx->last_ticks = SDL_GetTicks(); } @@ -564,21 +531,18 @@ int main(int argc, char **argv) SDL_SetWindowResizable(win, SDL_TRUE); // Create render context - Dav1dPlayRenderContext *rd_ctx = dp_rd_ctx_create(win); + Dav1dPlayRenderContext *rd_ctx = dp_rd_ctx_create(win, argc, argv); if (rd_ctx == NULL) { fprintf(stderr, "Failed creating render context\n"); return 5; } - // Parse and validate arguments - dp_rd_ctx_parse_args(rd_ctx, argc, argv); - if (rd_ctx->settings.zerocopy) { - if (renderer_info.alloc_pic) { + if (renderer_info->alloc_pic) { rd_ctx->lib_settings.allocator = (Dav1dPicAllocator) { .cookie = rd_ctx->rd_priv, - .alloc_picture_callback = renderer_info.alloc_pic, - .release_picture_callback = renderer_info.release_pic, + .alloc_picture_callback = renderer_info->alloc_pic, + .release_picture_callback = renderer_info->release_pic, }; } else { fprintf(stderr, "--zerocopy unsupported by compiled renderer\n"); diff --git a/examples/dp_renderer.h b/examples/dp_renderer.h index 0650601..639ccc7 100644 --- a/examples/dp_renderer.h +++ b/examples/dp_renderer.h @@ -24,11 +24,57 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include <inttypes.h> +#include <string.h> + +#include "dav1d/dav1d.h" + +#include <SDL_config.h> +#ifdef HAVE_PLACEBO +# include <libplacebo/config.h> +#endif + +// Check libplacebo Vulkan rendering +#if defined(HAVE_VULKAN) && defined(SDL_VIDEO_VULKAN) +# if defined(PL_HAVE_VULKAN) && PL_HAVE_VULKAN +# define HAVE_RENDERER_PLACEBO +# define HAVE_PLACEBO_VULKAN +# endif +#endif + +// Check libplacebo OpenGL rendering +#if defined(PL_HAVE_OPENGL) && PL_HAVE_OPENGL +# define HAVE_RENDERER_PLACEBO +# define HAVE_PLACEBO_OPENGL +#endif + +/** + * Settings structure + * Hold all settings available for the player, + * this is usually filled by parsing arguments + * from the console. + */ +typedef struct { + const char *inputfile; + const char *renderer_name; + int highquality; + int untimed; + int zerocopy; +} Dav1dPlaySettings; + +#define WINDOW_WIDTH 910 +#define WINDOW_HEIGHT 512 + +#define DAV1D_EVENT_NEW_FRAME 1 +#define DAV1D_EVENT_DEC_QUIT 2 + /** * Renderer info */ typedef struct rdr_info { + // Renderer name + const char *name; // Cookie passed to the renderer implementation callbacks void *cookie; // Callback to create the renderer @@ -45,8 +91,25 @@ typedef struct rdr_info void (*release_pic)(Dav1dPicture *pic, void *cookie); } Dav1dPlayRenderInfo; -#ifdef HAVE_RENDERER_PLACEBO -# include "dp_renderer_placebo.h" -#else -# include "dp_renderer_sdl.h" -#endif +extern const Dav1dPlayRenderInfo rdr_placebo; +extern const Dav1dPlayRenderInfo rdr_sdl; + +// Available renderes ordered by priority +static const Dav1dPlayRenderInfo* const dp_renderers[] = { + &rdr_placebo, + &rdr_sdl, +}; + +static inline const Dav1dPlayRenderInfo *dp_get_renderer(const char *name) +{ + for (size_t i = 0; i < (sizeof(dp_renderers)/sizeof(*dp_renderers)); ++i) + { + if (dp_renderers[i]->name == NULL) + continue; + + if (name == NULL || strcmp(name, dp_renderers[i]->name) == 0) { + return dp_renderers[i]; + } + } + return NULL; +} diff --git a/examples/dp_renderer_placebo.h b/examples/dp_renderer_placebo.c index 82034fd..0464ed8 100644 --- a/examples/dp_renderer_placebo.h +++ b/examples/dp_renderer_placebo.c @@ -24,6 +24,13 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include "dp_renderer.h" + +#ifdef HAVE_RENDERER_PLACEBO +#include <assert.h> + +#include <SDL.h> + #include <libplacebo/renderer.h> #include <libplacebo/utils/upload.h> @@ -486,7 +493,8 @@ static void placebo_release_pic(Dav1dPicture *pic, void *cookie) SDL_UnlockMutex(rd_priv_ctx->lock); } -static const Dav1dPlayRenderInfo renderer_info = { +const Dav1dPlayRenderInfo rdr_placebo = { + .name = "placebo", .create_renderer = placebo_renderer_create, .destroy_renderer = placebo_renderer_destroy, .render = placebo_render, @@ -494,3 +502,7 @@ static const Dav1dPlayRenderInfo renderer_info = { .alloc_pic = placebo_alloc_pic, .release_pic = placebo_release_pic, }; + +#else +const Dav1dPlayRenderInfo rdr_placebo = { NULL }; +#endif diff --git a/examples/dp_renderer_sdl.h b/examples/dp_renderer_sdl.c index 5bddfd8..4784d98 100644 --- a/examples/dp_renderer_sdl.h +++ b/examples/dp_renderer_sdl.c @@ -24,6 +24,12 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include "dp_renderer.h" + +#include <assert.h> + +#include <SDL.h> + /** * Renderer context for SDL */ @@ -146,7 +152,8 @@ static int sdl_update_texture(void *cookie, Dav1dPicture *dav1d_pic, return 0; } -static const Dav1dPlayRenderInfo renderer_info = { +const Dav1dPlayRenderInfo rdr_sdl = { + .name = "sdl", .create_renderer = sdl_renderer_create, .destroy_renderer = sdl_renderer_destroy, .render = sdl_render, diff --git a/examples/meson.build b/examples/meson.build index 648077e..50e097a 100644 --- a/examples/meson.build +++ b/examples/meson.build @@ -36,6 +36,8 @@ endif dav1dplay_sources = files( 'dav1dplay.c', 'dp_fifo.c', + 'dp_renderer_placebo.c', + 'dp_renderer_sdl.c', ) sdl2_dependency = dependency('sdl2', version: '>= 2.0.1', required: true) |