35#include <AMF/core/Factory.h>
36#include <AMF/core/Surface.h>
37#include <AMF/components/ColorSpace.h>
38#include <AMF/components/DisplayCapture.h>
57#define OFFSET(x) offsetof(AMFGrabContext, x)
58#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
63 {
"duplicate_output",
"Use display output duplication for screen capture",
OFFSET(duplicate_output),
AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1,
FLAGS },
65 {
"capture_mode",
"Capture synchronization mode",
OFFSET(capture_mode),
AV_OPT_TYPE_INT, {.i64 = AMF_DISPLAYCAPTURE_MODE_KEEP_FRAMERATE}, 0, 2,
FLAGS,
"mode" },
66 {
"keep_framerate",
"Capture component maintains the frame rate", 0,
AV_OPT_TYPE_CONST, {.i64 = AMF_DISPLAYCAPTURE_MODE_KEEP_FRAMERATE}, 0, 0,
FLAGS,
"mode" },
67 {
"wait_for_present",
"Capture component waits for flip (present) event", 0,
AV_OPT_TYPE_CONST, {.i64 = AMF_DISPLAYCAPTURE_MODE_WAIT_FOR_PRESENT}, 0, 0,
FLAGS,
"mode" },
68 {
"get_current",
"Returns current visible surface immediately", 0,
AV_OPT_TYPE_CONST, {.i64 = AMF_DISPLAYCAPTURE_MODE_GET_CURRENT_SURFACE}, 0, 0,
FLAGS,
"mode" },
79typedef MMRESULT (WINAPI *timeBeginPeriod_fn)(UINT uPeriod);
80typedef MMRESULT (WINAPI *timeEndPeriod_fn)(UINT uPeriod);
84 ctx->winmmdll = dlopen(
"Winmm.dll", 0);
86 timeBeginPeriod_fn
fn = (timeBeginPeriod_fn)dlsym(
ctx->winmmdll,
"timeBeginPeriod");
88 ctx->timerPrecision = 1;
89 while (
fn(
ctx->timerPrecision) == TIMERR_NOCANDO)
91 ++
ctx->timerPrecision;
99 timeEndPeriod_fn
fn = (timeEndPeriod_fn)dlsym(
ctx->winmmdll,
"timeEndPeriod");
101 fn(
ctx->timerPrecision);
102 dlclose(
ctx->winmmdll);
111 AMFInterface *surface = (AMFInterface*)(
data);
112 if (surface && surface->pVtbl)
113 surface->pVtbl->Release(surface);
122 ctx->capture->pVtbl->Drain(
ctx->capture);
123 ctx->capture->pVtbl->Terminate(
ctx->capture);
124 ctx->capture->pVtbl->Release(
ctx->capture);
130 amf_restore_timer_precision(
ctx);
138 amf_increase_timer_precision(
ctx);
155 AMFVariantStruct var = {0};
156 AMFSize resolution = {0};
158 res = amf_device_ctx->
factory->pVtbl->CreateComponent(amf_device_ctx->
factory,
164 AMF_ASSIGN_PROPERTY_INT64(res,
ctx->capture, AMF_DISPLAYCAPTURE_MONITOR_INDEX,
ctx->monitor_index);
170 if (
ctx->framerate.num > 0 &&
ctx->framerate.den > 0)
175 AMF_ASSIGN_PROPERTY_BOOL(res,
ctx->capture, AMF_DISPLAYCAPTURE_DUPLICATEOUTPUT,
ctx->duplicate_output);
177 av_log(avctx,
AV_LOG_ERROR,
"Failed to set AMF_DISPLAYCAPTURE_DUPLICATEOUTPUT: %d\n", res);
181 AMF_ASSIGN_PROPERTY_RATE(res,
ctx->capture, AMF_DISPLAYCAPTURE_FRAMERATE,
framerate);
187 AMF_ASSIGN_PROPERTY_INT64(res,
ctx->capture, AMF_DISPLAYCAPTURE_MODE,
ctx->capture_mode);
192 res =
ctx->capture->pVtbl->Init(
ctx->capture, AMF_SURFACE_UNKNOWN, 0, 0);
198 res =
ctx->capture->pVtbl->GetProperty(
ctx->capture, AMF_DISPLAYCAPTURE_RESOLUTION, &var);
199 if (res == AMF_OK && var.type == AMF_VARIANT_SIZE) {
200 resolution = var.sizeValue;
201 outlink->
w = resolution.width;
202 outlink->
h = resolution.height;
205 outlink->
w, outlink->
h);
208 AMFVariantClear(&var);
212 res =
ctx->capture->pVtbl->GetProperty(
ctx->capture, AMF_DISPLAYCAPTURE_FORMAT, &var);
213 if (res == AMF_OK && var.type == AMF_VARIANT_INT64) {
214 ctx->format = (AMF_SURFACE_FORMAT)var.int64Value;
217 ctx->format = AMF_SURFACE_BGRA;
224 AMFVariantClear(&var);
266 frames_ctx->
width = outlink->
w;
267 frames_ctx->
height = outlink->
h;
291 AMFSurface *surface =
NULL;
294 AMFData *data_out =
NULL;
304 res =
ctx->capture->pVtbl->QueryOutput(
ctx->capture, &data_out);
306 if (res == AMF_REPEAT) {
311 if (res == AMF_EOF) {
317 if (res != AMF_OK || !data_out) {
324 AMFGuid guid = IID_AMFSurface();
325 ret = data_out->pVtbl->QueryInterface(data_out, &guid, (
void**)&surface);
326 data_out->pVtbl->Release(data_out);
327 if (ret != AMF_OK || !surface) {
334 surface->pVtbl->Release(surface);
338 frame->width = outlink->
w;
339 frame->height = outlink->
h;
342 amf_pts
pts = surface->pVtbl->GetPts(surface);
347 frame->data[0] = (uint8_t*)surface;
351 if (!
frame->buf[0]) {
353 surface->pVtbl->Release(surface);
357 ret = surface->pVtbl->Convert(surface, AMF_MEMORY_HOST);
360 for (
i = 0;
i < surface->pVtbl->GetPlanesCount(surface);
i++) {
361 plane = surface->pVtbl->GetPlaneAt(surface,
i);
362 frame->data[
i] = plane->pVtbl->GetNative(plane);
363 frame->linesize[
i] = plane->pVtbl->GetHPitch(plane);
371 format_amf = surface->pVtbl->GetFormat(surface);
388 .p.name =
"vsrc_amf",
390 .p.priv_class = &amf_capture_class,
const FFFilter ff_vsrc_amf_capture
#define AMF_RETURN_IF_FALSE(avctx, exp, ret_value,...)
Error handling helper.
static AVFormatContext * ctx
simple assert() macros that are a bit more flexible than ISO C assert().
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Main libavfilter public API header.
#define i(width, name, range_min, range_max)
int(* init)(AVBSFContext *ctx)
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
@ AV_OPT_TYPE_VIDEO_RATE
Underlying C type is AVRational.
@ AV_OPT_TYPE_INT
Underlying C type is int.
@ AV_OPT_TYPE_BOOL
Underlying C type is int.
#define AVFILTER_FLAG_HWDEVICE
The filter can create hardware frames using AVFilterContext.hw_device_ctx.
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.
#define AV_BUFFER_FLAG_READONLY
Always treat the buffer as read-only, even when it has only one reference.
AVBufferRef * av_buffer_create(uint8_t *data, size_t size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags)
Create an AVBuffer from an existing array.
#define AVERROR_FILTER_NOT_FOUND
Filter not found.
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
#define AVERROR_EXTERNAL
Generic error in an external library.
#define AVERROR_EOF
End of file.
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
#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_VERBOSE
Detailed information.
#define AV_LOG_INFO
Standard information.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
static AVBufferRef * hw_device_ctx
int av_hwdevice_ctx_create(AVBufferRef **pdevice_ref, enum AVHWDeviceType type, const char *device, AVDictionary *opts, int flags)
Open a device of the specified type and create an AVHWDeviceContext for it.
int av_hwdevice_ctx_create_derived(AVBufferRef **dst_ref_ptr, enum AVHWDeviceType type, AVBufferRef *src_ref, int flags)
Create a new device of the specified type from an existing device.
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
AVBufferRef * av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
Allocate an AVHWFramesContext tied to a given device context.
enum AVPixelFormat av_amf_to_av_format(enum AMF_SURFACE_FORMAT fmt)
#define AMF_GOTO_FAIL_IF_FALSE(avctx, exp, ret_value,...)
static av_cold void uninit(AVBitStreamFilterContext *ctx)
#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 FilterLink * ff_filter_link(AVFilterLink *link)
#define FILTER_SINGLE_PIXFMT(pix_fmt_)
#define AVFILTER_DEFINE_CLASS(fname)
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Memory handling functions.
@ AV_PIX_FMT_AMF_SURFACE
HW acceleration through AMF.
AMF_SURFACE_FORMAT format
amf_bool duplicate_output
amf_uint32 timerPrecision
AVBufferRef * device_ctx_ref
This struct is allocated as AVHWDeviceContext.hwctx.
A reference to a data buffer.
uint8_t * data
The data buffer.
Describe the class of an AVClass context structure.
int extra_hw_frames
Sets the number of extra hardware frames which the filter will allocate on its output links for use i...
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.
int format
agreed upon media format
A filter pad used for either input or output.
This structure describes decoded (raw) audio or video data.
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
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.
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
int initial_pool_size
Initial size of the frame pool.
int width
The allocated dimensions of the frames in this pool.
Rational number (pair of numerator and denominator).
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.
static int amf_config_props(AVFilterLink *outlink)
static av_cold int amf_init(AVFilterContext *avctx)
static int amf_init_vsrc(AVFilterLink *outlink)
static const AVFilterPad amf_outputs[]
static av_cold void amf_uninit(AVFilterContext *avctx)
static void amf_release_surface(void *opaque, uint8_t *data)
static int amf_capture_frame(AVFilterLink *outlink)
static const AVOption amf_capture_options[]