avfilter/vsrc_ddagrab: make output format user configurable

This commit is contained in:
Timo Rothenpieler 2022-08-06 14:54:58 +02:00
parent f0abd07996
commit 38595ebe3b
2 changed files with 44 additions and 1 deletions

View File

@ -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

View File

@ -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);