aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/NvFBC.h2006
-rw-r--r--include/NvFBCLibrary.hpp246
-rw-r--r--include/capture/capture.h68
-rw-r--r--include/capture/kms.h50
-rw-r--r--include/capture/kms_cuda.h20
-rw-r--r--include/capture/kms_vaapi.h20
-rw-r--r--include/capture/nvfbc.h22
-rw-r--r--include/capture/xcomposite.h51
-rw-r--r--include/capture/xcomposite_cuda.h14
-rw-r--r--include/capture/xcomposite_vaapi.h13
-rw-r--r--include/color_conversion.h58
-rw-r--r--include/cuda.h108
-rw-r--r--include/cursor.h26
-rw-r--r--include/defs.h28
-rw-r--r--include/egl.h285
-rw-r--r--include/library_loader.h17
-rw-r--r--include/overclock.h17
-rw-r--r--include/shader.h19
-rw-r--r--include/sound.hpp26
-rw-r--r--include/utils.h46
-rw-r--r--include/vec2.h12
-rw-r--r--include/window_texture.h27
-rw-r--r--include/xnvctrl.h45
23 files changed, 968 insertions, 2256 deletions
diff --git a/include/NvFBC.h b/include/NvFBC.h
deleted file mode 100644
index 8990eea..0000000
--- a/include/NvFBC.h
+++ /dev/null
@@ -1,2006 +0,0 @@
-/*!
- * \file
- *
- * This file contains the interface constants, structure definitions and
- * function prototypes defining the NvFBC API for Linux.
- *
- * Copyright (c) 2013-2020, NVIDIA CORPORATION. All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef _NVFBC_H_
-#define _NVFBC_H_
-
-#include <stdint.h>
-
-/*!
- * \mainpage NVIDIA Framebuffer Capture (NvFBC) for Linux.
- *
- * NvFBC is a high performance, low latency API to capture the framebuffer of
- * an X server screen.
- *
- * The output from NvFBC captures everything that would be visible if we were
- * directly looking at the monitor. This includes window manager decoration,
- * mouse cursor, overlay, etc.
- *
- * It is ideally suited to desktop or fullscreen application capture and
- * remoting.
- */
-
-/*!
- * \defgroup FBC_REQ Requirements
- *
- * The following requirements are provided by the regular NVIDIA Display Driver
- * package:
- *
- * - OpenGL core >= 4.2:
- * Required. NvFBC relies on OpenGL to perform frame capture and
- * post-processing.
- *
- * - Vulkan 1.1:
- * Required.
- *
- * - libcuda.so.1 >= 5.5:
- * Optional. Used for capture to video memory with CUDA interop.
- *
- * The following requirements must be installed separately depending on the
- * Linux distribution being used:
- *
- * - XRandR extension >= 1.2:
- * Optional. Used for RandR output tracking.
- *
- * - libX11-xcb.so.1 >= 1.2:
- * Required. NvFBC uses a mix of Xlib and XCB. Xlib is needed to use GLX,
- * XCB is needed to make NvFBC more resilient against X server terminations
- * while a capture session is active.
- *
- * - libxcb.so.1 >= 1.3:
- * Required. See above.
- *
- * - xorg-server >= 1.3:
- * Optional. Required for push model to work properly.
- *
- * Note that all optional dependencies are dlopen()'d at runtime. Failure to
- * load an optional library is not fatal.
- */
-
-/*!
- * \defgroup FBC_CHANGES ChangeLog
- *
- * NvFBC Linux API version 0.1
- * - Initial BETA release.
- *
- * NvFBC Linux API version 0.2
- * - Added 'bEnableMSE' field to NVFBC_H264_HW_ENC_CONFIG.
- * - Added 'dwMSE' field to NVFBC_TOH264_GRAB_FRAME_PARAMS.
- * - Added 'bEnableAQ' field to NVFBC_H264_HW_ENC_CONFIG.
- * - Added 'NVFBC_H264_PRESET_LOSSLESS_HP' enum to NVFBC_H264_PRESET.
- * - Added 'NVFBC_BUFFER_FORMAT_YUV444P' enum to NVFBC_BUFFER_FORMAT.
- * - Added 'eInputBufferFormat' field to NVFBC_H264_HW_ENC_CONFIG.
- * - Added '0' and '244' values for NVFBC_H264_HW_ENC_CONFIG::dwProfile.
- *
- * NvFBC Linux API version 0.3
- * - Improved multi-threaded support by implementing an API locking mechanism.
- * - Added 'nvFBCBindContext' API entry point.
- * - Added 'nvFBCReleaseContext' API entry point.
- *
- * NvFBC Linux API version 1.0
- * - Added codec agnostic interface for HW encoding.
- * - Deprecated H.264 interface.
- * - Added support for H.265/HEVC HW encoding.
- *
- * NvFBC Linux API version 1.1
- * - Added 'nvFBCToHwGetCaps' API entry point.
- * - Added 'dwDiffMapScalingFactor' field to NVFBC_TOSYS_SETUP_PARAMS.
- *
- * NvFBC Linux API version 1.2
- * - Deprecated ToHwEnc interface.
- * - Added ToGL interface that captures frames to an OpenGL texture in video
- * memory.
- * - Added 'bDisableAutoModesetRecovery' field to
- * NVFBC_CREATE_CAPTURE_SESSION_PARAMS.
- * - Added 'bExternallyManagedContext' field to NVFBC_CREATE_HANDLE_PARAMS.
- *
- * NvFBC Linux API version 1.3
- * - Added NVFBC_BUFFER_FORMAT_RGBA
- * - Added 'dwTimeoutMs' field to NVFBC_TOSYS_GRAB_FRAME_PARAMS,
- * NVFBC_TOCUDA_GRAB_FRAME_PARAMS, and NVFBC_TOGL_GRAB_FRAME_PARAMS.
- *
- * NvFBC Linux API version 1.4
- * - Clarified that NVFBC_BUFFER_FORMAT_{ARGB,RGB,RGBA} are byte-order formats.
- * - Renamed NVFBC_BUFFER_FORMAT_YUV420P to NVFBC_BUFFER_FORMAT_NV12.
- * - Added new requirements.
- * - Made NvFBC more resilient against the X server terminating during an active
- * capture session. See new comments for ::NVFBC_ERR_X.
- * - Relaxed requirement that 'frameSize' must have a width being a multiple of
- * 4 and a height being a multiple of 2.
- * - Added 'bRoundFrameSize' field to NVFBC_CREATE_CAPTURE_SESSION_PARAMS.
- * - Relaxed requirement that the scaling factor for differential maps must be
- * a multiple of the size of the frame.
- * - Added 'diffMapSize' field to NVFBC_TOSYS_SETUP_PARAMS and
- * NVFBC_TOGL_SETUP_PARAMS.
- *
- * NvFBC Linux API version 1.5
- * - Added NVFBC_BUFFER_FORMAT_BGRA
- *
- * NvFBC Linux API version 1.6
- * - Added the 'NVFBC_TOSYS_GRAB_FLAGS_NOWAIT_IF_NEW_FRAME_READY',
- * 'NVFBC_TOCUDA_GRAB_FLAGS_NOWAIT_IF_NEW_FRAME_READY', and
- * 'NVFBC_TOGL_GRAB_FLAGS_NOWAIT_IF_NEW_FRAME_READY' capture flags.
- * - Exposed debug and performance logs through the NVFBC_LOG_LEVEL environment
- * variable. Setting it to "1" enables performance logs, setting it to "2"
- * enables debugging logs, setting it to "3" enables both.
- * - Logs are printed to stdout or to the file pointed by the NVFBC_LOG_FILE
- * environment variable.
- * - Added 'ulTimestampUs' to NVFBC_FRAME_GRAB_INFO.
- * - Added 'dwSamplingRateMs' to NVFBC_CREATE_CAPTURE_SESSION_PARAMS.
- * - Added 'bPushModel' to NVFBC_CREATE_CAPTURE_SESSION_PARAMS.
- *
- * NvFBC Linux API version 1.7
- * - Retired the NVFBC_CAPTURE_TO_HW_ENCODER interface.
- * This interface has been deprecated since NvFBC 1.2 and has received no
- * updates or new features since. We recommend using the NVIDIA Video Codec
- * SDK to encode NvFBC frames.
- * See: https://developer.nvidia.com/nvidia-video-codec-sdk
- * - Added a 'Capture Modes' section to those headers.
- * - Added a 'Post Processing' section to those headers.
- * - Added an 'Environment Variables' section to those headers.
- * - Added 'bInModeset' to NVFBC_GET_STATUS_PARAMS.
- * - Added 'bAllowDirectCapture' to NVFBC_CREATE_CAPTURE_SESSION_PARAMS.
- * - Added 'bDirectCaptured' to NVFBC_FRAME_GRAB_INFO.
- * - Added 'bRequiredPostProcessing' to NVFBC_FRAME_GRAB_INFO.
- */
-
-/*!
- * \defgroup FBC_MODES Capture Modes
- *
- * When creating a capture session, NvFBC instantiates a capture subsystem
- * living in the NVIDIA X driver.
- *
- * This subsystem listens for damage events coming from applications then
- * generates (composites) frames for NvFBC when new content is available.
- *
- * This capture server can operate on a timer where it periodically checks if
- * there are any pending damage events, or it can generate frames as soon as it
- * receives a new damage event.
- * See NVFBC_CREATE_CAPTURE_SESSION_PARAMS::dwSamplingRateMs,
- * and NVFBC_CREATE_CAPTURE_SESSION_PARAMS::bPushModel.
- *
- * NvFBC can also attach itself to a fullscreen unoccluded application and have
- * it copy its frames directly into a buffer owned by NvFBC upon present. This
- * mode bypasses the X server.
- * See NVFBC_CREATE_CAPTURE_SESSION_PARAMS::bAllowDirectCapture.
- *
- * NvFBC is designed to capture frames with as few copies as possible. The
- * NVIDIA X driver composites frames directly into the NvFBC buffers, and
- * direct capture copies frames directly into these buffers as well.
- *
- * Depending on the configuration of a capture session, an extra copy (rendering
- * pass) may be needed. See the 'Post Processing' section.
- */
-
-/*!
- * \defgroup FBC_PP Post Processing
- *
- * Depending on the configuration of a capture session, NvFBC might require to
- * do post processing on frames.
- *
- * Post processing is required for the following reasons:
- * - NvFBC needs to do a pixel format conversion.
- * - Diffmaps are requested.
- * - Capture to system memory is requested.
- *
- * NvFBC needs to do a conversion if the requested pixel format does not match
- * the native format. The native format is NVFBC_BUFFER_FORMAT_BGRA.
- *
- * Note: post processing is *not* required for frame scaling and frame cropping.
- *
- * Skipping post processing can reduce capture latency. An application can know
- * whether post processing was required by checking
- * NVFBC_FRAME_GRAB_INFO::bRequiredPostProcessing.
- */
-
-/*!
- * \defgroup FBC_ENVVAR Environment Variables
- *
- * Below are the environment variables supported by NvFBC:
- *
- * - NVFBC_LOG_LEVEL
- * Bitfield where the first bit enables debug logs and the second bit enables
- * performance logs. Both can be enabled by setting this envvar to 3.
- *
- * - NVFBC_LOG_FILE
- * Write all NvFBC logs to the given file.
- *
- * - NVFBC_FORCE_ALLOW_DIRECT_CAPTURE
- * Used to override NVFBC_CREATE_CAPTURE_SESSION_PARAMS::bAllowDirectCapture.
- *
- * - NVFBC_FORCE_POST_PROCESSING
- * Used to force the post processing step, even if it could be skipped.
- * See the 'Post Processing' section.
- */
-
-/*!
- * \defgroup FBC_STRUCT Structure Definition
- *
- * @{
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*!
- * Calling convention.
- */
-#define NVFBCAPI
-
-/*!
- * NvFBC API major version.
- */
-#define NVFBC_VERSION_MAJOR 1
-
-/*!
- * NvFBC API minor version.
- */
-#define NVFBC_VERSION_MINOR 7
-
-/*!
- * NvFBC API version.
- */
-#define NVFBC_VERSION (uint32_t) (NVFBC_VERSION_MINOR | (NVFBC_VERSION_MAJOR << 8))
-
-/*!
- * Creates a version number for structure parameters.
- */
-#define NVFBC_STRUCT_VERSION(typeName, ver) \
- (uint32_t) (sizeof(typeName) | ((ver) << 16) | (NVFBC_VERSION << 24))
-
-/*!
- * Defines error codes.
- *
- * \see NvFBCGetLastErrorStr
- */
-typedef enum _NVFBCSTATUS
-{
- /*!
- * This indicates that the API call returned with no errors.
- */
- NVFBC_SUCCESS = 0,
- /*!
- * This indicates that the API version between the client and the library
- * is not compatible.
- */
- NVFBC_ERR_API_VERSION = 1,
- /*!
- * An internal error occurred.
- */
- NVFBC_ERR_INTERNAL = 2,
- /*!
- * This indicates that one or more of the parameter passed to the API call
- * is invalid.
- */
- NVFBC_ERR_INVALID_PARAM = 3,
- /*!
- * This indicates that one or more of the pointers passed to the API call
- * is invalid.
- */
- NVFBC_ERR_INVALID_PTR = 4,
- /*!
- * This indicates that the handle passed to the API call to identify the
- * client is invalid.
- */
- NVFBC_ERR_INVALID_HANDLE = 5,
- /*!
- * This indicates that the maximum number of threaded clients of the same
- * process has been reached. The limit is 10 threads per process.
- * There is no limit on the number of process.
- */
- NVFBC_ERR_MAX_CLIENTS = 6,
- /*!
- * This indicates that the requested feature is not currently supported
- * by the library.
- */
- NVFBC_ERR_UNSUPPORTED = 7,
- /*!
- * This indicates that the API call failed because it was unable to allocate
- * enough memory to perform the requested operation.
- */
- NVFBC_ERR_OUT_OF_MEMORY = 8,
- /*!
- * This indicates that the API call was not expected. This happens when
- * API calls are performed in a wrong order, such as trying to capture
- * a frame prior to creating a new capture session; or trying to set up
- * a capture to video memory although a capture session to system memory
- * was created.
- */
- NVFBC_ERR_BAD_REQUEST = 9,
- /*!
- * This indicates an X error, most likely meaning that the X server has
- * been terminated. When this error is returned, the only resort is to
- * create another FBC handle using NvFBCCreateHandle().
- *
- * The previous handle should still be freed with NvFBCDestroyHandle(), but
- * it might leak resources, in particular X, GLX, and GL resources since
- * it is no longer possible to communicate with an X server to free them
- * through the driver.
- *
- * The best course of action to eliminate this potential leak is to close
- * the OpenGL driver, close the forked process running the capture, or
- * restart the application.
- */
- NVFBC_ERR_X = 10,
- /*!
- * This indicates a GLX error.
- */
- NVFBC_ERR_GLX = 11,
- /*!
- * This indicates an OpenGL error.
- */
- NVFBC_ERR_GL = 12,
- /*!
- * This indicates a CUDA error.
- */
- NVFBC_ERR_CUDA = 13,
- /*!
- * This indicates a HW encoder error.
- */
- NVFBC_ERR_ENCODER = 14,
- /*!
- * This indicates an NvFBC context error.
- */
- NVFBC_ERR_CONTEXT = 15,
- /*!
- * This indicates that the application must recreate the capture session.
- *
- * This error can be returned if a modeset event occurred while capturing
- * frames, and NVFBC_CREATE_HANDLE_PARAMS::bDisableAutoModesetRecovery
- * was set to NVFBC_TRUE.
- */
- NVFBC_ERR_MUST_RECREATE = 16,
- /*!
- * This indicates a Vulkan error.
- */
- NVFBC_ERR_VULKAN = 17,
-} NVFBCSTATUS;
-
-/*!
- * Defines boolean values.
- */
-typedef enum _NVFBC_BOOL
-{
- /*!
- * False value.
- */
- NVFBC_FALSE = 0,
- /*!
- * True value.
- */
- NVFBC_TRUE,
-} NVFBC_BOOL;
-
-/*!
- * Maximum size in bytes of an error string.
- */
-#define NVFBC_ERR_STR_LEN 512
-
-/*!
- * Capture type.
- */
-typedef enum _NVFBC_CAPTURE_TYPE
-{
- /*!
- * Capture frames to a buffer in system memory.
- */
- NVFBC_CAPTURE_TO_SYS = 0,
- /*!
- * Capture frames to a CUDA device in video memory.
- *
- * Specifying this will dlopen() libcuda.so.1 and fail if not available.
- */
- NVFBC_CAPTURE_SHARED_CUDA,
- /*!
- * Retired. Do not use.
- */
- /* NVFBC_CAPTURE_TO_HW_ENCODER, */
- /*!
- * Capture frames to an OpenGL buffer in video memory.
- */
- NVFBC_CAPTURE_TO_GL = 3,
-} NVFBC_CAPTURE_TYPE;
-
-/*!
- * Tracking type.
- *
- * NvFBC can track a specific region of the framebuffer to capture.
- *
- * An X screen corresponds to the entire framebuffer.
- *
- * An RandR CRTC is a component of the GPU that reads pixels from a region of
- * the X screen and sends them through a pipeline to an RandR output.
- * A physical monitor can be connected to an RandR output. Tracking an RandR
- * output captures the region of the X screen that the RandR CRTC is sending to
- * the RandR output.
- */
-typedef enum
-{
- /*!
- * By default, NvFBC tries to track a connected primary output. If none is
- * found, then it tries to track the first connected output. If none is
- * found then it tracks the entire X screen.
- *
- * If the XRandR extension is not available, this option has the same effect
- * as ::NVFBC_TRACKING_SCREEN.
- *
- * This default behavior might be subject to changes in the future.
- */
- NVFBC_TRACKING_DEFAULT = 0,
- /*!
- * Track an RandR output specified by its ID in the appropriate field.
- *
- * The list of connected outputs can be queried via NvFBCGetStatus().
- * This list can also be obtained using e.g., xrandr(1).
- *
- * If the XRandR extension is not available, setting this option returns an
- * error.
- */
- NVFBC_TRACKING_OUTPUT,
- /*!
- * Track the entire X screen.
- */
- NVFBC_TRACKING_SCREEN,
-} NVFBC_TRACKING_TYPE;
-
-/*!
- * Buffer format.
- */
-typedef enum _NVFBC_BUFFER_FORMAT
-{
- /*!
- * Data will be converted to ARGB8888 byte-order format. 32 bpp.
- */
- NVFBC_BUFFER_FORMAT_ARGB = 0,
- /*!
- * Data will be converted to RGB888 byte-order format. 24 bpp.
- */
- NVFBC_BUFFER_FORMAT_RGB,
- /*!
- * Data will be converted to NV12 format using HDTV weights
- * according to ITU-R BT.709. 12 bpp.
- */
- NVFBC_BUFFER_FORMAT_NV12,
- /*!
- * Data will be converted to YUV 444 planar format using HDTV weights
- * according to ITU-R BT.709. 24 bpp
- */
- NVFBC_BUFFER_FORMAT_YUV444P,
- /*!
- * Data will be converted to RGBA8888 byte-order format. 32 bpp.
- */
- NVFBC_BUFFER_FORMAT_RGBA,
- /*!
- * Native format. No pixel conversion needed.
- * BGRA8888 byte-order format. 32 bpp.
- */
- NVFBC_BUFFER_FORMAT_BGRA,
-} NVFBC_BUFFER_FORMAT;
-
-#define NVFBC_BUFFER_FORMAT_YUV420P NVFBC_BUFFER_FORMAT_NV12
-
-/*!
- * Handle used to identify an NvFBC session.
- */
-typedef uint64_t NVFBC_SESSION_HANDLE;
-
-/*!
- * Box used to describe an area of the tracked region to capture.
- *
- * The coordinates are relative to the tracked region.
- *
- * E.g., if the size of the X screen is 3520x1200 and the tracked RandR output
- * scans a region of 1600x1200+1920+0, then setting a capture box of
- * 800x600+100+50 effectively captures a region of 800x600+2020+50 relative to
- * the X screen.
- */
-typedef struct _NVFBC_BOX
-{
- /*!
- * [in] X offset of the box.
- */
- uint32_t x;
- /*!
- * [in] Y offset of the box.
- */
- uint32_t y;
- /*!
- * [in] Width of the box.
- */
- uint32_t w;
- /*!
- * [in] Height of the box.
- */
- uint32_t h;
-} NVFBC_BOX;
-
-/*!
- * Size used to describe the size of a frame.
- */
-typedef struct _NVFBC_SIZE
-{
- /*!
- * [in] Width.
- */
- uint32_t w;
- /*!
- * [in] Height.
- */
- uint32_t h;
-} NVFBC_SIZE;
-
-/*!
- * Describes information about a captured frame.
- */
-typedef struct _NVFBC_FRAME_GRAB_INFO
-{
- /*!
- * [out] Width of the captured frame.
- */
- uint32_t dwWidth;
- /*!
- * [out] Height of the captured frame.
- */
- uint32_t dwHeight;
- /*!
- * [out] Size of the frame in bytes.
- */
- uint32_t dwByteSize;
- /*!
- * [out] Incremental ID of the current frame.
- *
- * This can be used to identify a frame.
- */
- uint32_t dwCurrentFrame;
- /*!
- * [out] Whether the captured frame is a new frame.
- *
- * When using non blocking calls it is possible to capture a frame
- * that was already captured before if the display server did not
- * render a new frame in the meantime. In that case, this flag
- * will be set to NVFBC_FALSE.
- *
- * When using blocking calls each captured frame will have
- * this flag set to NVFBC_TRUE since the blocking mechanism waits for
- * the display server to render a new frame.
- *
- * Note that this flag does not guarantee that the content of
- * the frame will be different compared to the previous captured frame.
- *
- * In particular, some compositing managers report the entire
- * framebuffer as damaged when an application refreshes its content.
- *
- * Consider a single X screen spanned across physical displays A and B
- * and an NvFBC application tracking display A. Depending on the
- * compositing manager, it is possible that an application refreshing
- * itself on display B will trigger a frame capture on display A.
- *
- * Workarounds include:
- * - Using separate X screens
- * - Disabling the composite extension
- * - Using a compositing manager that properly reports what regions
- * are damaged
- * - Using NvFBC's diffmaps to find out if the frame changed
- */
- NVFBC_BOOL bIsNewFrame;
- /*!
- * [out] Frame timestamp
- *
- * Time in micro seconds when the display server started rendering the
- * frame.
- *
- * This does not account for when the frame was captured. If capturing an
- * old frame (e.g., bIsNewFrame is NVFBC_FALSE) the reported timestamp
- * will reflect the time when the old frame was rendered by the display
- * server.
- */
- uint64_t ulTimestampUs;
- /*
- * [out] Number of frames generated since the last capture.
- *
- * This can help applications tell whether they missed frames or there
- * were no frames generated by the server since the last capture.
- */
- uint32_t dwMissedFrames;
- /*
- * [out] Whether the captured frame required post processing.
- *
- * See the 'Post Processing' section.
- */
- NVFBC_BOOL bRequiredPostProcessing;
- /*
- * [out] Whether this frame was obtained via direct capture.
- *
- * See NVFBC_CREATE_CAPTURE_SESSION_PARAMS::bAllowDirectCapture.
- */
- NVFBC_BOOL bDirectCapture;
-} NVFBC_FRAME_GRAB_INFO;
-
-/*!
- * Defines parameters for the CreateHandle() API call.
- */
-typedef struct _NVFBC_CREATE_HANDLE_PARAMS
-{
- /*!
- * [in] Must be set to NVFBC_CREATE_HANDLE_PARAMS_VER
- */
- uint32_t dwVersion;
- /*!
- * [in] Application specific private information passed to the NvFBC
- * session.
- */
- const void *privateData;
- /*!
- * [in] Size of the application specific private information passed to the
- * NvFBC session.
- */
- uint32_t privateDataSize;
- /*!
- * [in] Whether NvFBC should not create and manage its own graphics context
- *
- * NvFBC internally uses OpenGL to perfom graphics operations on the
- * captured frames. By default, NvFBC will create and manage (e.g., make
- * current, detect new threads, etc.) its own OpenGL context.
- *
- * If set to NVFBC_TRUE, NvFBC will use the application's context. It will
- * be the application's responsibility to make sure that a context is
- * current on the thread calling into the NvFBC API.
- */
- NVFBC_BOOL bExternallyManagedContext;
- /*!
- * [in] GLX context
- *
- * GLX context that NvFBC should use internally to create pixmaps and
- * make them current when creating a new capture session.
- *
- * Note: NvFBC expects a context created against a GLX_RGBA_TYPE render
- * type.
- */
- void *glxCtx;
- /*!
- * [in] GLX framebuffer configuration
- *
- * Framebuffer configuration that was used to create the GLX context, and
- * that will be used to create pixmaps internally.
- *
- * Note: NvFBC expects a configuration having at least the following
- * attributes:
- * GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT
- * GLX_BIND_TO_TEXTURE_RGBA_EXT, 1
- * GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT
- */
- void *glxFBConfig;
-} NVFBC_CREATE_HANDLE_PARAMS;
-
-/*!
- * NVFBC_CREATE_HANDLE_PARAMS structure version.
- */
-#define NVFBC_CREATE_HANDLE_PARAMS_VER NVFBC_STRUCT_VERSION(NVFBC_CREATE_HANDLE_PARAMS, 2)
-
-/*!
- * Defines parameters for the ::NvFBCDestroyHandle() API call.
- */
-typedef struct _NVFBC_DESTROY_HANDLE_PARAMS
-{
- /*!
- * [in] Must be set to NVFBC_DESTROY_HANDLE_PARAMS_VER
- */
- uint32_t dwVersion;
-} NVFBC_DESTROY_HANDLE_PARAMS;
-
-/*!
- * NVFBC_DESTROY_HANDLE_PARAMS structure version.
- */
-#define NVFBC_DESTROY_HANDLE_PARAMS_VER NVFBC_STRUCT_VERSION(NVFBC_DESTROY_HANDLE_PARAMS, 1)
-
-/*!
- * Maximum number of connected RandR outputs to an X screen.
- */
-#define NVFBC_OUTPUT_MAX 5
-
-/*!
- * Maximum size in bytes of an RandR output name.
- */
-#define NVFBC_OUTPUT_NAME_LEN 128
-
-/*!
- * Describes an RandR output.
- *
- * Filling this structure relies on the XRandR extension. This feature cannot
- * be used if the extension is missing or its version is below the requirements.
- *
- * \see Requirements
- */
-typedef struct _NVFBC_OUTPUT
-{
- /*!
- * Identifier of the RandR output.
- */
- uint32_t dwId;
- /*!
- * Name of the RandR output, as reported by tools such as xrandr(1).
- *
- * Example: "DVI-I-0"
- */
- char name[NVFBC_OUTPUT_NAME_LEN];
- /*!
- * Region of the X screen tracked by the RandR CRTC driving this RandR
- * output.
- */
- NVFBC_BOX trackedBox;
-} NVFBC_RANDR_OUTPUT_INFO;
-
-/*!
- * Defines parameters for the ::NvFBCGetStatus() API call.
- */
-typedef struct _NVFBC_GET_STATUS_PARAMS
-{
- /*!
- * [in] Must be set to NVFBC_GET_STATUS_PARAMS_VER
- */
- uint32_t dwVersion;
- /*!
- * [out] Whether or not framebuffer capture is supported by the graphics
- * driver.
- */
- NVFBC_BOOL bIsCapturePossible;
- /*!
- * [out] Whether or not there is already a capture session on this system.
- */
- NVFBC_BOOL bCurrentlyCapturing;
- /*!
- * [out] Whether or not it is possible to create a capture session on this
- * system.
- */
- NVFBC_BOOL bCanCreateNow;
- /*!
- * [out] Size of the X screen (framebuffer).
- */
- NVFBC_SIZE screenSize;
- /*!
- * [out] Whether the XRandR extension is available.
- *
- * If this extension is not available then it is not possible to have
- * information about RandR outputs.
- */
- NVFBC_BOOL bXRandRAvailable;
- /*!
- * [out] Array of outputs connected to the X screen.
- *
- * An application can track a specific output by specifying its ID when
- * creating a capture session.
- *
- * Only if XRandR is available.
- */
- NVFBC_RANDR_OUTPUT_INFO outputs[NVFBC_OUTPUT_MAX];
- /*!
- * [out] Number of outputs connected to the X screen.
- *
- * This must be used to parse the array of connected outputs.
- *
- * Only if XRandR is available.
- */
- uint32_t dwOutputNum;
- /*!
- * [out] Version of the NvFBC library running on this system.
- */
- uint32_t dwNvFBCVersion;
- /*!
- * [out] Whether the X server is currently in modeset.
- *
- * When the X server is in modeset, it must give up all its video
- * memory allocations. It is not possible to create a capture
- * session until the modeset is over.
- *
- * Note that VT-switches are considered modesets.
- */
- NVFBC_BOOL bInModeset;
-} NVFBC_GET_STATUS_PARAMS;
-
-/*!
- * NVFBC_GET_STATUS_PARAMS structure version.
- */
-#define NVFBC_GET_STATUS_PARAMS_VER NVFBC_STRUCT_VERSION(NVFBC_GET_STATUS_PARAMS, 2)
-
-/*!
- * Defines parameters for the ::NvFBCCreateCaptureSession() API call.
- */
-typedef struct _NVFBC_CREATE_CAPTURE_SESSION_PARAMS
-{
- /*!
- * [in] Must be set to NVFBC_CREATE_CAPTURE_SESSION_PARAMS_VER
- */
- uint32_t dwVersion;
- /*!
- * [in] Desired capture type.
- *
- * Note that when specyfing ::NVFBC_CAPTURE_SHARED_CUDA NvFBC will try to
- * dlopen() the corresponding libraries. This means that NvFBC can run on
- * a system without the CUDA library since it does not link against them.
- */
- NVFBC_CAPTURE_TYPE eCaptureType;
- /*!
- * [in] What region of the framebuffer should be tracked.
- */
- NVFBC_TRACKING_TYPE eTrackingType;
- /*!
- * [in] ID of the output to track if eTrackingType is set to
- * ::NVFBC_TRACKING_OUTPUT.
- */
- uint32_t dwOutputId;
- /*!
- * [in] Crop the tracked region.
- *
- * The coordinates are relative to the tracked region.
- *
- * It can be set to 0 to capture the entire tracked region.
- */
- NVFBC_BOX captureBox;
- /*!
- * [in] Desired size of the captured frame.
- *
- * This parameter allow to scale the captured frame.
- *
- * It can be set to 0 to disable frame resizing.
- */
- NVFBC_SIZE frameSize;
- /*!
- * [in] Whether the mouse cursor should be composited to the frame.
- *
- * Disabling the cursor will not generate new frames when only the cursor
- * is moved.
- */
- NVFBC_BOOL bWithCursor;
- /*!
- * [in] Whether NvFBC should not attempt to recover from modesets.
- *
- * NvFBC is able to detect when a modeset event occured and can automatically
- * re-create a capture session with the same settings as before, then resume
- * its frame capture session transparently.
- *
- * This option allows to disable this behavior. NVFBC_ERR_MUST_RECREATE
- * will be returned in that case.
- *
- * It can be useful in the cases when an application needs to do some work
- * between setting up a capture and grabbing the first frame.
- *
- * For example: an application using the ToGL interface needs to register
- * resources with EncodeAPI prior to encoding frames.
- *
- * Note that during modeset recovery, NvFBC will try to re-create the
- * capture session every second until it succeeds.
- */
- NVFBC_BOOL bDisableAutoModesetRecovery;
- /*!
- * [in] Whether NvFBC should round the requested frameSize.
- *
- * When disabled, NvFBC will not attempt to round the requested resolution.
- *
- * However, some pixel formats have resolution requirements. E.g., YUV/NV
- * formats must have a width being a multiple of 4, and a height being a
- * multiple of 2. RGB formats don't have such requirements.
- *
- * If the resolution doesn't meet the requirements of the format, then NvFBC
- * will fail at setup time.
- *
- * When enabled, NvFBC will round the requested width to the next multiple
- * of 4 and the requested height to the next multiple of 2.
- *
- * In this case, requesting any resolution will always work with every
- * format. However, an NvFBC client must be prepared to handle the case
- * where the requested resolution is different than the captured resolution.
- *
- * NVFBC_FRAME_GRAB_INFO::dwWidth and NVFBC_FRAME_GRAB_INFO::dwHeight should
- * always be used for getting information about captured frames.
- */
- NVFBC_BOOL bRoundFrameSize;
- /*!
- * [in] Rate in ms at which the display server generates new frames
- *
- * This controls the frequency at which the display server will generate
- * new frames if new content is available. This effectively controls the
- * capture rate when using blocking calls.
- *
- * Note that lower values will increase the CPU and GPU loads.
- *
- * The default value is 16ms (~ 60 Hz).
- */
- uint32_t dwSamplingRateMs;
- /*!
- * [in] Enable push model for frame capture
- *
- * When set to NVFBC_TRUE, the display server will generate frames whenever
- * it receives a damage event from applications.
- *
- * Setting this to NVFBC_TRUE will ignore ::dwSamplingRateMs.
- *
- * Using push model with the NVFBC_*_GRAB_FLAGS_NOWAIT_IF_NEW_FRAME_READY
- * capture flag should guarantee the shortest amount of time between an
- * application rendering a frame and an NvFBC client capturing it, provided
- * that the NvFBC client is able to process the frames quickly enough.
- *
- * Note that applications running at high frame rates will increase CPU and
- * GPU loads.
- */
- NVFBC_BOOL bPushModel;
- /*!
- * [in] Allow direct capture
- *
- * Direct capture allows NvFBC to attach itself to a fullscreen graphics
- * application. Whenever that application presents a frame, it makes a copy
- * of it directly into a buffer owned by NvFBC thus bypassing the X server.
- *
- * When direct capture is *not* enabled, the NVIDIA X driver generates a
- * frame for NvFBC when it receives a damage event from an application if push
- * model is enabled, or periodically checks if there are any pending damage
- * events otherwise (see NVFBC_CREATE_CAPTURE_SESSION_PARAMS::dwSamplingRateMs).
- *
- * Direct capture is possible under the following conditions:
- * - Direct capture is allowed
- * - Push model is enabled (see NVFBC_CREATE_CAPTURE_SESSION_PARAMS::bPushModel)
- * - The mouse cursor is not composited (see NVFBC_CREATE_CAPTURE_SESSION_PARAMS::bWithCursor)
- * - No viewport transformation is required. This happens when the remote
- * desktop is e.g. rotated.
- *
- * When direct capture is possible, NvFBC will automatically attach itself
- * to a fullscreen unoccluded application, if such exists.
- *
- * Notes:
- * - This includes compositing desktops such as GNOME (e.g., gnome-shell
- * is the fullscreen unoccluded application).
- * - There can be only one fullscreen unoccluded application at a time.
- * - The NVIDIA X driver monitors which application qualifies or no
- * longer qualifies.
- *
- * For example, if a fullscreen application is launched in GNOME, NvFBC will
- * detach from gnome-shell and attach to that application.
- *
- * Attaching and detaching happens automatically from the perspective of an
- * NvFBC client. When detaching from an application, the X driver will
- * transparently resume generating frames for NvFBC.
- *
- * An application can know whether a given frame was obtained through
- * direct capture by checking NVFBC_FRAME_GRAB_INFO::bDirectCapture.
- */
- NVFBC_BOOL bAllowDirectCapture;
-} NVFBC_CREATE_CAPTURE_SESSION_PARAMS;
-
-/*!
- * NVFBC_CREATE_CAPTURE_SESSION_PARAMS structure version.
- */
-#define NVFBC_CREATE_CAPTURE_SESSION_PARAMS_VER NVFBC_STRUCT_VERSION(NVFBC_CREATE_CAPTURE_SESSION_PARAMS, 6)
-
-/*!
- * Defines parameters for the ::NvFBCDestroyCaptureSession() API call.
- */
-typedef struct _NVFBC_DESTROY_CAPTURE_SESSION_PARAMS
-{
- /*!
- * [in] Must be set to NVFBC_DESTROY_CAPTURE_SESSION_PARAMS_VER
- */
- uint32_t dwVersion;
-} NVFBC_DESTROY_CAPTURE_SESSION_PARAMS;
-
-/*!
- * NVFBC_DESTROY_CAPTURE_SESSION_PARAMS structure version.
- */
-#define NVFBC_DESTROY_CAPTURE_SESSION_PARAMS_VER NVFBC_STRUCT_VERSION(NVFBC_DESTROY_CAPTURE_SESSION_PARAMS, 1)
-
-/*!
- * Defines parameters for the ::NvFBCBindContext() API call.
- */
-typedef struct _NVFBC_BIND_CONTEXT_PARAMS
-{
- /*!
- * [in] Must be set to NVFBC_BIND_CONTEXT_PARAMS_VER
- */
- uint32_t dwVersion;
-} NVFBC_BIND_CONTEXT_PARAMS;
-
-/*!
- * NVFBC_BIND_CONTEXT_PARAMS structure version.
- */
-#define NVFBC_BIND_CONTEXT_PARAMS_VER NVFBC_STRUCT_VERSION(NVFBC_BIND_CONTEXT_PARAMS, 1)
-
-/*!
- * Defines parameters for the ::NvFBCReleaseContext() API call.
- */
-typedef struct _NVFBC_RELEASE_CONTEXT_PARAMS
-{
- /*!
- * [in] Must be set to NVFBC_RELEASE_CONTEXT_PARAMS_VER
- */
- uint32_t dwVersion;
-} NVFBC_RELEASE_CONTEXT_PARAMS;
-
-/*!
- * NVFBC_RELEASE_CONTEXT_PARAMS structure version.
- */
-#define NVFBC_RELEASE_CONTEXT_PARAMS_VER NVFBC_STRUCT_VERSION(NVFBC_RELEASE_CONTEXT_PARAMS, 1)
-
-/*!
- * Defines flags that can be used when capturing to system memory.
- */
-typedef enum
-{
- /*!
- * Default, capturing waits for a new frame or mouse move.
- *
- * The default behavior of blocking grabs is to wait for a new frame until
- * after the call was made. But it's possible that there is a frame already
- * ready that the client hasn't seen.
- * \see NVFBC_TOSYS_GRAB_FLAGS_NOWAIT_IF_NEW_FRAME_READY
- */
- NVFBC_TOSYS_GRAB_FLAGS_NOFLAGS = 0,
- /*!
- * Capturing does not wait for a new frame nor a mouse move.
- *
- * It is therefore possible to capture the same frame multiple times.
- * When this occurs, the dwCurrentFrame parameter of the
- * NVFBC_FRAME_GRAB_INFO structure is not incremented.
- */
- NVFBC_TOSYS_GRAB_FLAGS_NOWAIT = (1 << 0),
- /*!
- * Forces the destination buffer to be refreshed even if the frame has not
- * changed since previous capture.
- *
- * By default, if the captured frame is identical to the previous one, NvFBC
- * will omit one copy and not update the destination buffer.
- *
- * Setting that flag will prevent this behavior. This can be useful e.g.,
- * if the application has modified the buffer in the meantime.
- */
- NVFBC_TOSYS_GRAB_FLAGS_FORCE_REFRESH = (1 << 1),
- /*!
- * Similar to NVFBC_TOSYS_GRAB_FLAGS_NOFLAGS, except that the capture will
- * not wait if there is already a frame available that the client has
- * never seen yet.
- */
- NVFBC_TOSYS_GRAB_FLAGS_NOWAIT_IF_NEW_FRAME_READY = (1 << 2),
-} NVFBC_TOSYS_GRAB_FLAGS;
-
-/*!
- * Defines parameters for the ::NvFBCToSysSetUp() API call.
- */
-typedef struct _NVFBC_TOSYS_SETUP_PARAMS
-{
- /*!
- * [in] Must be set to NVFBC_TOSYS_SETUP_PARAMS_VER
- */
- uint32_t dwVersion;
- /*!
- * [in] Desired buffer format.
- */
- NVFBC_BUFFER_FORMAT eBufferFormat;
- /*!
- * [out] Pointer to a pointer to a buffer in system memory.
- *
- * This buffer contains the pixel value of the requested format. Refer to
- * the description of the buffer formats to understand the memory layout.
- *
- * The application does not need to allocate memory for this buffer. It
- * should not free this buffer either. This buffer is automatically
- * re-allocated when needed (e.g., when the resolution changes).
- *
- * This buffer is allocated by the NvFBC library to the proper size. This
- * size is returned in the dwByteSize field of the
- * ::NVFBC_FRAME_GRAB_INFO structure.
- */
- void **ppBuffer;
- /*!
- * [in] Whether differential maps should be generated.
- */
- NVFBC_BOOL bWithDiffMap;
- /*!
- * [out] Pointer to a pointer to a buffer in system memory.
- *
- * This buffer contains the differential map of two frames. It must be read
- * as an array of unsigned char. Each unsigned char is either 0 or
- * non-zero. 0 means that the pixel value at the given location has not
- * changed since the previous captured frame. Non-zero means that the pixel
- * value has changed.
- *
- * The application does not need to allocate memory for this buffer. It
- * should not free this buffer either. This buffer is automatically
- * re-allocated when needed (e.g., when the resolution changes).
- *
- * This buffer is allocated by the NvFBC library to the proper size. The
- * size of the differential map is returned in ::diffMapSize.
- *
- * This option is not compatible with the ::NVFBC_BUFFER_FORMAT_YUV420P and
- * ::NVFBC_BUFFER_FORMAT_YUV444P buffer formats.
- */
- void **ppDiffMap;
- /*!
- * [in] Scaling factor of the differential maps.
- *
- * For example, a scaling factor of 16 means that one pixel of the diffmap
- * will represent 16x16 pixels of the original frames.
- *
- * If any of these 16x16 pixels is different between the current and the
- * previous frame, then the corresponding pixel in the diffmap will be set
- * to non-zero.
- *
- * The default scaling factor is 1. A dwDiffMapScalingFactor of 0 will be
- * set to 1.
- */
- uint32_t dwDiffMapScalingFactor;
- /*!
- * [out] Size of the differential map.
- *
- * Only set if bWithDiffMap is set to NVFBC_TRUE.
- */
- NVFBC_SIZE diffMapSize;
-} NVFBC_TOSYS_SETUP_PARAMS;
-
-/*!
- * NVFBC_TOSYS_SETUP_PARAMS structure version.
- */
-#define NVFBC_TOSYS_SETUP_PARAMS_VER NVFBC_STRUCT_VERSION(NVFBC_TOSYS_SETUP_PARAMS, 3)
-
-/*!
- * Defines parameters for the ::NvFBCToSysGrabFrame() API call.
- */
-typedef struct _NVFBC_TOSYS_GRAB_FRAME_PARAMS
-{
- /*!
- * [in] Must be set to NVFBC_TOSYS_GRAB_FRAME_PARAMS_VER
- */
- uint32_t dwVersion;
- /*!
- * [in] Flags defining the behavior of this frame capture.
- */
- uint32_t dwFlags;
- /*!
- * [out] Information about the captured frame.
- *
- * Can be NULL.
- */
- NVFBC_FRAME_GRAB_INFO *pFrameGrabInfo;
- /*!
- * [in] Wait timeout in milliseconds.
- *
- * When capturing frames with the NVFBC_TOSYS_GRAB_FLAGS_NOFLAGS or
- * NVFBC_TOSYS_GRAB_FLAGS_NOWAIT_IF_NEW_FRAME_READY flags,
- * NvFBC will wait for a new frame or mouse move until the below timer
- * expires.
- *
- * When timing out, the last captured frame will be returned. Note that as
- * long as the NVFBC_TOSYS_GRAB_FLAGS_FORCE_REFRESH flag is not set,
- * returning an old frame will incur no performance penalty.
- *
- * NvFBC clients can use the return value of the grab frame operation to
- * find out whether a new frame was captured, or the timer expired.
- *
- * Note that the behavior of blocking calls is to wait for a new frame
- * *after* the call has been made. When using timeouts, it is possible
- * that NvFBC will return a new frame (e.g., it has never been captured
- * before) even though no new frame was generated after the grab call.
- *
- * For the precise definition of what constitutes a new frame, see
- * ::bIsNewFrame.
- *
- * Set to 0 to disable timeouts.
- */
- uint32_t dwTimeoutMs;
-} NVFBC_TOSYS_GRAB_FRAME_PARAMS;
-
-/*!
- * NVFBC_TOSYS_GRAB_FRAME_PARAMS structure version.
- */
-#define NVFBC_TOSYS_GRAB_FRAME_PARAMS_VER NVFBC_STRUCT_VERSION(NVFBC_TOSYS_GRAB_FRAME_PARAMS, 2)
-
-/*!
- * Defines flags that can be used when capturing to a CUDA buffer in video memory.
- */
-typedef enum
-{
- /*!
- * Default, capturing waits for a new frame or mouse move.
- *
- * The default behavior of blocking grabs is to wait for a new frame until
- * after the call was made. But it's possible that there is a frame already
- * ready that the client hasn't seen.
- * \see NVFBC_TOCUDA_GRAB_FLAGS_NOWAIT_IF_NEW_FRAME_READY
- */
- NVFBC_TOCUDA_GRAB_FLAGS_NOFLAGS = 0,
- /*!
- * Capturing does not wait for a new frame nor a mouse move.
- *
- * It is therefore possible to capture the same frame multiple times.
- * When this occurs, the dwCurrentFrame parameter of the
- * NVFBC_FRAME_GRAB_INFO structure is not incremented.
- */
- NVFBC_TOCUDA_GRAB_FLAGS_NOWAIT = (1 << 0),
- /*!
- * [in] Forces the destination buffer to be refreshed even if the frame
- * has not changed since previous capture.
- *
- * By default, if the captured frame is identical to the previous one, NvFBC
- * will omit one copy and not update the destination buffer.
- *
- * Setting that flag will prevent this behavior. This can be useful e.g.,
- * if the application has modified the buffer in the meantime.
- */
- NVFBC_TOCUDA_GRAB_FLAGS_FORCE_REFRESH = (1 << 1),
- /*!
- * Similar to NVFBC_TOCUDA_GRAB_FLAGS_NOFLAGS, except that the capture will
- * not wait if there is already a frame available that the client has
- * never seen yet.
- */
- NVFBC_TOCUDA_GRAB_FLAGS_NOWAIT_IF_NEW_FRAME_READY = (1 << 2),
-} NVFBC_TOCUDA_FLAGS;
-
-/*!
- * Defines parameters for the ::NvFBCToCudaSetUp() API call.
- */
-typedef struct _NVFBC_TOCUDA_SETUP_PARAMS
-{
- /*!
- * [in] Must be set to NVFBC_TOCUDA_SETUP_PARAMS_VER
- */
- uint32_t dwVersion;
- /*!
- * [in] Desired buffer format.
- */
- NVFBC_BUFFER_FORMAT eBufferFormat;
-} NVFBC_TOCUDA_SETUP_PARAMS;
-
-/*!
- * NVFBC_TOCUDA_SETUP_PARAMS structure version.
- */
-#define NVFBC_TOCUDA_SETUP_PARAMS_VER NVFBC_STRUCT_VERSION(NVFBC_TOCUDA_SETUP_PARAMS, 1)
-
-/*!
- * Defines parameters for the ::NvFBCToCudaGrabFrame() API call.
- */
-typedef struct _NVFBC_TOCUDA_GRAB_FRAME_PARAMS
-{
- /*!
- * [in] Must be set to NVFBC_TOCUDA_GRAB_FRAME_PARAMS_VER.
- */
- uint32_t dwVersion;
- /*!
- * [in] Flags defining the behavior of this frame capture.
- */
- uint32_t dwFlags;
- /*!
- * [out] Pointer to a ::CUdeviceptr
- *
- * The application does not need to allocate memory for this CUDA device.
- *
- * The application does need to create its own CUDA context to use this
- * CUDA device.
- *
- * This ::CUdeviceptr will be mapped to a segment in video memory containing
- * the frame. It is not possible to process a CUDA device while capturing
- * a new frame. If the application wants to do so, it must copy the CUDA
- * device using ::cuMemcpyDtoD or ::cuMemcpyDtoH beforehand.
- */
- void *pCUDADeviceBuffer;
- /*!
- * [out] Information about the captured frame.
- *
- * Can be NULL.
- */
- NVFBC_FRAME_GRAB_INFO *pFrameGrabInfo;
- /*!
- * [in] Wait timeout in milliseconds.
- *
- * When capturing frames with the NVFBC_TOCUDA_GRAB_FLAGS_NOFLAGS or
- * NVFBC_TOCUDA_GRAB_FLAGS_NOWAIT_IF_NEW_FRAME_READY flags,
- * NvFBC will wait for a new frame or mouse move until the below timer
- * expires.
- *
- * When timing out, the last captured frame will be returned. Note that as
- * long as the NVFBC_TOCUDA_GRAB_FLAGS_FORCE_REFRESH flag is not set,
- * returning an old frame will incur no performance penalty.
- *
- * NvFBC clients can use the return value of the grab frame operation to
- * find out whether a new frame was captured, or the timer expired.
- *
- * Note that the behavior of blocking calls is to wait for a new frame
- * *after* the call has been made. When using timeouts, it is possible
- * that NvFBC will return a new frame (e.g., it has never been captured
- * before) even though no new frame was generated after the grab call.
- *
- * For the precise definition of what constitutes a new frame, see
- * ::bIsNewFrame.
- *
- * Set to 0 to disable timeouts.
- */
- uint32_t dwTimeoutMs;
-} NVFBC_TOCUDA_GRAB_FRAME_PARAMS;
-
-/*!
- * NVFBC_TOCUDA_GRAB_FRAME_PARAMS structure version.
- */
-#define NVFBC_TOCUDA_GRAB_FRAME_PARAMS_VER NVFBC_STRUCT_VERSION(NVFBC_TOCUDA_GRAB_FRAME_PARAMS, 2)
-
-/*!
- * Defines flags that can be used when capturing to an OpenGL buffer in video memory.
- */
-typedef enum
-{
- /*!
- * Default, capturing waits for a new frame or mouse move.
- *
- * The default behavior of blocking grabs is to wait for a new frame until
- * after the call was made. But it's possible that there is a frame already
- * ready that the client hasn't seen.
- * \see NVFBC_TOGL_GRAB_FLAGS_NOWAIT_IF_NEW_FRAME_READY
- */
- NVFBC_TOGL_GRAB_FLAGS_NOFLAGS = 0,
- /*!
- * Capturing does not wait for a new frame nor a mouse move.
- *
- * It is therefore possible to capture the same frame multiple times.
- * When this occurs, the dwCurrentFrame parameter of the
- * NVFBC_FRAME_GRAB_INFO structure is not incremented.
- */
- NVFBC_TOGL_GRAB_FLAGS_NOWAIT = (1 << 0),
- /*!
- * [in] Forces the destination buffer to be refreshed even if the frame
- * has not changed since previous capture.
- *
- * By default, if the captured frame is identical to the previous one, NvFBC
- * will omit one copy and not update the destination buffer.
- *
- * Setting that flag will prevent this behavior. This can be useful e.g.,
- * if the application has modified the buffer in the meantime.
- */
- NVFBC_TOGL_GRAB_FLAGS_FORCE_REFRESH = (1 << 1),
- /*!
- * Similar to NVFBC_TOGL_GRAB_FLAGS_NOFLAGS, except that the capture will
- * not wait if there is already a frame available that the client has
- * never seen yet.
- */
- NVFBC_TOGL_GRAB_FLAGS_NOWAIT_IF_NEW_FRAME_READY = (1 << 2),
-} NVFBC_TOGL_FLAGS;
-
-/*!
- * Maximum number of GL textures that can be used to store frames.
- */
-#define NVFBC_TOGL_TEXTURES_MAX 2
-
-/*!
- * Defines parameters for the ::NvFBCToGLSetUp() API call.
- */
-typedef struct _NVFBC_TOGL_SETUP_PARAMS
-{
- /*!
- * [in] Must be set to NVFBC_TOGL_SETUP_PARAMS_VER
- */
- uint32_t dwVersion;
- /*!
- * [in] Desired buffer format.
- */
- NVFBC_BUFFER_FORMAT eBufferFormat;
- /*!
- * [in] Whether differential maps should be generated.
- */
- NVFBC_BOOL bWithDiffMap;
- /*!
- * [out] Pointer to a pointer to a buffer in system memory.
- *
- * \see NVFBC_TOSYS_SETUP_PARAMS::ppDiffMap
- */
- void **ppDiffMap;
- /*!
- * [in] Scaling factor of the differential maps.
- *
- * \see NVFBC_TOSYS_SETUP_PARAMS::dwDiffMapScalingFactor
- */
- uint32_t dwDiffMapScalingFactor;
- /*!
- * [out] List of GL textures that will store the captured frames.
- *
- * This array is 0 terminated. The number of textures varies depending on
- * the capture settings (such as whether diffmaps are enabled).
- *
- * An application wishing to interop with, for example, EncodeAPI will need
- * to register these textures prior to start encoding frames.
- *
- * After each frame capture, the texture holding the current frame will be
- * returned in NVFBC_TOGL_GRAB_FRAME_PARAMS::dwTexture.
- */
- uint32_t dwTextures[NVFBC_TOGL_TEXTURES_MAX];
- /*!
- * [out] GL target to which the texture should be bound.
- */
- uint32_t dwTexTarget;
- /*!
- * [out] GL format of the textures.
- */
- uint32_t dwTexFormat;
- /*!
- * [out] GL type of the textures.
- */
- uint32_t dwTexType;
- /*!
- * [out] Size of the differential map.
- *
- * Only set if bWithDiffMap is set to NVFBC_TRUE.
- */
- NVFBC_SIZE diffMapSize;
-} NVFBC_TOGL_SETUP_PARAMS;
-
-/*!
- * NVFBC_TOGL_SETUP_PARAMS structure version.
- */
-#define NVFBC_TOGL_SETUP_PARAMS_VER NVFBC_STRUCT_VERSION(NVFBC_TOGL_SETUP_PARAMS, 2)
-
-/*!
- * Defines parameters for the ::NvFBCToGLGrabFrame() API call.
- */
-typedef struct _NVFBC_TOGL_GRAB_FRAME_PARAMS
-{
- /*!
- * [in] Must be set to NVFBC_TOGL_GRAB_FRAME_PARAMS_VER.
- */
- uint32_t dwVersion;
- /*!
- * [in] Flags defining the behavior of this frame capture.
- */
- uint32_t dwFlags;
- /*!
- * [out] Index of the texture storing the current frame.
- *
- * This is an index in the NVFBC_TOGL_SETUP_PARAMS::dwTextures array.
- */
- uint32_t dwTextureIndex;
- /*!
- * [out] Information about the captured frame.
- *
- * Can be NULL.
- */
- NVFBC_FRAME_GRAB_INFO *pFrameGrabInfo;
- /*!
- * [in] Wait timeout in milliseconds.
- *
- * When capturing frames with the NVFBC_TOGL_GRAB_FLAGS_NOFLAGS or
- * NVFBC_TOGL_GRAB_FLAGS_NOWAIT_IF_NEW_FRAME_READY flags,
- * NvFBC will wait for a new frame or mouse move until the below timer
- * expires.
- *
- * When timing out, the last captured frame will be returned. Note that as
- * long as the NVFBC_TOGL_GRAB_FLAGS_FORCE_REFRESH flag is not set,
- * returning an old frame will incur no performance penalty.
- *
- * NvFBC clients can use the return value of the grab frame operation to
- * find out whether a new frame was captured, or the timer expired.
- *
- * Note that the behavior of blocking calls is to wait for a new frame
- * *after* the call has been made. When using timeouts, it is possible
- * that NvFBC will return a new frame (e.g., it has never been captured
- * before) even though no new frame was generated after the grab call.
- *
- * For the precise definition of what constitutes a new frame, see
- * ::bIsNewFrame.
- *
- * Set to 0 to disable timeouts.
- */
- uint32_t dwTimeoutMs;
-} NVFBC_TOGL_GRAB_FRAME_PARAMS;
-
-/*!
- * NVFBC_TOGL_GRAB_FRAME_PARAMS structure version.
- */
-#define NVFBC_TOGL_GRAB_FRAME_PARAMS_VER NVFBC_STRUCT_VERSION(NVFBC_TOGL_GRAB_FRAME_PARAMS, 2)
-
-/*! @} FBC_STRUCT */
-
-/*!
- * \defgroup FBC_FUNC API Entry Points
- *
- * Entry points are thread-safe and can be called concurrently.
- *
- * The locking model includes a global lock that protects session handle
- * management (\see NvFBCCreateHandle, \see NvFBCDestroyHandle).
- *
- * Each NvFBC session uses a local lock to protect other entry points. Note
- * that in certain cases, a thread can hold the local lock for an undefined
- * amount of time, such as grabbing a frame using a blocking call.
- *
- * Note that a context is associated with each session. NvFBC clients wishing
- * to share a session between different threads are expected to release and
- * bind the context appropriately (\see NvFBCBindContext,
- * \see NvFBCReleaseContext). This is not required when each thread uses its
- * own NvFBC session.
- *
- * @{
- */
-
-/*!
- * Gets the last error message that got recorded for a client.
- *
- * When NvFBC returns an error, it will save an error message that can be
- * queried through this API call. Only the last message is saved.
- * The message and the return code should give enough information about
- * what went wrong.
- *
- * \param [in] sessionHandle
- * Handle to the NvFBC client.
- * \return
- * A NULL terminated error message, or an empty string. Its maximum length
- * is NVFBC_ERROR_STR_LEN.
- */
-const char* NVFBCAPI NvFBCGetLastErrorStr(const NVFBC_SESSION_HANDLE sessionHandle);
-
-/*!
- * \brief Allocates a new handle for an NvFBC client.
- *
- * This function allocates a session handle used to identify an FBC client.
- *
- * This function implicitly calls NvFBCBindContext().
- *
- * \param [out] pSessionHandle
- * Pointer that will hold the allocated session handle.
- * \param [in] pParams
- * ::NVFBC_CREATE_HANDLE_PARAMS
- *
- * \return
- * ::NVFBC_SUCCESS \n
- * ::NVFBC_ERR_INVALID_PTR \n
- * ::NVFBC_ERR_API_VERSION \n
- * ::NVFBC_ERR_INTERNAL \n
- * ::NVFBC_ERR_OUT_OF_MEMORY \n
- * ::NVFBC_ERR_MAX_CLIENTS \n
- * ::NVFBC_ERR_X \n
- * ::NVFBC_ERR_GLX \n
- * ::NVFBC_ERR_GL
- *
- */
-NVFBCSTATUS NVFBCAPI NvFBCCreateHandle(NVFBC_SESSION_HANDLE *pSessionHandle, NVFBC_CREATE_HANDLE_PARAMS *pParams);
-
-/*!
- * \brief Destroys the handle of an NvFBC client.
- *
- * This function uninitializes an FBC client.
- *
- * This function implicitly calls NvFBCReleaseContext().
- *
- * After this fucntion returns, it is not possible to use this session handle
- * for any further API call.
- *
- * \param [in] sessionHandle
- * FBC session handle.
- * \param [in] pParams
- * ::NVFBC_DESTROY_HANDLE_PARAMS
- *
- * \return
- * ::NVFBC_SUCCESS \n
- * ::NVFBC_ERR_INVALID_HANDLE \n
- * ::NVFBC_ERR_API_VERSION \n
- * ::NVFBC_ERR_BAD_REQUEST \n
- * ::NVFBC_ERR_INTERNAL \n
- * ::NVFBC_ERR_CONTEXT \n
- * ::NVFBC_ERR_X
- */
-NVFBCSTATUS NVFBCAPI NvFBCDestroyHandle(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_DESTROY_HANDLE_PARAMS *pParams);
-
-/*!
- * \brief Gets the current status of the display driver.
- *
- * This function queries the display driver for various information.
- *
- * \param [in] sessionHandle
- * FBC session handle.
- * \param [in] pParams
- * ::NVFBC_GET_STATUS_PARAMS
- *
- * \return
- * ::NVFBC_SUCCESS \n
- * ::NVFBC_ERR_INVALID_HANDLE \n
- * ::NVFBC_ERR_API_VERSION \n
- * ::NVFBC_ERR_INTERNAL \n
- * ::NVFBC_ERR_X
- */
-NVFBCSTATUS NVFBCAPI NvFBCGetStatus(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_GET_STATUS_PARAMS *pParams);
-
-/*!
- * \brief Binds the FBC context to the calling thread.
- *
- * The NvFBC library internally relies on objects that must be bound to a
- * thread. Such objects are OpenGL contexts and CUDA contexts.
- *
- * This function binds these objects to the calling thread.
- *
- * The FBC context must be bound to the calling thread for most NvFBC entry
- * points, otherwise ::NVFBC_ERR_CONTEXT is returned.
- *
- * If the FBC context is already bound to a different thread,
- * ::NVFBC_ERR_CONTEXT is returned. The other thread must release the context
- * first by calling the ReleaseContext() entry point.
- *
- * If the FBC context is already bound to the current thread, this function has
- * no effects.
- *
- * \param [in] sessionHandle
- * FBC session handle.
- * \param [in] pParams
- * ::NVFBC_DESTROY_CAPTURE_SESSION_PARAMS
- *
- * \return
- * ::NVFBC_SUCCESS \n
- * ::NVFBC_ERR_INVALID_HANDLE \n
- * ::NVFBC_ERR_API_VERSION \n
- * ::NVFBC_ERR_BAD_REQUEST \n
- * ::NVFBC_ERR_CONTEXT \n
- * ::NVFBC_ERR_INTERNAL \n
- * ::NVFBC_ERR_X
- */
-NVFBCSTATUS NVFBCAPI NvFBCBindContext(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_BIND_CONTEXT_PARAMS *pParams);
-
-/*!
- * \brief Releases the FBC context from the calling thread.
- *
- * If the FBC context is bound to a different thread, ::NVFBC_ERR_CONTEXT is
- * returned.
- *
- * If the FBC context is already released, this functino has no effects.
- *
- * \param [in] sessionHandle
- * FBC session handle.
- * \param [in] pParams
- * ::NVFBC_SUCCESS \n
- * ::NVFBC_ERR_INVALID_HANDLE \n
- * ::NVFBC_ERR_API_VERSION \n
- * ::NVFBC_ERR_BAD_REQUEST \n
- * ::NVFBC_ERR_CONTEXT \n
- * ::NVFBC_ERR_INTERNAL \n
- * ::NVFBC_ERR_X
- */
-NVFBCSTATUS NVFBCAPI NvFBCReleaseContext(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_RELEASE_CONTEXT_PARAMS *pParams);
-
-/*!
- * \brief Creates a capture session for an FBC client.
- *
- * This function starts a capture session of the desired type (system memory,
- * video memory with CUDA interop, or H.264 compressed frames in system memory).
- *
- * Not all types are supported on all systems. Also, it is possible to use
- * NvFBC without having the CUDA library. In this case, requesting a capture
- * session of the concerned type will return an error.
- *
- * After this function returns, the display driver will start generating frames
- * that can be captured using the corresponding API call.
- *
- * \param [in] sessionHandle
- * FBC session handle.
- * \param [in] pParams
- * ::NVFBC_CREATE_CAPTURE_SESSION_PARAMS
- *
- * \return
- * ::NVFBC_SUCCESS \n
- * ::NVFBC_ERR_INVALID_HANDLE \n
- * ::NVFBC_ERR_API_VERSION \n
- * ::NVFBC_ERR_BAD_REQUEST \n
- * ::NVFBC_ERR_CONTEXT \n
- * ::NVFBC_ERR_INVALID_PARAM \n
- * ::NVFBC_ERR_OUT_OF_MEMORY \n
- * ::NVFBC_ERR_X \n
- * ::NVFBC_ERR_GLX \n
- * ::NVFBC_ERR_GL \n
- * ::NVFBC_ERR_CUDA \n
- * ::NVFBC_ERR_MUST_RECREATE \n
- * ::NVFBC_ERR_INTERNAL
- */
-NVFBCSTATUS NVFBCAPI NvFBCCreateCaptureSession(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_CREATE_CAPTURE_SESSION_PARAMS *pParams);
-
-/*!
- * \brief Destroys a capture session for an FBC client.
- *
- * This function stops a capture session and frees allocated objects.
- *
- * After this function returns, it is possible to create another capture
- * session using the corresponding API call.
- *
- * \param [in] sessionHandle
- * FBC session handle.
- * \param [in] pParams
- * ::NVFBC_DESTROY_CAPTURE_SESSION_PARAMS
- *
- * \return
- * ::NVFBC_SUCCESS \n
- * ::NVFBC_ERR_INVALID_HANDLE \n
- * ::NVFBC_ERR_API_VERSION \n
- * ::NVFBC_ERR_BAD_REQUEST \n
- * ::NVFBC_ERR_CONTEXT \n
- * ::NVFBC_ERR_INTERNAL \n
- * ::NVFBC_ERR_X
- */
-NVFBCSTATUS NVFBCAPI NvFBCDestroyCaptureSession(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_DESTROY_CAPTURE_SESSION_PARAMS *pParams);
-
-/*!
- * \brief Sets up a capture to system memory session.
- *
- * This function configures how the capture to system memory should behave. It
- * can be called anytime and several times after the capture session has been
- * created. However, it must be called at least once prior to start capturing
- * frames.
- *
- * This function allocates the buffer that will contain the captured frame.
- * The application does not need to free this buffer. The size of this buffer
- * is returned in the ::NVFBC_FRAME_GRAB_INFO structure.
- *
- * \param [in] sessionHandle
- * FBC session handle.
- * \param [in] pParams
- * ::NVFBC_TOSYS_SETUP_PARAMS
- *
- * \return
- * ::NVFBC_SUCCESS \n
- * ::NVFBC_ERR_INVALID_HANDLE \n
- * ::NVFBC_ERR_API_VERSION \n
- * ::NVFBC_ERR_BAD_REQUEST \n
- * ::NVFBC_ERR_INTERNAL \n
- * ::NVFBC_ERR_CONTEXT \n
- * ::NVFBC_ERR_UNSUPPORTED \n
- * ::NVFBC_ERR_INVALID_PTR \n
- * ::NVFBC_ERR_INVALID_PARAM \n
- * ::NVFBC_ERR_OUT_OF_MEMORY \n
- * ::NVFBC_ERR_X
- */
-NVFBCSTATUS NVFBCAPI NvFBCToSysSetUp(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_TOSYS_SETUP_PARAMS *pParams);
-
-/*!
- * \brief Captures a frame to a buffer in system memory.
- *
- * This function triggers a frame capture to a buffer in system memory that was
- * registered with the ToSysSetUp() API call.
- *
- * Note that it is possible that the resolution of the desktop changes while
- * capturing frames. This should be transparent for the application.
- *
- * When the resolution changes, the capture session is recreated using the same
- * parameters, and necessary buffers are re-allocated. The frame counter is not
- * reset.
- *
- * An application can detect that the resolution changed by comparing the
- * dwByteSize member of the ::NVFBC_FRAME_GRAB_INFO against a previous
- * frame and/or dwWidth and dwHeight.
- *
- * During a change of resolution the capture is paused even in asynchronous
- * mode.
- *
- * \param [in] sessionHandle
- * FBC session handle.
- * \param [in] pParams
- * ::NVFBC_TOSYS_GRAB_FRAME_PARAMS
- *
- * \return
- * ::NVFBC_SUCCESS \n
- * ::NVFBC_ERR_INVALID_HANDLE \n
- * ::NVFBC_ERR_API_VERSION \n
- * ::NVFBC_ERR_BAD_REQUEST \n
- * ::NVFBC_ERR_CONTEXT \n
- * ::NVFBC_ERR_INVALID_PTR \n
- * ::NVFBC_ERR_INTERNAL \n
- * ::NVFBC_ERR_X \n
- * ::NVFBC_ERR_MUST_RECREATE \n
- * \see NvFBCCreateCaptureSession \n
- * \see NvFBCToSysSetUp
- */
-NVFBCSTATUS NVFBCAPI NvFBCToSysGrabFrame(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_TOSYS_GRAB_FRAME_PARAMS *pParams);
-
-/*!
- * \brief Sets up a capture to video memory session.
- *
- * This function configures how the capture to video memory with CUDA interop
- * should behave. It can be called anytime and several times after the capture
- * session has been created. However, it must be called at least once prior
- * to start capturing frames.
- *
- * \param [in] sessionHandle
- * FBC session handle.
- *
- * \param [in] pParams
- * ::NVFBC_TOCUDA_SETUP_PARAMS
- *
- * \return
- * ::NVFBC_SUCCESS \n
- * ::NVFBC_ERR_INVALID_HANDLE \n
- * ::NVFBC_ERR_API_VERSION \n
- * ::NVFBC_ERR_BAD_REQUEST \n
- * ::NVFBC_ERR_INTERNAL \n
- * ::NVFBC_ERR_CONTEXT \n
- * ::NVFBC_ERR_UNSUPPORTED \n
- * ::NVFBC_ERR_GL \n
- * ::NVFBC_ERR_X
- */
-NVFBCSTATUS NVFBCAPI NvFBCToCudaSetUp(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_TOCUDA_SETUP_PARAMS *pParams);
-
-/*!
- * \brief Captures a frame to a CUDA device in video memory.
- *
- * This function triggers a frame capture to a CUDA device in video memory.
- *
- * Note about changes of resolution: \see NvFBCToSysGrabFrame
- *
- * \param [in] sessionHandle
- * FBC session handle.
- *
- * \param [in] pParams
- * ::NVFBC_TOCUDA_GRAB_FRAME_PARAMS
- *
- * \return
- * ::NVFBC_SUCCESS \n
- * ::NVFBC_ERR_INVALID_HANDLE \n
- * ::NVFBC_ERR_API_VERSION \n
- * ::NVFBC_ERR_BAD_REQUEST \n
- * ::NVFBC_ERR_CONTEXT \n
- * ::NVFBC_ERR_INVALID_PTR \n
- * ::NVFBC_ERR_CUDA \n
- * ::NVFBC_ERR_INTERNAL \n
- * ::NVFBC_ERR_X \n
- * ::NVFBC_ERR_MUST_RECREATE \n
- * \see NvFBCCreateCaptureSession \n
- * \see NvFBCToCudaSetUp
- */
-NVFBCSTATUS NVFBCAPI NvFBCToCudaGrabFrame(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_TOCUDA_GRAB_FRAME_PARAMS *pParams);
-
-/*!
- * \brief Sets up a capture to OpenGL buffer in video memory session.
- *
- * This function configures how the capture to video memory should behave.
- * It can be called anytime and several times after the capture session has been
- * created. However, it must be called at least once prior to start capturing
- * frames.
- *
- * \param [in] sessionHandle
- * FBC session handle.
- *
- * \param [in] pParams
- * ::NVFBC_TOGL_SETUP_PARAMS
- *
- * \return
- * ::NVFBC_SUCCESS \n
- * ::NVFBC_ERR_INVALID_HANDLE \n
- * ::NVFBC_ERR_API_VERSION \n
- * ::NVFBC_ERR_BAD_REQUEST \n
- * ::NVFBC_ERR_INTERNAL \n
- * ::NVFBC_ERR_CONTEXT \n
- * ::NVFBC_ERR_UNSUPPORTED \n
- * ::NVFBC_ERR_GL \n
- * ::NVFBC_ERR_X
- */
-NVFBCSTATUS NVFBCAPI NvFBCToGLSetUp(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_TOGL_SETUP_PARAMS *pParams);
-
-/*!
- * \brief Captures a frame to an OpenGL buffer in video memory.
- *
- * This function triggers a frame capture to a selected resource in video memory.
- *
- * Note about changes of resolution: \see NvFBCToSysGrabFrame
- *
- * \param [in] sessionHandle
- * FBC session handle.
- *
- * \param [in] pParams
- * ::NVFBC_TOGL_GRAB_FRAME_PARAMS
- *
- * \return
- * ::NVFBC_SUCCESS \n
- * ::NVFBC_ERR_INVALID_HANDLE \n
- * ::NVFBC_ERR_API_VERSION \n
- * ::NVFBC_ERR_BAD_REQUEST \n
- * ::NVFBC_ERR_CONTEXT \n
- * ::NVFBC_ERR_INVALID_PTR \n
- * ::NVFBC_ERR_INTERNAL \n
- * ::NVFBC_ERR_X \n
- * ::NVFBC_ERR_MUST_RECREATE \n
- * \see NvFBCCreateCaptureSession \n
- * \see NvFBCToCudaSetUp
- */
-NVFBCSTATUS NVFBCAPI NvFBCToGLGrabFrame(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_TOGL_GRAB_FRAME_PARAMS *pParams);
-
-/*!
- * \cond FBC_PFN
- *
- * Defines API function pointers
- */
-typedef const char* (NVFBCAPI* PNVFBCGETLASTERRORSTR)(const NVFBC_SESSION_HANDLE sessionHandle);
-typedef NVFBCSTATUS (NVFBCAPI* PNVFBCCREATEHANDLE)(NVFBC_SESSION_HANDLE *pSessionHandle, NVFBC_CREATE_HANDLE_PARAMS *pParams);
-typedef NVFBCSTATUS (NVFBCAPI* PNVFBCDESTROYHANDLE)(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_DESTROY_HANDLE_PARAMS *pParams);
-typedef NVFBCSTATUS (NVFBCAPI* PNVFBCBINDCONTEXT)(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_BIND_CONTEXT_PARAMS *pParams);
-typedef NVFBCSTATUS (NVFBCAPI* PNVFBCRELEASECONTEXT)(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_RELEASE_CONTEXT_PARAMS *pParams);
-typedef NVFBCSTATUS (NVFBCAPI* PNVFBCGETSTATUS)(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_GET_STATUS_PARAMS *pParams);
-typedef NVFBCSTATUS (NVFBCAPI* PNVFBCCREATECAPTURESESSION)(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_CREATE_CAPTURE_SESSION_PARAMS *pParams);
-typedef NVFBCSTATUS (NVFBCAPI* PNVFBCDESTROYCAPTURESESSION)(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_DESTROY_CAPTURE_SESSION_PARAMS *pParams);
-typedef NVFBCSTATUS (NVFBCAPI* PNVFBCTOSYSSETUP)(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_TOSYS_SETUP_PARAMS *pParams);
-typedef NVFBCSTATUS (NVFBCAPI* PNVFBCTOSYSGRABFRAME)(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_TOSYS_GRAB_FRAME_PARAMS *pParams);
-typedef NVFBCSTATUS (NVFBCAPI* PNVFBCTOCUDASETUP)(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_TOCUDA_SETUP_PARAMS *pParams);
-typedef NVFBCSTATUS (NVFBCAPI* PNVFBCTOCUDAGRABFRAME)(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_TOCUDA_GRAB_FRAME_PARAMS *pParams);
-typedef NVFBCSTATUS (NVFBCAPI* PNVFBCTOGLSETUP)(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_TOGL_SETUP_PARAMS *pParams);
-typedef NVFBCSTATUS (NVFBCAPI* PNVFBCTOGLGRABFRAME)(const NVFBC_SESSION_HANDLE sessionHandle, NVFBC_TOGL_GRAB_FRAME_PARAMS *pParams);
-
-/// \endcond
-
-/*! @} FBC_FUNC */
-
-/*!
- * \ingroup FBC_STRUCT
- *
- * Structure populated with API function pointers.
- */
-typedef struct
-{
- uint32_t dwVersion; //!< [in] Must be set to NVFBC_VERSION.
- PNVFBCGETLASTERRORSTR nvFBCGetLastErrorStr; //!< [out] Pointer to ::NvFBCGetLastErrorStr().
- PNVFBCCREATEHANDLE nvFBCCreateHandle; //!< [out] Pointer to ::NvFBCCreateHandle().
- PNVFBCDESTROYHANDLE nvFBCDestroyHandle; //!< [out] Pointer to ::NvFBCDestroyHandle().
- PNVFBCGETSTATUS nvFBCGetStatus; //!< [out] Pointer to ::NvFBCGetStatus().
- PNVFBCCREATECAPTURESESSION nvFBCCreateCaptureSession; //!< [out] Pointer to ::NvFBCCreateCaptureSession().
- PNVFBCDESTROYCAPTURESESSION nvFBCDestroyCaptureSession; //!< [out] Pointer to ::NvFBCDestroyCaptureSession().
- PNVFBCTOSYSSETUP nvFBCToSysSetUp; //!< [out] Pointer to ::NvFBCToSysSetUp().
- PNVFBCTOSYSGRABFRAME nvFBCToSysGrabFrame; //!< [out] Pointer to ::NvFBCToSysGrabFrame().
- PNVFBCTOCUDASETUP nvFBCToCudaSetUp; //!< [out] Pointer to ::NvFBCToCudaSetUp().
- PNVFBCTOCUDAGRABFRAME nvFBCToCudaGrabFrame; //!< [out] Pointer to ::NvFBCToCudaGrabFrame().
- void* pad1; //!< [out] Retired. Do not use.
- void* pad2; //!< [out] Retired. Do not use.
- void* pad3; //!< [out] Retired. Do not use.
- PNVFBCBINDCONTEXT nvFBCBindContext; //!< [out] Pointer to ::NvFBCBindContext().
- PNVFBCRELEASECONTEXT nvFBCReleaseContext; //!< [out] Pointer to ::NvFBCReleaseContext().
- void* pad4; //!< [out] Retired. Do not use.
- void* pad5; //!< [out] Retired. Do not use.
- void* pad6; //!< [out] Retired. Do not use.
- void* pad7; //!< [out] Retired. Do not use.
- PNVFBCTOGLSETUP nvFBCToGLSetUp; //!< [out] Pointer to ::nvFBCToGLSetup().
- PNVFBCTOGLGRABFRAME nvFBCToGLGrabFrame; //!< [out] Pointer to ::nvFBCToGLGrabFrame().
-} NVFBC_API_FUNCTION_LIST;
-
-/*!
- * \ingroup FBC_FUNC
- *
- * \brief Entry Points to the NvFBC interface.
- *
- * Creates an instance of the NvFBC interface, and populates the
- * pFunctionList with function pointers to the API routines implemented by
- * the NvFBC interface.
- *
- * \param [out] pFunctionList
- *
- * \return
- * ::NVFBC_SUCCESS \n
- * ::NVFBC_ERR_INVALID_PTR \n
- * ::NVFBC_ERR_API_VERSION
- */
-NVFBCSTATUS NVFBCAPI NvFBCCreateInstance(NVFBC_API_FUNCTION_LIST *pFunctionList);
-/*!
- * \ingroup FBC_FUNC
- *
- * Defines function pointer for the ::NvFBCCreateInstance() API call.
- */
-typedef NVFBCSTATUS (NVFBCAPI* PNVFBCCREATEINSTANCE)(NVFBC_API_FUNCTION_LIST *pFunctionList);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // _NVFBC_H_
diff --git a/include/NvFBCLibrary.hpp b/include/NvFBCLibrary.hpp
deleted file mode 100644
index 6d115a4..0000000
--- a/include/NvFBCLibrary.hpp
+++ /dev/null
@@ -1,246 +0,0 @@
-#pragma once
-
-#include "NvFBC.h"
-#include <cuda.h>
-
-#include <dlfcn.h>
-#include <string.h>
-#include <stdio.h>
-
-class NvFBCLibrary {
-public:
- ~NvFBCLibrary() {
- if(fbc_handle_created) {
- NVFBC_DESTROY_CAPTURE_SESSION_PARAMS destroy_capture_params;
- memset(&destroy_capture_params, 0, sizeof(destroy_capture_params));
- destroy_capture_params.dwVersion = NVFBC_DESTROY_CAPTURE_SESSION_PARAMS_VER;
- nv_fbc_function_list.nvFBCDestroyCaptureSession(nv_fbc_handle, &destroy_capture_params);
-
- NVFBC_DESTROY_HANDLE_PARAMS destroy_params;
- memset(&destroy_params, 0, sizeof(destroy_params));
- destroy_params.dwVersion = NVFBC_DESTROY_HANDLE_PARAMS_VER;
- nv_fbc_function_list.nvFBCDestroyHandle(nv_fbc_handle, &destroy_params);
- }
-
- if(library)
- dlclose(library);
- }
-
- bool load() {
- if(library)
- return true;
-
- dlerror(); // clear
- void *lib = dlopen("libnvidia-fbc.so.1", RTLD_NOW);
- if(!lib) {
- fprintf(stderr, "Error: failed to load libnvidia-fbc.so.1, error: %s\n", dlerror());
- return false;
- }
-
- nv_fbc_create_instance = (PNVFBCCREATEINSTANCE)dlsym(lib, "NvFBCCreateInstance");
- if(!nv_fbc_create_instance) {
- fprintf(stderr, "Error: unable to resolve symbol 'NvFBCCreateInstance'\n");
- dlclose(lib);
- return false;
- }
-
- memset(&nv_fbc_function_list, 0, sizeof(nv_fbc_function_list));
- nv_fbc_function_list.dwVersion = NVFBC_VERSION;
- NVFBCSTATUS status = nv_fbc_create_instance(&nv_fbc_function_list);
- if(status != NVFBC_SUCCESS) {
- fprintf(stderr, "Error: failed to create NvFBC instance (status: %d)\n", status);
- dlclose(lib);
- return false;
- }
-
- library = lib;
- return true;
- }
-
- // If |display_to_capture| is "screen", then the entire x11 screen is captured (all displays)
- bool create(const char *display_to_capture, uint32_t fps, /*out*/ uint32_t *display_width, /*out*/ uint32_t *display_height, uint32_t x = 0, uint32_t y = 0, uint32_t width = 0, uint32_t height = 0, bool direct_capture = false) {
- if(!library || !display_to_capture || !display_width || !display_height || fbc_handle_created)
- return false;
-
- const bool capture_region = (x > 0 || y > 0 || width > 0 || height > 0);
-
- NVFBCSTATUS status;
- NVFBC_TRACKING_TYPE tracking_type;
- bool capture_session_created = false;
- uint32_t output_id = 0;
- fbc_handle_created = false;
-
- NVFBC_CREATE_HANDLE_PARAMS create_params;
- memset(&create_params, 0, sizeof(create_params));
- create_params.dwVersion = NVFBC_CREATE_HANDLE_PARAMS_VER;
-
- status = nv_fbc_function_list.nvFBCCreateHandle(&nv_fbc_handle, &create_params);
- if(status != NVFBC_SUCCESS) {
- fprintf(stderr, "Error: %s\n", nv_fbc_function_list.nvFBCGetLastErrorStr(nv_fbc_handle));
- return false;
- }
- fbc_handle_created = true;
-
- NVFBC_GET_STATUS_PARAMS status_params;
- memset(&status_params, 0, sizeof(status_params));
- status_params.dwVersion = NVFBC_GET_STATUS_PARAMS_VER;
-
- status = nv_fbc_function_list.nvFBCGetStatus(nv_fbc_handle, &status_params);
- if(status != NVFBC_SUCCESS) {
- fprintf(stderr, "Error: %s\n", nv_fbc_function_list.nvFBCGetLastErrorStr(nv_fbc_handle));
- goto error_cleanup;
- }
-
- if(status_params.bCanCreateNow == NVFBC_FALSE) {
- fprintf(stderr, "Error: it's not possible to create a capture session on this system\n");
- goto error_cleanup;
- }
-
- tracking_type = strcmp(display_to_capture, "screen") == 0 ? NVFBC_TRACKING_SCREEN : NVFBC_TRACKING_OUTPUT;
- if(tracking_type == NVFBC_TRACKING_OUTPUT) {
- if(!status_params.bXRandRAvailable) {
- fprintf(stderr, "Error: the xrandr extension is not available\n");
- goto error_cleanup;
- }
-
- if(status_params.bInModeset) {
- fprintf(stderr, "Error: the x server is in modeset, unable to record\n");
- goto error_cleanup;
- }
-
- output_id = get_output_id_from_display_name(status_params.outputs, status_params.dwOutputNum, display_to_capture, display_width, display_height);
- if(output_id == 0) {
- fprintf(stderr, "Error: display '%s' not found\n", display_to_capture);
- goto error_cleanup;
- }
- } else {
- *display_width = status_params.screenSize.w;
- *display_height = status_params.screenSize.h;
- }
-
- NVFBC_CREATE_CAPTURE_SESSION_PARAMS create_capture_params;
- memset(&create_capture_params, 0, sizeof(create_capture_params));
- create_capture_params.dwVersion = NVFBC_CREATE_CAPTURE_SESSION_PARAMS_VER;
- create_capture_params.eCaptureType = NVFBC_CAPTURE_SHARED_CUDA;
- create_capture_params.bWithCursor = direct_capture ? NVFBC_FALSE : NVFBC_TRUE;
- if(capture_region) {
- create_capture_params.captureBox = { x, y, width, height };
- *display_width = width;
- *display_height = height;
- }
- create_capture_params.eTrackingType = tracking_type;
- create_capture_params.dwSamplingRateMs = 1000 / fps;
- create_capture_params.bAllowDirectCapture = direct_capture ? NVFBC_TRUE : NVFBC_FALSE;
- create_capture_params.bPushModel = direct_capture ? NVFBC_TRUE : NVFBC_FALSE;
- if(tracking_type == NVFBC_TRACKING_OUTPUT)
- create_capture_params.dwOutputId = output_id;
-
- status = nv_fbc_function_list.nvFBCCreateCaptureSession(nv_fbc_handle, &create_capture_params);
- if(status != NVFBC_SUCCESS) {
- fprintf(stderr, "Error: %s\n", nv_fbc_function_list.nvFBCGetLastErrorStr(nv_fbc_handle));
- goto error_cleanup;
- }
- capture_session_created = true;
-
- NVFBC_TOCUDA_SETUP_PARAMS setup_params;
- memset(&setup_params, 0, sizeof(setup_params));
- setup_params.dwVersion = NVFBC_TOCUDA_SETUP_PARAMS_VER;
- setup_params.eBufferFormat = NVFBC_BUFFER_FORMAT_BGRA;
-
- status = nv_fbc_function_list.nvFBCToCudaSetUp(nv_fbc_handle, &setup_params);
- if(status != NVFBC_SUCCESS) {
- fprintf(stderr, "Error: %s\n", nv_fbc_function_list.nvFBCGetLastErrorStr(nv_fbc_handle));
- goto error_cleanup;
- }
-
- return true;
-
- error_cleanup:
- if(fbc_handle_created) {
- if(capture_session_created) {
- NVFBC_DESTROY_CAPTURE_SESSION_PARAMS destroy_capture_params;
- memset(&destroy_capture_params, 0, sizeof(destroy_capture_params));
- destroy_capture_params.dwVersion = NVFBC_DESTROY_CAPTURE_SESSION_PARAMS_VER;
- nv_fbc_function_list.nvFBCDestroyCaptureSession(nv_fbc_handle, &destroy_capture_params);
- }
-
- NVFBC_DESTROY_HANDLE_PARAMS destroy_params;
- memset(&destroy_params, 0, sizeof(destroy_params));
- destroy_params.dwVersion = NVFBC_DESTROY_HANDLE_PARAMS_VER;
- nv_fbc_function_list.nvFBCDestroyHandle(nv_fbc_handle, &destroy_params);
- fbc_handle_created = false;
- }
- output_id = 0;
- return false;
- }
-
- bool capture(/*out*/ CUdeviceptr *cu_device_ptr, uint32_t *byte_size) {
- if(!library || !fbc_handle_created || !cu_device_ptr || !byte_size)
- return false;
-
- NVFBCSTATUS status;
- NVFBC_FRAME_GRAB_INFO frame_info;
- memset(&frame_info, 0, sizeof(frame_info));
-
- NVFBC_TOCUDA_GRAB_FRAME_PARAMS grab_params;
- memset(&grab_params, 0, sizeof(grab_params));
- grab_params.dwVersion = NVFBC_TOCUDA_GRAB_FRAME_PARAMS_VER;
- grab_params.dwFlags = NVFBC_TOCUDA_GRAB_FLAGS_NOWAIT;
- grab_params.pFrameGrabInfo = &frame_info;
- grab_params.pCUDADeviceBuffer = cu_device_ptr;
-
- status = nv_fbc_function_list.nvFBCToCudaGrabFrame(nv_fbc_handle, &grab_params);
- if(status != NVFBC_SUCCESS) {
- fprintf(stderr, "Error: %s\n", nv_fbc_function_list.nvFBCGetLastErrorStr(nv_fbc_handle));
- return false;
- }
-
- *byte_size = frame_info.dwByteSize;
- // TODO: Check bIsNewFrame
- // TODO: Check dwWidth and dwHeight and update size in video output in ffmpeg. This can happen when xrandr is used to change monitor resolution
-
- return true;
- }
-private:
- static char to_upper(char c) {
- if(c >= 'a' && c <= 'z')
- return c - 32;
- else
- return c;
- }
-
- static bool strcase_equals(const char *str1, const char *str2) {
- for(;;) {
- char c1 = to_upper(*str1);
- char c2 = to_upper(*str2);
- if(c1 != c2)
- return false;
- if(c1 == '\0' || c2 == '\0')
- return true;
- ++str1;
- ++str2;
- }
- }
-
- // Returns 0 on failure
- uint32_t get_output_id_from_display_name(NVFBC_RANDR_OUTPUT_INFO *outputs, uint32_t num_outputs, const char *display_name, uint32_t *display_width, uint32_t *display_height) {
- if(!outputs)
- return 0;
-
- for(uint32_t i = 0; i < num_outputs; ++i) {
- if(strcase_equals(outputs[i].name, display_name)) {
- *display_width = outputs[i].trackedBox.w;
- *display_height = outputs[i].trackedBox.h;
- return outputs[i].dwId;
- }
- }
-
- return 0;
- }
-private:
- void *library = nullptr;
- PNVFBCCREATEINSTANCE nv_fbc_create_instance = nullptr;
- NVFBC_API_FUNCTION_LIST nv_fbc_function_list;
- NVFBC_SESSION_HANDLE nv_fbc_handle;
- bool fbc_handle_created = false;
-}; \ No newline at end of file
diff --git a/include/capture/capture.h b/include/capture/capture.h
new file mode 100644
index 0000000..2eb8e42
--- /dev/null
+++ b/include/capture/capture.h
@@ -0,0 +1,68 @@
+#ifndef GSR_CAPTURE_CAPTURE_H
+#define GSR_CAPTURE_CAPTURE_H
+
+#include "../color_conversion.h"
+#include <stdbool.h>
+
+typedef struct AVCodecContext AVCodecContext;
+typedef struct AVFrame AVFrame;
+typedef void* VADisplay;
+typedef struct _VADRMPRIMESurfaceDescriptor VADRMPRIMESurfaceDescriptor;
+typedef struct gsr_cuda gsr_cuda;
+typedef struct AVFrame AVFrame;
+typedef struct CUgraphicsResource_st *CUgraphicsResource;
+typedef struct CUarray_st *CUarray;
+typedef struct CUctx_st *CUcontext;
+typedef struct CUstream_st *CUstream;
+
+typedef struct gsr_capture gsr_capture;
+
+struct gsr_capture {
+ /* These methods should not be called manually. Call gsr_capture_* instead */
+ int (*start)(gsr_capture *cap, AVCodecContext *video_codec_context, AVFrame *frame);
+ void (*tick)(gsr_capture *cap, AVCodecContext *video_codec_context); /* can be NULL */
+ bool (*should_stop)(gsr_capture *cap, bool *err); /* can be NULL */
+ int (*capture)(gsr_capture *cap, AVFrame *frame);
+ void (*capture_end)(gsr_capture *cap, AVFrame *frame); /* can be NULL */
+ void (*destroy)(gsr_capture *cap, AVCodecContext *video_codec_context);
+
+ void *priv; /* can be NULL */
+ bool started;
+};
+
+typedef struct gsr_capture_base gsr_capture_base;
+
+struct gsr_capture_base {
+ gsr_egl *egl;
+
+ unsigned int input_texture;
+ unsigned int target_textures[2];
+ unsigned int cursor_texture;
+
+ gsr_color_conversion color_conversion;
+
+ AVCodecContext *video_codec_context;
+};
+
+typedef struct {
+ gsr_cuda *cuda;
+ CUgraphicsResource *cuda_graphics_resources;
+ CUarray *mapped_arrays;
+} gsr_cuda_context;
+
+int gsr_capture_start(gsr_capture *cap, AVCodecContext *video_codec_context, AVFrame *frame);
+void gsr_capture_tick(gsr_capture *cap, AVCodecContext *video_codec_context);
+bool gsr_capture_should_stop(gsr_capture *cap, bool *err);
+int gsr_capture_capture(gsr_capture *cap, AVFrame *frame);
+void gsr_capture_end(gsr_capture *cap, AVFrame *frame);
+/* Calls |gsr_capture_stop| as well */
+void gsr_capture_destroy(gsr_capture *cap, AVCodecContext *video_codec_context);
+
+bool gsr_capture_base_setup_vaapi_textures(gsr_capture_base *self, AVFrame *frame, VADisplay va_dpy, VADRMPRIMESurfaceDescriptor *prime, gsr_color_range color_range);
+bool gsr_capture_base_setup_cuda_textures(gsr_capture_base *self, AVFrame *frame, gsr_cuda_context *cuda_context, gsr_color_range color_range, gsr_source_color source_color, bool hdr);
+void gsr_capture_base_stop(gsr_capture_base *self);
+
+bool drm_create_codec_context(const char *card_path, AVCodecContext *video_codec_context, int width, int height, bool hdr, VADisplay *va_dpy);
+bool cuda_create_codec_context(CUcontext cu_ctx, AVCodecContext *video_codec_context, int width, int height, bool hdr, CUstream *cuda_stream);
+
+#endif /* GSR_CAPTURE_CAPTURE_H */
diff --git a/include/capture/kms.h b/include/capture/kms.h
new file mode 100644
index 0000000..674813a
--- /dev/null
+++ b/include/capture/kms.h
@@ -0,0 +1,50 @@
+#ifndef GSR_CAPTURE_KMS_H
+#define GSR_CAPTURE_KMS_H
+
+#include "capture.h"
+#include "../../kms/client/kms_client.h"
+#include "../color_conversion.h"
+#include "../vec2.h"
+#include "../defs.h"
+#include <stdbool.h>
+
+typedef struct AVCodecContext AVCodecContext;
+typedef struct AVMasteringDisplayMetadata AVMasteringDisplayMetadata;
+typedef struct AVContentLightMetadata AVContentLightMetadata;
+typedef struct gsr_capture_kms gsr_capture_kms;
+typedef struct gsr_egl gsr_egl;
+typedef struct AVFrame AVFrame;
+
+#define MAX_CONNECTOR_IDS 32
+
+typedef struct {
+ uint32_t connector_ids[MAX_CONNECTOR_IDS];
+ int num_connector_ids;
+} MonitorId;
+
+struct gsr_capture_kms {
+ gsr_capture_base base;
+
+ bool should_stop;
+ bool stop_is_error;
+
+ gsr_kms_client kms_client;
+ gsr_kms_response kms_response;
+
+ vec2i capture_pos;
+ vec2i capture_size;
+ MonitorId monitor_id;
+
+ AVMasteringDisplayMetadata *mastering_display_metadata;
+ AVContentLightMetadata *light_metadata;
+
+ gsr_monitor_rotation monitor_rotation;
+};
+
+/* Returns 0 on success */
+int gsr_capture_kms_start(gsr_capture_kms *self, const char *display_to_capture, gsr_egl *egl, AVCodecContext *video_codec_context, AVFrame *frame);
+void gsr_capture_kms_stop(gsr_capture_kms *self);
+bool gsr_capture_kms_capture(gsr_capture_kms *self, AVFrame *frame, bool hdr, bool screen_plane_use_modifiers, bool cursor_texture_is_external, bool record_cursor);
+void gsr_capture_kms_cleanup_kms_fds(gsr_capture_kms *self);
+
+#endif /* GSR_CAPTURE_KMS_H */
diff --git a/include/capture/kms_cuda.h b/include/capture/kms_cuda.h
new file mode 100644
index 0000000..fd0d396
--- /dev/null
+++ b/include/capture/kms_cuda.h
@@ -0,0 +1,20 @@
+#ifndef GSR_CAPTURE_KMS_CUDA_H
+#define GSR_CAPTURE_KMS_CUDA_H
+
+#include "../vec2.h"
+#include "../utils.h"
+#include "../color_conversion.h"
+#include "capture.h"
+
+typedef struct {
+ gsr_egl *egl;
+ const char *display_to_capture; /* if this is "screen", then the first monitor is captured. A copy is made of this */
+ gsr_gpu_info gpu_inf;
+ bool hdr;
+ gsr_color_range color_range;
+ bool record_cursor;
+} gsr_capture_kms_cuda_params;
+
+gsr_capture* gsr_capture_kms_cuda_create(const gsr_capture_kms_cuda_params *params);
+
+#endif /* GSR_CAPTURE_KMS_CUDA_H */
diff --git a/include/capture/kms_vaapi.h b/include/capture/kms_vaapi.h
new file mode 100644
index 0000000..196b597
--- /dev/null
+++ b/include/capture/kms_vaapi.h
@@ -0,0 +1,20 @@
+#ifndef GSR_CAPTURE_KMS_VAAPI_H
+#define GSR_CAPTURE_KMS_VAAPI_H
+
+#include "../vec2.h"
+#include "../utils.h"
+#include "../color_conversion.h"
+#include "capture.h"
+
+typedef struct {
+ gsr_egl *egl;
+ const char *display_to_capture; /* if this is "screen", then the first monitor is captured. A copy is made of this */
+ gsr_gpu_info gpu_inf;
+ bool hdr;
+ gsr_color_range color_range;
+ bool record_cursor;
+} gsr_capture_kms_vaapi_params;
+
+gsr_capture* gsr_capture_kms_vaapi_create(const gsr_capture_kms_vaapi_params *params);
+
+#endif /* GSR_CAPTURE_KMS_VAAPI_H */
diff --git a/include/capture/nvfbc.h b/include/capture/nvfbc.h
new file mode 100644
index 0000000..36bc2b6
--- /dev/null
+++ b/include/capture/nvfbc.h
@@ -0,0 +1,22 @@
+#ifndef GSR_CAPTURE_NVFBC_H
+#define GSR_CAPTURE_NVFBC_H
+
+#include "capture.h"
+#include "../vec2.h"
+
+typedef struct {
+ gsr_egl *egl;
+ const char *display_to_capture; /* if this is "screen", then the entire x11 screen is captured (all displays). A copy is made of this */
+ int fps;
+ vec2i pos;
+ vec2i size;
+ bool direct_capture;
+ bool overclock;
+ bool hdr;
+ gsr_color_range color_range;
+ bool record_cursor;
+} gsr_capture_nvfbc_params;
+
+gsr_capture* gsr_capture_nvfbc_create(const gsr_capture_nvfbc_params *params);
+
+#endif /* GSR_CAPTURE_NVFBC_H */
diff --git a/include/capture/xcomposite.h b/include/capture/xcomposite.h
new file mode 100644
index 0000000..ce0dbad
--- /dev/null
+++ b/include/capture/xcomposite.h
@@ -0,0 +1,51 @@
+#ifndef GSR_CAPTURE_XCOMPOSITE_H
+#define GSR_CAPTURE_XCOMPOSITE_H
+
+#include "capture.h"
+#include "../egl.h"
+#include "../vec2.h"
+#include "../color_conversion.h"
+#include "../window_texture.h"
+#include "../cursor.h"
+
+typedef struct {
+ gsr_egl *egl;
+ Window window;
+ bool follow_focused; /* If this is set then |window| is ignored */
+ vec2i region_size; /* This is currently only used with |follow_focused| */
+ gsr_color_range color_range;
+ bool record_cursor;
+} gsr_capture_xcomposite_params;
+
+typedef struct {
+ gsr_capture_base base;
+ gsr_capture_xcomposite_params params;
+ XEvent xev;
+
+ bool should_stop;
+ bool stop_is_error;
+ bool window_resized;
+ bool follow_focused_initialized;
+
+ Window window;
+ vec2i window_size;
+ vec2i texture_size;
+ double window_resize_timer;
+
+ WindowTexture window_texture;
+
+ Atom net_active_window_atom;
+
+ gsr_cursor cursor;
+ bool clear_next_frame;
+} gsr_capture_xcomposite;
+
+void gsr_capture_xcomposite_init(gsr_capture_xcomposite *self, const gsr_capture_xcomposite_params *params);
+
+int gsr_capture_xcomposite_start(gsr_capture_xcomposite *self, AVCodecContext *video_codec_context, AVFrame *frame);
+void gsr_capture_xcomposite_stop(gsr_capture_xcomposite *self);
+void gsr_capture_xcomposite_tick(gsr_capture_xcomposite *self, AVCodecContext *video_codec_context);
+bool gsr_capture_xcomposite_should_stop(gsr_capture_xcomposite *self, bool *err);
+int gsr_capture_xcomposite_capture(gsr_capture_xcomposite *self, AVFrame *frame);
+
+#endif /* GSR_CAPTURE_XCOMPOSITE_H */
diff --git a/include/capture/xcomposite_cuda.h b/include/capture/xcomposite_cuda.h
new file mode 100644
index 0000000..b93c6de
--- /dev/null
+++ b/include/capture/xcomposite_cuda.h
@@ -0,0 +1,14 @@
+#ifndef GSR_CAPTURE_XCOMPOSITE_CUDA_H
+#define GSR_CAPTURE_XCOMPOSITE_CUDA_H
+
+#include "capture.h"
+#include "xcomposite.h"
+
+typedef struct {
+ gsr_capture_xcomposite_params base;
+ bool overclock;
+} gsr_capture_xcomposite_cuda_params;
+
+gsr_capture* gsr_capture_xcomposite_cuda_create(const gsr_capture_xcomposite_cuda_params *params);
+
+#endif /* GSR_CAPTURE_XCOMPOSITE_CUDA_H */
diff --git a/include/capture/xcomposite_vaapi.h b/include/capture/xcomposite_vaapi.h
new file mode 100644
index 0000000..5d4b338
--- /dev/null
+++ b/include/capture/xcomposite_vaapi.h
@@ -0,0 +1,13 @@
+#ifndef GSR_CAPTURE_XCOMPOSITE_VAAPI_H
+#define GSR_CAPTURE_XCOMPOSITE_VAAPI_H
+
+#include "capture.h"
+#include "xcomposite.h"
+
+typedef struct {
+ gsr_capture_xcomposite_params base;
+} gsr_capture_xcomposite_vaapi_params;
+
+gsr_capture* gsr_capture_xcomposite_vaapi_create(const gsr_capture_xcomposite_vaapi_params *params);
+
+#endif /* GSR_CAPTURE_XCOMPOSITE_VAAPI_H */
diff --git a/include/color_conversion.h b/include/color_conversion.h
new file mode 100644
index 0000000..d05df6a
--- /dev/null
+++ b/include/color_conversion.h
@@ -0,0 +1,58 @@
+#ifndef GSR_COLOR_CONVERSION_H
+#define GSR_COLOR_CONVERSION_H
+
+#include "shader.h"
+#include "vec2.h"
+#include <stdbool.h>
+
+typedef enum {
+ GSR_COLOR_RANGE_LIMITED,
+ GSR_COLOR_RANGE_FULL
+} gsr_color_range;
+
+typedef enum {
+ GSR_SOURCE_COLOR_RGB,
+ GSR_SOURCE_COLOR_BGR
+} gsr_source_color;
+
+typedef enum {
+ GSR_DESTINATION_COLOR_NV12, /* YUV420, BT709, 8-bit */
+ GSR_DESTINATION_COLOR_P010 /* YUV420, BT2020, 10-bit */
+} gsr_destination_color;
+
+typedef struct {
+ int offset;
+ int rotation;
+} gsr_color_uniforms;
+
+typedef struct {
+ gsr_egl *egl;
+
+ gsr_source_color source_color;
+ gsr_destination_color destination_color;
+
+ unsigned int destination_textures[2];
+ int num_destination_textures;
+
+ gsr_color_range color_range;
+ bool load_external_image_shader;
+} gsr_color_conversion_params;
+
+typedef struct {
+ gsr_color_conversion_params params;
+ gsr_color_uniforms uniforms[4];
+ gsr_shader shaders[4];
+
+ unsigned int framebuffers[2];
+
+ unsigned int vertex_array_object_id;
+ unsigned int vertex_buffer_object_id;
+} gsr_color_conversion;
+
+int gsr_color_conversion_init(gsr_color_conversion *self, const gsr_color_conversion_params *params);
+void gsr_color_conversion_deinit(gsr_color_conversion *self);
+
+void gsr_color_conversion_draw(gsr_color_conversion *self, unsigned int texture_id, vec2i source_pos, vec2i source_size, vec2i texture_pos, vec2i texture_size, float rotation, bool external_texture);
+void gsr_color_conversion_clear(gsr_color_conversion *self);
+
+#endif /* GSR_COLOR_CONVERSION_H */
diff --git a/include/cuda.h b/include/cuda.h
new file mode 100644
index 0000000..fd1f9f9
--- /dev/null
+++ b/include/cuda.h
@@ -0,0 +1,108 @@
+#ifndef GSR_CUDA_H
+#define GSR_CUDA_H
+
+#include "overclock.h"
+#include <stddef.h>
+#include <stdbool.h>
+
+// To prevent hwcontext_cuda.h from including cuda.h
+#define CUDA_VERSION 11070
+
+#define CU_CTX_SCHED_AUTO 0
+
+#if defined(_WIN64) || defined(__LP64__)
+typedef unsigned long long CUdeviceptr_v2;
+#else
+typedef unsigned int CUdeviceptr_v2;
+#endif
+typedef CUdeviceptr_v2 CUdeviceptr;
+
+typedef int CUresult;
+typedef int CUdevice_v1;
+typedef CUdevice_v1 CUdevice;
+typedef struct CUctx_st *CUcontext;
+typedef struct CUstream_st *CUstream;
+typedef struct CUarray_st *CUarray;
+
+#define CUDA_SUCCESS 0
+
+typedef enum CUgraphicsMapResourceFlags_enum {
+ CU_GRAPHICS_MAP_RESOURCE_FLAGS_NONE = 0x00,
+ CU_GRAPHICS_MAP_RESOURCE_FLAGS_READ_ONLY = 0x01,
+ CU_GRAPHICS_MAP_RESOURCE_FLAGS_WRITE_DISCARD = 0x02
+} CUgraphicsMapResourceFlags;
+
+typedef enum CUgraphicsRegisterFlags_enum {
+ CU_GRAPHICS_REGISTER_FLAGS_NONE = 0x00,
+ CU_GRAPHICS_REGISTER_FLAGS_READ_ONLY = 0x01,
+ CU_GRAPHICS_REGISTER_FLAGS_WRITE_DISCARD = 0x02,
+ CU_GRAPHICS_REGISTER_FLAGS_SURFACE_LDST = 0x04,
+ CU_GRAPHICS_REGISTER_FLAGS_TEXTURE_GATHER = 0x08
+} CUgraphicsRegisterFlags;
+
+typedef enum CUmemorytype_enum {
+ CU_MEMORYTYPE_HOST = 0x01, /**< Host memory */
+ CU_MEMORYTYPE_DEVICE = 0x02, /**< Device memory */
+ CU_MEMORYTYPE_ARRAY = 0x03, /**< Array memory */
+ CU_MEMORYTYPE_UNIFIED = 0x04 /**< Unified device or host memory */
+} CUmemorytype;
+
+typedef struct CUDA_MEMCPY2D_st {
+ size_t srcXInBytes; /**< Source X in bytes */
+ size_t srcY; /**< Source Y */
+
+ CUmemorytype srcMemoryType; /**< Source memory type (host, device, array) */
+ const void *srcHost; /**< Source host pointer */
+ CUdeviceptr srcDevice; /**< Source device pointer */
+ CUarray srcArray; /**< Source array reference */
+ size_t srcPitch; /**< Source pitch (ignored when src is array) */
+
+ size_t dstXInBytes; /**< Destination X in bytes */
+ size_t dstY; /**< Destination Y */
+
+ CUmemorytype dstMemoryType; /**< Destination memory type (host, device, array) */
+ void *dstHost; /**< Destination host pointer */
+ CUdeviceptr dstDevice; /**< Destination device pointer */
+ CUarray dstArray; /**< Destination array reference */
+ size_t dstPitch; /**< Destination pitch (ignored when dst is array) */
+
+ size_t WidthInBytes; /**< Width of 2D memory copy in bytes */
+ size_t Height; /**< Height of 2D memory copy */
+} CUDA_MEMCPY2D_v2;
+typedef CUDA_MEMCPY2D_v2 CUDA_MEMCPY2D;
+
+typedef struct CUgraphicsResource_st *CUgraphicsResource;
+
+typedef struct gsr_cuda gsr_cuda;
+struct gsr_cuda {
+ gsr_overclock overclock;
+ bool do_overclock;
+
+ void *library;
+ CUcontext cu_ctx;
+
+ CUresult (*cuInit)(unsigned int Flags);
+ CUresult (*cuDeviceGetCount)(int *count);
+ CUresult (*cuDeviceGet)(CUdevice *device, int ordinal);
+ CUresult (*cuCtxCreate_v2)(CUcontext *pctx, unsigned int flags, CUdevice dev);
+ CUresult (*cuCtxDestroy_v2)(CUcontext ctx);
+ CUresult (*cuCtxPushCurrent_v2)(CUcontext ctx);
+ CUresult (*cuCtxPopCurrent_v2)(CUcontext *pctx);
+ CUresult (*cuGetErrorString)(CUresult error, const char **pStr);
+ CUresult (*cuMemcpy2D_v2)(const CUDA_MEMCPY2D *pCopy);
+ CUresult (*cuMemcpy2DAsync_v2)(const CUDA_MEMCPY2D *pcopy, CUstream hStream);
+ CUresult (*cuStreamSynchronize)(CUstream hStream);
+
+ CUresult (*cuGraphicsGLRegisterImage)(CUgraphicsResource *pCudaResource, unsigned int image, unsigned int target, unsigned int flags);
+ CUresult (*cuGraphicsEGLRegisterImage)(CUgraphicsResource *pCudaResource, void *image, unsigned int flags);
+ CUresult (*cuGraphicsResourceSetMapFlags)(CUgraphicsResource resource, unsigned int flags);
+ CUresult (*cuGraphicsMapResources)(unsigned int count, CUgraphicsResource *resources, CUstream hStream);
+ CUresult (*cuGraphicsUnmapResources)(unsigned int count, CUgraphicsResource *resources, CUstream hStream);
+ CUresult (*cuGraphicsUnregisterResource)(CUgraphicsResource resource);
+ CUresult (*cuGraphicsSubResourceGetMappedArray)(CUarray *pArray, CUgraphicsResource resource, unsigned int arrayIndex, unsigned int mipLevel);
+};
+
+bool gsr_cuda_load(gsr_cuda *self, Display *display, bool overclock);
+void gsr_cuda_unload(gsr_cuda *self);
+
+#endif /* GSR_CUDA_H */
diff --git a/include/cursor.h b/include/cursor.h
new file mode 100644
index 0000000..b1ec6bd
--- /dev/null
+++ b/include/cursor.h
@@ -0,0 +1,26 @@
+#ifndef GSR_CURSOR_H
+#define GSR_CURSOR_H
+
+#include "egl.h"
+#include "vec2.h"
+
+typedef struct {
+ gsr_egl *egl;
+ Display *display;
+ int x_fixes_event_base;
+
+ unsigned int texture_id;
+ vec2i size;
+ vec2i hotspot;
+ vec2i position;
+
+ bool cursor_image_set;
+} gsr_cursor;
+
+int gsr_cursor_init(gsr_cursor *self, gsr_egl *egl, Display *display);
+void gsr_cursor_deinit(gsr_cursor *self);
+
+void gsr_cursor_update(gsr_cursor *self, XEvent *xev);
+void gsr_cursor_tick(gsr_cursor *self, Window relative_to);
+
+#endif /* GSR_CURSOR_H */
diff --git a/include/defs.h b/include/defs.h
new file mode 100644
index 0000000..473583c
--- /dev/null
+++ b/include/defs.h
@@ -0,0 +1,28 @@
+#ifndef GSR_DEFS_H
+#define GSR_DEFS_H
+
+typedef enum {
+ GSR_GPU_VENDOR_AMD,
+ GSR_GPU_VENDOR_INTEL,
+ GSR_GPU_VENDOR_NVIDIA
+} gsr_gpu_vendor;
+
+typedef struct {
+ gsr_gpu_vendor vendor;
+ int gpu_version; /* 0 if unknown */
+} gsr_gpu_info;
+
+typedef enum {
+ GSR_MONITOR_ROT_0,
+ GSR_MONITOR_ROT_90,
+ GSR_MONITOR_ROT_180,
+ GSR_MONITOR_ROT_270
+} gsr_monitor_rotation;
+
+typedef enum {
+ GSR_CONNECTION_X11,
+ GSR_CONNECTION_WAYLAND,
+ GSR_CONNECTION_DRM
+} gsr_connection_type;
+
+#endif /* GSR_DEFS_H */
diff --git a/include/egl.h b/include/egl.h
new file mode 100644
index 0000000..afdb5a9
--- /dev/null
+++ b/include/egl.h
@@ -0,0 +1,285 @@
+#ifndef GSR_EGL_H
+#define GSR_EGL_H
+
+/* OpenGL EGL library with a hidden window context (to allow using the opengl functions) */
+
+#include <X11/X.h>
+#include <X11/Xutil.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include "vec2.h"
+#include "defs.h"
+
+#ifdef _WIN64
+typedef signed long long int khronos_intptr_t;
+typedef unsigned long long int khronos_uintptr_t;
+typedef signed long long int khronos_ssize_t;
+typedef unsigned long long int khronos_usize_t;
+#else
+typedef signed long int khronos_intptr_t;
+typedef unsigned long int khronos_uintptr_t;
+typedef signed long int khronos_ssize_t;
+typedef unsigned long int khronos_usize_t;
+#endif
+
+typedef void* EGLDisplay;
+typedef void* EGLNativeDisplayType;
+typedef uintptr_t EGLNativeWindowType;
+typedef uintptr_t EGLNativePixmapType;
+typedef void* EGLConfig;
+typedef void* EGLSurface;
+typedef void* EGLContext;
+typedef void* EGLClientBuffer;
+typedef void* EGLImage;
+typedef void* EGLImageKHR;
+typedef void *GLeglImageOES;
+typedef void (*__eglMustCastToProperFunctionPointerType)(void);
+typedef struct __GLXFBConfigRec *GLXFBConfig;
+typedef struct __GLXcontextRec *GLXContext;
+typedef XID GLXDrawable;
+typedef void(*__GLXextFuncPtr)(void);
+
+#define EGL_SUCCESS 0x3000
+#define EGL_BUFFER_SIZE 0x3020
+#define EGL_RENDERABLE_TYPE 0x3040
+#define EGL_OPENGL_API 0x30A2
+#define EGL_OPENGL_BIT 0x0008
+#define EGL_NONE 0x3038
+#define EGL_CONTEXT_CLIENT_VERSION 0x3098
+#define EGL_BACK_BUFFER 0x3084
+#define EGL_GL_TEXTURE_2D 0x30B1
+#define EGL_TRUE 1
+#define EGL_IMAGE_PRESERVED_KHR 0x30D2
+#define EGL_NATIVE_PIXMAP_KHR 0x30B0
+#define EGL_LINUX_DRM_FOURCC_EXT 0x3271
+#define EGL_WIDTH 0x3057
+#define EGL_HEIGHT 0x3056
+#define EGL_DMA_BUF_PLANE0_FD_EXT 0x3272
+#define EGL_DMA_BUF_PLANE0_OFFSET_EXT 0x3273
+#define EGL_DMA_BUF_PLANE0_PITCH_EXT 0x3274
+#define EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT 0x3443
+#define EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT 0x3444
+#define EGL_LINUX_DMA_BUF_EXT 0x3270
+#define EGL_RED_SIZE 0x3024
+#define EGL_ALPHA_SIZE 0x3021
+#define EGL_BLUE_SIZE 0x3022
+#define EGL_GREEN_SIZE 0x3023
+#define EGL_CONTEXT_PRIORITY_LEVEL_IMG 0x3100
+#define EGL_CONTEXT_PRIORITY_HIGH_IMG 0x3101
+#define EGL_CONTEXT_PRIORITY_MEDIUM_IMG 0x3102
+#define EGL_CONTEXT_PRIORITY_LOW_IMG 0x3103
+#define EGL_DEVICE_EXT 0x322C
+#define EGL_DRM_DEVICE_FILE_EXT 0x3233
+
+#define GL_FLOAT 0x1406
+#define GL_FALSE 0
+#define GL_TRUE 1
+#define GL_TRIANGLES 0x0004
+#define GL_TEXTURE_2D 0x0DE1
+#define GL_TEXTURE_EXTERNAL_OES 0x8D65
+#define GL_RED 0x1903
+#define GL_GREEN 0x1904
+#define GL_BLUE 0x1905
+#define GL_ALPHA 0x1906
+#define GL_TEXTURE_SWIZZLE_RGBA 0x8E46
+#define GL_RG 0x8227
+#define GL_RGB 0x1907
+#define GL_RGBA 0x1908
+#define GL_RGBA8 0x8058
+#define GL_R8 0x8229
+#define GL_RG8 0x822B
+#define GL_R16 0x822A
+#define GL_RG16 0x822C
+#define GL_UNSIGNED_BYTE 0x1401
+#define GL_COLOR_BUFFER_BIT 0x00004000
+#define GL_TEXTURE_WRAP_S 0x2802
+#define GL_TEXTURE_WRAP_T 0x2803
+#define GL_TEXTURE_MAG_FILTER 0x2800
+#define GL_TEXTURE_MIN_FILTER 0x2801
+#define GL_TEXTURE_WIDTH 0x1000
+#define GL_TEXTURE_HEIGHT 0x1001
+#define GL_NEAREST 0x2600
+#define GL_CLAMP_TO_EDGE 0x812F
+#define GL_LINEAR 0x2601
+#define GL_FRAMEBUFFER 0x8D40
+#define GL_COLOR_ATTACHMENT0 0x8CE0
+#define GL_FRAMEBUFFER_COMPLETE 0x8CD5
+#define GL_STREAM_DRAW 0x88E0
+#define GL_ARRAY_BUFFER 0x8892
+#define GL_BLEND 0x0BE2
+#define GL_SRC_ALPHA 0x0302
+#define GL_ONE_MINUS_SRC_ALPHA 0x0303
+#define GL_DEBUG_OUTPUT 0x92E0
+
+#define GL_VENDOR 0x1F00
+#define GL_RENDERER 0x1F01
+
+#define GL_COMPILE_STATUS 0x8B81
+#define GL_INFO_LOG_LENGTH 0x8B84
+#define GL_FRAGMENT_SHADER 0x8B30
+#define GL_VERTEX_SHADER 0x8B31
+#define GL_COMPILE_STATUS 0x8B81
+#define GL_LINK_STATUS 0x8B82
+
+typedef unsigned int (*FUNC_eglExportDMABUFImageQueryMESA)(EGLDisplay dpy, EGLImageKHR image, int *fourcc, int *num_planes, uint64_t *modifiers);
+typedef unsigned int (*FUNC_eglExportDMABUFImageMESA)(EGLDisplay dpy, EGLImageKHR image, int *fds, int32_t *strides, int32_t *offsets);
+typedef void (*FUNC_glEGLImageTargetTexture2DOES)(unsigned int target, GLeglImageOES image);
+typedef GLXContext (*FUNC_glXCreateContextAttribsARB)(Display *dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list);
+typedef void (*FUNC_glXSwapIntervalEXT)(Display * dpy, GLXDrawable drawable, int interval);
+typedef int (*FUNC_glXSwapIntervalMESA)(unsigned int interval);
+typedef int (*FUNC_glXSwapIntervalSGI)(int interval);
+typedef void (*GLDEBUGPROC)(unsigned int source, unsigned int type, unsigned int id, unsigned int severity, int length, const char *message, const void *userParam);
+typedef int (*FUNC_eglQueryDisplayAttribEXT)(EGLDisplay dpy, int32_t attribute, intptr_t *value);
+typedef const char* (*FUNC_eglQueryDeviceStringEXT)(void *device, int32_t name);
+
+#define GSR_MAX_OUTPUTS 32
+
+typedef struct {
+ Display *dpy;
+ Window window;
+} gsr_x11;
+
+typedef struct {
+ uint32_t wl_name;
+ void *output;
+ vec2i pos;
+ vec2i size;
+ int32_t transform;
+ char *name;
+} gsr_wayland_output;
+
+typedef struct {
+ void *dpy;
+ void *window;
+ void *registry;
+ void *surface;
+ void *compositor;
+ gsr_wayland_output outputs[GSR_MAX_OUTPUTS];
+ int num_outputs;
+} gsr_wayland;
+
+typedef enum {
+ GSR_GL_CONTEXT_TYPE_EGL,
+ GSR_GL_CONTEXT_TYPE_GLX
+} gsr_gl_context_type;
+
+typedef struct gsr_egl gsr_egl;
+struct gsr_egl {
+ void *egl_library;
+ void *glx_library;
+ void *gl_library;
+
+ gsr_gl_context_type context_type;
+
+ EGLDisplay egl_display;
+ EGLSurface egl_surface;
+ EGLContext egl_context;
+ const char *dri_card_path;
+
+ void *glx_context;
+ void *glx_fb_config;
+
+ gsr_gpu_info gpu_info;
+
+ gsr_x11 x11;
+ gsr_wayland wayland;
+ char card_path[128];
+
+ int32_t (*eglGetError)(void);
+ EGLDisplay (*eglGetDisplay)(EGLNativeDisplayType display_id);
+ unsigned int (*eglInitialize)(EGLDisplay dpy, int32_t *major, int32_t *minor);
+ unsigned int (*eglTerminate)(EGLDisplay dpy);
+ unsigned int (*eglChooseConfig)(EGLDisplay dpy, const int32_t *attrib_list, EGLConfig *configs, int32_t config_size, int32_t *num_config);
+ EGLSurface (*eglCreateWindowSurface)(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const int32_t *attrib_list);
+ EGLContext (*eglCreateContext)(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const int32_t *attrib_list);
+ unsigned int (*eglMakeCurrent)(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
+ EGLImage (*eglCreateImage)(EGLDisplay dpy, EGLContext ctx, unsigned int target, EGLClientBuffer buffer, const intptr_t *attrib_list);
+ unsigned int (*eglDestroyContext)(EGLDisplay dpy, EGLContext ctx);
+ unsigned int (*eglDestroySurface)(EGLDisplay dpy, EGLSurface surface);
+ unsigned int (*eglDestroyImage)(EGLDisplay dpy, EGLImage image);
+ unsigned int (*eglSwapInterval)(EGLDisplay dpy, int32_t interval);
+ unsigned int (*eglSwapBuffers)(EGLDisplay dpy, EGLSurface surface);
+ unsigned int (*eglBindAPI)(unsigned int api);
+ __eglMustCastToProperFunctionPointerType (*eglGetProcAddress)(const char *procname);
+
+ FUNC_eglExportDMABUFImageQueryMESA eglExportDMABUFImageQueryMESA;
+ FUNC_eglExportDMABUFImageMESA eglExportDMABUFImageMESA;
+ FUNC_glEGLImageTargetTexture2DOES glEGLImageTargetTexture2DOES;
+ FUNC_eglQueryDisplayAttribEXT eglQueryDisplayAttribEXT;
+ FUNC_eglQueryDeviceStringEXT eglQueryDeviceStringEXT;
+
+ __GLXextFuncPtr (*glXGetProcAddress)(const unsigned char *procName);
+ GLXFBConfig* (*glXChooseFBConfig)(Display *dpy, int screen, const int *attribList, int *nitems);
+ Bool (*glXMakeContextCurrent)(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx);
+ // TODO: Remove
+ GLXContext (*glXCreateNewContext)(Display *dpy, GLXFBConfig config, int renderType, GLXContext shareList, Bool direct);
+ void (*glXDestroyContext)(Display *dpy, GLXContext ctx);
+ void (*glXSwapBuffers)(Display *dpy, GLXDrawable drawable);
+ FUNC_glXCreateContextAttribsARB glXCreateContextAttribsARB;
+
+ /* Optional */
+ FUNC_glXSwapIntervalEXT glXSwapIntervalEXT;
+ FUNC_glXSwapIntervalMESA glXSwapIntervalMESA;
+ FUNC_glXSwapIntervalSGI glXSwapIntervalSGI;
+
+ unsigned int (*glGetError)(void);
+ const unsigned char* (*glGetString)(unsigned int name);
+ void (*glFlush)(void);
+ void (*glFinish)(void);
+ void (*glClear)(unsigned int mask);
+ void (*glClearColor)(float red, float green, float blue, float alpha);
+ void (*glGenTextures)(int n, unsigned int *textures);
+ void (*glDeleteTextures)(int n, const unsigned int *texture);
+ void (*glBindTexture)(unsigned int target, unsigned int texture);
+ void (*glTexParameteri)(unsigned int target, unsigned int pname, int param);
+ void (*glTexParameteriv)(unsigned int target, unsigned int pname, const int *params);
+ void (*glGetTexLevelParameteriv)(unsigned int target, int level, unsigned int pname, int *params);
+ void (*glTexImage2D)(unsigned int target, int level, int internalFormat, int width, int height, int border, unsigned int format, unsigned int type, const void *pixels);
+ void (*glCopyImageSubData)(unsigned int srcName, unsigned int srcTarget, int srcLevel, int srcX, int srcY, int srcZ, unsigned int dstName, unsigned int dstTarget, int dstLevel, int dstX, int dstY, int dstZ, int srcWidth, int srcHeight, int srcDepth);
+ void (*glClearTexImage)(unsigned int texture, unsigned int level, unsigned int format, unsigned int type, const void *data);
+ void (*glGenFramebuffers)(int n, unsigned int *framebuffers);
+ void (*glBindFramebuffer)(unsigned int target, unsigned int framebuffer);
+ void (*glDeleteFramebuffers)(int n, const unsigned int *framebuffers);
+ void (*glViewport)(int x, int y, int width, int height);
+ void (*glFramebufferTexture2D)(unsigned int target, unsigned int attachment, unsigned int textarget, unsigned int texture, int level);
+ void (*glDrawBuffers)(int n, const unsigned int *bufs);
+ unsigned int (*glCheckFramebufferStatus)(unsigned int target);
+ void (*glBindBuffer)(unsigned int target, unsigned int buffer);
+ void (*glGenBuffers)(int n, unsigned int *buffers);
+ void (*glBufferData)(unsigned int target, khronos_ssize_t size, const void *data, unsigned int usage);
+ void (*glBufferSubData)(unsigned int target, khronos_intptr_t offset, khronos_ssize_t size, const void *data);
+ void (*glDeleteBuffers)(int n, const unsigned int *buffers);
+ void (*glGenVertexArrays)(int n, unsigned int *arrays);
+ void (*glBindVertexArray)(unsigned int array);
+ void (*glDeleteVertexArrays)(int n, const unsigned int *arrays);
+ unsigned int (*glCreateProgram)(void);
+ unsigned int (*glCreateShader)(unsigned int type);
+ void (*glAttachShader)(unsigned int program, unsigned int shader);
+ void (*glBindAttribLocation)(unsigned int program, unsigned int index, const char *name);
+ void (*glCompileShader)(unsigned int shader);
+ void (*glLinkProgram)(unsigned int program);
+ void (*glShaderSource)(unsigned int shader, int count, const char *const*string, const int *length);
+ void (*glUseProgram)(unsigned int program);
+ void (*glGetProgramInfoLog)(unsigned int program, int bufSize, int *length, char *infoLog);
+ void (*glGetShaderiv)(unsigned int shader, unsigned int pname, int *params);
+ void (*glGetShaderInfoLog)(unsigned int shader, int bufSize, int *length, char *infoLog);
+ void (*glDeleteProgram)(unsigned int program);
+ void (*glDeleteShader)(unsigned int shader);
+ void (*glGetProgramiv)(unsigned int program, unsigned int pname, int *params);
+ void (*glVertexAttribPointer)(unsigned int index, int size, unsigned int type, unsigned char normalized, int stride, const void *pointer);
+ void (*glEnableVertexAttribArray)(unsigned int index);
+ void (*glDrawArrays)(unsigned int mode, int first, int count);
+ void (*glEnable)(unsigned int cap);
+ void (*glBlendFunc)(unsigned int sfactor, unsigned int dfactor);
+ int (*glGetUniformLocation)(unsigned int program, const char *name);
+ void (*glUniform1f)(int location, float v0);
+ void (*glUniform2f)(int location, float v0, float v1);
+ void (*glDebugMessageCallback)(GLDEBUGPROC callback, const void *userParam);
+};
+
+bool gsr_egl_load(gsr_egl *self, Display *dpy, bool wayland, bool is_monitor_capture);
+void gsr_egl_unload(gsr_egl *self);
+
+void gsr_egl_update(gsr_egl *self);
+
+#endif /* GSR_EGL_H */
diff --git a/include/library_loader.h b/include/library_loader.h
new file mode 100644
index 0000000..47bc9f0
--- /dev/null
+++ b/include/library_loader.h
@@ -0,0 +1,17 @@
+#ifndef GSR_LIBRARY_LOADER_H
+#define GSR_LIBRARY_LOADER_H
+
+#include <stdbool.h>
+
+typedef struct {
+ void **func;
+ const char *name;
+} dlsym_assign;
+
+void* dlsym_print_fail(void *handle, const char *name, bool required);
+/* |dlsyms| should be null terminated */
+bool dlsym_load_list(void *handle, const dlsym_assign *dlsyms);
+/* |dlsyms| should be null terminated */
+void dlsym_load_list_optional(void *handle, const dlsym_assign *dlsyms);
+
+#endif /* GSR_LIBRARY_LOADER_H */
diff --git a/include/overclock.h b/include/overclock.h
new file mode 100644
index 0000000..d6ff901
--- /dev/null
+++ b/include/overclock.h
@@ -0,0 +1,17 @@
+#ifndef GSR_OVERCLOCK_H
+#define GSR_OVERCLOCK_H
+
+#include "xnvctrl.h"
+
+typedef struct {
+ gsr_xnvctrl xnvctrl;
+ int num_performance_levels;
+} gsr_overclock;
+
+bool gsr_overclock_load(gsr_overclock *self, Display *display);
+void gsr_overclock_unload(gsr_overclock *self);
+
+bool gsr_overclock_start(gsr_overclock *self);
+void gsr_overclock_stop(gsr_overclock *self);
+
+#endif /* GSR_OVERCLOCK_H */
diff --git a/include/shader.h b/include/shader.h
new file mode 100644
index 0000000..57d1096
--- /dev/null
+++ b/include/shader.h
@@ -0,0 +1,19 @@
+#ifndef GSR_SHADER_H
+#define GSR_SHADER_H
+
+typedef struct gsr_egl gsr_egl;
+
+typedef struct {
+ gsr_egl *egl;
+ unsigned int program_id;
+} gsr_shader;
+
+/* |vertex_shader| or |fragment_shader| may be NULL */
+int gsr_shader_init(gsr_shader *self, gsr_egl *egl, const char *vertex_shader, const char *fragment_shader);
+void gsr_shader_deinit(gsr_shader *self);
+
+int gsr_shader_bind_attribute_location(gsr_shader *self, const char *attribute, int location);
+void gsr_shader_use(gsr_shader *self);
+void gsr_shader_use_none(gsr_shader *self);
+
+#endif /* GSR_SHADER_H */
diff --git a/include/sound.hpp b/include/sound.hpp
index 666d009..77bec99 100644
--- a/include/sound.hpp
+++ b/include/sound.hpp
@@ -18,20 +18,36 @@
#ifndef GPU_SCREEN_RECORDER_H
#define GPU_SCREEN_RECORDER_H
+#include <vector>
+#include <string>
+
typedef struct {
void *handle;
- void *buffer;
- int buffer_size;
unsigned int frames;
} SoundDevice;
+struct AudioInput {
+ std::string name;
+ std::string description;
+};
+
+struct MergedAudioInputs {
+ std::vector<AudioInput> audio_inputs;
+};
+
+typedef enum {
+ S16,
+ S32,
+ F32
+} AudioFormat;
+
/*
Get a sound device by name, returning the device into the @device parameter.
The device should be closed with @sound_device_close after it has been used
to clean up internal resources.
Returns 0 on success, or a negative value on failure.
*/
-int sound_device_get_by_name(SoundDevice *device, const char *name = "default", unsigned int num_channels = 2, unsigned int period_frame_size = 32);
+int sound_device_get_by_name(SoundDevice *device, const char *device_name, const char *description, unsigned int num_channels, unsigned int period_frame_size, AudioFormat audio_format);
void sound_device_close(SoundDevice *device);
@@ -39,6 +55,8 @@ void sound_device_close(SoundDevice *device);
Returns the next chunk of audio into @buffer.
Returns the number of frames read, or a negative value on failure.
*/
-int sound_device_read_next_chunk(SoundDevice *device, void **buffer);
+int sound_device_read_next_chunk(SoundDevice *device, void **buffer, double timeout_sec, double *latency_seconds);
+
+std::vector<AudioInput> get_pulseaudio_inputs();
#endif /* GPU_SCREEN_RECORDER_H */
diff --git a/include/utils.h b/include/utils.h
new file mode 100644
index 0000000..74fdd59
--- /dev/null
+++ b/include/utils.h
@@ -0,0 +1,46 @@
+#ifndef GSR_UTILS_H
+#define GSR_UTILS_H
+
+#include "vec2.h"
+#include "../include/egl.h"
+#include "../include/defs.h"
+#include <stdbool.h>
+#include <stdint.h>
+#include <X11/extensions/Xrandr.h>
+
+typedef struct {
+ const char *name;
+ int name_len;
+ vec2i pos;
+ vec2i size;
+ XRRCrtcInfo *crt_info; /* Only on x11 */
+ uint32_t connector_id; /* Only on x11 and drm */
+ gsr_monitor_rotation rotation; /* Only on x11 and wayland */
+ uint32_t monitor_identifier; /* Only on drm and wayland */
+} gsr_monitor;
+
+typedef struct {
+ const char *name;
+ int name_len;
+ gsr_monitor *monitor;
+ bool found_monitor;
+} get_monitor_by_name_userdata;
+
+double clock_get_monotonic_seconds(void);
+
+typedef void (*active_monitor_callback)(const gsr_monitor *monitor, void *userdata);
+void for_each_active_monitor_output_x11(Display *display, active_monitor_callback callback, void *userdata);
+void for_each_active_monitor_output(const gsr_egl *egl, gsr_connection_type connection_type, active_monitor_callback callback, void *userdata);
+bool get_monitor_by_name(const gsr_egl *egl, gsr_connection_type connection_type, const char *name, gsr_monitor *monitor);
+gsr_monitor_rotation drm_monitor_get_display_server_rotation(const gsr_egl *egl, const gsr_monitor *monitor);
+
+bool gl_get_gpu_info(gsr_egl *egl, gsr_gpu_info *info);
+
+/* |output| should be at least 128 bytes in size */
+bool gsr_get_valid_card_path(gsr_egl *egl, char *output);
+/* |render_path| should be at least 128 bytes in size */
+bool gsr_card_path_get_render_path(const char *card_path, char *render_path);
+
+int even_number_ceil(int value);
+
+#endif /* GSR_UTILS_H */
diff --git a/include/vec2.h b/include/vec2.h
new file mode 100644
index 0000000..3e33cfb
--- /dev/null
+++ b/include/vec2.h
@@ -0,0 +1,12 @@
+#ifndef VEC2_H
+#define VEC2_H
+
+typedef struct {
+ int x, y;
+} vec2i;
+
+typedef struct {
+ float x, y;
+} vec2f;
+
+#endif /* VEC2_H */
diff --git a/include/window_texture.h b/include/window_texture.h
new file mode 100644
index 0000000..75bb2a7
--- /dev/null
+++ b/include/window_texture.h
@@ -0,0 +1,27 @@
+#ifndef WINDOW_TEXTURE_H
+#define WINDOW_TEXTURE_H
+
+#include "egl.h"
+
+typedef struct {
+ Display *display;
+ Window window;
+ Pixmap pixmap;
+ unsigned int texture_id;
+ int redirected;
+ gsr_egl *egl;
+} WindowTexture;
+
+/* Returns 0 on success */
+int window_texture_init(WindowTexture *window_texture, Display *display, Window window, gsr_egl *egl);
+void window_texture_deinit(WindowTexture *self);
+
+/*
+ This should ONLY be called when the target window is resized.
+ Returns 0 on success.
+*/
+int window_texture_on_resize(WindowTexture *self);
+
+unsigned int window_texture_get_opengl_texture_id(WindowTexture *self);
+
+#endif /* WINDOW_TEXTURE_H */
diff --git a/include/xnvctrl.h b/include/xnvctrl.h
new file mode 100644
index 0000000..33fc442
--- /dev/null
+++ b/include/xnvctrl.h
@@ -0,0 +1,45 @@
+#ifndef GSR_XNVCTRL_H
+#define GSR_XNVCTRL_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#define NV_CTRL_GPU_NVCLOCK_OFFSET 409
+#define NV_CTRL_GPU_MEM_TRANSFER_RATE_OFFSET 410
+#define NV_CTRL_GPU_NVCLOCK_OFFSET_ALL_PERFORMANCE_LEVELS 424
+#define NV_CTRL_GPU_MEM_TRANSFER_RATE_OFFSET_ALL_PERFORMANCE_LEVELS 425
+
+#define NV_CTRL_TARGET_TYPE_GPU 1
+
+#define NV_CTRL_STRING_PERFORMANCE_MODES 29
+
+typedef struct _XDisplay Display;
+
+typedef struct {
+ int type;
+ union {
+ struct {
+ int64_t min;
+ int64_t max;
+ } range;
+ struct {
+ unsigned int ints;
+ } bits;
+ } u;
+ unsigned int permissions;
+} NVCTRLAttributeValidValuesRec;
+
+typedef struct {
+ Display *display;
+ void *library;
+
+ int (*XNVCTRLQueryExtension)(Display *dpy, int *event_basep, int *error_basep);
+ int (*XNVCTRLSetTargetAttributeAndGetStatus)(Display *dpy, int target_type, int target_id, unsigned int display_mask, unsigned int attribute, int value);
+ int (*XNVCTRLQueryValidTargetAttributeValues)(Display *dpy, int target_type, int target_id, unsigned int display_mask, unsigned int attribute, NVCTRLAttributeValidValuesRec *values);
+ int (*XNVCTRLQueryTargetStringAttribute)(Display *dpy, int target_type, int target_id, unsigned int display_mask, unsigned int attribute, char **ptr);
+} gsr_xnvctrl;
+
+bool gsr_xnvctrl_load(gsr_xnvctrl *self, Display *display);
+void gsr_xnvctrl_unload(gsr_xnvctrl *self);
+
+#endif /* GSR_XNVCTRL_H */