JSON scenes
A pl_scene is a compositor
configured from a JSON description: the placement and timing of each input,
plus the render options of every input and of the canvas as a whole.
pl_scene scene = pl_scene_create_json(log, json, strlen(json));
if (!scene)
return;
// Scenes must be initialized with a GPU before they can be rendered
if (!pl_compositor_init(scene->comp, gpu))
return;
// Provide the frames for each input, in the order they appear in the JSON
for (int i = 0; i < scene->comp->num_inputs; i++) {
pl_input input = scene->comp->inputs[i];
input->user_data = &sources[i];
input->get_frame = my_get_frame;
}
pl_scene_render(scene, &target, &queue_params, NULL);
pl_scene_destroy(&scene);
The scene owns the compositor, and with it pl_compositor.params as well as
the params of every input. Inputs may not be added to or removed from a
scene.
Structure
A scene is a JSON object with the following optional keys:
{
"params": { "border": "tiles", "dither": false },
"color": { "primaries": "bt.2020", "transfer": "pq" },
"inputs": [
{
"start_pts": "1001/30000",
"stop_pts": 12.5,
"fit": "cover",
"dst_rect": { "x0": 0.0, "y0": 0.0, "x1": 0.5, "y1": 0.5 },
"color": { "transfer": "pq", "hdr": { "max_luma": 1000 } },
"params": { "upscaler": "ewa_lanczossharp", "deband": true }
},
{
"z_index": 1,
"fit": "contain",
"dst_rect": { "x0": 0.5, "x1": 1.0 }
}
]
}
params: render options for the canvas, i.e. for composing the inputs and rendering the result onto the target frame. See render options.inputs: an array with one object per input, describing its timing, placement and frame property overrides, as well as its ownparams. See inputs.color,repr,chroma_location: overrides for the color space, representation and chroma location of the target frame. See color overrides.
Values
Every value is given as a JSON number, boolean or string:
- Numbers are passed on as written, so
1000,1e3and1000.0are all equivalent for a floating point option. trueandfalseare valid only for boolean options.- Strings are accepted for every option. This is how named values (e.g.
"fit": "cover") are given, and it also allows writing floating point values as fractions, such as"1001/30000".
Nested structs, such as the rects or the color overrides, are written as nested objects.
Keys are applied in the order they appear. Repeating a key is allowed, with the last occurrence taking effect.
Inputs
Each input object takes the following keys, all optional. Their meanings are
documented in full on the corresponding fields of pl_input.
| Key | Type | Default | Description |
|---|---|---|---|
start_pts |
number | 0 |
Output timestamp at which the input appears |
stop_pts |
number | unbounded | Output timestamp at which the input disappears again |
start_mode |
nearest, up, down |
nearest |
How start_pts is rounded onto the output frames |
stop_mode |
nearest, up, down |
nearest |
How stop_pts is rounded onto the output frames |
seek_pts |
number | 0 |
Position within the input's own timeline at start_pts |
z_index |
integer | 0 |
Compositing order, higher values are drawn on top |
rotation |
integer | 0 |
Extra rotation, in clockwise multiples of 90° |
fit |
see below | contain |
How the image is fitted into dst_rect |
src_rect |
rect | full frame | Part of the image to display |
dst_rect |
rect | full frame | Part of the canvas to display it in |
focus |
{ "x", "y" } |
0.5, 0.5 |
Focus point, deciding how the image is aligned within dst_rect |
color |
color space | unset | Overrides the color space of the input's frames |
repr |
color repr | unset | Overrides the color representation of the input's frames |
chroma_location |
chroma location | unset | Overrides the chroma location of the input's frames |
params |
render options | pl_render_default_params |
Render options for this input |
start_pts and stop_pts are given in the output timeline, while seek_pts
is given in the input timeline (the input's own timestamps).
The available fit modes are:
contain: Largest size contained withindst_rect, preserving aspect.cover: Smallest size that coversdst_rect, preserving aspect.fill: Stretched to the exact size ofdst_rect, ignoring aspect.scale_down: Likeplace, but scaled down likecontainif it would not fit otherwise.place: Unscaled, i.e. displayed at its native size.raw: Likeplace, but rounded to exact pixels, mapping image pixels one-to-one onto canvas pixels.
Rects
src_rect and dst_rect are given as an object with the keys x0, y0, x1
and y1, relative to the image and the canvas respectively, in the range
[0, 1]. Both are expressed in the displayed (i.e. rotated) orientation.
Leaving out a key keeps its default, so e.g. { "x1": 0.5 } selects the left
half. Swapping x0 and x1 (or y0 and y1) mirrors the image.
Color overrides
Any value set in color, repr or chroma_location replaces the corresponding value reported by
the input's frames (or, at the top level, of the target frame); unset values
(or auto) leave them as they are.
color takes the following keys:
primaries:auto,bt.601-525,bt.601-625,bt.709,bt.470m,ebu3213,bt.2020,apple,adobe,prophoto,cie1931,dci-p3,display-p3,v-gamut,s-gamut,film-c,aces-ap0,aces-ap1transfer:auto,bt.1886,srgb,linear,gamma1.8,gamma2.0,gamma2.2,gamma2.4,gamma2.6,gamma2.8,prophoto,st428,pq,hlg,v-log,s-log1,s-log2,scrgbhdr: an object with the keysmin_luma,max_luma,max_cllandmax_fall, all in cd/m²
repr takes the following keys:
sys:auto,bt.601,bt.709,smpte-240m,bt.2020-ncl,bt.2020-cl,bt.2100-pq,bt.2100-hlg,dolbyvision,ycgco,ycgco-re,ycgco-ro,rgb,xyzlevels:auto,limited,fullalpha:unknown,independent,premultiplied,nonebits: an object with the keyssample_depth,color_depthandbit_shift
chroma_location takes one of auto, left, center, top-left,
top-center, bottom-left or bottom-center.
Render options
Each params object takes the options documented for
pl_options, under the same keys as the corresponding option names.
"params": {
"preset": "high_quality",
"upscaler": "ewa_lanczossharp",
"deband": true,
"deband_iterations": 2,
"brightness": 0.1
}
As usual, the options of a section only take effect while that section is
enabled; for example, deband_iterations does nothing without
"deband": true. Since keys are applied in order, a preset should come
before any options it is meant to be combined with.
Canvas and input options
Every option takes effect in exactly one place, either on the canvas or on each input, whichever it applies to:
- Options affecting the canvas as a whole are taken from the top-level
params, and are ignored in theparamsof an input. These include things likebackground,border,dither, etc. - Options affecting the image are taken from the
paramsof each input, and are ignored in the top-levelparams. These include things likeframe_mixer,deband, the color adjustment, etc. - All other options, such as the scalers or the color mapping, apply to whichever of the two they are given for.
The border is the part of the canvas not covered by the lowest visible input,
which is also the input it is blurred from with border=blur. The background
is drawn below all inputs.
Animations
Any option, whether a field of an input (such as the rects, focus or the
timestamps) or one of its render options (such as brightness), can be
animated by giving it an array of keyframes instead of a single value:
"dst_rect": {
"x1": [
{ "pts": 0.0, "value": 0.5, "easing": [0.42, 0, 0.58, 1] },
{ "pts": 2.0, "value": 1.0 }
]
}
Each keyframe takes the following keys:
pts: The output timestamp of the keyframe, in the same timebase aspl_queue_params.pts. Required.value: The value at that timestamp, given and range checked like any other value of the option. Required.easing: How to transition from this keyframe to the next one, as the control points[x1, y1, x2, y2]of a cubic Bézier curve from(0, 0)to(1, 1), like the CSScubic-bezier()function, or as the name of one of the predefined curves below.x1andx2must lie in the range[0, 1]. If omitted, the value is held until the next keyframe. Only supported for numeric options, with the values of integer options rounded to the nearest integer; all other options always hold their value until the next keyframe.
The predefined easing curves are:
| Name | Control points |
|---|---|
| linear | [0, 0, 1, 1] |
| ease | [0.25, 0.1, 0.25, 1] |
| ease-in | [0.42, 0, 1, 1] |
| ease-out | [0, 0, 0.58, 1] |
| ease-in-out | [0.42, 0, 0.58, 1] |
Keyframes may be listed in any order, however, keyframes with the same pts
keep the order they were given in, which can be used to jump from one value
to another instantly. Before the first keyframe, and after the last one, the
option keeps the value of the corresponding boundary keyframe.
The animated values are only updated by pl_scene_update(), which should be
called for every output frame before rendering it, with the same pts as
passed to the compositor. Until the first update, every animated option has the
value of its first keyframe.
The values in between keyframes are clamped to the valid range of the option,
so a curve that overshoots (with y1 or y2 outside of [0, 1]) stops at the
limits of that range.
Presets, such as preset, cannot be animated.
Since changes to a render option may imply recompiling the affected shaders,
animating any render option also enables dynamic_constants for the
params it belongs to.