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