]> git.sesse.net Git - nageru/blob - simple.lua
Allow changing FFmpeg URL from the context menu.
[nageru] / simple.lua
1 -- The theme is what decides what's actually shown on screen, what kind of
2 -- transitions are available (if any), and what kind of inputs there are,
3 -- if any. In general, it drives the entire display logic by creating Movit
4 -- chains, setting their parameters and then deciding which to show when.
5 --
6 -- Themes are written in Lua, which reflects a simplified form of the Movit API
7 -- where all the low-level details (such as texture formats) are handled by the
8 -- C++ side and you generally just build chains.
9 --
10 -- This is a much simpler theme than the default theme; it only allows you to
11 -- switch between inputs and set white balance, no transitions or the likes.
12 -- Thus, it should be simpler to understand.
13
14 local input_neutral_color = {{0.5, 0.5, 0.5}, {0.5, 0.5, 0.5}}
15
16 local live_signal_num = 0
17 local preview_signal_num = 1
18
19 -- A chain to show a single input, with white balance. In a real example,
20 -- we'd probably want to support deinterlacing and high-quality scaling
21 -- (if the input isn't exactly what we want). However, we don't want these
22 -- things always on, so we'd need to generate more chains for the various
23 -- cases. In such a simple example, just having two is fine.
24 function make_simple_chain(hq)
25         local chain = EffectChain.new(16, 9)
26
27         local input = chain:add_live_input(false, false)  -- No deinterlacing, no bounce override.
28         input:connect_signal(0)  -- First input card. Can be changed whenever you want.
29         local wb_effect = chain:add_effect(WhiteBalanceEffect.new())
30         chain:finalize(hq)
31
32         return {
33                 chain = chain,
34                 input = input,
35                 wb_effect = wb_effect,
36         }
37 end
38
39 -- We only make two chains; one for the live view and one for the previews.
40 -- (Since they have different outputs, you cannot mix and match them.)
41 local simple_hq_chain = make_simple_chain(true)
42 local simple_lq_chain = make_simple_chain(false)
43
44 -- API ENTRY POINT
45 -- Returns the number of outputs in addition to the live (0) and preview (1).
46 -- Called only once, at the start of the program.
47 function num_channels()
48         return 2
49 end
50
51 -- API ENTRY POINT
52 -- Returns the name for each additional channel (starting from 2).
53 -- Called at the start of the program, and then each frame for live
54 -- channels in case they change resolution.
55 function channel_name(channel)
56         if channel == 2 then
57                 return "First input"
58         elseif channel == 3 then
59                 return "Second input"
60         end
61 end
62
63 -- API ENTRY POINT
64 -- Returns, given a channel number, which signal it corresponds to (starting from 0).
65 -- Should return -1 if the channel does not correspond to a simple signal.
66 -- (The information is used for whether right-click on the channel should bring up
67 -- an input selector or not.)
68 -- Called once for each channel, at the start of the program.
69 -- Will never be called for live (0) or preview (1).
70 function channel_signal(channel)
71         if channel == 2 then
72                 return 0
73         elseif channel == 3 then
74                 return 1
75         else
76                 return -1
77         end
78 end
79
80 -- API ENTRY POINT
81 -- Called every frame. Returns the color (if any) to paint around the given
82 -- channel. Returns a CSS color (typically to mark live and preview signals);
83 -- "transparent" is allowed.
84 -- Will never be called for live (0) or preview (1).
85 function channel_color(channel)
86         return "transparent"
87 end
88
89 -- API ENTRY POINT
90 -- Returns if a given channel supports setting white balance (starting from 2).
91 -- Called only once for each channel, at the start of the program.
92 function supports_set_wb(channel)
93         return channel == 2 or channel == 3
94 end
95
96 -- API ENTRY POINT
97 -- Gets called with a new gray point when the white balance is changing.
98 -- The color is in linear light (not sRGB gamma).
99 function set_wb(channel, red, green, blue)
100         if channel == 2 then
101                 input_neutral_color[1] = { red, green, blue }
102         elseif channel == 3 then
103                 input_neutral_color[2] = { red, green, blue }
104         end
105 end
106
107 -- API ENTRY POINT
108 -- Called every frame.
109 function get_transitions(t)
110         if live_signal_num == preview_signal_num then
111                 -- No transitions possible.
112                 return {}
113         else
114                 return {"Cut"}
115         end
116 end
117
118 -- API ENTRY POINT
119 -- Called when the user clicks a transition button. For our case,
120 -- we only do cuts, so we ignore the parameters; just switch live and preview.
121 function transition_clicked(num, t)
122         local temp = live_signal_num
123         live_signal_num = preview_signal_num
124         preview_signal_num = temp
125 end
126
127 -- API ENTRY POINT
128 function channel_clicked(num)
129         preview_signal_num = num
130 end
131
132 -- API ENTRY POINT
133 -- Called every frame. Get the chain for displaying at input <num>,
134 -- where 0 is live, 1 is preview, 2 is the first channel to display
135 -- in the bottom bar, and so on up to num_channels()+1. t is the
136 -- current time in seconds. width and height are the dimensions of
137 -- the output, although you can ignore them if you don't need them
138 -- (they're useful if you want to e.g. know what to resample by).
139 --
140 -- <signals> is basically an exposed InputState, which you can use to
141 -- query for information about the signals at the point of the current
142 -- frame. In particular, you can call get_width() and get_height()
143 -- for any signal number, and use that to e.g. assist in chain selection.
144 --
145 -- You should return two objects; the chain itself, and then a
146 -- function (taking no parameters) that is run just before rendering.
147 -- The function needs to call connect_signal on any inputs, so that
148 -- it gets updated video data for the given frame. (You are allowed
149 -- to switch which input your input is getting from between frames,
150 -- but not calling connect_signal results in undefined behavior.)
151 -- If you want to change any parameters in the chain, this is also
152 -- the right place.
153 --
154 -- NOTE: The chain returned must be finalized with the Y'CbCr flag
155 -- if and only if num==0.
156 function get_chain(num, t, width, height, signals)
157         local chain, signal_num
158         if num == 0 then  -- Live (right pane).
159                 chain = simple_hq_chain
160                 signal_num = live_signal_num
161         elseif num == 1 then  -- Preview (left pane).
162                 chain = simple_lq_chain
163                 signal_num = preview_signal_num
164         else  -- One of the two previews (bottom panes).
165                 chain = simple_lq_chain
166                 signal_num = num - 2
167         end
168
169         prepare = function()
170                 chain.input:connect_signal(signal_num)
171                 local color = input_neutral_color[signal_num + 1]
172                 chain.wb_effect:set_vec3("neutral_color", color[1], color[2], color[3])
173         end
174         return chain.chain, prepare
175 end