1 /*
2 * Copyright © 2020, VideoLAN and dav1d authors
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this
9 * list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
19 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27 #include <inttypes.h>
28 #include <string.h>
29
30 #include "dav1d/dav1d.h"
31
32 #include <SDL.h>
33 #ifdef HAVE_PLACEBO
34 # include <libplacebo/config.h>
35 #endif
36
37 // Check libplacebo Vulkan rendering
38 #if defined(HAVE_VULKAN) && defined(SDL_VIDEO_VULKAN)
39 # if defined(PL_HAVE_VULKAN) && PL_HAVE_VULKAN
40 # define HAVE_RENDERER_PLACEBO
41 # define HAVE_PLACEBO_VULKAN
42 # endif
43 #endif
44
45 // Check libplacebo OpenGL rendering
46 #if defined(PL_HAVE_OPENGL) && PL_HAVE_OPENGL
47 # define HAVE_RENDERER_PLACEBO
48 # define HAVE_PLACEBO_OPENGL
49 #endif
50
51 /**
52 * Settings structure
53 * Hold all settings available for the player,
54 * this is usually filled by parsing arguments
55 * from the console.
56 */
57 typedef struct {
58 const char *inputfile;
59 const char *renderer_name;
60 int highquality;
61 int untimed;
62 int zerocopy;
63 int gpugrain;
64 } Dav1dPlaySettings;
65
66 #define WINDOW_WIDTH 910
67 #define WINDOW_HEIGHT 512
68
69 enum {
70 DAV1D_EVENT_NEW_FRAME,
71 DAV1D_EVENT_SEEK_FRAME,
72 DAV1D_EVENT_DEC_QUIT
73 };
74
75 /**
76 * Renderer info
77 */
78 typedef struct rdr_info
79 {
80 // Renderer name
81 const char *name;
82 // Cookie passed to the renderer implementation callbacks
83 void *cookie;
84 // Callback to create the renderer
85 void* (*create_renderer)();
86 // Callback to destroy the renderer
87 void (*destroy_renderer)(void *cookie);
88 // Callback to the render function that renders a prevously sent frame
89 void (*render)(void *cookie, const Dav1dPlaySettings *settings);
90 // Callback to the send frame function, _may_ also unref dav1d_pic!
91 int (*update_frame)(void *cookie, Dav1dPicture *dav1d_pic,
92 const Dav1dPlaySettings *settings);
93 // Callback for alloc/release pictures (optional)
94 int (*alloc_pic)(Dav1dPicture *pic, void *cookie);
95 void (*release_pic)(Dav1dPicture *pic, void *cookie);
96 // Whether or not this renderer can apply on-GPU film grain synthesis
97 int supports_gpu_grain;
98 } Dav1dPlayRenderInfo;
99
100 extern const Dav1dPlayRenderInfo rdr_placebo_vk;
101 extern const Dav1dPlayRenderInfo rdr_placebo_gl;
102 extern const Dav1dPlayRenderInfo rdr_sdl;
103
104 // Available renderes ordered by priority
105 static const Dav1dPlayRenderInfo* const dp_renderers[] = {
106 &rdr_placebo_vk,
107 &rdr_placebo_gl,
108 &rdr_sdl,
109 };
110
dp_get_renderer(const char * name)111 static inline const Dav1dPlayRenderInfo *dp_get_renderer(const char *name)
112 {
113 for (size_t i = 0; i < (sizeof(dp_renderers)/sizeof(*dp_renderers)); ++i)
114 {
115 if (dp_renderers[i]->name == NULL)
116 continue;
117
118 if (name == NULL || strcmp(name, dp_renderers[i]->name) == 0) {
119 return dp_renderers[i];
120 }
121 }
122 return NULL;
123 }
124
dp_create_sdl_window(int window_flags)125 static inline SDL_Window *dp_create_sdl_window(int window_flags)
126 {
127 SDL_Window *win;
128 window_flags |= SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI;
129
130 win = SDL_CreateWindow("Dav1dPlay", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
131 WINDOW_WIDTH, WINDOW_HEIGHT, window_flags);
132 SDL_SetWindowResizable(win, SDL_TRUE);
133
134 return win;
135 }
136