The "out_color_matrix" and "out_range" properties match the same options in vf_scale; the others attempt to follow the same pattern.
Unified · Split
| @@ -39,6 +39,17 @@ typedef struct ScaleVAAPIContext { · 38 unmodified lines | |||
| 39 | 39 | ||
| 40 | char *w_expr; // width expression string | 40 | char *w_expr; // width expression string |
| 41 | char *h_expr; // height expression string | 41 | char *h_expr; // height expression string |
| 42 | |||
| 43 | char *colour_primaries_string; | ||
| 44 | char *colour_transfer_string; | ||
| 45 | char *colour_matrix_string; | ||
| 46 | int colour_range; | ||
| 47 | char *chroma_location_string; | ||
| 48 | |||
| 49 | enum AVColorPrimaries colour_primaries; | ||
| 50 | enum AVColorTransferCharacteristic colour_transfer; | ||
| 51 | enum AVColorSpace colour_matrix; | ||
| 52 | enum AVChromaLocation chroma_location; | ||
| 42 | } ScaleVAAPIContext; | 53 | } ScaleVAAPIContext; |
| 43 | 54 | ||
| 44 | static const char *scale_vaapi_mode_name(int mode) | 55 | static const char *scale_vaapi_mode_name(int mode) |
| @@ -110,6 +121,17 @@ static int scale_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame) · 65 unmodified lines | |||
| 110 | if (err < 0) | 121 | if (err < 0) |
| 111 | return err; | 122 | return err; |
| 112 | 123 | ||
| 124 | if (ctx->colour_primaries != AVCOL_PRI_UNSPECIFIED) | ||
| 125 | output_frame->color_primaries = ctx->colour_primaries; | ||
| 126 | if (ctx->colour_transfer != AVCOL_TRC_UNSPECIFIED) | ||
| 127 | output_frame->color_trc = ctx->colour_transfer; | ||
| 128 | if (ctx->colour_matrix != AVCOL_SPC_UNSPECIFIED) | ||
| 129 | output_frame->colorspace = ctx->colour_matrix; | ||
| 130 | if (ctx->colour_range != AVCOL_RANGE_UNSPECIFIED) | ||
| 131 | output_frame->color_range = ctx->colour_range; | ||
| 132 | if (ctx->chroma_location != AVCHROMA_LOC_UNSPECIFIED) | ||
| 133 | output_frame->chroma_location = ctx->chroma_location; | ||
| 134 | |||
| 113 | err = ff_vaapi_vpp_init_params(avctx, ¶ms, | 135 | err = ff_vaapi_vpp_init_params(avctx, ¶ms, |
| 114 | input_frame, output_frame); | 136 | input_frame, output_frame); |
| 115 | if (err < 0) | 137 | if (err < 0) |
| @@ -155,6 +177,24 @@ static av_cold int scale_vaapi_init(AVFilterContext *avctx) · 39 unmodified lines | |||
| 155 | vpp_ctx->output_format = AV_PIX_FMT_NONE; | 177 | vpp_ctx->output_format = AV_PIX_FMT_NONE; |
| 156 | } | 178 | } |
| 157 | 179 | ||
| 180 | #define STRING_OPTION(var_name, func_name, default_value) do { \ | ||
| 181 | if (ctx->var_name ## _string) { \ | ||
| 182 | int var = av_ ## func_name ## _from_name(ctx->var_name ## _string); \ | ||
| 183 | if (var < 0) { \ | ||
| 184 | av_log(avctx, AV_LOG_ERROR, "Invalid %s.\n", #var_name); \ | ||
| 185 | return AVERROR(EINVAL); \ | ||
| 186 | } \ | ||
| 187 | ctx->var_name = var; \ | ||
| 188 | } else { \ | ||
| 189 | ctx->var_name = default_value; \ | ||
| 190 | } \ | ||
| 191 | } while (0) | ||
| 192 | |||
| 193 | STRING_OPTION(colour_primaries, color_primaries, AVCOL_PRI_UNSPECIFIED); | ||
| 194 | STRING_OPTION(colour_transfer, color_transfer, AVCOL_TRC_UNSPECIFIED); | ||
| 195 | STRING_OPTION(colour_matrix, color_space, AVCOL_SPC_UNSPECIFIED); | ||
| 196 | STRING_OPTION(chroma_location, chroma_location, AVCHROMA_LOC_UNSPECIFIED); | ||
| 197 | |||
| 158 | return 0; | 198 | return 0; |
| 159 | } | 199 | } |
| 160 | 200 | ||
| @@ -178,6 +218,36 @@ static const AVOption scale_vaapi_options[] = { · 17 unmodified lines | |||
| 178 | 0, AV_OPT_TYPE_CONST, { .i64 = VA_FILTER_SCALING_HQ }, 0, 0, FLAGS, "mode" }, | 218 | 0, AV_OPT_TYPE_CONST, { .i64 = VA_FILTER_SCALING_HQ }, 0, 0, FLAGS, "mode" }, |
| 179 | { "nl_anamorphic", "Use nolinear anamorphic scaling algorithm", | 219 | { "nl_anamorphic", "Use nolinear anamorphic scaling algorithm", |
| 180 | 0, AV_OPT_TYPE_CONST, { .i64 = VA_FILTER_SCALING_NL_ANAMORPHIC }, 0, 0, FLAGS, "mode" }, | 220 | 0, AV_OPT_TYPE_CONST, { .i64 = VA_FILTER_SCALING_NL_ANAMORPHIC }, 0, 0, FLAGS, "mode" }, |
| 221 | |||
| 222 | // These colour properties match the ones of the same name in vf_scale. | ||
| 223 | { "out_color_matrix", "Output colour matrix coefficient set", | ||
| 224 | OFFSET(colour_matrix_string), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = FLAGS }, | ||
| 225 | { "out_range", "Output colour range", | ||
| 226 | OFFSET(colour_range), AV_OPT_TYPE_INT, { .i64 = AVCOL_RANGE_UNSPECIFIED }, | ||
| 227 | AVCOL_RANGE_UNSPECIFIED, AVCOL_RANGE_JPEG, FLAGS, "range" }, | ||
| 228 | { "full", "Full range", | ||
| 229 | 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_JPEG }, 0, 0, FLAGS, "range" }, | ||
| 230 | { "limited", "Limited range", | ||
| 231 | 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_MPEG }, 0, 0, FLAGS, "range" }, | ||
| 232 | { "jpeg", "Full range", | ||
| 233 | 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_JPEG }, 0, 0, FLAGS, "range" }, | ||
| 234 | { "mpeg", "Limited range", | ||
| 235 | 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_MPEG }, 0, 0, FLAGS, "range" }, | ||
| 236 | { "tv", "Limited range", | ||
| 237 | 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_MPEG }, 0, 0, FLAGS, "range" }, | ||
| 238 | { "pc", "Full range", | ||
| 239 | 0, AV_OPT_TYPE_CONST, { .i64 = AVCOL_RANGE_JPEG }, 0, 0, FLAGS, "range" }, | ||
| 240 | // These colour properties are new here. | ||
| 241 | { "out_color_primaries", "Output colour primaries", | ||
| 242 | OFFSET(colour_primaries_string), AV_OPT_TYPE_STRING, | ||
| 243 | { .str = NULL }, .flags = FLAGS }, | ||
| 244 | { "out_color_transfer", "Output colour transfer characteristics", | ||
| 245 | OFFSET(colour_transfer_string), AV_OPT_TYPE_STRING, | ||
| 246 | { .str = NULL }, .flags = FLAGS }, | ||
| 247 | { "out_chroma_location", "Output chroma sample location", | ||
| 248 | OFFSET(chroma_location_string), AV_OPT_TYPE_STRING, | ||
| 249 | { .str = NULL }, .flags = FLAGS }, | ||
| 250 | |||
| 181 | { NULL }, | 251 | { NULL }, |
| 182 | }; | 252 | }; |
| 183 | 253 | ||