local input1 = scene:add_input()
input1:display(1)
+ -- Note that add_effect returns its input for convenience.
local mix_effect = scene:add_effect(MixEffect.new(), input0, input1)
scene:finalize()
-- Or by numerical index:
input0_scaled:choose(1) -- Chooses ResizeEffect
-Note that add_effect returns its input for convenience. All alternatives must
-have the same amount of inputs, with an exception for IdentityEffect, which can
-coexist with an effect requiring any amount of inputs (if selected, the IdentityEffect
-just passes its first input unchanged).
-
Actually, add_optional_effect() is just a wrapper around add_effect() with
IdentityEffect as the other alternative, and disable() is a convenience version of
choose(IdentityEffect).
+All alternatives must
+have the same amount of inputs, with an exception for IdentityEffect, which can
+coexist with an effect requiring any amount of inputs (if selected, the IdentityEffect
+just passes its first input unchanged). Similarly, if you set a parameter with
+set_int() or similar, it must be valid for all alternatives (again excepting
+IdentityEffect); if there is one that can only be used on a certain alternative,
+you must set it directly on the effect::
+
+ local resample_effect = ResampleEffect.new()
+ resample_effect:set_float("zoom_x", 1.0001) -- Not valid for ResizeEffect.
+
+ local input0_scaled = scene:add_effect({resample_effect, ResizeEffect.new()})
+ input0_scaled:set_int("width", 1280) -- Set on both alternatives.
+ input0_scaled:set_int("height", 720)
+
+ -- This is also possible, as choose() returns the chosen effect:
+ input0_scaled:choose(ResampleEffect):set_float("zoom_y", 1.0001)
+
Actually, more versions are created than you'd immediately expect.
In particular, the output format for the live output and all previews are
different (Y'CbCr versus RGBA), which is also handled transparently for you.
channel when asked; it can vary from frame to frame. A typical use is to mark
the currently playing input as red, or the preview as green.
-And finally, there are two entry points related to white balance::
+
+.. _white-balance:
+
+White balance
+.............
+
+Finally, there are two entry points related to white balance. The first one
+is::
Nageru.set_supports_wb(2, true)
- function set_wb(channel, red, green, blue)
If the first function is called with a true value (at the start of the theme),
the channel will get a “Set WB” button next to it, which will activate a color
-picker. When the user picks a color (ostensibly with a gray point), the second
+picker, to select the gray point. To actually *apply* this white balance change,
+you have two options. If you're using Nageru 1.9.2 or newer, it's as simple
+as adding one element to the scene::
+
+ scene:add_white_balance()
+
+The white balance effect will automatically figure out which input it is
+connected to, and fetch its gray point if needed. (If it is connected to
+e.g. a mix of several inputs, such as a camera and an overlay, you will need to
+give the input to fetch white balance from as as a parameter.)
+
+If, on the other hand, you are using Nageru 1.9.1 or older (or just wish
+for more manual control), there's an entry point you will need to implement::
+
+ function set_wb(channel, red, green, blue)
+
+When the user picks a gray point, this function
function will be called (with the RGB values in linear light—not sRGB!),
and the theme can then use it to adjust the white balance for that channel.
The typical way to to this is to have a *WhiteBalanceEffect* on each input
resample_effect:always_disable_if_disabled(crop_effect)
+Also, since Nageru 1.9.1, you can disable an optional effect if a given other
+effect is *enabled*::
+
+ overlay1_effect:promise_to_disable_if_enabled(overlay2_effect)
+ overlay2_effect:promise_to_disable_if_enabled(overlay1_effect)
+
+Note that the latter is a promise from the user, not automatic disabling; since
+it is mostly useful for mutual exclusions, Nageru wouldn't know which of the
+two to disable. (If you violate the promise, you will get an error message at
+runtime.) It can still be useful for reducing the number of alternatives, though.
+
For more advanced exclusions, you may choose to split up the scenes into several
distinct ones that you manage yourself; indeed, before Nageru 1.9.0, that was
the only option. At some point, however, you may choose to simply accept the
You can use this either for display purposes, or for choosing the right
effect alternatives. In particular, you may want to disable scaling if
the frame is already of the correct resolution.
+
+
+Overriding the status line
+--------------------------
+
+Some users may wish to override the status line, e.g. with recording time.
+If so, it is possible (since Nageru 1.9.1) to declare a function **format_status_line**::
+
+ function format_status_line(disk_space_text, file_length_seconds)
+ if file_length_seconds > 86400.0 then
+ return "Time to make a new segment"
+ else
+ return "Disk space left: " .. disk_space_text
+ end
+ end
+
+As demonstrated, it is given the disk space text (that would normally
+be there), and the length of the current recording file in seconds.
+HTML is supported.