summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimo Rothenpieler <timo@rothenpieler.org>2022-08-06 14:54:58 +0200
committerTimo Rothenpieler <timo@rothenpieler.org>2022-08-06 15:50:15 +0200
commit38595ebe3b1303d85ab83f2fd0d0899af55abb00 (patch)
treec74f0f50c2f328bd0bc4106f692eb59f4fb2a856
parentf0abd07996c35d2160488cb7e6794eb6d22cecc9 (diff)
avfilter/vsrc_ddagrab: make output format user configurable
-rw-r--r--doc/filters.texi16
-rw-r--r--libavfilter/vsrc_ddagrab.c29
2 files changed, 44 insertions, 1 deletions
diff --git a/doc/filters.texi b/doc/filters.texi
index 4a5412c91d..dd7ee1394a 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -26531,6 +26531,22 @@ Horizontal offset of the captured video.
@item offset_y
Vertical offset of the captured video.
+@item output_fmt
+Desired filter output format.
+Defaults to 8 Bit BGRA.
+
+It accepts the following values:
+@table @samp
+@item auto
+Passes all supported output formats to DDA and returns what DDA decides to use.
+@item 8bit
+@item bgra
+8 Bit formats always work, and DDA will convert to them if neccesary.
+@item 10bit
+@item x2bgr10
+Filter initialization will fail if 10 bit format is requested but unavailable.
+@end table
+
@end table
@subsection Examples
diff --git a/libavfilter/vsrc_ddagrab.c b/libavfilter/vsrc_ddagrab.c
index 2f33a40f6f..5300d46fc1 100644
--- a/libavfilter/vsrc_ddagrab.c
+++ b/libavfilter/vsrc_ddagrab.c
@@ -97,6 +97,7 @@ typedef struct DdagrabContext {
int height;
int offset_x;
int offset_y;
+ int out_fmt;
} DdagrabContext;
#define OFFSET(x) offsetof(DdagrabContext, x)
@@ -108,6 +109,12 @@ static const AVOption ddagrab_options[] = {
{ "video_size", "set video frame size", OFFSET(width), AV_OPT_TYPE_IMAGE_SIZE, { .str = NULL }, 0, 0, FLAGS },
{ "offset_x", "capture area x offset", OFFSET(offset_x), AV_OPT_TYPE_INT, { .i64 = 0 }, INT_MIN, INT_MAX, FLAGS },
{ "offset_y", "capture area y offset", OFFSET(offset_y), AV_OPT_TYPE_INT, { .i64 = 0 }, INT_MIN, INT_MAX, FLAGS },
+ { "output_fmt", "desired output format", OFFSET(out_fmt), AV_OPT_TYPE_INT, { .i64 = DXGI_FORMAT_B8G8R8A8_UNORM }, 0, INT_MAX, FLAGS, "output_fmt" },
+ { "auto", "let dda pick its preferred format", 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, 0, INT_MAX, FLAGS, "output_fmt" },
+ { "8bit", "only output default 8 Bit format", 0, AV_OPT_TYPE_CONST, { .i64 = DXGI_FORMAT_B8G8R8A8_UNORM }, 0, INT_MAX, FLAGS, "output_fmt" },
+ { "bgra", "only output 8 Bit BGRA", 0, AV_OPT_TYPE_CONST, { .i64 = DXGI_FORMAT_B8G8R8A8_UNORM }, 0, INT_MAX, FLAGS, "output_fmt" },
+ { "10bit", "only output default 10 Bit format", 0, AV_OPT_TYPE_CONST, { .i64 = DXGI_FORMAT_R10G10B10A2_UNORM }, 0, INT_MAX, FLAGS, "output_fmt" },
+ { "x2bgr10", "only output 10 Bit X2BGR10", 0, AV_OPT_TYPE_CONST, { .i64 = DXGI_FORMAT_R10G10B10A2_UNORM }, 0, INT_MAX, FLAGS, "output_fmt" },
{ NULL }
};
@@ -208,6 +215,16 @@ static av_cold int init_dxgi_dda(AVFilterContext *avctx)
DXGI_FORMAT_R10G10B10A2_UNORM,
DXGI_FORMAT_B8G8R8A8_UNORM
};
+ int nb_formats = FF_ARRAY_ELEMS(formats);
+
+ if(dda->out_fmt == DXGI_FORMAT_B8G8R8A8_UNORM) {
+ formats[0] = DXGI_FORMAT_B8G8R8A8_UNORM;
+ nb_formats = 1;
+ } else if (dda->out_fmt) {
+ formats[0] = dda->out_fmt;
+ formats[1] = DXGI_FORMAT_B8G8R8A8_UNORM;
+ nb_formats = 2;
+ }
IDXGIOutput_Release(dxgi_output);
dxgi_output = NULL;
@@ -219,7 +236,7 @@ static av_cold int init_dxgi_dda(AVFilterContext *avctx)
hr = IDXGIOutput5_DuplicateOutput1(dxgi_output5,
(IUnknown*)dda->device_hwctx->device,
0,
- FF_ARRAY_ELEMS(formats),
+ nb_formats,
formats,
&dda->dxgi_outdupl);
IDXGIOutput5_Release(dxgi_output5);
@@ -242,6 +259,11 @@ static av_cold int init_dxgi_dda(AVFilterContext *avctx)
#else
{
#endif
+ if (dda->out_fmt && dda->out_fmt != DXGI_FORMAT_B8G8R8A8_UNORM) {
+ av_log(avctx, AV_LOG_ERROR, "Only 8 bit output supported with legacy API\n");
+ return AVERROR(ENOTSUP);
+ }
+
hr = IDXGIOutput_QueryInterface(dxgi_output, &IID_IDXGIOutput1, (void**)&dxgi_output1);
IDXGIOutput_Release(dxgi_output);
dxgi_output = NULL;
@@ -704,6 +726,11 @@ static int ddagrab_config_props(AVFilterLink *outlink)
if (ret < 0)
return ret;
+ if (dda->out_fmt && dda->raw_format != dda->out_fmt) {
+ av_log(avctx, AV_LOG_ERROR, "Requested output format unavailable.\n");
+ return AVERROR(ENOTSUP);
+ }
+
dda->width -= FFMAX(dda->width - dda->raw_width + dda->offset_x, 0);
dda->height -= FFMAX(dda->height - dda->raw_height + dda->offset_y, 0);