36#include <libplacebo/options.h>
37#include <libplacebo/renderer.h>
38#include <libplacebo/utils/libav.h>
39#include <libplacebo/utils/frame_queue.h>
40#include <libplacebo/vulkan.h>
153 struct pl_custom_lut *
lut;
300 av_log(log_ctx, av_lev,
"%s\n", msg);
323 switch (gamut_mode) {
324 case GAMUT_MAP_CLIP: p->gamut_mapping = &pl_gamut_map_clip;
return;
339 const struct pl_filter_config **opt,
340 const char *
name,
int frame_mixing)
342 const struct pl_filter_preset *
preset, *presets_avail;
343 presets_avail = frame_mixing ? pl_frame_mixers : pl_scale_filters;
345 if (!strcmp(
name,
"help")) {
370 if ((ret =
av_file_map(
s->lut_filename, &lutbuf, &lutbuf_size, 0,
s)) < 0) {
372 "The LUT file '%s' could not be read: %s\n",
377 s->lut = pl_lut_parse_cube(
s->log, lutbuf, lutbuf_size);
389 pl_options
opts =
s->opts;
390 int gamut_mode =
s->gamut_mode;
392 opts->deinterlace_params = *pl_deinterlace_params(
393 .
algo =
s->deinterlace,
394 .skip_spatial_check =
s->skip_spatial_check,
397 opts->deband_params = *pl_deband_params(
398 .iterations =
s->deband_iterations,
399 .threshold =
s->deband_threshold,
400 .radius =
s->deband_radius,
401 .grain =
s->deband_grain,
404 opts->sigmoid_params = pl_sigmoid_default_params;
406 opts->color_adjustment = (
struct pl_color_adjustment) {
407 .brightness =
s->brightness,
408 .contrast =
s->contrast,
409 .saturation =
s->saturation,
413 .temperature = (
s->temperature - 6500.0) / 3500.0,
416 opts->peak_detect_params = (
struct pl_peak_detect_params) {
417 PL_PEAK_DETECT_DEFAULTS
418 .smoothing_period =
s->smoothing,
419 .scene_threshold_low =
s->scene_low,
420 .scene_threshold_high =
s->scene_high,
421 .percentile =
s->percentile,
424 opts->color_map_params = (
struct pl_color_map_params) {
425 PL_COLOR_MAP_DEFAULTS
427 .tone_mapping_param =
s->tonemapping_param,
428 .inverse_tone_mapping =
s->inverse_tonemapping,
429 .lut_size =
s->tonemapping_lut_size,
430 .contrast_recovery =
s->contrast_recovery,
431 .contrast_smoothness =
s->contrast_smoothness,
436 opts->dither_params = *pl_dither_params(
437 .method =
s->dithering,
438 .lut_size =
s->dither_lut_size,
439 .temporal =
s->dither_temporal,
442 opts->cone_params = *pl_cone_params(
444 .strength =
s->cone_str,
447 opts->params = (
struct pl_render_params) {
449 .antiringing_strength =
s->antiringing,
450 .background_transparency = 1.0f - (
float)
s->fillcolor[3] / UINT8_MAX,
451 .background_color = {
452 (
float)
s->fillcolor[0] / UINT8_MAX,
453 (
float)
s->fillcolor[1] / UINT8_MAX,
454 (
float)
s->fillcolor[2] / UINT8_MAX,
456 .corner_rounding =
s->corner_rounding,
458 .deinterlace_params = &
opts->deinterlace_params,
459 .deband_params =
s->deband ? &
opts->deband_params :
NULL,
460 .sigmoid_params =
s->sigmoid ? &
opts->sigmoid_params :
NULL,
461 .color_adjustment = &
opts->color_adjustment,
462 .peak_detect_params =
s->peakdetect ? &
opts->peak_detect_params :
NULL,
463 .color_map_params = &
opts->color_map_params,
464 .dither_params =
s->dithering >= 0 ? &
opts->dither_params :
NULL,
465 .cone_params =
s->cones ? &
opts->cone_params :
NULL,
468 .num_hooks =
s->num_hooks,
470 .skip_anti_aliasing =
s->skip_aa,
471 .disable_linear_scaling =
s->disable_linear,
472 .disable_builtin_scalers =
s->disable_builtin,
473 .force_dither =
s->force_dither,
474 .disable_fbos =
s->disable_fbos,
482 if (!pl_options_set_str(
s->opts, e->
key, e->
value)) {
497 const struct pl_hook *hook;
499 hook = pl_mpv_user_shader_parse(
s->gpu, shader,
len);
505 s->hooks[
s->num_hooks++] = hook;
518 if (
s->normalize_sar &&
s->fit_mode !=
FIT_FILL) {
520 "a fit mode other than 'fill'\n");
524 s->log = pl_log_create(PL_API_VER, pl_log_params(
533 s->opts = pl_options_alloc(
s->log);
539 if (
s->shader_cache &&
s->shader_cache[0]) {
540 s->cache = pl_cache_create(pl_cache_params(
542 .get = pl_cache_get_file,
543 .set = pl_cache_set_file,
544 .priv =
s->shader_cache,
552 if (
s->out_format_string) {
556 s->out_format_string);
564 for (
int i = 0;
i <
s->nb_inputs;
i++) {
593 if (strcmp(
s->fps_string,
"none") != 0)
599 if (!
s->inherit_device) {
604 vkhwctx = avhwctx->
hwctx;
615static void lock_queue(
void *priv, uint32_t qf, uint32_t qidx)
619#if FF_API_VULKAN_SYNC_QUEUES
621 hwctx->lock_queue(avhwctx, qf, qidx);
630#if FF_API_VULKAN_SYNC_QUEUES
632 hwctx->unlock_queue(avhwctx, qf, qidx);
644 input->
queue = pl_queue_create(
s->gpu);
645 input->
renderer = pl_renderer_create(
s->log,
s->gpu);
653 pl_renderer_destroy(&input->
renderer);
654 pl_queue_destroy(&input->
queue);
660 struct pl_vulkan_queue *pl_qf)
662 pl_qf->index = qf->
idx;
663 pl_qf->count = qf->
num;
681 struct pl_vulkan_import_params import_params = {
682 .instance = hwctx->
inst,
692 .queue_graphics = { VK_QUEUE_FAMILY_IGNORED },
693 .queue_compute = { VK_QUEUE_FAMILY_IGNORED },
694 .queue_transfer = { VK_QUEUE_FAMILY_IGNORED },
696 .max_api_version = VK_API_VERSION_1_3,
698 for (
int i = 0;
i < hwctx->
nb_qf;
i++) {
700 if (qf->
flags & VK_QUEUE_GRAPHICS_BIT)
702 if (qf->
flags & VK_QUEUE_COMPUTE_BIT)
704 if (qf->
flags & VK_QUEUE_TRANSFER_BIT)
709 s->vulkan = pl_vulkan_import(
s->log, &import_params);
710 s->have_hwdevice = 1;
712 s->vulkan = pl_vulkan_create(
s->log, pl_vulkan_params(
719 hwctx ?
"importing" :
"creating");
724 s->gpu =
s->vulkan->gpu;
725 pl_gpu_set_cache(
s->gpu,
s->cache);
728 if (
s->shader_bin_len)
731 if (
s->shader_path &&
s->shader_path[0]) {
740 s->inputs =
av_calloc(
s->nb_inputs,
sizeof(*
s->inputs));
743 for (
int i = 0;
i <
s->nb_inputs;
i++)
745 s->nb_active =
s->nb_inputs;
746 s->linear_rr = pl_renderer_create(
s->log,
s->gpu);
760 pl_tex_destroy(
s->gpu, &
s->tex[
i]);
761 for (
int i = 0;
i <
s->num_hooks;
i++)
762 pl_mpv_user_shader_destroy(&
s->hooks[
i]);
764 for (
int i = 0;
i <
s->nb_inputs;
i++)
769 pl_lut_free(&
s->lut);
770 pl_cache_destroy(&
s->cache);
771 pl_renderer_destroy(&
s->linear_rr);
772 pl_tex_destroy(
s->gpu, &
s->linear_tex);
773 pl_options_free(&
s->opts);
774 pl_vulkan_destroy(&
s->vulkan);
775 pl_log_destroy(&
s->log);
790 const char *
arg,
char *res,
int res_len,
804 for (
int i = 0;
i <
mix->num_frames;
i++) {
805 if (
i+1 ==
mix->num_frames ||
mix->timestamps[
i+1] > 0)
806 return pl_get_mapped_avframe(
mix->frames[
i]);
817 struct pl_frame *target,
double target_pts)
825 for (
int i = 0;
i < in->
mix.num_frames;
i++) {
828 struct pl_frame *image = (
struct pl_frame *) in->
mix.frames[
i];
829 const AVFrame *
src = pl_get_mapped_avframe(image);
864 image->crop.x1 = image->crop.x0 +
s->var_values[
VAR_CROP_W];
865 image->crop.y1 = image->crop.y0 +
s->var_values[
VAR_CROP_H];
867 const pl_rect2df crop_orig = image->crop;
868 pl_rotation rot_total = PL_ROTATION_360 + image->rotation - target->rotation;
869 if (rot_total % PL_ROTATION_180 == PL_ROTATION_90) {
872 FFSWAP(
float, image->crop.x0, image->crop.y0);
873 FFSWAP(
float, image->crop.x1, image->crop.y1);
880 target->crop.x1 = target->crop.x0 +
s->var_values[
VAR_POS_W];
881 target->crop.y1 = target->crop.y0 +
s->var_values[
VAR_POS_H];
886 if (rot_total % PL_ROTATION_180 == PL_ROTATION_90)
887 sar_in = 1.0 / sar_in;
889 pl_rect2df
fixed = crop_orig;
890 pl_rect2df_stretch(&
fixed, sar_in / sar_out, 1.0);
892 switch (
s->fit_mode) {
894 if (
s->normalize_sar)
895 pl_rect2df_aspect_copy(&target->crop, &
fixed,
s->pad_crop_ratio);
898 pl_rect2df_aspect_copy(&target->crop, &
fixed, 0.0);
901 pl_rect2df_aspect_copy(&target->crop, &
fixed, 1.0);
904 const float sx =
fabsf(pl_rect_w(
fixed)) / pl_rect_w(target->crop);
905 const float sy =
fabsf(pl_rect_h(
fixed)) / pl_rect_h(target->crop);
906 pl_rect2df_stretch(&target->crop, sx, sy);
910 pl_rect2df_aspect_fit(&target->crop, &
fixed, 0.0);
919 int err = 0, ok, changed = 0;
921 pl_options
opts =
s->opts;
925 struct pl_frame target;
931 int idx_start = 0, nb_visible = 0;
932 for (
int i = 0;
i <
s->nb_inputs;
i++) {
934 struct pl_frame
dummy;
935 if (in->
qstatus != PL_QUEUE_OK || !in->
mix.num_frames)
937 const struct pl_frame *cur = pl_frame_mix_nearest(&in->
mix);
946 const bool cropped = x0 > 0 || y0 > 0 || x1 < outlink->
w || y1 < outlink->
h;
947 if (!cropped && cur->repr.alpha == PL_ALPHA_NONE) {
966 out->width = outlink->
w;
967 out->height = outlink->
h;
982 if (
s->color_trc >= 0)
983 out->color_trc =
s->color_trc;
984 if (
s->color_primaries >= 0)
985 out->color_primaries =
s->color_primaries;
986 if (
s->chroma_location >= 0)
987 out->chroma_location =
s->chroma_location;
990 if (
out->width !=
ref->width ||
out->height !=
ref->height)
992 if (
ref->color_trc !=
out->color_trc ||
ref->color_primaries !=
out->color_primaries)
996 if (
s->apply_filmgrain)
1000 out->sample_aspect_ratio =
ref->sample_aspect_ratio;
1005 out->sample_aspect_ratio =
av_mul_q(
ref->sample_aspect_ratio, stretch);
1015 ok = pl_map_avframe_ex(
s->gpu, &target, pl_avframe_params(
1020 ok = pl_frame_recreate_from_avframe(
s->gpu, &target,
s->tex,
out);
1027 struct pl_frame orig_target = target;
1028 bool use_linear_compositor =
false;
1029 if (
s->linear_tex && target.color.transfer != PL_COLOR_TRC_LINEAR &&
1030 !
s->disable_linear && nb_visible > 1) {
1031 target = (
struct pl_frame) {
1035 .component_mapping = {0, 1, 2, 3},
1036 .texture =
s->linear_tex,
1038 .repr = pl_color_repr_rgb,
1039 .color = orig_target.color,
1040 .rotation = orig_target.rotation,
1042 target.repr.alpha = PL_ALPHA_PREMULTIPLIED;
1043 target.color.transfer = PL_COLOR_TRC_LINEAR;
1044 use_linear_compositor =
true;
1048 struct pl_render_params tmp_params =
opts->params;
1049 for (
int i = 0;
i <
s->nb_inputs;
i++) {
1056 if (in->
qstatus != PL_QUEUE_OK || !in->
mix.num_frames ||
i < idx_start) {
1057 pl_renderer_flush_cache(in->
renderer);
1060 tmp_params.skip_caching_single_frame = high_fps;
1062 pl_render_image_mix(in->
renderer, &in->
mix, &target, &tmp_params);
1066 target.repr.alpha = PL_ALPHA_INDEPENDENT;
1067 tmp_params.blend_params = &pl_alpha_overlay;
1068 tmp_params.background = tmp_params.border = PL_CLEAR_SKIP;
1071 if (use_linear_compositor) {
1073 target.crop = orig_target.crop = (
struct pl_rect2df) {0};
1074 target.repr.alpha = PL_ALPHA_PREMULTIPLIED;
1075 pl_render_image(
s->linear_rr, &target, &orig_target, &
opts->params);
1076 target = orig_target;
1079 pl_render_image(
s->linear_rr,
NULL, &target, &
opts->params);
1083 pl_unmap_avframe(
s->gpu, &target);
1084 }
else if (!pl_download_avframe(
s->gpu, &target,
out)) {
1096 const struct pl_source_frame *
src,
1097 struct pl_frame *
out)
1101 bool ok = pl_map_avframe_ex(gpu,
out, pl_avframe_params(
1104 .map_dovi =
s->apply_dovi,
1107 out->lut_type =
s->lut_type;
1108 out->rotation +=
s->rotation;
1110 if (!
s->apply_filmgrain)
1111 out->film_grain.type = PL_FILM_GRAIN_NONE;
1118 const struct pl_source_frame *
src)
1120 pl_unmap_avframe(gpu,
frame);
1139 struct pl_source_frame
src = {
1142 .first_field =
s->deinterlace ? pl_field_from_avframe(in) : PL_FIELD_NONE,
1157 if (
s->send_fields &&
src.first_field != PL_FIELD_NONE) {
1189 int ret, ok = 0, retry = 0;
1198 for (
int i = 0;
i <
s->nb_inputs;
i++) {
1208 out_pts = INT64_MAX;
1209 for (
int i = 0;
i <
s->nb_inputs;
i++) {
1213 }
else if (!in->
status) {
1224 for (
int i = 0;
i <
s->nb_inputs;
i++) {
1229 pl_renderer_destroy(&in->
renderer);
1230 pl_queue_destroy(&in->
queue);
1237 .radius = pl_frame_mix_radius(&
s->opts->params),
1247 ok |= in->
mix.num_frames > 0;
1256 ok |=
s->fps.num &&
s->nb_active > 0;
1262 for (
int i = 0;
i <
s->nb_inputs;
i++)
1265 }
else if (
s->nb_active == 0) {
1267 int status =
s->inputs[0].status;
1268 int64_t status_pts =
s->inputs[0].status_pts;
1269 for (
int i = 1;
i <
s->nb_inputs;
i++) {
1272 status =
s->inputs[
i].status;
1273 status_pts =
s->inputs[
i].status_pts;
1306 if (
s->have_hwdevice) {
1317 if (!pl_test_pixfmt(
s->gpu,
pixfmt))
1330 if (!pl_test_pixfmt_caps(
s->gpu,
pixfmt, PL_FMT_CAP_RENDERABLE))
1338 if (!infmts || !outfmts) {
1343 for (
int i = 0;
i <
s->nb_inputs;
i++) {
1374 if (outfmts && !outfmts->refcount)
1385 if (
s->rotation % PL_ROTATION_180 == PL_ROTATION_90) {
1402 "hardware frames context on the input.\n");
1418 s->vkctx.input_format = inlink->
format;
1443 &outlink->
w, &outlink->
h));
1445 s->reset_sar |=
s->normalize_sar ||
s->nb_inputs > 1;
1448 int force_oar =
s->force_original_aspect_ratio;
1458 force_oar,
s->force_divisible_by,
1459 s->reset_sar ? sar_in : 1.0));
1462 int w_adj =
s->reset_sar ? sar_in * inlink->
w : inlink->
w;
1463 outlink->
w =
FFMIN(outlink->
w, w_adj);
1464 outlink->
h =
FFMIN(outlink->
h, inlink->
h);
1467 if (
s->nb_inputs > 1 && !
s->disable_fbos) {
1469 const enum pl_fmt_caps caps = PL_FMT_CAP_BLENDABLE | PL_FMT_CAP_BLITTABLE;
1470 pl_fmt fmt = pl_find_fmt(
s->gpu, PL_FMT_FLOAT, 4, 16, 0, caps);
1473 ok = pl_tex_recreate(
s->gpu, &
s->linear_tex, pl_tex_params(
1480 .storable = fmt->caps & PL_FMT_CAP_STORABLE,
1486 "for compositing multiple inputs, falling back to non-linear "
1514 for (
int i = 1;
i <
s->nb_inputs;
i++) {
1522 if (
s->deinterlace &&
s->send_fields) {
1542 s->vkctx.output_width = outlink->
w;
1543 s->vkctx.output_height = outlink->
h;
1546 s->vkctx.output_format =
s->vkctx.input_format;
1548 s->vkctx.output_format =
s->out_format;
1553 vkfc->
usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
1561#define OFFSET(x) offsetof(LibplaceboContext, x)
1562#define STATIC (AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_VIDEO_PARAM)
1563#define DYNAMIC (STATIC | AV_OPT_FLAG_RUNTIME_PARAM)
1567 {
"inherit_device",
"Inherit the Vulkan device from the input's hardware frames context",
1581 {
"force_original_aspect_ratio",
"decrease or increase w/h if necessary to keep the original AR",
OFFSET(force_original_aspect_ratio),
AV_OPT_TYPE_INT, { .i64 = 0 }, 0,
SCALE_FORCE_OAR_NB-1,
STATIC, .unit =
"force_oar" },
1585 {
"force_divisible_by",
"enforce that the output resolution is divisible by a defined integer when force_original_aspect_ratio is used",
OFFSET(force_divisible_by),
AV_OPT_TYPE_INT, { .i64 = 1 }, 1, 256,
STATIC },
1586 {
"reset_sar",
"force SAR normalization to 1:1 by adjusting pos_x/y/w/h",
OFFSET(reset_sar),
AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1,
STATIC },
1587 {
"normalize_sar",
"like reset_sar, but pad/crop instead of stretching the video",
OFFSET(normalize_sar),
AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1,
STATIC },
1588 {
"pad_crop_ratio",
"ratio between padding and cropping when normalizing SAR (0=pad, 1=crop)",
OFFSET(pad_crop_ratio),
AV_OPT_TYPE_FLOAT, {.dbl=0.0}, 0.0, 1.0,
DYNAMIC },
1590 {
"fill",
"Stretch content, ignoring aspect ratio", 0,
AV_OPT_TYPE_CONST, {.i64 =
FIT_FILL }, 0, 0,
STATIC, .unit =
"fit_mode" },
1591 {
"contain",
"Stretch content, padding to preserve aspect", 0,
AV_OPT_TYPE_CONST, {.i64 =
FIT_CONTAIN }, 0, 0,
STATIC, .unit =
"fit_mode" },
1592 {
"cover",
"Stretch content, cropping to preserve aspect", 0,
AV_OPT_TYPE_CONST, {.i64 =
FIT_COVER }, 0, 0,
STATIC, .unit =
"fit_mode" },
1593 {
"none",
"Keep input unscaled, padding and cropping as needed", 0,
AV_OPT_TYPE_CONST, {.i64 =
FIT_NONE }, 0, 0,
STATIC, .unit =
"fit_mode" },
1594 {
"place",
"Keep input unscaled, padding and cropping as needed", 0,
AV_OPT_TYPE_CONST, {.i64 =
FIT_NONE }, 0, 0,
STATIC, .unit =
"fit_mode" },
1595 {
"scale_down",
"Downscale only if larger, padding to preserve aspect", 0,
AV_OPT_TYPE_CONST, {.i64 =
FIT_SCALE_DOWN }, 0, 0,
STATIC, .unit =
"fit_mode" },
1602 {
"lut_type",
"Application mode of the custom LUT",
OFFSET(lut_type),
AV_OPT_TYPE_INT, { .i64 = PL_LUT_UNKNOWN }, 0, PL_LUT_CONVERSION,
STATIC, .unit =
"lut_type" },
1608 {
"extra_opts",
"Pass extra libplacebo-specific options using a :-separated list of key=value pairs",
OFFSET(extra_opts),
AV_OPT_TYPE_DICT, .flags =
DYNAMIC },
1612 {
"auto",
"keep the same colorspace", 0,
AV_OPT_TYPE_CONST, {.i64=-1}, INT_MIN, INT_MAX,
STATIC, .unit =
"colorspace"},
1636 {
"auto",
"keep the same color primaries", 0,
AV_OPT_TYPE_CONST, {.i64=-1}, INT_MIN, INT_MAX,
STATIC, .unit =
"color_primaries"},
1653 {
"auto",
"keep the same color transfer", 0,
AV_OPT_TYPE_CONST, {.i64=-1}, INT_MIN, INT_MAX,
STATIC, .unit =
"color_trc"},
1673 {
"auto",
"keep the same chroma location", 0,
AV_OPT_TYPE_CONST, {.i64=-1}, 0, 0,
STATIC, .unit =
"chroma_location"},
1683 {
"rotate",
"rotate the input clockwise",
OFFSET(rotation),
AV_OPT_TYPE_INT, {.i64=PL_ROTATION_0}, PL_ROTATION_0, PL_ROTATION_360,
DYNAMIC, .unit =
"rotation"},
1705 {
"deinterlace",
"Deinterlacing mode",
OFFSET(deinterlace),
AV_OPT_TYPE_INT, {.i64 = PL_DEINTERLACE_WEAVE}, 0, PL_DEINTERLACE_ALGORITHM_COUNT - 1,
DYNAMIC, .unit =
"deinterlace" },
1706 {
"weave",
"Weave fields together (no-op)", 0,
AV_OPT_TYPE_CONST, {.i64 = PL_DEINTERLACE_WEAVE}, 0, 0,
STATIC, .unit =
"deinterlace" },
1707 {
"bob",
"Naive bob deinterlacing", 0,
AV_OPT_TYPE_CONST, {.i64 = PL_DEINTERLACE_BOB}, 0, 0,
STATIC, .unit =
"deinterlace" },
1708 {
"yadif",
"Yet another deinterlacing filter", 0,
AV_OPT_TYPE_CONST, {.i64 = PL_DEINTERLACE_YADIF}, 0, 0,
STATIC, .unit =
"deinterlace" },
1709#if PL_API_VER >= 353
1710 {
"bwdif",
"Bob weaver deinterlacing filter", 0,
AV_OPT_TYPE_CONST, {.i64 = PL_DEINTERLACE_BWDIF}, 0, 0,
STATIC, .unit =
"deinterlace" },
1757 {
"tonemapping_param",
"Tunable parameter for some tone-mapping functions",
OFFSET(tonemapping_param),
AV_OPT_TYPE_FLOAT, {.dbl = 0.0}, 0.0, 100.0, .flags =
DYNAMIC },
1758 {
"inverse_tonemapping",
"Inverse tone mapping (range expansion)",
OFFSET(inverse_tonemapping),
AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1,
DYNAMIC },
1761 {
"contrast_smoothness",
"HDR contrast recovery smoothness",
OFFSET(contrast_smoothness),
AV_OPT_TYPE_FLOAT, {.dbl = 3.50}, 1.0, 32.0,
DYNAMIC },
1763 {
"dithering",
"Dither method to use",
OFFSET(dithering),
AV_OPT_TYPE_INT, {.i64 = PL_DITHER_BLUE_NOISE}, -1, PL_DITHER_METHOD_COUNT - 1,
DYNAMIC, .unit =
"dither" },
1765 {
"blue",
"Blue noise", 0,
AV_OPT_TYPE_CONST, {.i64 = PL_DITHER_BLUE_NOISE}, 0, 0,
STATIC, .unit =
"dither" },
1766 {
"ordered",
"Ordered LUT", 0,
AV_OPT_TYPE_CONST, {.i64 = PL_DITHER_ORDERED_LUT}, 0, 0,
STATIC, .unit =
"dither" },
1767 {
"ordered_fixed",
"Fixed function ordered", 0,
AV_OPT_TYPE_CONST, {.i64 = PL_DITHER_ORDERED_FIXED}, 0, 0,
STATIC, .unit =
"dither" },
1768 {
"white",
"White noise", 0,
AV_OPT_TYPE_CONST, {.i64 = PL_DITHER_WHITE_NOISE}, 0, 0,
STATIC, .unit =
"dither" },
1801 .p.name =
"libplacebo",
1803 .p.priv_class = &libplacebo_class,
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
static const char *const format[]
const FFFilter ff_vf_libplacebo
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
#define av_assert0(cond)
assert() equivalent, that is always enabled.
int ff_append_inpad_free_name(AVFilterContext *f, AVFilterPad *p)
int ff_inlink_acknowledge_status(AVFilterLink *link, int *rstatus, int64_t *rpts)
Test and acknowledge the change of status on the link.
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
int ff_outlink_frame_wanted(AVFilterLink *link)
Test if a frame is wanted on an output link.
int ff_filter_process_command(AVFilterContext *ctx, const char *cmd, const char *arg, char *res, int res_len, int flags)
Generic processing of user supplied commands that are set in the same way as the filter options.
int ff_inlink_consume_frame(AVFilterLink *link, AVFrame **rframe)
Take a frame from the link's FIFO and update the link's stats.
void ff_inlink_request_frame(AVFilterLink *link)
Mark that a frame is wanted on the link.
char * av_asprintf(const char *fmt,...)
#define flags(name, subs,...)
#define i(width, name, range_min, range_max)
static IPT saturation(const CmsCtx *ctx, IPT ipt)
static const AVColorPrimariesDesc color_primaries[AVCOL_PRI_NB]
static __device__ float fabsf(float a)
int(* init)(AVBSFContext *ctx)
void av_expr_free(AVExpr *e)
Free a parsed expression previously created with av_expr_parse().
double av_expr_eval(AVExpr *e, const double *const_values, void *opaque)
Evaluate a previously parsed expression.
int av_expr_parse(AVExpr **expr, const char *s, const char *const *const_names, const char *const *func1_names, double(*const *funcs1)(void *, double), const char *const *func2_names, double(*const *funcs2)(void *, double, double), int log_offset, void *log_ctx)
Parse an expression.
simple arithmetic expression evaluator
reference-counted frame API
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
@ AV_OPT_TYPE_BINARY
Underlying C type is a uint8_t* that is either NULL or points to an array allocated with the av_mallo...
@ AV_OPT_TYPE_FLAGS
Underlying C type is unsigned int.
@ AV_OPT_TYPE_INT
Underlying C type is int.
@ AV_OPT_TYPE_FLOAT
Underlying C type is float.
@ AV_OPT_TYPE_DICT
Underlying C type is AVDictionary*.
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
@ AV_OPT_TYPE_STRING
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
@ AV_OPT_TYPE_COLOR
Underlying C type is uint8_t[4].
#define AVFILTER_FLAG_HWDEVICE
The filter can create hardware frames using AVFilterContext.hw_device_ctx.
#define AVFILTER_FLAG_DYNAMIC_INPUTS
The number of the filter inputs is not determined just by AVFilter.inputs.
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
#define AV_DICT_IGNORE_SUFFIX
Return first entry in a dictionary whose first part corresponds to the search key,...
#define AVERROR_EXIT
Immediate exit was requested; the called function should not be restarted.
#define AVERROR_EXTERNAL
Generic error in an external library.
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
AVFifo * av_fifo_alloc2(size_t nb_elems, size_t elem_size, unsigned int flags)
Allocate and initialize an AVFifo with a given element size.
void av_fifo_freep2(AVFifo **f)
Free an AVFifo and reset pointer to NULL.
#define AV_FIFO_FLAG_AUTO_GROW
Automatically resize the FIFO on writes, so that the data fits.
int av_fifo_peek(const AVFifo *f, void *buf, size_t nb_elems, size_t offset)
Read data from a FIFO without modifying FIFO state.
int av_fifo_write(AVFifo *f, const void *buf, size_t nb_elems)
Write data into a FIFO.
void av_fifo_drain2(AVFifo *f, size_t size)
Discard the specified amount of data from an AVFifo.
#define AV_FRAME_FLAG_INTERLACED
A flag to mark frames whose content is interlaced.
#define AV_FRAME_FLAG_TOP_FIELD_FIRST
A flag to mark frames where the top field is displayed first if the content is interlaced.
AVFrameSideData * av_frame_get_side_data(const AVFrame *frame, enum AVFrameSideDataType type)
void av_frame_remove_side_data(AVFrame *frame, enum AVFrameSideDataType type)
Remove and free all side data instances of the given type.
void av_frame_side_data_remove_by_props(AVFrameSideData ***sd, int *nb_sd, int props)
Remove and free all side data instances that match any of the given side data properties.
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
@ AV_SIDE_DATA_PROP_SIZE_DEPENDENT
Side data depends on the video dimensions.
@ AV_SIDE_DATA_PROP_COLOR_DEPENDENT
Side data depends on the video color space.
@ AV_FRAME_DATA_DOVI_METADATA
Parsed Dolby Vision metadata, suitable for passing to a software implementation.
@ AV_FRAME_DATA_FILM_GRAIN_PARAMS
Film grain parameters for a frame, described by AVFilmGrainParams.
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
#define AV_LOG_WARNING
Something somehow does not look correct.
#define AV_LOG_FATAL
Something went wrong and recovery is not possible.
#define AV_LOG_VERBOSE
Detailed information.
#define AV_LOG_INFO
Standard information.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
int av_log_get_level(void)
Get the current log level.
AVRational av_mul_q(AVRational b, AVRational c)
Multiply two rationals.
AVRational av_gcd_q(AVRational a, AVRational b, int max_den, AVRational def)
Return the best rational so that a and b are multiple of it.
static double av_q2d(AVRational a)
Convert an AVRational to a double.
static int av_cmp_q(AVRational a, AVRational b)
Compare two rationals.
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
AVRational av_div_q(AVRational b, AVRational c)
Divide one rational by another.
int64_t av_rescale_q_rnd(int64_t a, AVRational bq, AVRational cq, enum AVRounding rnd)
Rescale a 64-bit integer by 2 rational numbers with specified rounding.
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
@ AV_ROUND_UP
Round toward +infinity.
#define AV_TIME_BASE
Internal time base represented as integer.
#define AV_TIME_BASE_Q
Internal time base represented as fractional value.
@ AV_HWDEVICE_TYPE_VULKAN
const VkFormat * av_vkfmt_from_pixfmt(enum AVPixelFormat p)
Returns the optimal per-plane Vulkan format for a given sw_format, one for each plane.
enum AVPixelFormat pixfmt
static av_cold void uninit(AVBitStreamFilterContext *ctx)
static int activate(AVBitStreamFilterContext *ctx)
static int get_log_level(int level)
static int mix(int c0, int c1)
#define fixed(width, name, value)
static void log_cb(cmsContext ctx, cmsUInt32Number error, const char *str)
#define FILTER_OUTPUTS(array)
#define FF_FILTER_FLAG_HWFRAME_AWARE
The filter is aware of hardware frames, and any hardware frame context should not be automatically pr...
static void ff_outlink_set_status(AVFilterLink *link, int status, int64_t pts)
Set the status field of a link from the source filter.
#define FFERROR_NOT_READY
Filters implementation helper functions and internal structures.
#define FF_FILTER_FORWARD_STATUS_BACK_ALL(outlink, filter)
Forward the status on an output link to all input links.
static FilterLink * ff_filter_link(AVFilterLink *link)
#define AVFILTER_DEFINE_CLASS(fname)
#define FILTER_QUERY_FUNC2(func)
void av_file_unmap(uint8_t *bufptr, size_t size)
Unmap or free the buffer bufptr created by av_file_map().
int av_file_map(const char *filename, uint8_t **bufptr, size_t *size, int log_offset, void *log_ctx)
Read the file with name filename, and put its content in a newly allocated buffer or map it with mmap...
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
#define FF_DISABLE_DEPRECATION_WARNINGS
#define FF_ENABLE_DEPRECATION_WARNINGS
void ff_vk_uninit(FFVulkanContext *s)
Frees main context.
static av_always_inline av_const float roundf(float x)
#define FFSWAP(type, a, b)
void * av_calloc(size_t nmemb, size_t size)
Memory handling functions.
static const char *const var_names[]
int av_parse_video_rate(AVRational *rate, const char *arg)
Parse str and store the detected values in *rate.
enum AVPixelFormat av_pix_fmt_desc_get_id(const AVPixFmtDescriptor *desc)
const AVPixFmtDescriptor * av_pix_fmt_desc_next(const AVPixFmtDescriptor *prev)
Iterate over all pixel format descriptors known to libavutil.
enum AVPixelFormat av_get_pix_fmt(const char *name)
Return the pixel format corresponding to name.
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
#define AV_PIX_FMT_FLAG_HWACCEL
Pixel format is an HW accelerated format.
#define AV_PIX_FMT_FLAG_BE
Pixel format is big-endian.
@ AVCHROMA_LOC_TOPLEFT
ITU-R 601, SMPTE 274M 296M S314M(DV 4:1:1), mpeg2 4:2:2.
@ AVCHROMA_LOC_NB
Not part of ABI.
@ AVCHROMA_LOC_LEFT
MPEG-2/4 4:2:0, H.264 default for 4:2:0.
@ AVCHROMA_LOC_BOTTOMLEFT
@ AVCHROMA_LOC_CENTER
MPEG-1 4:2:0, JPEG 4:2:0, H.263 4:2:0.
@ AVCHROMA_LOC_UNSPECIFIED
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
@ AVCOL_RANGE_UNSPECIFIED
@ AVCOL_RANGE_NB
Not part of ABI.
@ AVCOL_RANGE_JPEG
Full range content.
@ AVALPHA_MODE_NB
Not part of ABI.
@ AVALPHA_MODE_STRAIGHT
Alpha channel is independent of color values.
@ AVALPHA_MODE_UNSPECIFIED
Unknown alpha handling, or no alpha channel.
@ AVALPHA_MODE_PREMULTIPLIED
Alpha channel is multiplied into color values.
AVPixelFormat
Pixel format.
@ AV_PIX_FMT_VULKAN
Vulkan hardware images.
@ AVCOL_PRI_BT470BG
also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM
@ AVCOL_PRI_FILM
colour filters using Illuminant C
@ AVCOL_PRI_SMPTE432
SMPTE ST 432-1 (2010) / P3 D65 / Display P3.
@ AVCOL_PRI_BT709
also ITU-R BT1361 / IEC 61966-2-4 / SMPTE RP 177 Annex B
@ AVCOL_PRI_EXT_NB
Not part of ABI.
@ AVCOL_PRI_SMPTE240M
identical to above, also called "SMPTE C" even though it uses D65
@ AVCOL_PRI_EBU3213
EBU Tech. 3213-E (nothing there) / one of JEDEC P22 group phosphors.
@ AVCOL_PRI_SMPTE431
SMPTE ST 431-2 (2011) / DCI P3.
@ AVCOL_PRI_SMPTE428
SMPTE ST 428-1 (CIE 1931 XYZ)
@ AVCOL_PRI_SMPTE170M
also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC
@ AVCOL_PRI_BT2020
ITU-R BT2020.
@ AVCOL_PRI_BT470M
also FCC Title 47 Code of Federal Regulations 73.682 (a)(20)
@ AVCOL_TRC_SMPTE170M
also ITU-R BT601-6 525 or 625 / ITU-R BT1358 525 or 625 / ITU-R BT1700 NTSC
@ AVCOL_TRC_SMPTE2084
SMPTE ST 2084 for 10-, 12-, 14- and 16-bit systems.
@ AVCOL_TRC_GAMMA22
also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM
@ AVCOL_TRC_BT1361_ECG
ITU-R BT1361 Extended Colour Gamut.
@ AVCOL_TRC_IEC61966_2_4
IEC 61966-2-4.
@ AVCOL_TRC_LINEAR
"Linear transfer characteristics"
@ AVCOL_TRC_GAMMA28
also ITU-R BT470BG
@ AVCOL_TRC_ARIB_STD_B67
ARIB STD-B67, known as "Hybrid log-gamma".
@ AVCOL_TRC_BT2020_12
ITU-R BT2020 for 12-bit system.
@ AVCOL_TRC_IEC61966_2_1
IEC 61966-2-1 (sRGB or sYCC)
@ AVCOL_TRC_EXT_NB
Not part of ABI.
@ AVCOL_TRC_BT2020_10
ITU-R BT2020 for 10-bit system.
@ AVCOL_TRC_BT709
also ITU-R BT1361
@ AVCOL_SPC_BT709
also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / derived in SMPTE RP 177 Annex B
@ AVCOL_SPC_BT470BG
also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601
@ AVCOL_SPC_BT2020_CL
ITU-R BT2020 constant luminance system.
@ AVCOL_SPC_NB
Not part of ABI.
@ AVCOL_SPC_RGB
order of coefficients is actually GBR, also IEC 61966-2-1 (sRGB), YZX and ST 428-1
@ AVCOL_SPC_BT2020_NCL
ITU-R BT2020 non-constant luminance system.
@ AVCOL_SPC_SMPTE170M
also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC / functionally identical to above
@ AVCOL_SPC_SMPTE240M
derived from 170M primaries and D65 white point, 170M is derived from BT470 System M's primaries
@ AVCOL_SPC_YCGCO
used by Dirac / VC-2 and H.264 FRext, see ITU-T SG16
@ AVCOL_SPC_ICTCP
ITU-R BT.2100-0, ICtCp.
int ff_scale_adjust_dimensions(AVFilterLink *inlink, int *ret_w, int *ret_h, int force_original_aspect_ratio, int force_divisible_by, double w_adj)
Transform evaluated width and height obtained from ff_scale_eval_dimensions into actual target width ...
int ff_scale_eval_dimensions(void *log_ctx, const char *w_expr, const char *h_expr, AVFilterLink *inlink, AVFilterLink *outlink, int *ret_w, int *ret_h)
Parse and evaluate string expressions for width and height.
@ SCALE_FORCE_OAR_DISABLE
@ SCALE_FORCE_OAR_INCREASE
@ SCALE_FORCE_OAR_DECREASE
#define FF_ARRAY_ELEMS(a)
uint8_t * data
The data buffer.
AVFilterLink ** inputs
array of pointers to input links
void * priv
private data for use by the filter
AVBufferRef * hw_device_ctx
For filters which will create hardware frames, sets the device the filter should create them in.
A link between two filters.
int w
agreed upon image width
int h
agreed upon image height
AVFilterContext * src
source filter
AVRational time_base
Define the time base used by the PTS of the frames/samples which will pass through this link.
AVRational sample_aspect_ratio
agreed upon sample aspect ratio
enum AVColorSpace colorspace
For non-YUV links, these are respectively set to fallback values (as appropriate for that colorspace)...
enum AVAlphaMode alpha_mode
alpha mode (for videos with an alpha channel)
AVFilterContext * dst
dest filter
int format
agreed upon media format
enum AVColorRange color_range
agreed upon YUV color range
A filter pad used for either input or output.
const char * name
Pad name.
This structure describes decoded (raw) audio or video data.
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
void * opaque
Frame owner's private data.
int64_t duration
Duration of the frame, in the same units as pts.
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
enum AVHWDeviceType type
This field identifies the underlying API used for hardware access.
This struct describes a set or pool of "hardware" frames (i.e.
AVBufferRef * device_ref
A reference to the parent AVHWDeviceContext.
void * hwctx
The format-specific data, allocated and freed automatically along with this context.
AVHWDeviceContext * device_ctx
The parent AVHWDeviceContext.
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
uint8_t log2_chroma_w
Amount to shift the luma width right to find the chroma width.
uint64_t flags
Combination of AV_PIX_FMT_FLAG_... flags.
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Rational number (pair of numerator and denominator).
Main Vulkan context, allocated as AVHWDeviceContext.hwctx.
VkPhysicalDevice phys_dev
Physical device.
AVVulkanDeviceQueueFamily qf[64]
Queue families used.
const char *const * enabled_dev_extensions
Enabled device extensions.
VkDevice act_dev
Active device.
VkInstance inst
Vulkan instance.
VkPhysicalDeviceFeatures2 device_features
This structure should be set to the set of features that present and enabled during device creation.
int nb_enabled_dev_extensions
VkDeviceQueueCreateFlags queue_flags
PFN_vkGetInstanceProcAddr get_proc_addr
Pointer to a vkGetInstanceProcAddr loading function.
Allocated as AVHWFramesContext.hwctx, used to set pool-specific options.
VkImageUsageFlagBits usage
Defines extra usage of output frames.
Link properties exposed to filter code, but not external callers.
AVRational frame_rate
Frame rate of the stream on the link, or 1/0 if unknown or variable.
AVBufferRef * hw_frames_ctx
For hwaccel pixel formats, this should be a reference to the AVHWFramesContext describing the frames.
struct pl_custom_lut * lut
double var_values[VAR_VARS_NB]
float contrast_smoothness
AVDictionary * extra_opts
enum AVPixelFormat out_format
AVRational fps
parsed FPS, or 0/0 for "none"
int force_original_aspect_ratio
const struct pl_hook * hooks[2]
static int ref[MAX_W *MAX_W]
static AVFormatContext * ctx
static AVDictionary * opts
static float sigmoid(float x)
static int libplacebo_config_output(AVFilterLink *outlink)
static int update_settings(AVFilterContext *ctx)
static int find_scaler(AVFilterContext *avctx, const struct pl_filter_config **opt, const char *name, int frame_mixing)
static const AVOption libplacebo_options[]
static void pl_av_log(void *log_ctx, enum pl_log_level level, const char *msg)
static int parse_shader(AVFilterContext *avctx, const void *shader, size_t len)
static int init_vulkan(AVFilterContext *avctx, const AVVulkanDeviceContext *hwctx)
static const AVFilterPad libplacebo_outputs[]
static void lock_queue(void *priv, uint32_t qf, uint32_t qidx)
static void libplacebo_uninit(AVFilterContext *avctx)
static int handle_input(AVFilterContext *ctx, LibplaceboInput *input)
static int output_frame(AVFilterContext *ctx, int64_t pts)
static void unlock_queue(void *priv, uint32_t qf, uint32_t qidx)
static void unmap_frame(pl_gpu gpu, struct pl_frame *frame, const struct pl_source_frame *src)
static void set_gamut_mode(struct pl_color_map_params *p, int gamut_mode)
static int libplacebo_process_command(AVFilterContext *ctx, const char *cmd, const char *arg, char *res, int res_len, int flags)
static void drain_input_pts(LibplaceboInput *in, int64_t until)
static int libplacebo_init(AVFilterContext *avctx)
static int parse_custom_lut(AVFilterContext *avctx)
static const AVFrame * ref_frame(const struct pl_frame_mix *mix)
static bool map_frame(pl_gpu gpu, pl_tex *tex, const struct pl_source_frame *src, struct pl_frame *out)
static void discard_frame(const struct pl_source_frame *src)
static int libplacebo_config_input(AVFilterLink *inlink)
static AVRational max_q(AVRational a, AVRational b)
static int copy_pl_queue(const AVVulkanDeviceContext *hwctx, const AVVulkanDeviceQueueFamily *qf, struct pl_vulkan_queue *pl_qf)
static int input_init(AVFilterContext *avctx, LibplaceboInput *input, int idx)
static const struct pl_tone_map_function * get_tonemapping_func(int tm)
static int libplacebo_query_format(const AVFilterContext *ctx, AVFilterFormatsConfig **cfg_in, AVFilterFormatsConfig **cfg_out)
static double q2d_fallback(AVRational q, const double def)
static void update_crops(AVFilterContext *ctx, LibplaceboInput *in, struct pl_frame *target, double target_pts)
static int libplacebo_activate(AVFilterContext *ctx)
static enum pl_log_level get_log_level(void)
static void input_uninit(LibplaceboInput *input)
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
int ff_vk_filter_config_input(AVFilterLink *inlink)
int ff_vk_filter_config_output(AVFilterLink *outlink)