summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Plattner <aplattner@nvidia.com>2009-01-13 16:18:44 -0800
committerAaron Plattner <aplattner@nvidia.com>2009-01-13 16:39:42 -0800
commitb11a35a13b478615d60fe1908665b8f4349aa780 (patch)
treef99d2239f64e86cea84b221db79c88e0143cf7db
Initial commit.
-rw-r--r--include/vdpau/vdpau.h3808
-rw-r--r--include/vdpau/vdpau_x11.h174
-rw-r--r--src/vdpau_wrapper.c133
-rw-r--r--trace/vdpau_trace.cpp4293
4 files changed, 8408 insertions, 0 deletions
diff --git a/include/vdpau/vdpau.h b/include/vdpau/vdpau.h
new file mode 100644
index 0000000..c61893b
--- /dev/null
+++ b/include/vdpau/vdpau.h
@@ -0,0 +1,3808 @@
+/*
+ * This source file is documented using Doxygen markup.
+ * See http://www.stack.nl/~dimitri/doxygen/
+ */
+
+/*
+ * This copyright notice applies to this header file:
+ *
+ * Copyright (c) 2008 NVIDIA Corporation
+ *
+ * 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.
+ */
+
+/**
+ * \mainpage Video Decode and Presentation API for Unix
+ *
+ * \section intro Introduction
+ *
+ * The Video Decode and Presentation API for Unix (VDPAU) provides
+ * a complete solution for decoding, post-processing, compositing,
+ * and displaying compressed or uncompressed video streams. These
+ * video streams may be combined (composited) with bitmap content,
+ * to implement OSDs and other application user interfaces.
+ *
+ * \section api_partitioning API Partitioning
+ *
+ * VDPAU is split into two distinct modules:
+ * - \ref api_core
+ * - \ref api_winsys
+ *
+ * The intent is that most VDPAU functionality exists and
+ * operates identically across all possible Windowing Systems.
+ * This functionality is the \ref api_core.
+ *
+ * However, a small amount of functionality must be included that
+ * is tightly coupled to the underlying Windowing System. This
+ * functionality is the \ref api_winsys. Possibly examples
+ * include:
+ * - Creation of the initial VDPAU \ref VdpDevice "VdpDevice"
+ * handle, since this act requires intimate knowledge of the
+ * underlying Window System, such as specific display handle or
+ * driver identification.
+ * - Conversion of VDPAU surfaces to/from underlying Window
+ * System surface types, e.g. to allow manipulation of
+ * VDPAU-generated surfaces via native Window System APIs.
+ *
+ * \section objects Object Types
+ *
+ * VDPAU is roughly object oriented; most functionality is
+ * exposed by creating an object (handle) of a certain class
+ * (type), then executing various functions against that handle.
+ * The set of object classes supported, and their purpose, is
+ * discussed below.
+ *
+ * \subsection device_type Device Type
+ *
+ * A \ref VdpDevice "VdpDevice" is the root object in VDPAU's
+ * object system. The \ref api_winsys allows creation of a \ref
+ * VdpDevice "VdpDevice" object handle, from which all other API
+ * entry points can be retrieved and invoked.
+ *
+ * \subsection surface_types Surface Types
+ *
+ * A surface stores pixel information. Various types of surfaces
+ * existing for different purposes:
+ *
+ * - \ref VdpVideoSurface "VdpVideoSurface"s store decompressed
+ * YCbCr video frames in an implementation-defined internal
+ * format.
+ * - \ref VdpOutputSurface "VdpOutputSurface"s store RGB 4:4:4
+ * data. They are legal render targets for video
+ * post-processing and compositing operations.
+ * - \ref VdpBitmapSurface "VdpBitmapSurface"s store RGB 4:4:4
+ * data. These surfaces are designed to contain read-only
+ * bitmap data, to be used for OSD or application UI
+ * compositing.
+ *
+ * \subsection transfer_types Transfer Types
+ *
+ * A data transfer object reads data from a surface (or
+ * surfaces), processes it, and writes the result to another
+ * surface. Various types of processing are possible:
+ *
+ * - \ref VdpDecoder "VdpDecoder" objects process compressed video
+ * data, and generate decompressed images.
+ * - \ref VdpOutputSurface "VdpOutputSurface"s have their own \ref
+ * VdpOutputSurfaceRender "rendering functionality".
+ * - \ref VdpVideoMixer "VdpVideoMixer" objects perform video
+ * post-processing, de-interlacing, and compositing.
+ * - \ref VdpPresentationQueue "VdpPresentationQueue" is
+ * responsible for timestamp-based display of surfaces.
+ *
+ * \section data_flow Data Flow
+ *
+ * Compressed video data originates in the application's memory
+ * space. This memory is typically obtained using \c malloc, and
+ * filled via regular file or network read system calls.
+ * Alternatively, the application may \c mmap a file.
+ *
+ * The compressed data is then processed using a \ref VdpDecoder
+ * "VdpDecoder", which will decompress the field or frame,
+ * and write the result into a \ref VdpVideoSurface
+ * "VdpVideoSurface". This action may require reading pixel data
+ * from some number of other \ref VdpVideoSurface "VdpVideoSurface"
+ * objects, depending on the type of compressed data and
+ * field/frame in question.
+ *
+ * If the application wishes to display any form of OSD or
+ * user-interface, this must be created in a \ref
+ * VdpOutputSurface "VdpOutputSurface".
+ *
+ * This process begins with the creation of \ref VdpBitmapSurface
+ * "VdpBitmapSurface" objects to contain the OSD/UI's static data,
+ * such as individual glyphs.
+ *
+ * \ref VdpOutputSurface "VdpOutputSurface" \ref
+ * VdpOutputSurfaceRender "rendering functionality" may be used
+ * to composite together various \ref VdpBitmapSurface
+ * "VdpBitmapSurface"s and \ref VdpOutputSurface
+ * "VdpOutputSurface"s, into another VdpOutputSurface
+ * "VdpOutputSurface".
+ *
+ * Once video has been decoded, it must be post-processed. This
+ * involves various steps such as color space conversion,
+ * de-interlacing, and other video adjustments. This step is
+ * performed using an \ref VdpVideoMixer "VdpVideoMixer" object.
+ * This object can not only perform the aforementioned video
+ * post-processing, but also composite the video with a number of
+ * \ref VdpOutputSurface "VdpOutputSurface"s, thus allowing complex
+ * user interfaces to be built. The final result is written into
+ * another \ref VdpOutputSurface "VdpOutputSurface".
+ *
+ * Note that at this point, the resultant \ref VdpOutputSurface
+ * "VdpOutputSurface" may be fed back through the above path,
+ * either using \ref VdpOutputSurface "VdpOutputSurface" \ref
+ * VdpOutputSurfaceRender "rendering functionality",
+ * or as input to the \ref VdpVideoMixer "VdpVideoMixer" object.
+ *
+ * Finally, the resultant \ref VdpOutputSurface
+ * "VdpOutputSurface" must be displayed on screen. This is the job
+ * of the \ref VdpPresentationQueue "VdpPresentationQueue" object.
+ *
+ * \image html vdpau_data_flow.png
+ *
+ * \section entry_point_retrieval Entry Point Retrieval
+ *
+ * VDPAU is designed so that multiple implementations can be
+ * used without application changes. For example, VDPAU could be
+ * hosted on X11, or via direct GPU access.
+ *
+ * The key technology behind this is the use of function
+ * pointers and a "get proc address" style API for all entry
+ * points. Put another way, functions are not called directly
+ * via global symbols set up by the linker, but rather through
+ * pointers.
+ *
+ * In practical terms, the \ref api_winsys provides factory
+ * functions which not only create and return \ref VdpDevice
+ * "VdpDevice" objects, but also a function pointer to a \ref
+ * VdpGetProcAddress function, through which all entry point
+ * function pointers will be retrieved.
+ *
+ * \subsection entry_point_philosophy Philosophy
+ *
+ * It is entirely possible to envisage a simpler scheme whereby
+ * such function pointers are hidden. That is, the application
+ * would link against a wrapper library that exposed "real"
+ * functions. The application would then call such functions
+ * directly, by symbol, like any other function. The wrapper
+ * library would handle loading the appropriate back-end, and
+ * implementing a similar "get proc address" scheme internally.
+ *
+ * However, the above scheme does not work well in the context
+ * of separated \ref api_core and \ref api_winsys. In this
+ * scenario, one would require a separate wrapper library per
+ * Window System, since each Window System would have a
+ * different function name and prototype for the main factory
+ * function. If an application then wanted to be Window System
+ * agnostic (making final determination at run-time via some
+ * form of plugin), it may then need to link against two
+ * wrapper libraries, which would cause conflicts for all
+ * symbols other than the main factory function.
+ *
+ * Another disadvantage of the wrapper library approach is the
+ * extra level of function call required; the wrapper library
+ * would internally implement the existing "get proc address"
+ * and "function pointer" style dispatch anyway. Exposing this
+ * directly to the application is slightly more efficient.
+ *
+ * \section threading Multi-threading
+ *
+ * All VDPAU functionality is fully thread-safe; any number of
+ * threads may call into any VDPAU functions at any time. VDPAU
+ * may not be called from signal-handlers.
+ *
+ * Note, however, that this simply guarantees that internal
+ * VDPAU state will not be corrupted by thread usage, and that
+ * crashes and deadlocks will not occur. Completely arbitrary
+ * thread usage may not generate the results that an application
+ * desires. In particular, care must be taken when multiple
+ * threads are performing operations on the same VDPAU objects.
+ *
+ * VDPAU implementations guarantee correct flow of surface
+ * content through the rendering pipeline, but only when
+ * function calls that read from or write to a surface return to
+ * the caller prior to any thread calling any other function(s)
+ * that read from or write to the surface. Invoking multiple
+ * reads from a surface in parallel is OK.
+ *
+ * Note that this restriction is placed upon VDPAU function
+ * invocations, and specifically not upon any back-end
+ * hardware's physical rendering operations. VDPAU
+ * implementations are expected to internally synchronize such
+ * hardware operations.
+ *
+ * In a single-threaded application, the above restriction comes
+ * naturally; each function call completes before it is possible
+ * to begin a new function call.
+ *
+ * In a multi-threaded application, threads may need to be
+ * synchronized. For example, consider the situation where:
+ *
+ * - Thread 1 is parsing compressed video data, passing them
+ * through a \ref VdpDecoder "VdpDecoder" object, and filling a
+ * ring-buffer of \ref VdpVideoSurface "VdpVideoSurface"s
+ * - Thread 2 is consuming those \ref VdpVideoSurface
+ * "VdpVideoSurface"s, and using a \ref VdpVideoMixer
+ * "VdpVideoMixer" to process them and composite them with UI.
+ *
+ * In this case, the threads must synchronize to ensure that
+ * thread 1's call to \ref VdpDecoderRender has returned prior to
+ * thread 2's call(s) to \ref VdpVideoMixerRender that use that
+ * specific surface. This could be achieved using the following
+ * pseudo-code:
+ *
+ * \code
+ * Queue<VdpVideoSurface> q_full_surfaces;
+ * Queue<VdpVideoSurface> q_empty_surfaces;
+ *
+ * thread_1() {
+ * for (;;) {
+ * VdpVideoSurface s = q_empty_surfaces.get();
+ * // Parse compressed stream here
+ * VdpDecoderRender(s, ...);
+ * q_full_surfaces.put(s);
+ * }
+ * }
+ *
+ * // This would need to be more complex if
+ * // VdpVideoMixerRender were to be provided with more
+ * // than one field/frame at a time.
+ * thread_1() {
+ * for (;;) {
+ * // Possibly, other rendering operations to mixer
+ * // layer surfaces here.
+ * VdpOutputSurface t = ...;
+ * VdpPresentationQueueBlockUntilSurfaceIdle(t);
+ * VdpVideoSurface s = q_full_surfaces.get();
+ * VdpVideoMixerRender(s, t, ...);
+ * q_empty_surfaces.put(s);
+ * // Possibly, other rendering operations to "t" here
+ * VdpPresentationQueueDisplay(t, ...);
+ * }
+ * }
+ * \endcode
+ *
+ * Finally, note that VDPAU makes no guarantees regarding any
+ * level of parallelism in any given implementation. Put another
+ * way, use of multi-threading is not guaranteed to yield any
+ * performance gain, and in theory could even slightly reduce
+ * performance due to threading/synchronization overhead.
+ *
+ * However, the intent of the threading requirements is to allow
+ * for e.g. video decoding and video mixer operations to proceed
+ * in parallel in hardware. Given a (presumably multi-threaded)
+ * application that kept each portion of the hardware busy, this
+ * would yield a performance increase.
+ *
+ * \section endianness Surface Endianness
+ *
+ * When dealing with surface content, i.e. the input/output of
+ * Put/GetBits functions, applications must take care to access
+ * memory in the correct fashion, so as to avoid endianness
+ * issues.
+ *
+ * By established convention in the 3D graphics world, RGBA data
+ * is defined to be an array of 32-bit pixels containing packed
+ * RGBA components, not as an array of bytes or interleaved RGBA
+ * components. VDPAU follows this convention. As such,
+ * applications are expected to access such surfaces as arrays
+ * of 32-bit components (i.e. using a 32-bit pointer), and not
+ * as interleaved arrays of 8-bit components (i.e. using an
+ * 8-bit pointer.) Deviation from this convention will lead to
+ * endianness issues, unless appropriate care is taken.
+ *
+ * The same convention is followed for some packed YCbCr formats
+ * such as \ref VDP_YCBCR_FORMAT_Y8U8V8A8; i.e. they are
+ * considered arrays of 32-bit pixels, and hence should be
+ * accessed as such.
+ *
+ * For YCbCr formats with chroma decimation and/or planar
+ * formats, however, this convention is awkward. Therefore,
+ * formats such as \ref VDP_YCBCR_FORMAT_NV12 are defined as
+ * arrays of (potentially interleaved) byte-sized components.
+ * Hence, applications should manipulate such data 8-bits at a
+ * time, using 8-bit pointers.
+ *
+ * Note that one common usage for the input/output of
+ * Put/GetBits APIs is file I/O. Typical file I/O APIs treat all
+ * memory as a simple array of 8-bit values. This violates the
+ * rule requiring surface data to be accessed in its true native
+ * format. As such, applications may be required to solve
+ * endianness issues. Possible solutions include:
+ *
+ * - Authoring static UI data files according to the endianness
+ * of the target execution platform.
+ * - Conditionally byte-swapping Put/GetBits data buffers at
+ * run-time based on execution platform.
+ *
+ * Note: Complete details regarding each surface format's
+ * precise pixel layout is included with the documentation of
+ * each surface type. For example, see \ref
+ * VDP_RGBA_FORMAT_B8G8R8A8.
+ *
+ * \section video_mixer_usage Video Mixer Usage
+ *
+ * \subsection video_surface_content VdpVideoSurface Content
+ *
+ * Each \ref VdpVideoSurface "VdpVideoSurface" is expected to
+ * contain an entire frame's-worth of data, irrespective of
+ * whether an interlaced of progressive sequence is being
+ * decoded.
+ *
+ * Depending on the exact encoding structure of the compressed
+ * video stream, the application may need to call \ref
+ * VdpDecoderRender twice to fill a single \ref VdpVideoSurface
+ * "VdpVideoSurface". When the stream contains an encoded
+ * progressive frame, or a "frame coded" interlaced field-pair,
+ * a single \ref VdpDecoderRender call will fill the entire
+ * surface. When the stream contains separately encoded
+ * interlaced fields, two \ref VdpDecoderRender calls will be
+ * required; one for the top field, and one for the bottom
+ * field.
+ *
+ * Implementation note: When \ref VdpDecoderRender renders an
+ * interlaced field, this operation must not disturb the content
+ * of the other field in the surface.
+ *
+ * \subsection vm_render_surfaces VdpVideoMixerRender surface list
+ *
+ * The \ref VdpVideoMixerRender API receives \ref VdpVideoSurface
+ * "VdpVideoSurface" IDs for any number of fields/frames. The
+ * application should strive to provide as many fields/frames as
+ * practical, to enable advanced video processing
+ * algorithms. At a minimum, the current field/frame must be
+ * provided. It is recommended that at least 2 past and 1 future
+ * frame be provided in all cases.
+ *
+ * Note that it is entirely possible, in general, for any of the
+ * \ref VdpVideoMixer "VdpVideoMixer" post-processing steps to
+ * require access to multiple input fields/frames.
+ *
+ * It is legal for an application not to provide some or all of
+ * the surfaces other than the "current" surface. Note that this
+ * may cause degraded operation of the \ref VdpVideoMixer
+ * "VdpVideoMixer" algorithms. However, this may be required in
+ * the case of temporary file or network read errors, decode
+ * errors, etc.
+ *
+ * When an application chooses not to provide a particular
+ * surface to \ref VdpVideoMixerRender, then this "slot" in the
+ * surface list must be filled with the special value \ref
+ * VDP_INVALID_HANDLE, to explicitly indicate that the picture
+ * is missing; do not simply shuffle other surfaces together to
+ * fill in the gap.
+ *
+ * The \ref VdpVideoMixerRender parameter \b
+ * current_picture_structure applies to \b
+ * video_surface_current. The picture structure for the other
+ * surfaces will be automatically derived from that for the
+ * current picture as detailed below.
+ *
+ * If \b current_picture_structure is \ref
+ * VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME, then all surfaces are
+ * assumed to be frames. Otherwise, the picture structure is
+ * assumed to alternate between top and bottom field, anchored
+ * against \b current_picture_structure and \b
+ * video_surface_current.
+ *
+ * \subsection deinterlacing Applying de-interlacing
+ *
+ * Note that \ref VdpVideoMixerRender disables de-interlacing
+ * when \b current_picture_structure is \ref
+ * VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME; frames by definition
+ * need no de-interlacing.
+ *
+ * Weave de-interlacing may be obtained by giving the video
+ * mixer a surface containing two interlaced fields, but
+ * informing the \ref VdpVideoMixer "VdpVideoMixer" that the
+ * surface has \ref VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME.
+ *
+ * Bob de-interlacing is the default for interlaced content.
+ * More advanced de-interlacing techniques may be available,
+ * depending on the implementation. Such features need to be
+ * requested when creating the \ref VdpVideoMixer "VdpVideoMixer",
+ * and subsequently enabled.
+ *
+ * If the source material is marked progressive, two options are
+ * available for \ref VdpVideoMixerRender usage:
+ *
+ * -# Simply pass the allegedly progressive frames through the
+ * mixer, marking them as progressive. This equates to a
+ * so-called "flag following" mode.
+ * -# Apply any pulldown flags in the stream, yielding a higher
+ * rate stream of interlaced fields. These should then be
+ * passed through the mixer, marked as fields, with
+ * de-interlacing enabled, and inverse telecine optionally
+ * enabled. This should allow for so-called "bad edit"
+ * detection. However, it requires more processing power from
+ * the hardware.
+ *
+ * If the source material is marked interlaced, the decoded
+ * interlaced fields should always be marked as fields when
+ * processing them with the mixer. Some de-interlacing
+ * algorithm is then always applied. Inverse telecine may be
+ * useful in cases where some portions, or all of, the
+ * interlaced stream is telecined film.
+ *
+ * \section extending Extending the API
+ *
+ * \subsection extend_enums Enumerations and Other Constants
+ *
+ * VDPAU defines a number of enumeration types.
+ *
+ * When modifying VDPAU, existing enumeration constants must
+ * continue to exist (although they may be deprecated), and do
+ * so in the existing order.
+ *
+ * The above discussion naturally applies to "manually" defined
+ * enumerations, using pre-processor macros, too.
+ *
+ * \subsection extend_structs Structures
+ *
+ * In most case, VDPAU includes no provision for modifying existing
+ * structure definitions, although they may be deprecated.
+ *
+ * New structures may be created, together with new API entry
+ * points or feature/attribute/parameter values, to expose new
+ * functionality.
+ *
+ * A few structures are considered plausible candidates for future extension.
+ * Such structures include a version number as the first field, indicating the
+ * exact layout of the client-provided data. Such structures may only be
+ * modified by adding new fields to the end of the structure, so that the
+ * original structure definition is completely compatible with a leading
+ * subset of fields of the extended structure.
+ *
+ * \subsection extend_functions Functions
+ *
+ * Existing functions may not be modified, although they may be
+ * deprecated.
+ *
+ * New functions may be added at will. Note the enumeration
+ * requirements when modifying the enumeration that defines the
+ * list of entry points.
+ *
+ * \section preemption_note Display Preemption
+ *
+ * Please note that the display may be preempted away from
+ * VDPAU at any time. See \ref display_preemption for more
+ * details.
+ *
+ * \subsection trademarks Trademarks
+ *
+ * VDPAU is a trademark of NVIDIA Corporation. You may freely use the
+ * VDPAU trademark, as long as trademark ownership is attributed to
+ * NVIDIA Corporation.
+ */
+
+/**
+ * \file vdpau.h
+ * \brief The Core API
+ *
+ * This file contains the \ref api_core "Core API".
+ */
+
+#ifndef _VDPAU_H
+#define _VDPAU_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup api_core Core API
+ *
+ * The core API encompasses all VDPAU functionality that operates
+ * in the same fashion across all Window Systems.
+ *
+ * @{
+ */
+
+/**
+ * \defgroup base_types Basic Types
+ *
+ * VDPAU primarily uses ISO C99 types from \c stdint.h.
+ *
+ * @{
+ */
+
+/** \brief A true \ref VdpBool value */
+#define VDP_TRUE 1
+/** \brief A false \ref VdpBool value */
+#define VDP_FALSE 0
+/**
+ * \brief A boolean value, holding \ref VDP_TRUE or \ref
+ * VDP_FALSE.
+ */
+typedef int VdpBool;
+
+/*@}*/
+
+/**
+ * \defgroup misc_types Miscellaneous Types
+ *
+ * @{
+ */
+
+/**
+ * \brief An invalid object handle value.
+ *
+ * This value may be used to represent an invalid, or
+ * non-existent, object (\ref VdpDevice "VdpDevice",
+ * \ref VdpVideoSurface "VdpVideoSurface", etc.)
+ *
+ * Note that most APIs require valid object handles in all
+ * cases, and will fail when presented with this value.
+ */
+#define VDP_INVALID_HANDLE 0xffffffffU
+
+/**
+ * \brief The set of all chroma formats for \ref VdpVideoSurface
+ * "VdpVideoSurface"s.
+ */
+typedef uint32_t VdpChromaType;
+
+/** \hideinitializer \brief 4:2:0 chroma format. */
+#define VDP_CHROMA_TYPE_420 (VdpChromaType)0
+/** \hideinitializer \brief 4:2:2 chroma format. */
+#define VDP_CHROMA_TYPE_422 (VdpChromaType)1
+/** \hideinitializer \brief 4:4:4 chroma format. */
+#define VDP_CHROMA_TYPE_444 (VdpChromaType)2
+
+/**
+ * \brief The set of all known YCbCr surface formats.
+ */
+typedef uint32_t VdpYCbCrFormat;
+
+/**
+ * \hideinitializer
+ * \brief The "NV12" YCbCr surface format.
+ *
+ * This format has a two planes, a Y plane and a UV plane.
+ *
+ * The Y plane is an array of byte-sized Y components.
+ * Applications should access this data via a uint8_t pointer.
+ *
+ * The UV plane is an array of interleaved byte-sized U and V
+ * components, in the order U, V, U, V. Applications should
+ * access this data via a uint8_t pointer.
+ */
+#define VDP_YCBCR_FORMAT_NV12 (VdpYCbCrFormat)0
+/**
+ * \hideinitializer
+ * \brief The "YV12" YCbCr surface format.
+ *
+ * This format has a three planes, a Y plane, a U plane, and a V
+ * plane.
+ *
+ * Each of the planes is an array of byte-sized components.
+ *
+ * Applications should access this data via a uint8_t pointer.
+ */
+#define VDP_YCBCR_FORMAT_YV12 (VdpYCbCrFormat)1
+/**
+ * \hideinitializer
+ * \brief The "UYVY" YCbCr surface format.
+ *
+ * This format may also be known as Y422, UYNV, HDYC.
+ *
+ * This format has a single plane.
+ *
+ * This plane is an array of interleaved byte-sized Y, U, and V
+ * components, in the order U, Y, V, Y, U, Y, V, Y.
+ *
+ * Applications should access this data via a uint8_t pointer.
+ */
+#define VDP_YCBCR_FORMAT_UYVY (VdpYCbCrFormat)2
+/**
+ * \hideinitializer
+ * \brief The "YUYV" YCbCr surface format.
+ *
+ * This format may also be known as YUY2, YUNV, V422.
+ *
+ * This format has a single plane.
+ *
+ * This plane is an array of interleaved byte-sized Y, U, and V
+ * components, in the order Y, U, Y, V, Y, U, Y, V.
+ *
+ * Applications should access this data via a uint8_t pointer.
+ */
+#define VDP_YCBCR_FORMAT_YUYV (VdpYCbCrFormat)3
+/**
+ * \hideinitializer
+ * \brief A packed YCbCr format.
+ *
+ * This format has a single plane.
+ *
+ * This plane is an array packed 32-bit pixel data. Within each
+ * 32-bit pixel, bits [31:24] contain A, bits [23:16] contain V,
+ * bits [15:8] contain U, and bits [7:0] contain Y.
+ *
+ * Applications should access this data via a uint32_t pointer.
+ */
+#define VDP_YCBCR_FORMAT_Y8U8V8A8 (VdpYCbCrFormat)4
+/**
+ * \hideinitializer
+ * \brief A packed YCbCr format.
+ *
+ * This format has a single plane.
+ *
+ * This plane is an array packed 32-bit pixel data. Within each
+ * 32-bit pixel, bits [31:24] contain A, bits [23:16] contain Y,
+ * bits [15:8] contain U, and bits [7:0] contain V.
+ *
+ * Applications should access this data via a uint32_t pointer.
+ */
+#define VDP_YCBCR_FORMAT_V8U8Y8A8 (VdpYCbCrFormat)5
+
+/**
+ * \brief The set of all known RGB surface formats.
+ */
+typedef uint32_t VdpRGBAFormat;
+
+/**
+ * \hideinitializer
+ * \brief A packed RGB format.
+ *
+ * This format has a single plane.
+ *
+ * This plane is an array packed 32-bit pixel data. Within each
+ * 32-bit pixel, bits [31:24] contain A, bits [23:16] contain R,
+ * bits [15:8] contain G, and bits [7:0] contain B.
+ *
+ * Applications should access this data via a uint32_t pointer.
+ */
+#define VDP_RGBA_FORMAT_B8G8R8A8 (VdpRGBAFormat)0
+/**
+ * \hideinitializer
+ * \brief A packed RGB format.
+ *
+ * This format has a single plane.
+ *
+ * This plane is an array packed 32-bit pixel data. Within each
+ * 32-bit pixel, bits [31:24] contain A, bits [23:16] contain B,
+ * bits [15:8] contain G, and bits [7:0] contain R.
+ *
+ * Applications should access this data via a uint32_t pointer.
+ */
+#define VDP_RGBA_FORMAT_R8G8B8A8 (VdpRGBAFormat)1
+/**
+ * \hideinitializer
+ * \brief A packed RGB format.
+ *
+ * This format has a single plane.
+ *
+ * This plane is an array packed 32-bit pixel data. Within each
+ * 32-bit pixel, bits [31:30] contain A, bits [29:20] contain B,
+ * bits [19:10] contain G, and bits [9:0] contain R.
+ *
+ * Applications should access this data via a uint32_t pointer.
+ */
+#define VDP_RGBA_FORMAT_R10G10B10A2 (VdpRGBAFormat)2
+/**
+ * \hideinitializer
+ * \brief A packed RGB format.
+ *
+ * This format has a single plane.
+ *
+ * This plane is an array packed 32-bit pixel data. Within each
+ * 32-bit pixel, bits [31:30] contain A, bits [29:20] contain R,
+ * bits [19:10] contain G, and bits [9:0] contain B.
+ *
+ * Applications should access this data via a uint32_t pointer.
+ */
+#define VDP_RGBA_FORMAT_B10G10R10A2 (VdpRGBAFormat)3
+/**
+ * \hideinitializer
+ * \brief An alpha-only surface format.
+ *
+ * This format has a single plane.
+ *
+ * This plane is an array of byte-sized components.
+ *
+ * Applications should access this data via a uint8_t pointer.
+ */
+#define VDP_RGBA_FORMAT_A8 (VdpRGBAFormat)4
+
+/**
+ * \brief The set of all known indexed surface formats.
+ */
+typedef uint32_t VdpIndexedFormat;
+
+/**
+ * \hideinitializer
+ * \brief A 4-bit indexed format, with alpha.
+ *
+ * This format has a single plane.
+ *
+ * This plane is an array of byte-sized components. Within each
+ * byte, bits [7:4] contain I (index), and bits [3:0] contain A.
+ *
+ * Applications should access this data via a uint8_t pointer.
+ */
+#define VDP_INDEXED_FORMAT_A4I4 (VdpIndexedFormat)0
+/**
+ * \hideinitializer
+ * \brief A 4-bit indexed format, with alpha.
+ *
+ * This format has a single plane.
+ *
+ * This plane is an array of byte-sized components. Within each
+ * byte, bits [7:4] contain A, and bits [3:0] contain I (index).
+ *
+ * Applications should access this data via a uint8_t pointer.
+ */
+#define VDP_INDEXED_FORMAT_I4A4 (VdpIndexedFormat)1
+/**
+ * \hideinitializer
+ * \brief A 8-bit indexed format, with alpha.
+ *
+ * This format has a single plane.
+ *
+ * This plane is an array of interleaved byte-sized A and I
+ * (index) components, in the order A, I, A, I.
+ *
+ * Applications should access this data via a uint8_t pointer.
+ */
+#define VDP_INDEXED_FORMAT_A8I8 (VdpIndexedFormat)2
+/**
+ * \hideinitializer
+ * \brief A 8-bit indexed format, with alpha.
+ *
+ * This format has a single plane.
+ *
+ * This plane is an array of interleaved byte-sized A and I
+ * (index) components, in the order I, A, I, A.
+ *
+ * Applications should access this data via a uint8_t pointer.
+ */
+#define VDP_INDEXED_FORMAT_I8A8 (VdpIndexedFormat)3
+
+/**
+ * \brief A location within a surface.
+ *
+ * The VDPAU co-ordinate system has its origin at the top-left
+ * of a surface, with x and y components increasing right and
+ * down.
+ */
+typedef struct {
+ /** X co-ordinate. */
+ uint32_t x;
+ /** Y co-ordinate. */
+ uint32_t y;
+} VdpPoint;
+
+/**
+ * \brief A rectangular region of a surface.
+ *
+ * The co-ordinates are top-left inclusive, bottom-right
+ * exclusive.
+ *
+ * The VDPAU co-ordinate system has its origin at the top-left
+ * of a surface, with x and y components increasing right and
+ * down.
+ */
+typedef struct {
+ /** Left X co-ordinate. Inclusive. */
+ uint32_t x0;
+ /** Top Y co-ordinate. Inclusive. */
+ uint32_t y0;
+ /** Right X co-ordinate. Exclusive. */
+ uint32_t x1;
+ /** Bottom Y co-ordinate. Exclusive. */
+ uint32_t y1;
+} VdpRect;
+
+/**
+ * A constant RGBA color.
+ *
+ * Note that the components are stored as float values in the
+ * range 0.0...1.0 rather than format-specific integer values.
+ * This allows VdpColor values to be independent from the exact
+ * surface format(s) in use.
+ */
+typedef struct {
+ float red;
+ float green;
+ float blue;
+ float alpha;
+} VdpColor;
+
+/*@}*/
+
+/**
+ * \defgroup error_handling Error Handling
+ *
+ * @{
+ */
+
+/**
+ * \hideinitializer
+ * \brief The set of all possible error codes.
+ */
+typedef enum {
+ /** The operation completed successfully; no error. */
+ VDP_STATUS_OK = 0,
+ /**
+ * No backend implementation could be loaded.
+ */
+ VDP_STATUS_NO_IMPLEMENTATION,
+ /**
+ * The display was preempted, or a fatal error occurred.
+ *
+ * The application must re-initialize VDPAU.
+ */
+ VDP_STATUS_DISPLAY_PREEMPTED,
+ /**
+ * An invalid handle value was provided.
+ *
+ * Either the handle does not exist at all, or refers to an object of an
+ * incorrect type.
+ */
+ VDP_STATUS_INVALID_HANDLE,
+ /**
+ * An invalid pointer was provided.
+ *
+ * Typically, this means that a NULL pointer was provided for an "output"
+ * parameter.
+ */
+ VDP_STATUS_INVALID_POINTER,
+ /**
+ * An invalid/unsupported \ref VdpChromaType value was supplied.
+ */
+ VDP_STATUS_INVALID_CHROMA_TYPE,
+ /**
+ * An invalid/unsupported \ref VdpYCbCrFormat value was supplied.
+ */
+ VDP_STATUS_INVALID_Y_CB_CR_FORMAT,
+ /**
+ * An invalid/unsupported \ref VdpRGBAFormat value was supplied.
+ */
+ VDP_STATUS_INVALID_RGBA_FORMAT,
+ /**
+ * An invalid/unsupported \ref VdpIndexedFormat value was supplied.
+ */
+ VDP_STATUS_INVALID_INDEXED_FORMAT,
+ /**
+ * An invalid/unsupported \ref VdpColorStandard value was supplied.
+ */
+ VDP_STATUS_INVALID_COLOR_STANDARD,
+ /**
+ * An invalid/unsupported \ref VdpColorTableFormat value was supplied.
+ */
+ VDP_STATUS_INVALID_COLOR_TABLE_FORMAT,
+ /**
+ * An invalid/unsupported \ref VdpOutputSurfaceRenderBlendFactor value was
+ * supplied.
+ */
+ VDP_STATUS_INVALID_BLEND_FACTOR,
+ /**
+ * An invalid/unsupported \ref VdpOutputSurfaceRenderBlendEquation value
+ * was supplied.
+ */
+ VDP_STATUS_INVALID_BLEND_EQUATION,
+ /**
+ * An invalid/unsupported flag value/combination was supplied.
+ */
+ VDP_STATUS_INVALID_FLAG,
+ /**
+ * An invalid/unsupported \ref VdpDecoderProfile value was supplied.
+ */
+ VDP_STATUS_INVALID_DECODER_PROFILE,
+ /**
+ * An invalid/unsupported \ref VdpVideoMixerFeature value was supplied.
+ */
+ VDP_STATUS_INVALID_VIDEO_MIXER_FEATURE,
+ /**
+ * An invalid/unsupported \ref VdpVideoMixerParameter value was supplied.
+ */
+ VDP_STATUS_INVALID_VIDEO_MIXER_PARAMETER,
+ /**
+ * An invalid/unsupported \ref VdpVideoMixerAttribute value was supplied.
+ */
+ VDP_STATUS_INVALID_VIDEO_MIXER_ATTRIBUTE,
+ /**
+ * An invalid/unsupported \ref VdpVideoMixerPictureStructure value was
+ * supplied.
+ */
+ VDP_STATUS_INVALID_VIDEO_MIXER_PICTURE_STRUCTURE,
+ /**
+ * An invalid/unsupported \ref VdpFuncId value was supplied.
+ */
+ VDP_STATUS_INVALID_FUNC_ID,
+ /**
+ * The size of a supplied object does not match the object it is being
+ * used with.
+ *
+ * For example, a \ref VdpVideoMixer "VdpVideoMixer" is configured to
+ * process \ref VdpVideoSurface "VdpVideoSurface" objects of a specific
+ * size. If presented with a \ref VdpVideoSurface "VdpVideoSurface" of a
+ * different size, this error will be raised.
+ */
+ VDP_STATUS_INVALID_SIZE,
+ /**
+ * An invalid/unsupported value was supplied.
+ *
+ * This is a catch-all error code for values of type other than those
+ * with a specific error code.
+ */
+ VDP_STATUS_INVALID_VALUE,
+ /**
+ * An invalid/unsupported structure version was specified in a versioned
+ * structure. This implies that the implementation is older than the
+ * header file the application was built against.
+ */
+ VDP_STATUS_INVALID_STRUCT_VERSION,
+ /**
+ * The system does not have enough resources to complete the requested
+ * operation at this time.
+ */
+ VDP_STATUS_RESOURCES,
+ /**
+ * The set of handles supplied are not all related to the same VdpDevice.
+ *
+ * When performing operations that operate on multiple surfaces, such as
+ * \ref VdpOutputSurfaceRenderOutputSurface or \ref VdpVideoMixerRender,
+ * all supplied surfaces must have been created within the context of the
+ * same \ref VdpDevice "VdpDevice" object. This error is raised if they were
+ * not.
+ */
+ VDP_STATUS_HANDLE_DEVICE_MISMATCH,
+ /**
+ * A catch-all error, used when no other error code applies.
+ */
+ VDP_STATUS_ERROR,
+} VdpStatus;
+
+/**
+ * \brief Retrieve a string describing an error code.
+ * \param[in] status The error code.
+ * \return A pointer to the string. Note that this is a
+ * statically allocated read-only string. As such, the
+ * application must not free the returned pointer. The
+ * pointer is valid as long as the VDPAU implementation is
+ * present within the application's address space.
+ */
+typedef char const * VdpGetErrorString(
+ VdpStatus status
+);
+
+/*@}*/
+
+/**
+ * \defgroup versioning Versioning
+ *
+ *
+ * @{
+ */
+
+/**
+ * \brief The VDPAU version described by this header file.
+ *
+ * Note that VDPAU version numbers are simple integers that
+ * increase monotonically (typically by value 1) with each VDPAU
+ * header revision.
+ */
+#define VDPAU_VERSION 0
+
+/**
+ * \brief Retrieve the VDPAU version implemented by the backend.
+ * \param[out] api_version The API version.
+ * \return VdpStatus The completion status of the operation.
+ */
+typedef VdpStatus VdpGetApiVersion(
+ /* output parameters follow */
+ uint32_t * api_version
+);
+
+/**
+ * \brief Retrieve an implementation-specific string description
+ * of the implementation. This typically includes detailed version
+ * information.
+ * \param[out] information_string A pointer to the information
+ * string. Note that this is a statically allocated
+ * read-only string. As such, the application must not
+ * free the returned pointer. The pointer is valid as long
+ * as the implementation is present within the
+ * application's address space.
+ * \return VdpStatus The completion status of the operation.
+ *
+ * Note that the returned string is useful for information
+ * reporting. It is not intended that the application should
+ * parse this string in order to determine any information about
+ * the implementation.
+ */
+typedef VdpStatus VdpGetInformationString(
+ /* output parameters follow */
+ char const * * information_string
+);
+
+/*@}*/
+
+/**
+ * \defgroup VdpDevice VdpDevice; Primary API object
+ *
+ * The VdpDevice is the root of the VDPAU object system. Using a
+ * VdpDevice object, all other object types may be created. See
+ * the sections describing those other object types for details
+ * on object creation.
+ *
+ * Note that VdpDevice objects are created using the \ref
+ * api_winsys.
+ *
+ * @{
+ */
+
+/**
+ * \brief An opaque handle representing a VdpDevice object.
+ */
+typedef uint32_t VdpDevice;
+
+/**
+ * \brief Destroy a VdpDevice.
+ * \param[in] device The device to destroy.
+ * \return VdpStatus The completion status of the operation.
+ */
+typedef VdpStatus VdpDeviceDestroy(
+ VdpDevice device
+);
+
+/*@}*/
+
+/**
+ * \defgroup VdpCSCMatrix VdpCSCMatrix; CSC Matrix Manipulation
+ *
+ * When converting from YCbCr to RGB data formats, a color space
+ * conversion operation must be performed. This operation is
+ * parameterized using a "color space conversion matrix". The
+ * VdpCSCMatrix is a data structure representing this
+ * information.
+ *
+ * @{
+ */
+
+/**
+ * \brief Storage for a color space conversion matrix.
+ *
+ * Note that the application may choose to construct the matrix
+ * content by either:
+ * - Directly filling in the fields of the CSC matrix
+ * - Using the \ref VdpGenerateCSCMatrix helper function.
+ *
+ * The color space conversion equation is as follows:
+ *
+ * \f[
+ * \left( \begin{array}{c} R \\ G \\ B \end{array} \right)
+ * =
+ * \left( \begin{array}{cccc}
+ * m_{0,0} & m_{0,1} & m_{0,2} & m_{0,3} \\
+ * m_{1,0} & m_{1,1} & m_{1,2} & m_{1,3} \\
+ * m_{2,0} & m_{2,1} & m_{2,2} & m_{2,3}
+ * \end{array}
+ * \right)
+ * *
+ * \left( \begin{array}{c} Y \\ Cb \\ Cr \\ 1.0 \end{array}
+ * \right)
+ * \f]
+ */
+typedef float VdpCSCMatrix[3][4];
+
+#define VDP_PROCAMP_VERSION 0
+
+/**
+ * \brief Procamp operation parameterization data.
+ *
+ * When performing a color space conversion operation, various
+ * adjustments can be performed at the same time, such as
+ * brightness and contrast. This structure defines the level of
+ * adjustments to make.
+ */
+typedef struct {
+ /**
+ * This field must be filled with VDP_PROCAMP_VERSION
+ */
+ uint32_t struct_version;
+ /**
+ * Brightness adjustment amount. A value clamped between
+ * -1.0 and 1.0. 0.0 represents no modification.
+ */
+ float brightness;
+ /**
+ * Contrast adjustment amount. A value clamped between
+ * 0.0 and 10.0. 1.0 represents no modification.
+ */
+ float contrast;
+ /**
+ * Saturation adjustment amount. A value clamped between 0.0 and
+ * 10.0. 1.0 represents no modification.
+ */
+ float saturation;
+ /**
+ * Hue adjustment amount. A value clamped between
+ * -PI and PI. 0.0 represents no modification.
+ */
+ float hue;
+} VdpProcamp;
+
+/**
+ * \brief YCbCr color space specification.
+ *
+ * A number of YCbCr color spaces exist. This enumeration
+ * defines the specifications known to VDPAU.
+ */
+typedef uint32_t VdpColorStandard;
+
+/** \hideinitializer \brief ITU-R BT.601 */
+#define VDP_COLOR_STANDARD_ITUR_BT_601 (VdpColorStandard)0
+/** \hideinitializer \brief ITU-R BT.709 */
+#define VDP_COLOR_STANDARD_ITUR_BT_709 (VdpColorStandard)1
+/** \hideinitializer \brief SMPTE-240M */
+#define VDP_COLOR_STANDARD_SMPTE_240M (VdpColorStandard)2
+
+/**
+ * \brief Generate a color space conversion matrix
+ * \param[in] procamp The procamp adjustments to make. If NULL,
+ * no adjustments will be made.
+ * \param[in] standard The YCbCr color space to convert from.
+ * \param[out] csc_matrix The CSC matrix to initialize.
+ * \return VdpStatus The completion status of the operation.
+ */
+typedef VdpStatus VdpGenerateCSCMatrix(
+ VdpProcamp * procamp,
+ VdpColorStandard standard,
+ /* output parameters follow */
+ VdpCSCMatrix * csc_matrix
+);
+
+/*@}*/
+
+/**
+ * \defgroup VdpVideoSurface VdpVideoSurface; Video Surface object
+ *
+ * A VdpVideoSurface stores YCbCr data in an internal format,
+ * with a variety of possible chroma sub-sampling options.
+ *
+ * A VdpVideoSurface may be filled with:
+ * - Data provided by the CPU via \ref
+ * VdpVideoSurfacePutBitsYCbCr (i.e. software decode.)
+ * - The result of applying a \ref VdpDecoder "VdpDecoder" to
+ * compressed video data.
+ *
+ * VdpVideoSurface content may be accessed by:
+ * - The application via \ref VdpVideoSurfaceGetBitsYCbCr
+ * - The Hardware that implements \ref VdpOutputSurface
+ * "VdpOutputSurface" \ref VdpOutputSurfaceRender
+ * "rendering functionality".
+ * - The Hardware the implements \ref VdpVideoMixer
+ * "VdpVideoMixer" functionality.
+ *
+ * VdpVideoSurfaces are not directly displayable. They must be
+ * converted into a displayable format using \ref VdpVideoMixer
+ * "VdpVideoMixer" objects.
+ *
+ * See \ref video_mixer_usage for additional information.
+ *
+ * @{
+ */
+
+/**
+ * \brief Query the implementation's VdpVideoSurface
+ * capabilities.
+ * \param[in] device The device to query.
+ * \param[in] surface_chroma_type The type of chroma type for
+ * which information is requested.
+ * \param[out] is_supported Is this chroma type supported?
+ * \param[out] max_width The maximum supported surface width for
+ * this chroma type.
+ * \param[out] max_height The maximum supported surface height
+ * for this chroma type.
+ * \return VdpStatus The completion status of the operation.
+ */
+typedef VdpStatus VdpVideoSurfaceQueryCapabilities(
+ VdpDevice device,
+ VdpChromaType surface_chroma_type,
+ /* output parameters follow */
+ VdpBool * is_supported,
+ uint32_t * max_width,
+ uint32_t * max_height
+);
+
+/**
+ * \brief Query the implementation's VdpVideoSurface
+ * GetBits/PutBits capabilities.
+ * \param[in] device The device to query.
+ * \param[in] surface_chroma_type The type of chroma type for
+ * which information is requested.
+ * \param[in] bits_ycbcr_format The format of application "bits"
+ * buffer for which information is requested.
+ * \param[out] is_supported Is this chroma type supported?
+ * \return VdpStatus The completion status of the operation.
+ */
+typedef VdpStatus VdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities(
+ VdpDevice device,
+ VdpChromaType surface_chroma_type,
+ VdpYCbCrFormat bits_ycbcr_format,
+ /* output parameters follow */
+ VdpBool * is_supported
+);
+
+/**
+ * \brief An opaque handle representing a VdpVideoSurface
+ * object.
+ */
+typedef uint32_t VdpVideoSurface;
+
+/**
+ * \brief Create a VdpVideoSurface.
+ * \param[in] device The device that will contain the surface.
+ * \param[in] chroma_type The chroma type of the new surface.
+ * \param[in] width The width of the new surface.
+ * \param[in] height The height of the new surface.
+ * \param[out] surface The new surface's handle.
+ * \return VdpStatus The completion status of the operation.
+ *
+ * The memory backing the surface may not be initialized during
+ * creation. Applications are expected to initialize any region
+ * that they use, via \ref VdpDecoderRender or \ref
+ * VdpVideoSurfacePutBitsYCbCr.
+ */
+typedef VdpStatus VdpVideoSurfaceCreate(
+ VdpDevice device,
+ VdpChromaType chroma_type,
+ uint32_t width,
+ uint32_t height,
+ /* output parameters follow */
+ VdpVideoSurface * surface
+);
+
+/**
+ * \brief Destroy a VdpVideoSurface.
+ * \param[in] surface The surface's handle.
+ * \return VdpStatus The completion status of the operation.
+ */
+typedef VdpStatus VdpVideoSurfaceDestroy(
+ VdpVideoSurface surface
+);
+
+/**
+ * \brief Retrieve the parameters used to create a
+ * VdpVideoSurface.
+ * \param[in] surface The surface's handle.
+ * \param[out] chroma_type The chroma type of the surface.
+ * \param[out] width The width of the surface.
+ * \param[out] height The height of the surface.
+ * \return VdpStatus The completion status of the operation.
+ */
+typedef VdpStatus VdpVideoSurfaceGetParameters(
+ VdpVideoSurface surface,
+ /* output parameters follow */
+ VdpChromaType * chroma_type,
+ uint32_t * width,
+ uint32_t * height
+);
+
+/**
+ * \brief Copy image data from a VdpVideoSurface to application
+ * memory in a specified YCbCr format.
+ * \param[in] surface The surface's handle.
+ * \param[in] destination_ycbcr_format The format of the
+ * application's data buffers.
+ * \param[in] destination_data Pointers to the application data
+ * buffers into which the image data will be written. Note
+ * that this is an array of pointers, one per plane. The
+ * destination_format parameter will define how many
+ * planes are required.
+ * \param[in] destination_pitches Pointers to the pitch values
+ * for the application data buffers. Note that this is an
+ * array of pointers, one per plane. The
+ * destination_format parameter will define how many
+ * planes are required.
+ * \return VdpStatus The completion status of the operation.
+ */
+typedef VdpStatus VdpVideoSurfaceGetBitsYCbCr(
+ VdpVideoSurface surface,
+ VdpYCbCrFormat destination_ycbcr_format,
+ void * const * destination_data,
+ uint32_t const * destination_pitches
+);
+
+/**
+ * \brief Copy image data from application memory in a specific
+ * YCbCr format to a VdpVideoSurface.
+ * \param[in] surface The surface's handle.
+ * \param[in] source_ycbcr_format The format of the
+ * application's data buffers.
+ * \param[in] source_data Pointers to the application data
+ * buffers from which the image data will be copied. Note
+ * that this is an array of pointers, one per plane. The
+ * source_format parameter will define how many
+ * planes are required.
+ * \param[in] source_pitches Pointers to the pitch values
+ * for the application data buffers. Note that this is an
+ * array of pointers, one per plane. The
+ * source_format parameter will define how many
+ * planes are required.
+ * \return VdpStatus The completion status of the operation.
+ */
+typedef VdpStatus VdpVideoSurfacePutBitsYCbCr(
+ VdpVideoSurface surface,
+ VdpYCbCrFormat source_ycbcr_format,
+ void const * const * source_data,
+ uint32_t const * source_pitches
+);
+
+/*@}*/
+
+/**
+ * \defgroup VdpOutputSurface VdpOutputSurface; Output Surface \
+ * object
+ *
+ * A VdpOutputSurface stores RGBA data in a defined format.
+ *
+ * A VdpOutputSurface may be filled with:
+ * - Data provided by the CPU via the various
+ * VdpOutputSurfacePutBits functions.
+ * - Using the VdpOutputSurface \ref VdpOutputSurfaceRender
+ * "rendering functionality".
+ * - Using a \ref VdpVideoMixer "VdpVideoMixer" object.
+ *
+ * VdpOutputSurface content may be accessed by:
+ * - The application via the various VdpOutputSurfaceGetBits
+ * functions.
+ * - The Hardware that implements VdpOutputSurface
+ * \ref VdpOutputSurfaceRender "rendering functionality".
+ * - The Hardware the implements \ref VdpVideoMixer
+ * "VdpVideoMixer" functionality.
+ * - The Hardware that implements \ref VdpPresentationQueue
+ * "VdpPresentationQueue" functionality,
+ *
+ * VdpVideoSurfaces are directly displayable using a \ref
+ * VdpPresentationQueue "VdpPresentationQueue" object.
+ *
+ * @{
+ */
+
+/**
+ * \brief The set of all known color table formats, for use with
+ * \ref VdpOutputSurfacePutBitsIndexed.
+ */
+typedef uint32_t VdpColorTableFormat;
+
+/**
+ * \hideinitializer
+ * \brief 8-bit per component packed into 32-bits
+ *
+ * This format is an array of packed 32-bit RGB color values.
+ * Bits [31:24] are unused, bits [23:16] contain R, bits [15:8]
+ * contain G, and bits [7:0] contain B. Note: The format is
+ * physically an array of uint32_t values, and should be accessed
+ * as such by the application in order to avoid endianness
+ * issues.
+ */
+#define VDP_COLOR_TABLE_FORMAT_B8G8R8X8 (VdpColorTableFormat)0
+
+/**
+ * \brief Query the implementation's VdpOutputSurface
+ * capabilities.
+ * \param[in] device The device to query.
+ * \param[in] surface_rgba_format The surface format for
+ * which information is requested.
+ * \param[out] is_supported Is this surface format supported?
+ * \param[out] max_width The maximum supported surface width for
+ * this chroma type.
+ * \param[out] max_height The maximum supported surface height
+ * for this chroma type.
+ * \return VdpStatus The completion status of the operation.
+ */
+typedef VdpStatus VdpOutputSurfaceQueryCapabilities(
+ VdpDevice device,
+ VdpRGBAFormat surface_rgba_format,
+ /* output parameters follow */
+ VdpBool * is_supported,
+ uint32_t * max_width,
+ uint32_t * max_height
+);
+
+/**
+ * \brief Query the implementation's capability to perform a
+ * PutBits operation using application data matching the
+ * surface's format.
+ * \param[in] device The device to query.
+ * \param[in] surface_rgba_format The surface format for
+ * which information is requested.
+ * \param[out] is_supported Is this surface format supported?
+ * \return VdpStatus The completion status of the operation.
+ */
+typedef VdpStatus VdpOutputSurfaceQueryGetPutBitsNativeCapabilities(
+ VdpDevice device,
+ VdpRGBAFormat surface_rgba_format,
+ /* output parameters follow */
+ VdpBool * is_supported
+);
+
+/**
+ * \brief Query the implementation's capability to perform a
+ * PutBits operation using application data in a specific
+ * indexed format.
+ * \param[in] device The device to query.
+ * \param[in] surface_rgba_format The surface format for
+ * which information is requested.
+ * \param[in] bits_indexed_format The format of the application
+ * data buffer.
+ * \param[in] color_table_format The format of the color lookup
+ * table.
+ * \param[out] is_supported Is this surface format supported?
+ * \return VdpStatus The completion status of the operation.
+ */
+typedef VdpStatus VdpOutputSurfaceQueryPutBitsIndexedCapabilities(
+ VdpDevice device,
+ VdpRGBAFormat surface_rgba_format,
+ VdpIndexedFormat bits_indexed_format,
+ VdpColorTableFormat color_table_format,
+ /* output parameters follow */
+ VdpBool * is_supported
+);
+
+/**
+ * \brief Query the implementation's capability to perform a
+ * PutBits operation using application data in a specific
+ * YCbCr/YUB format.
+ * \param[in] device The device to query.
+ * \param[in] surface_rgba_format The surface format for which
+ * information is requested.
+ * \param[in] bits_ycbcr_format The format of the application
+ * data buffer.
+ * \param[out] is_supported Is this surface format supported?
+ * \return VdpStatus The completion status of the operation.
+ */
+typedef VdpStatus VdpOutputSurfaceQueryPutBitsYCbCrCapabilities(
+ VdpDevice device,
+ VdpRGBAFormat surface_rgba_format,
+ VdpYCbCrFormat bits_ycbcr_format,
+ /* output parameters follow */
+ VdpBool * is_supported
+);
+
+/**
+ * \brief An opaque handle representing a VdpOutputSurface
+ * object.
+ */
+typedef uint32_t VdpOutputSurface;
+
+/**
+ * \brief Create a VdpOutputSurface.
+ * \param[in] device The device that will contain the surface.
+ * \param[in] rgba_format The format of the new surface.
+ * \param[in] width The width of the new surface.
+ * \param[in] height The height of the new surface.
+ * \param[out] surface The new surface's handle.
+ * \return VdpStatus The completion status of the operation.
+ *
+ * The memory backing the surface will be initialized to 0 color
+ * and 0 alpha (i.e. black.)
+ */
+typedef VdpStatus VdpOutputSurfaceCreate(
+ VdpDevice device,
+ VdpRGBAFormat rgba_format,
+ uint32_t width,
+ uint32_t height,
+ /* output parameters follow */
+ VdpOutputSurface * surface
+);
+
+/**
+ * \brief Destroy a VdpOutputSurface.
+ * \param[in] surface The surface's handle.
+ * \return VdpStatus The completion status of the operation.
+ */
+typedef VdpStatus VdpOutputSurfaceDestroy(
+ VdpOutputSurface surface
+);
+
+/**
+ * \brief Retrieve the parameters used to create a
+ * VdpOutputSurface.
+ * \param[in] surface The surface's handle.
+ * \param[out] rgba_format The format of the surface.
+ * \param[out] width The width of the surface.
+ * \param[out] height The height of the surface.
+ * \return VdpStatus The completion status of the operation.
+ */
+typedef VdpStatus VdpOutputSurfaceGetParameters(
+ VdpOutputSurface surface,
+ /* output parameters follow */
+ VdpRGBAFormat * rgba_format,
+ uint32_t * width,
+ uint32_t * height
+);
+
+/**
+ * \brief Copy image data from a VdpOutputSurface to application
+ * memory in the surface's native format.
+ * \param[in] surface The surface's handle.
+ * \param[in] source_rect The sub-rectangle of the source
+ * surface to copy. If NULL, the entire surface will be
+ * retrieved.
+ * \param[in] destination_data Pointers to the application data
+ * buffers into which the image data will be written. Note
+ * that this is an array of pointers, one per plane. The
+ * destination_format parameter will define how many
+ * planes are required.
+ * \param[in] destination_pitches Pointers to the pitch values
+ * for the application data buffers. Note that this is an
+ * array of pointers, one per plane. The
+ * destination_format parameter will define how many
+ * planes are required.
+ * \return VdpStatus The completion status of the operation.
+ */
+typedef VdpStatus VdpOutputSurfaceGetBitsNative(
+ VdpOutputSurface surface,
+ VdpRect const * source_rect,
+ void * const * destination_data,
+ uint32_t const * destination_pitches
+);
+
+/**
+ * \brief Copy image data from application memory in the
+ * surface's native format to a VdpOutputSurface.
+ * \param[in] surface The surface's handle.
+ * \param[in] source_data Pointers to the application data
+ * buffers from which the image data will be copied. Note
+ * that this is an array of pointers, one per plane. The
+ * source_format parameter will define how many
+ * planes are required.
+ * \param[in] source_pitches Pointers to the pitch values
+ * for the application data buffers. Note that this is an
+ * array of pointers, one per plane. The
+ * source_format parameter will define how many
+ * planes are required.
+ * \param[in] destination_rect The sub-rectangle of the surface
+ * to fill with application data. If NULL, the entire
+ * surface will be updated.
+ * \return VdpStatus The completion status of the operation.
+ */
+typedef VdpStatus VdpOutputSurfacePutBitsNative(
+ VdpOutputSurface surface,
+ void const * const * source_data,
+ uint32_t const * source_pitches,
+ VdpRect const * destination_rect
+);
+
+/**
+ * \brief Copy image data from application memory in a specific
+ * indexed format to a VdpOutputSurface.
+ * \param[in] surface The surface's handle.
+ * \param[in] source_indexed_format The format of the
+ * application's data buffers.
+ * \param[in] source_data Pointers to the application data
+ * buffers from which the image data will be copied. Note
+ * that this is an array of pointers, one per plane. The
+ * source_indexed_format parameter will define how many
+ * planes are required.
+ * \param[in] source_pitches Pointers to the pitch values
+ * for the application data buffers. Note that this is an
+ * array of pointers, one per plane. The
+ * source_indexed_format parameter will define how many
+ * planes are required.
+ * \param[in] destination_rect The sub-rectangle of the surface
+ * to fill with application data. If NULL, the entire
+ * surface will be updated.
+ * \param[in] color_table_format The format of the color_table.
+ * \param[in] color_table A table that maps between source index
+ * and target color data. See \ref VdpColorTableFormat for
+ * details regarding the memory layout.
+ * \return VdpStatus The completion status of the operation.
+ */
+typedef VdpStatus VdpOutputSurfacePutBitsIndexed(
+ VdpOutputSurface surface,
+ VdpIndexedFormat source_indexed_format,
+ void const * const * source_data,
+ uint32_t const * source_pitch,
+ VdpRect const * destination_rect,
+ VdpColorTableFormat color_table_format,
+ void const * color_table
+);
+
+/**
+ * \brief Copy image data from application memory in a specific
+ * YCbCr format to a VdpOutputSurface.
+ * \param[in] surface The surface's handle.
+ * \param[in] source_ycbcr_format The format of the
+ * application's data buffers.
+ * \param[in] source_data Pointers to the application data
+ * buffers from which the image data will be copied. Note
+ * that this is an array of pointers, one per plane. The
+ * source_ycbcr_format parameter will define how many
+ * planes are required.
+ * \param[in] source_pitches Pointers to the pitch values
+ * for the application data buffers. Note that this is an
+ * array of pointers, one per plane. The
+ * source_ycbcr_format parameter will define how many
+ * planes are required.
+ * \param[in] destination_rect The sub-rectangle of the surface
+ * to fill with application data. If NULL, the entire
+ * surface will be updated.
+ * \param[in] csc_matrix The color space conversion matrix used
+ * by the copy operation. If NULL, a default matrix will
+ * be used internally. Th default matrix is equivalent to
+ * ITU-R BT.601 with no procamp changes.
+ * \return VdpStatus The completion status of the operation.
+ */
+typedef VdpStatus VdpOutputSurfacePutBitsYCbCr(
+ VdpOutputSurface surface,
+ VdpYCbCrFormat source_ycbcr_format,
+ void const * const * source_data,
+ uint32_t const * source_pitches,
+ VdpRect const * destination_rect,
+ VdpCSCMatrix const * csc_matrix
+);
+
+/*@}*/
+
+/**
+ * \defgroup VdpBitmapSurface VdpBitmapSurface; Bitmap Surface \
+ * object
+ *
+ * A VdpBitmapSurface stores RGBA data in a defined format.
+ *
+ * A VdpBitmapSurface may be filled with:
+ * - Data provided by the CPU via the \ref
+ * VdpBitmapSurfacePutBitsNative function.
+ *
+ * VdpBitmapSurface content may be accessed by:
+ * - The Hardware that implements \ref VdpOutputSurface
+ * "VdpOutputSurface" \ref VdpOutputSurfaceRender
+ * "rendering functionality"
+ *
+ * VdpBitmapSurface objects are intended to store static read-only data, such
+ * as font glyphs, and the bitmaps used to compose an applications'
+ * user-interface.
+ *
+ * The primary differences between VdpBitmapSurfaces and
+ * \ref VdpOutputSurface "VdpOutputSurface"s are:
+ *
+ * - You cannot render to a VdpBitmapSurface, just upload native data via
+ * the PutBits API.
+ *
+ * - The read-only nature of a VdpBitmapSurface gives the implementation more
+ * flexibility in its choice of data storage location for the bitmap data.
+ * For example, some implementations may choose to store some/all
+ * VdpBitmapSurface objects in system memory to relieve GPU memory pressure.
+ *
+ * - VdpBitmapSurface and VdpOutputSurface may support different subsets of all
+ * known RGBA formats.
+ *
+ * @{
+ */
+
+/**
+ * \brief Query the implementation's VdpBitmapSurface
+ * capabilities.
+ * \param[in] device The device to query.
+ * \param[in] surface_rgba_format The surface format for
+ * which information is requested.
+ * \param[out] is_supported Is this surface format supported?
+ * \param[out] max_width The maximum supported surface width for
+ * this chroma type.
+ * \param[out] max_height The maximum supported surface height
+ * for this chroma type.
+ * \return VdpStatus The completion status of the operation.
+ */
+typedef VdpStatus VdpBitmapSurfaceQueryCapabilities(
+ VdpDevice device,
+ VdpRGBAFormat surface_rgba_format,
+ /* output parameters follow */
+ VdpBool * is_supported,
+ uint32_t * max_width,
+ uint32_t * max_height
+);
+
+/**
+ * \brief An opaque handle representing a VdpBitmapSurface
+ * object.
+ */
+typedef uint32_t VdpBitmapSurface;
+
+/**
+ * \brief Create a VdpBitmapSurface.
+ * \param[in] device The device that will contain the surface.
+ * \param[in] rgba_format The format of the new surface.
+ * \param[in] width The width of the new surface.
+ * \param[in] height The height of the new surface.
+ * \param[in] frequently_accessed Is this bitmap used
+ * frequently, or infrequently, by compositing options?
+ * Implementations may use this as a hint to determine how
+ * to allocate the underlying storage for the surface.
+ * \param[out] surface The new surface's handle.
+ * \return VdpStatus The completion status of the operation.
+ *
+ * The memory backing the surface may not be initialized
+ * during creation. Applications are expected initialize any
+ * region that they use, via \ref VdpBitmapSurfacePutBitsNative.
+ */
+typedef VdpStatus VdpBitmapSurfaceCreate(
+ VdpDevice device,
+ VdpRGBAFormat rgba_format,
+ uint32_t width,
+ uint32_t height,
+ VdpBool frequently_accessed,
+ /* output parameters follow */
+ VdpBitmapSurface * surface
+);
+
+/**
+ * \brief Destroy a VdpBitmapSurface.
+ * \param[in] surface The surface's handle.
+ * \return VdpStatus The completion status of the operation.
+ */
+typedef VdpStatus VdpBitmapSurfaceDestroy(
+ VdpBitmapSurface surface
+);
+
+/**
+ * \brief Retrieve the parameters used to create a
+ * VdpBitmapSurface.
+ * \param[in] surface The surface's handle.
+ * \param[out] rgba_format The format of the surface.
+ * \param[out] width The width of the surface.
+ * \param[out] height The height of the surface.
+ * \param[out] frequently_accessed The frequently_accessed state
+ * of the surface.
+ * \return VdpStatus The completion status of the operation.
+ */
+typedef VdpStatus VdpBitmapSurfaceGetParameters(
+ VdpBitmapSurface surface,
+ /* output parameters follow */
+ VdpRGBAFormat * rgba_format,
+ uint32_t * width,
+ uint32_t * height,
+ VdpBool * frequently_accessed
+);
+
+/**
+ * \brief Copy image data from application memory in the
+ * surface's native format to a VdpBitmapSurface.
+ * \param[in] surface The surface's handle.
+ * \param[in] source_data Pointers to the application data
+ * buffers from which the image data will be copied. Note
+ * that this is an array of pointers, one per plane. The
+ * source_format parameter will define how many
+ * planes are required.
+ * \param[in] source_pitches Pointers to the pitch values
+ * for the application data buffers. Note that this is an
+ * array of pointers, one per plane. The
+ * source_format parameter will define how many
+ * planes are required.
+ * \param[in] destination_rect The sub-rectangle of the surface
+ * to fill with application data. If NULL, the entire
+ * surface will be updated.
+ * \return VdpStatus The completion status of the operation.
+ */
+typedef VdpStatus VdpBitmapSurfacePutBitsNative(
+ VdpBitmapSurface surface,
+ void const * const * source_data,
+ uint32_t const * source_pitches,
+ VdpRect const * destination_rect
+);
+
+/*@}*/
+
+/**
+ * \defgroup VdpOutputSurfaceRender VdpOutputSurface Rendering \
+ * Functionality
+ *
+ * \ref VdpOutputSurface "VdpOutputSurface" objects
+ * directly provide some rendering/compositing operations. These
+ * are described below.
+ *
+ * @{
+ */
+
+/**
+ * \hideinitializer
+ * \brief The blending equation factors.
+ */
+typedef enum {
+ VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ZERO = 0,
+ VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE = 1,
+ VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_SRC_COLOR = 2,
+ VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_SRC_COLOR = 3,
+ VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_SRC_ALPHA = 4,
+ VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA = 5,
+ VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_DST_ALPHA = 6,
+ VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_DST_ALPHA = 7,
+ VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_DST_COLOR = 8,
+ VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_DST_COLOR = 9,
+ VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_SRC_ALPHA_SATURATE = 10,
+ VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_CONSTANT_COLOR = 11,
+ VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR = 12,
+ VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_CONSTANT_ALPHA = 13,
+ VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA = 14,
+} VdpOutputSurfaceRenderBlendFactor;
+
+/**
+ * \hideinitializer
+ * \brief The blending equations.
+ */
+typedef enum {
+ VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_SUBTRACT = 0,
+ VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_REVERSE_SUBTRACT = 1,
+ VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_ADD = 2,
+ VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_MIN = 3,
+ VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_MAX = 4,
+} VdpOutputSurfaceRenderBlendEquation;
+
+#define VDP_OUTPUT_SURFACE_RENDER_BLEND_STATE_VERSION 0
+
+/**
+ * \brief Complete blending operation definition.
+ */
+typedef struct {
+ /**
+ * This field must be filled with VDP_OUTPUT_SURFACE_RENDER_BLEND_STATE_VERSIION
+ */
+ uint32_t struct_version;
+ VdpOutputSurfaceRenderBlendFactor blend_factor_source_color;
+ VdpOutputSurfaceRenderBlendFactor blend_factor_destination_color;
+ VdpOutputSurfaceRenderBlendFactor blend_factor_source_alpha;
+ VdpOutputSurfaceRenderBlendFactor blend_factor_destination_alpha;
+ VdpOutputSurfaceRenderBlendEquation blend_equation_color;
+ VdpOutputSurfaceRenderBlendEquation blend_equation_alpha;
+ VdpColor blend_constant;
+} VdpOutputSurfaceRenderBlendState;
+
+/**
+ * \hideinitializer
+ * \brief Do not rotate source_surface prior to compositing.
+ */
+#define VDP_OUTPUT_SURFACE_RENDER_ROTATE_0 0
+
+/**
+ * \hideinitializer
+ * \brief Rotate source_surface 90 degrees clockwise prior to
+ * compositing.
+ */
+#define VDP_OUTPUT_SURFACE_RENDER_ROTATE_90 1
+
+/**
+ * \hideinitializer
+ * \brief Rotate source_surface 180 degrees prior to
+ * compositing.
+ */
+#define VDP_OUTPUT_SURFACE_RENDER_ROTATE_180 2
+
+/**
+ * \hideinitializer
+ * \brief Rotate source_surface 270 degrees clockwise prior to
+ * compositing.
+ */
+#define VDP_OUTPUT_SURFACE_RENDER_ROTATE_270 3
+
+/**
+ * \hideinitializer
+ * \brief A separate color is used for each vertex of the
+ * smooth-shaded quad. Hence, colors array contains 4
+ * elements rather than 1. See description of colors
+ * array.
+ */
+#define VDP_OUTPUT_SURFACE_RENDER_COLOR_PER_VERTEX (1 << 2)
+
+/**
+ * \brief Composite a sub-rectangle of a \ref VdpOutputSurface
+ * "VdpOutputSurface" into a sub-rectangle of another
+ * \ref VdpOutputSurface VdpOutputSurface.
+ * \param[in] destination_surface The destination surface of the
+ * compositing operation.
+ * \param[in] destination_rect The sub-rectangle of the
+ * destination surface to update. If NULL, the entire
+ * destination surface will be updated.
+ * \param[in] source_surface The source surface for the
+ * compositing operation. The surface is treated as having
+ * four components: red, green, blue and alpha. Any
+ * missing components are treated as 1.0. For example, for
+ * an A8 VdpOutputSurface, alpha will come from the surface
+ * but red, green and blue will be treated as 1.0. If
+ * source_surface is NULL, all components will be treated
+ * as 1.0. Note that destination_surface and
+ * source_surface must have been allocated via the same
+ * \ref VdpDevice "VdpDevice".
+ * \param[in] source_rect The sub-rectangle of the source
+ * surface to read from. If NULL, the entire
+ * source_surface will be read. Left/right ot top/bottom
+ * co-ordinates may be swapped to flip the source. Any
+ * flip occurs prior to any requested rotation. Values
+ * from outside the source surface are valid and samples
+ * at those locations will be taken from the nearest edge.
+ * \param[in] colors A pointer to an array of \ref VdpColor
+ * "VdpColor" objects. If the flag
+ * VDP_OUTPUT_SURFACE_RENDER_COLOR_PER_VERTEX is set,
+ * VDPAU will four entries from the array, and treat them
+ * as the colors corresponding to the upper-left,
+ * upper-right, lower-right and lower-left corners of the
+ * post-rotation source (i.e. indices 0, 1, 2 and 3 run
+ * clockwise from the upper left corner). If the flag
+ * VDP_OUTPUT_SURFACE_RENDER_COLOR_PER_VERTEX is not
+ * set, VDPAU will use the single VdpColor for all four
+ * corners. If colors is NULL then red, green, blue and
+ * alpha values of 1.0 will be used.
+ * \param[in] blend_state If a blend state is provided, the
+ * blend state will be used for the composite operation. If
+ * NULL, blending is effectively disabled, which is
+ * equivalent to a blend equation of ADD, source blend
+ * factors of ONE and destination blend factors of ZERO. The
+ * blend math is the familiar OpenGL blend math:
+ * \f[
+ * dst.a = equation(blendFactorDstAlpha*dst.a,
+ * blendFactorSrcAlpha*src.a);
+ * \f]
+ * \f[
+ * dst.rgb = equation(blendFactorDstColor*dst.rgb,
+ * blendFactorSrcColor*src.rgb);
+ * \f]
+ * \param[in] flags A set of flags influencing how the
+ * compositing operation works.
+ * \arg \ref VDP_OUTPUT_SURFACE_RENDER_ROTATE_0
+ * \arg \ref VDP_OUTPUT_SURFACE_RENDER_ROTATE_90
+ * \arg \ref VDP_OUTPUT_SURFACE_RENDER_ROTATE_180
+ * \arg \ref VDP_OUTPUT_SURFACE_RENDER_ROTATE_270
+ * \arg \ref VDP_OUTPUT_SURFACE_RENDER_COLOR_PER_VERTEX
+ * \return VdpStatus The completion status of the operation.
+ *
+ * The general compositing pipeline is as follows.
+ *
+ * -# Extract source_rect from source_surface.
+ *
+ * -# The extracted source is rotated 0, 90, 180 or 270 degrees
+ * according to the flags.
+ *
+ * -# The rotated source is component-wise multiplied by a
+ * smooth-shaded quad with a (potentially) different color at
+ * each vertex.
+ *
+ * -# The resulting rotated, smooth-shaded quad is scaled to the
+ * size of destination_rect and composited with
+ * destination_surface using the provided blend state.
+ *
+ */
+typedef VdpStatus VdpOutputSurfaceRenderOutputSurface(
+ VdpOutputSurface destination_surface,
+ VdpRect const * destination_rect,
+ VdpOutputSurface source_surface,
+ VdpRect const * source_rect,
+ VdpColor const * colors,
+ VdpOutputSurfaceRenderBlendState const * blend_state,
+ uint32_t flags
+);
+
+/**
+ * \brief Composite a sub-rectangle of a \ref VdpOutputSurface
+ * "VdpOutputSurface" into a sub-rectangle of another
+ * \ref VdpOutputSurface VdpOutputSurface.
+ * \param[in] destination_surface The destination surface of the
+ * compositing operation.
+ * \param[in] destination_rect The sub-rectangle of the
+ * destination surface to update. If NULL, the entire
+ * destination surface will be updated.
+ * \param[in] source_surface The source surface for the
+ * compositing operation. The surface is treated as having
+ * four components: red, green, blue and alpha. Any
+ * missing components are treated as 1.0. For example, for
+ * an A8 VdpBitmapSurface, alpha will come from the surface
+ * but red, green and blue will be treated as 1.0. If
+ * source_surface is NULL, all components will be treated
+ * as 1.0. Note that destination_surface and
+ * source_surface must have been allocated via the same
+ * \ref VdpDevice "VdpDevice".
+ * \param[in] source_rect The sub-rectangle of the source
+ * surface to read from. If NULL, the entire
+ * source_surface will be read. Left/right ot top/bottom
+ * co-ordinates may be swapped to flip the source. Any
+ * flip occurs prior to any requested rotation. Values
+ * from outside the source surface are valid and samples
+ * at those locations will be taken from the nearest edge.
+ * \param[in] colors A pointer to an array of \ref VdpColor
+ * "VdpColor" objects. If the flag
+ * VDP_OUTPUT_SURFACE_RENDER_COLOR_PER_VERTEX is set,
+ * VDPAU will four entries from the array, and treat them
+ * as the colors corresponding to the upper-left,
+ * upper-right, lower-right and lower-left corners of the
+ * post-rotation source (i.e. indices 0, 1, 2 and 3 run
+ * clockwise from the upper left corner). If the flag
+ * VDP_OUTPUT_SURFACE_RENDER_COLOR_PER_VERTEX is not
+ * set, VDPAU will use the single VdpColor for all four
+ * corners. If colors is NULL then red, green, blue and
+ * alpha values of 1.0 will be used.
+ * \param[in] blend_state If a blend state is provided, the
+ * blend state will be used for the composite operation. If
+ * NULL, blending is effectively disabled, which is
+ * equivalent to a blend equation of ADD, source blend
+ * factors of ONE and destination blend factors of ZERO. The
+ * blend math is the familiar OpenGL blend math:
+ * \f[
+ * dst.a = equation(blendFactorDstAlpha*dst.a,
+ * blendFactorSrcAlpha*src.a);
+ * \f]
+ * \f[
+ * dst.rgb = equation(blendFactorDstColor*dst.rgb,
+ * blendFactorSrcColor*src.rgb);
+ * \f]
+ * \param[in] flags A set of flags influencing how the
+ * compositing operation works.
+ * \arg \ref VDP_OUTPUT_SURFACE_RENDER_ROTATE_0
+ * \arg \ref VDP_OUTPUT_SURFACE_RENDER_ROTATE_90
+ * \arg \ref VDP_OUTPUT_SURFACE_RENDER_ROTATE_180
+ * \arg \ref VDP_OUTPUT_SURFACE_RENDER_ROTATE_270
+ * \arg \ref VDP_OUTPUT_SURFACE_RENDER_COLOR_PER_VERTEX
+ * \return VdpStatus The completion status of the operation.
+ *
+ * The general compositing pipeline is as follows.
+ *
+ * -# Extract source_rect from source_surface.
+ *
+ * -# The extracted source is rotated 0, 90, 180 or 270 degrees
+ * according to the flags.
+ *
+ * -# The rotated source is component-wise multiplied by a
+ * smooth-shaded quad with a (potentially) different color at
+ * each vertex.
+ *
+ * -# The resulting rotated, smooth-shaded quad is scaled to the
+ * size of destination_rect and composited with
+ * destination_surface using the provided blend state.
+ *
+ */
+typedef VdpStatus VdpOutputSurfaceRenderBitmapSurface(
+ VdpOutputSurface destination_surface,
+ VdpRect const * destination_rect,
+ VdpBitmapSurface source_surface,
+ VdpRect const * source_rect,
+ VdpColor const * colors,
+ VdpOutputSurfaceRenderBlendState const * blend_state,
+ uint32_t flags
+);
+
+/*@}*/
+
+/**
+ * \defgroup VdpDecoder VdpDecoder; Video Decoding object
+ *
+ * The VdpDecoder object decodes compressed video data, writing
+ * the results to a \ref VdpVideoSurface "VdpVideoSurface".
+ *
+ * A specific VDPAU implementation may support decoding multiple
+ * types of compressed video data. However, VdpDecoder objects
+ * are able to decode a specific type of compressed video data.
+ * This type must be specified during creation.
+ *
+ * @{
+ */
+
+/**
+ * \brief The set of all known compressed video formats, and
+ * associated profiles, that may be decoded.
+ */
+typedef uint32_t VdpDecoderProfile;
+
+/** \hideinitializer */
+#define VDP_DECODER_PROFILE_MPEG1 (VdpDecoderProfile)0
+/** \hideinitializer */
+#define VDP_DECODER_PROFILE_MPEG2_SIMPLE (VdpDecoderProfile)1
+/** \hideinitializer */
+#define VDP_DECODER_PROFILE_MPEG2_MAIN (VdpDecoderProfile)2
+/** \hideinitializer */
+/** \brief MPEG 4 part 10 == H.264 == AVC */
+#define VDP_DECODER_PROFILE_H264_BASELINE (VdpDecoderProfile)6
+/** \hideinitializer */
+#define VDP_DECODER_PROFILE_H264_MAIN (VdpDecoderProfile)7
+/** \hideinitializer */
+#define VDP_DECODER_PROFILE_H264_HIGH (VdpDecoderProfile)8
+/** \hideinitializer */
+#define VDP_DECODER_PROFILE_VC1_SIMPLE (VdpDecoderProfile)9
+/** \hideinitializer */
+#define VDP_DECODER_PROFILE_VC1_MAIN (VdpDecoderProfile)10
+/** \hideinitializer */
+#define VDP_DECODER_PROFILE_VC1_ADVANCED (VdpDecoderProfile)11
+
+/** \hideinitializer */
+#define VDP_DECODER_LEVEL_MPEG1_NA 0
+
+/** \hideinitializer */
+#define VDP_DECODER_LEVEL_MPEG2_LL 0
+/** \hideinitializer */
+#define VDP_DECODER_LEVEL_MPEG2_ML 1
+/** \hideinitializer */
+#define VDP_DECODER_LEVEL_MPEG2_HL14 2
+/** \hideinitializer */
+#define VDP_DECODER_LEVEL_MPEG2_HL 3
+
+/** \hideinitializer */
+#define VDP_DECODER_LEVEL_H264_1 10
+/** \hideinitializer */
+#define VDP_DECODER_LEVEL_H264_1b 9
+/** \hideinitializer */
+#define VDP_DECODER_LEVEL_H264_1_1 11
+/** \hideinitializer */
+#define VDP_DECODER_LEVEL_H264_1_2 12
+/** \hideinitializer */
+#define VDP_DECODER_LEVEL_H264_1_3 13
+/** \hideinitializer */
+#define VDP_DECODER_LEVEL_H264_2 20
+/** \hideinitializer */
+#define VDP_DECODER_LEVEL_H264_2_1 21
+/** \hideinitializer */
+#define VDP_DECODER_LEVEL_H264_2_2 22
+/** \hideinitializer */
+#define VDP_DECODER_LEVEL_H264_3 30
+/** \hideinitializer */
+#define VDP_DECODER_LEVEL_H264_3_1 31
+/** \hideinitializer */
+#define VDP_DECODER_LEVEL_H264_3_2 32
+/** \hideinitializer */
+#define VDP_DECODER_LEVEL_H264_4 40
+/** \hideinitializer */
+#define VDP_DECODER_LEVEL_H264_4_1 41
+/** \hideinitializer */
+#define VDP_DECODER_LEVEL_H264_4_2 42
+/** \hideinitializer */
+#define VDP_DECODER_LEVEL_H264_5 50
+/** \hideinitializer */
+#define VDP_DECODER_LEVEL_H264_5_1 51
+
+/** \hideinitializer */
+#define VDP_DECODER_LEVEL_VC1_SIMPLE_LOW 0
+/** \hideinitializer */
+#define VDP_DECODER_LEVEL_VC1_SIMPLE_MEDIUM 1
+
+/** \hideinitializer */
+#define VDP_DECODER_LEVEL_VC1_MAIN_LOW 0
+/** \hideinitializer */
+#define VDP_DECODER_LEVEL_VC1_MAIN_MEDIUM 1
+/** \hideinitializer */
+#define VDP_DECODER_LEVEL_VC1_MAIN_HIGH 2
+
+/** \hideinitializer */
+#define VDP_DECODER_LEVEL_VC1_ADVANCED_L0 0
+/** \hideinitializer */
+#define VDP_DECODER_LEVEL_VC1_ADVANCED_L1 1
+/** \hideinitializer */
+#define VDP_DECODER_LEVEL_VC1_ADVANCED_L2 2
+/** \hideinitializer */
+#define VDP_DECODER_LEVEL_VC1_ADVANCED_L3 3
+/** \hideinitializer */
+#define VDP_DECODER_LEVEL_VC1_ADVANCED_L4 4
+
+/**
+ * \brief Query the implementation's VdpDecoder capabilities.
+ * \param[in] device The device to query.
+ * \param[in] profile The decoder profile for which information is requested.
+ * \param[out] is_supported Is this profile supported?
+ * \param[out] max_level The maximum specification level supported for this
+ * profile.
+ * \param[out] max_macroblocks The maximum supported surface size in
+ * macroblocks. Note that this could be greater than that dictated by
+ * the maximum level.
+ * \param[out] max_width The maximum supported surface width for this profile.
+ * Note that this could be greater than that dictated by the maximum
+ * level.
+ * \param[out] max_height The maximum supported surface height for this
+ * profile. Note that this could be greater than that dictated by the
+ * maximum level.
+ * \return VdpStatus The completion status of the operation.
+ */
+typedef VdpStatus VdpDecoderQueryCapabilities(
+ VdpDevice device,
+ VdpDecoderProfile profile,
+ /* output parameters follow */
+ VdpBool * is_supported,
+ uint32_t * max_level,
+ uint32_t * max_macroblocks,
+ uint32_t * max_width,
+ uint32_t * max_height
+);
+
+/**
+ * \brief An opaque handle representing a VdpDecoder object.
+ */
+typedef uint32_t VdpDecoder;
+
+/**
+ * \brief Create a VdpDecoder.
+ * \param[in] device The device that will contain the surface.
+ * \param[in] profile The video format the decoder will decode.
+ * \param[in] width The width of the new surface.
+ * \param[in] height The height of the new surface.
+ * \param[in] max_references The maximum number of references that may be
+ * used by a single frame in the stream to be decoded. This parameter
+ * exists mainly for formats such as H.264, where different streams
+ * may use a different number of references. Requesting too many
+ * references may waste memory, but decoding should still operate
+ * correctly. Requesting too few references will cause decoding to
+ * fail.
+ * \param[out] decoder The new decoder's handle.
+ * \return VdpStatus The completion status of the operation.
+ */
+typedef VdpStatus VdpDecoderCreate(
+ VdpDevice device,
+ VdpDecoderProfile profile,
+ uint32_t width,
+ uint32_t height,
+ uint32_t max_references,
+ /* output parameters follow */
+ VdpDecoder * decoder
+);
+
+/**
+ * \brief Destroy a VdpDecoder.
+ * \param[in] surface The decoder's handle.
+ * \return VdpStatus The completion status of the operation.
+ */
+typedef VdpStatus VdpDecoderDestroy(
+ VdpDecoder decoder
+);
+
+/**
+ * \brief Retrieve the parameters used to create a
+ * VdpDecoder.
+ * \param[in] surface The surface's handle.
+ * \param[out] profile The video format used to create the
+ * decoder.
+ * \param[out] width The width of surfaces decode by the
+ * decoder.
+ * \param[out] height The height of surfaces decode by the
+ * decoder
+ * \return VdpStatus The completion status of the operation.
+ */
+typedef VdpStatus VdpDecoderGetParameters(
+ VdpDecoder decoder,
+ /* output parameters follow */
+ VdpDecoderProfile * profile,
+ uint32_t * width,
+ uint32_t * height
+);
+
+#define VDP_BITSTREAM_BUFFER_VERSION 0
+
+/**
+ * \brief Application data buffer containing compressed video
+ * data.
+ */
+typedef struct {
+ /**
+ * This field must be filled with VDP_BITSTREAM_BUFFER_VERSION
+ */
+ uint32_t struct_version;
+ /** A pointer to the bitstream data bytes */
+ void const * bitstream;
+ /** The number of data bytes */
+ uint32_t bitstream_bytes;
+} VdpBitstreamBuffer;
+
+/**
+ * \brief A generic "picture information" pointer type.
+ *
+ * This type serves solely to document the expected usage of a
+ * generic (void *) function parameter. In actual usage, the
+ * application is expected to physically provide a pointer to an
+ * instance of one of the "real" VdpPictureInfo* structures,
+ * picking the type appropriate for the decoder object in
+ * question.
+ */
+typedef void * VdpPictureInfo;
+
+/**
+ * \brief Picture parameter information for an MPEG 1 or MPEG 2
+ * picture.
+ *
+ * Note: References to "copy of bitstream field" in the field descriptions
+ * may refer to data literally parsed from the bitstream, or derived from
+ * the bitstream using a mechanism described in the specification.
+ */
+typedef struct {
+ /**
+ * Reference used by B and P frames.
+ * Set to VDP_INVALID_HANDLE when not used.
+ */
+ VdpVideoSurface forward_reference;
+ /**
+ * Reference used by B frames.
+ * Set to VDP_INVALID_HANDLE when not used.
+ */
+ VdpVideoSurface backward_reference;
+ /** Number of slices in the bitstream provided. */
+ uint32_t slice_count;
+
+ /** Copy of the MPEG bitstream field. */
+ uint8_t picture_structure;
+ /** Copy of the MPEG bitstream field. */
+ uint8_t picture_coding_type;
+ /** Copy of the MPEG bitstream field. */
+ uint8_t intra_dc_precision;
+ /** Copy of the MPEG bitstream field. */
+ uint8_t frame_pred_frame_dct;
+ /** Copy of the MPEG bitstream field. */
+ uint8_t concealment_motion_vectors;
+ /** Copy of the MPEG bitstream field. */
+ uint8_t intra_vlc_format;
+ /** Copy of the MPEG bitstream field. */
+ uint8_t alternate_scan;
+ /** Copy of the MPEG bitstream field. */
+ uint8_t q_scale_type;
+ /** Copy of the MPEG bitstream field. */
+ uint8_t top_field_first;
+ /** Copy of the MPEG-1 bitstream field. For MPEG-2, set to 0. */
+ uint8_t full_pel_forward_vector;
+ /** Copy of the MPEG-1 bitstream field. For MPEG-2, set to 0. */
+ uint8_t full_pel_backward_vector;
+ /**
+ * Copy of the MPEG bitstream field.
+ * For MPEG-1, fill both horizontal and vertical entries.
+ */
+ uint8_t f_code[2][2];
+ /** Copy of the MPEG bitstream field, converted to raster order. */
+ uint8_t intra_quantizer_matrix[64];
+ /** Copy of the MPEG bitstream field, converted to raster order. */
+ uint8_t non_intra_quantizer_matrix[64];
+} VdpPictureInfoMPEG1Or2;
+
+/**
+ * \brief Information about an H.264 reference frame
+ *
+ * Note: References to "copy of bitstream field" in the field descriptions
+ * may refer to data literally parsed from the bitstream, or derived from
+ * the bitstream using a mechanism described in the specification.
+ */
+typedef struct {
+ /**
+ * The surface that contains the reference image.
+ * Set to VDP_INVALID_HANDLE for unused entries.
+ */
+ VdpVideoSurface surface;
+ /** Is this a long term reference (else short term). */
+ VdpBool is_long_term;
+ /**
+ * Is the top field used as a reference.
+ * Set to VDP_FALSE for unused entries.
+ */
+ VdpBool top_is_reference;
+ /**
+ * Is the bottom field used as a reference.
+ * Set to VDP_FALSE for unused entries.
+ */
+ VdpBool bottom_is_reference;
+ /** [0]: top, [1]: bottom */
+ int32_t field_order_cnt[2];
+ /**
+ * Copy of the H.264 bitstream field:
+ * frame_num from slice_header for short-term references,
+ * LongTermPicNum from decoding algorithm for long-term references.
+ */
+ uint16_t frame_idx;
+} VdpReferenceFrameH264;
+
+/**
+ * \brief Picture parameter information for an H.264 picture.
+ *
+ * Note: The \ref referenceFrames array must contain the "DPB" as
+ * defined by the H.264 specification. In particular, once a
+ * reference frame has been decoded to a surface, that surface must
+ * continue to appear in the DPB until no longer required to predict
+ * any future frame. Once a surface is removed from the DPB, it can
+ * no longer be used as a reference, unless decoded again.
+ *
+ * Also note that only surfaces previously generated using \ref
+ * VdpDecoderRender may be used as reference frames. In particular,
+ * surfaces filled using any "put bits" API will not work.
+ *
+ * Note: References to "copy of bitstream field" in the field descriptions
+ * may refer to data literally parsed from the bitstream, or derived from
+ * the bitstream using a mechanism described in the specification.
+ */
+typedef struct {
+ /** Number of slices in the bitstream provided. */
+ uint32_t slice_count;
+ /** [0]: top, [1]: bottom */
+ int32_t field_order_cnt[2];
+ /** Will the decoded frame be used as a reference later. */
+ VdpBool is_reference;
+
+ /** Copy of the H.264 bitstream field. */
+ uint16_t frame_num;
+ /** Copy of the H.264 bitstream field. */
+ uint8_t field_pic_flag;
+ /** Copy of the H.264 bitstream field. */
+ uint8_t bottom_field_flag;
+ /** Copy of the H.264 bitstream field. */
+ uint8_t num_ref_frames;
+ /** Copy of the H.264 bitstream field. */
+ uint8_t mb_adaptive_frame_field_flag;
+ /** Copy of the H.264 bitstream field. */
+ uint8_t constrained_intra_pred_flag;
+ /** Copy of the H.264 bitstream field. */
+ uint8_t weighted_pred_flag;
+ /** Copy of the H.264 bitstream field. */
+ uint8_t weighted_bipred_idc;
+ /** Copy of the H.264 bitstream field. */
+ uint8_t frame_mbs_only_flag;
+ /** Copy of the H.264 bitstream field. */
+ uint8_t transform_8x8_mode_flag;
+ /** Copy of the H.264 bitstream field. */
+ int8_t chroma_qp_index_offset;
+ /** Copy of the H.264 bitstream field. */
+ int8_t second_chroma_qp_index_offset;
+ /** Copy of the H.264 bitstream field. */
+ int8_t pic_init_qp_minus26;
+ /** Copy of the H.264 bitstream field. */
+ uint8_t num_ref_idx_l0_active_minus1;
+ /** Copy of the H.264 bitstream field. */
+ uint8_t num_ref_idx_l1_active_minus1;
+ /** Copy of the H.264 bitstream field. */
+ uint8_t log2_max_frame_num_minus4;
+ /** Copy of the H.264 bitstream field. */
+ uint8_t pic_order_cnt_type;
+ /** Copy of the H.264 bitstream field. */
+ uint8_t log2_max_pic_order_cnt_lsb_minus4;
+ /** Copy of the H.264 bitstream field. */
+ uint8_t delta_pic_order_always_zero_flag;
+ /** Copy of the H.264 bitstream field. */
+ uint8_t direct_8x8_inference_flag;
+ /** Copy of the H.264 bitstream field. */
+ uint8_t entropy_coding_mode_flag;
+ /** Copy of the H.264 bitstream field. */
+ uint8_t pic_order_present_flag;
+ /** Copy of the H.264 bitstream field. */
+ uint8_t deblocking_filter_control_present_flag;
+ /** Copy of the H.264 bitstream field. */
+ uint8_t redundant_pic_cnt_present_flag;
+
+ /** Copy of the H.264 bitstream field, converted to raster order. */
+ uint8_t scaling_lists_4x4[6][16];
+ /** Copy of the H.264 bitstream field, converted to raster order. */
+ uint8_t scaling_lists_8x8[2][64];
+
+ /** See \ref VdpPictureInfoH264 for instructions regarding this field. */
+ VdpReferenceFrameH264 referenceFrames[16];
+} VdpPictureInfoH264;
+
+/**
+ * \brief Picture parameter information for a VC1 picture.
+ *
+ * Note: References to "copy of bitstream field" in the field descriptions
+ * may refer to data literally parsed from the bitstream, or derived from
+ * the bitstream using a mechanism described in the specification.
+ */
+typedef struct {
+ /**
+ * Reference used by B and P frames.
+ * Set to VDP_INVALID_HANDLE when not used.
+ */
+ VdpVideoSurface forward_reference;
+ /**
+ * Reference used by B frames.
+ * Set to VDP_INVALID_HANDLE when not used.
+ */
+ VdpVideoSurface backward_reference;
+
+ /** Number of slices in the bitstream provided. */
+ uint32_t slice_count;
+ /** I=0, P=1, B=3, BI=4 from 7.1.1.4. */
+ uint8_t picture_type;
+ /** Progressive=0, Frame-interlace=2, Field-interlace=3; see VC-1 7.1.1.15. */
+ uint8_t frame_coding_mode;
+
+ /** Copy of the VC-1 bitstream field. See VC-1 6.1.5. */
+ uint8_t postprocflag;
+ /** Copy of the VC-1 bitstream field. See VC-1 6.1.8. */
+ uint8_t pulldown;
+ /** Copy of the VC-1 bitstream field. See VC-1 6.1.9. */
+ uint8_t interlace;
+ /** Copy of the VC-1 bitstream field. See VC-1 6.1.10. */
+ uint8_t tfcntrflag;
+ /** Copy of the VC-1 bitstream field. See VC-1 6.1.11. */
+ uint8_t finterpflag;
+ /** Copy of the VC-1 bitstream field. See VC-1 6.1.3. */
+ uint8_t psf;
+ /** Copy of the VC-1 bitstream field. See VC-1 6.2.8. */
+ uint8_t dquant;
+ /** Copy of the VC-1 bitstream field. See VC-1 6.2.3. */
+ uint8_t panscan_flag;
+ /** Copy of the VC-1 bitstream field. See VC-1 6.2.4. */
+ uint8_t refdist_flag;
+ /** Copy of the VC-1 bitstream field. See VC-1 6.2.11. */
+ uint8_t quantizer;
+ /** Copy of the VC-1 bitstream field. See VC-1 6.2.7. */
+ uint8_t extended_mv;
+ /** Copy of the VC-1 bitstream field. See VC-1 6.2.14. */
+ uint8_t extended_dmv;
+ /** Copy of the VC-1 bitstream field. See VC-1 6.2.10. */
+ uint8_t overlap;
+ /** Copy of the VC-1 bitstream field. See VC-1 6.2.9. */
+ uint8_t vstransform;
+ /** Copy of the VC-1 bitstream field. See VC-1 6.2.5. */
+ uint8_t loopfilter;
+ /** Copy of the VC-1 bitstream field. See VC-1 6.2.6. */
+ uint8_t fastuvmc;
+ /** Copy of the VC-1 bitstream field. See VC-1 6.12.15. */
+ uint8_t range_mapy_flag;
+ /** Copy of the VC-1 bitstream field. */
+ uint8_t range_mapy;
+ /** Copy of the VC-1 bitstream field. See VC-1 6.2.16. */
+ uint8_t range_mapuv_flag;
+ /** Copy of the VC-1 bitstream field. */
+ uint8_t range_mapuv;
+
+ /**
+ * Copy of the VC-1 bitstream field. See VC-1 J.1.10.
+ * Only used by simple and main profiles.
+ */
+ uint8_t multires;
+ /**
+ * Copy of the VC-1 bitstream field. See VC-1 J.1.16.
+ * Only used by simple and main profiles.
+ */
+ uint8_t syncmarker;
+ /**
+ * Copy of the VC-1 bitstream field. See VC-1 J.1.17.
+ * Only used by simple and main profiles.
+ */
+ uint8_t rangered;
+ /**
+ * Copy of the VC-1 bitstream field. See VC-1 J.1.17.
+ * Only used by simple and main profiles.
+ */
+ uint8_t maxbframes;
+
+ /**
+ * Out-of-loop deblocking enable.
+ * Bit 0 of POSTPROC from VC-1 7.1.1.27
+ * Note that bit 1 of POSTPROC (dering enable) should not be included.
+ */
+ uint8_t deblockEnable;
+ /**
+ * Parameter used by VC-1 Annex H deblocking algorithm. Note that VDPAU
+ * implementations may choose which deblocking algorithm to use.
+ * See VC-1 7.1.1.6
+ */
+ uint8_t pquant;
+} VdpPictureInfoVC1;
+
+/**
+ * \brief Decode a compressed field/frame and render the result
+ * into a \ref VdpVideoSurface "VdpVideoSurface".
+ * \param[in] decoder The decoder object that will perform the
+ * decode operation.
+ * \param[in] target The video surface to render to.
+ * \param[in] picture_info A (pointer to a) structure containing
+ * information about the picture to be decoded. Note that
+ * the appropriate type of VdpPictureInfo* structure must
+ * be provided to match to profile that the decoder was
+ * created for.
+ * \param[in] bitstream_buffer_count The number of bitstream
+ * buffers containing compressed data for this picture.
+ * \param[in] bitstream_buffers An array of bitstream buffers.
+ * \return VdpStatus The completion status of the operation.
+ *
+ * See \ref video_mixer_usage for additional information.
+ */
+typedef VdpStatus VdpDecoderRender(
+ VdpDecoder decoder,
+ VdpVideoSurface target,
+ VdpPictureInfo const * picture_info,
+ uint32_t bitstream_buffer_count,
+ VdpBitstreamBuffer const * bitstream_buffers
+);
+
+/*@}*/
+
+/**
+ * \defgroup VdpVideoMixer VdpVideoMixer; Video Post-processing \
+ * and Compositing object
+ *
+ * VdpVideoMixer can perform some subset of the following
+ * post-processing steps on video:
+ * - De-interlacing
+ * - Various types, with or without inverse telecine
+ * - Noise-reduction
+ * - Sharpness adjustment
+ * - Color space conversion to RGB
+ * - Chroma format upscaling to 4:4:4
+ *
+ * A VdpVideoMixer takes a source \ref VdpVideoSurface
+ * "VdpVideoSurface" VdpVideoSurface and performs various video
+ * processing steps on it (potentially using information from
+ * past or future video surfaces). It scales the video and
+ * converts it to RGB, then optionally composites it with
+ * multiple auxiliary \ref VdpOutputSurface "VdpOutputSurface"s
+ * before writing the result to the destination \ref
+ * VdpOutputSurface "VdpOutputSurface".
+ *
+ * The video mixer compositing model is as follows:
+ *
+ * - A rectangle will be rendered on an output surface. No
+ * pixels will be rendered outside of this output rectangle.
+ * The contents of this rectangle will be a composite of many
+ * layers.
+ *
+ * - The first layer is the background color. The background
+ * color will fill the entire rectangle.
+ *
+ * - The second layer is the processed video which has been
+ * converted to RGB. These pixels will overwrite the
+ * background color of the first layer except where the second
+ * layer's rectangle does not completely cover the output
+ * rectangle. In those regions the background color will
+ * continue to show. If any portion of the second layer's
+ * output rectangle is outside of the output rectangle, those
+ * portions will be clipped.
+ *
+ * - The third layer contains some number of auxiliary layers
+ * (in the form of \ref VdpOutputSurface "VdpOutputSurface"s)
+ * which will be composited using the alpha value from the
+ * those surfaces. The compositing operations are equivalent
+ * to rendering with \ref VdpOutputSurfaceRenderOutputSurface
+ * using a source blend factor of SOURCE_ALPHA, a destination
+ * blend factor of ONE_MINUS_SOURCE_ALPHA and an equation of
+ * ADD.
+ *
+ * @{
+ */
+
+/**
+ * \brief A VdpVideoMixer feature that must be requested at
+ * creation time to be used.
+ *
+ * Certain advanced VdpVideoMixer features are optional, and the
+ * ability to use those features at all must be requested when
+ * the VdpVideoMixer object is created. Each feature is named via
+ * a specific VdpVideoMixerFeature value.
+ *
+ * Once requested, these features are permanently available
+ * within that specific VdpVideoMixer object. All features that
+ * are not explicitly requested at creation time default to
+ * being permanently unavailable.
+ *
+ * Even when requested, all features default to being initially
+ * disabled. However, applications can subsequently enable and
+ * disable features at any time. See \ref
+ * VdpVideoMixerSetFeatureEnables.
+ *
+ * Some features allow configuration of their operation. Each
+ * configurable item is an \ref VdpVideoMixerAttribute. These
+ * attributes may be manipulated at any time using \ref
+ * VdpVideoMixerSetAttributeValues.
+ */
+typedef uint32_t VdpVideoMixerFeature;
+
+/**
+ * \hideinitializer
+ * \brief A VdpVideoMixerFeature.
+ *
+ * When requested and enabled, motion adaptive temporal
+ * deinterlacing will be used on interlaced content.
+ *
+ * When multiple de-interlacing options are requested and
+ * enabled, the back-end implementation chooses the best
+ * algorithm to apply.
+ */
+#define VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL (VdpVideoMixerFeature)0
+/**
+ * \hideinitializer
+ * \brief A VdpVideoMixerFeature.
+ *
+ * When requested and enabled, this enables a more advanced
+ * version of temporal de-interlacing, that additionally uses
+ * edge-guided spatial interpolation.
+ *
+ * When multiple de-interlacing options are requested and
+ * enabled, the back-end implementation chooses the best
+ * algorithm to apply.
+ */
+#define VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL_SPATIAL (VdpVideoMixerFeature)1
+/**
+ * \hideinitializer
+ * \brief A VdpVideoMixerFeature.
+ *
+ * When requested and enabled, cadence detection will be enabled
+ * on interlaced content and the video mixer will try to extract
+ * progressive frames from pull-down material.
+ */
+#define VDP_VIDEO_MIXER_FEATURE_INVERSE_TELECINE (VdpVideoMixerFeature)2
+/**
+ * \hideinitializer
+ * \brief A VdpVideoMixerFeature.
+ *
+ * When requested and enabled, a noise reduction algorithm will
+ * be applied to the video.
+ */
+#define VDP_VIDEO_MIXER_FEATURE_NOISE_REDUCTION (VdpVideoMixerFeature)3
+/**
+ * \hideinitializer
+ * \brief A VdpVideoMixerFeature.
+ *
+ * When requested and enabled, a sharpening algorithm will be
+ * applied to the video.
+ */
+#define VDP_VIDEO_MIXER_FEATURE_SHARPNESS (VdpVideoMixerFeature)4
+/**
+ * \hideinitializer
+ * \brief A VdpVideoMixerFeature.
+ *
+ * When requested and enabled, the alpha of the rendered
+ * surface, which is normally set to the alpha of the background
+ * color, will be forced to 0.0 on pixels corresponding to
+ * source video surface luminance values in the range specified
+ * by attributes \ref VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MIN_LUMA
+ * to \ref VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MAX_LUMA. This
+ * keying is performed after scaling and de-interlacing.
+ */
+#define VDP_VIDEO_MIXER_FEATURE_LUMA_KEY (VdpVideoMixerFeature)5
+
+/**
+ * \brief A VdpVideoMixer creation parameter.
+ *
+ * When a VdpVideoMixer is created, certain parameters may be
+ * supplied. Each parameter is named via a specific
+ * VdpVideoMixerParameter value.
+ *
+ * Each parameter has a specific type, and specific default
+ * value if not specified at VdpVideoMixer creation time. The
+ * application may query the legal supported range for some
+ * parameters.
+ */
+typedef uint32_t VdpVideoMixerParameter;
+
+/**
+ * \hideinitializer
+ * \brief The exact width of input video surfaces.
+ *
+ * This attribute's type is uint32_t.
+ *
+ * This parameter defaults to 0 if not specified, which entails
+ * that it must be specified.
+ *
+ * The application may query this parameter's supported
+ * range.
+ */
+#define VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH (VdpVideoMixerParameter)0
+/**
+ * \hideinitializer
+ * \brief The exact height of input video surfaces.
+ *
+ * This attribute's type is uint32_t.
+ *
+ * This parameter defaults to 0 if not specified, which entails
+ * that it must be specified.
+ *
+ * The application may query this parameter's supported
+ * range.
+ */
+#define VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT (VdpVideoMixerParameter)1
+/**
+ * \hideinitializer
+ * \brief The chroma type of the input video surfaces the will
+ * process.
+ *
+ * This attribute's type is VdpChromaType.
+ *
+ * If not specified, this parameter defaults to
+ * VDP_CHROMA_TYPE_420.
+ *
+ * The application may not query this application's supported
+ * range, since it is a potentially disjoint enumeration.
+ */
+#define VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE (VdpVideoMixerParameter)2
+/**
+ * \hideinitializer
+ * \brief The number of auxiliary layers in the mixer's
+ * compositing model.
+ *
+ * Note that this indicates the maximum number of layers that
+ * may be processed by a given \ref VdpVideoMixer "VdpVideoMixer"
+ * object. Each individual \ref VdpVideoMixerRender invocation
+ * may choose to use a different number of actual layers, from 0
+ * up to this limit.
+ *
+ * This attribute's type is uint32_t.
+ *
+ * If not specified, this parameter defaults to 0.
+ *
+ * The application may query this parameter's supported
+ * range.
+ */
+#define VDP_VIDEO_MIXER_PARAMETER_LAYERS (VdpVideoMixerParameter)3
+
+/**
+ * \brief An adjustable attribute of VdpVideoMixer operation.
+ *
+ * Various attributes of VdpVideoMixer operation may be adjusted
+ * at any time. Each attribute is named via a specific
+ * VdpVideoMixerAttribute value.
+ *
+ * Each attribute has a specific type, and specific default
+ * value if not specified at VdpVideoMixer creation time. The
+ * application may query the legal supported range for some
+ * attributes.
+ */
+typedef uint32_t VdpVideoMixerAttribute;
+
+/**
+ * \hideinitializer
+ * \brief The background color in the VdpVideoMixer's compositing
+ * model.
+ *
+ * This attribute's type is VdpColor.
+ *
+ * This parameter defaults to black (all color components 0.0
+ * and alpha 1.0).
+ *
+ * The application may not query this parameter's supported
+ * range, since the type is not scalar.
+ */
+#define VDP_VIDEO_MIXER_ATTRIBUTE_BACKGROUND_COLOR (VdpVideoMixerAttribute)0
+/**
+ * \hideinitializer
+ * \brief The color-space conversion matrix used by the
+ * VdpVideoMixer.
+ *
+ * This attribute's type is \ref VdpCSCMatrix.
+ *
+ * Note: When using \ref VdpVideoMixerGetAttributeValues to retrieve the
+ * current CSC matrix, the attribute_values array must contain a pointer to
+ * a pointer a VdpCSCMatrix (VdpCSCMatrix** as a void *). The get function will
+ * either initialize the referenced CSC matrix to the current value, *or*
+ * clear the supplied pointer to NULL, if the previous set call supplied a
+ * value of NULL in parameter_values, to request the default matrix.
+ *
+ * \code
+ * VdpCSCMatrix matrix;
+ * VdpCSCMatrix * matrix_ptr;
+ * void * attribute_values[] = {&matrix_ptr};
+ * VdpStatus st = vdp_video_mixer_get_attribute_values(..., attribute_values, ...);
+ * \endcode
+ *
+ * This parameter defaults to a matrix suitable for ITU-R BT.601
+ * input surfaces, with no procamp adjustments.
+ *
+ * The application may not query this parameter's supported
+ * range, since the type is not scalar.
+ */
+#define VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX (VdpVideoMixerAttribute)1
+/**
+ * \hideinitializer
+ * \brief The amount of noise reduction algorithm to apply.
+ *
+ * This attribute's type is float.
+ *
+ * This parameter defaults to 0.0, which equates to no noise
+ * reduction.
+ *
+ * The application may query this parameter's supported range.
+ * However, the range is fixed as 0.0...1.0.
+ */
+#define VDP_VIDEO_MIXER_ATTRIBUTE_NOISE_REDUCTION_LEVEL (VdpVideoMixerAttribute)2
+/**
+ * \hideinitializer
+ * \brief The amount of sharpening, or blurring, to apply.
+ *
+ * This attribute's type is float.
+ *
+ * This parameter defaults to 0.0, which equates to no
+ * sharpening.
+ *
+ * Positive values request sharpening. Negative values request
+ * blurring.
+ *
+ * The application may query this parameter's supported range.
+ * However, the range is fixed as -1.0...1.0.
+ */
+#define VDP_VIDEO_MIXER_ATTRIBUTE_SHARPNESS_LEVEL (VdpVideoMixerAttribute)3
+/**
+ * \hideinitializer
+ * \brief The minimum luma value for the luma key algorithm.
+ *
+ * This attribute's type is float.
+ *
+ * This parameter defaults to 0.0.
+ *
+ * The application may query this parameter's supported range.
+ * However, the range is fixed as 0.0...1.0.
+ */
+#define VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MIN_LUMA (VdpVideoMixerAttribute)4
+/**
+ * \hideinitializer
+ * \brief The maximum luma value for the luma key algorithm.
+ *
+ * This attribute's type is float.
+ *
+ * This parameter defaults to 1.0.
+ *
+ * The application may query this parameter's supported range.
+ * However, the range is fixed as 0.0...1.0.
+ */
+#define VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MAX_LUMA (VdpVideoMixerAttribute)5
+
+/**
+ * \brief Query the implementation's support for a specific
+ * feature.
+ * \param[in] device The device to query.
+ * \param[in] feature The feature for which support is to be
+ * queried.
+ * \param[out] is_supported Is the specified feature supported?
+ * \return VdpStatus The completion status of the operation.
+ */
+typedef VdpStatus VdpVideoMixerQueryFeatureSupport(
+ VdpDevice device,
+ VdpVideoMixerFeature feature,
+ /* output parameters follow */
+ VdpBool * is_supported
+);
+
+/**
+ * \brief Query the implementation's support for a specific
+ * parameter.
+ * \param[in] device The device to query.
+ * \param[in] parameter The parameter for which support is to be
+ * queried.
+ * \param[out] is_supported Is the specified parameter
+ * supported?
+ * \return VdpStatus The completion status of the operation.
+ */
+typedef VdpStatus VdpVideoMixerQueryParameterSupport(
+ VdpDevice device,
+ VdpVideoMixerParameter parameter,
+ /* output parameters follow */
+ VdpBool * is_supported
+);
+
+/**
+ * \brief Query the implementation's support for a specific
+ * attribute.
+ * \param[in] device The device to query.
+ * \param[in] feature The feature for which support is to be
+ * queried.
+ * \param[out] is_supported Is the specified feature supported?
+ * \return VdpStatus The completion status of the operation.
+ */
+typedef VdpStatus VdpVideoMixerQueryAttributeSupport(
+ VdpDevice device,
+ VdpVideoMixerAttribute attribute,
+ /* output parameters follow */
+ VdpBool * is_supported
+);
+
+/**
+ * \brief Query the implementation's supported for a specific
+ * parameter.
+ * \param[in] device The device to query.
+ * \param[in] parameter The parameter for which support is to be
+ * queried.
+ * \param[out] min_value The minimum supported value.
+ * \param[out] max_value The maximum supported value.
+ * \return VdpStatus The completion status of the operation.
+ */
+typedef VdpStatus VdpVideoMixerQueryParameterValueRange(
+ VdpDevice device,
+ VdpVideoMixerParameter parameter,
+ /* output parameters follow */
+ void * min_value,
+ void * max_value
+);
+
+/**
+ * \brief Query the implementation's supported for a specific
+ * attribute.
+ * \param[in] device The device to query.
+ * \param[in] attribute The attribute for which support is to be
+ * queried.
+ * \param[out] min_value The minimum supported value.
+ * \param[out] max_value The maximum supported value.
+ * \return VdpStatus The completion status of the operation.
+ */
+typedef VdpStatus VdpVideoMixerQueryAttributeValueRange(
+ VdpDevice device,
+ VdpVideoMixerAttribute attribute,
+ /* output parameters follow */
+ void * min_value,
+ void * max_value
+);
+
+/**
+ * \brief An opaque handle representing a VdpVideoMixer object.
+ */
+typedef uint32_t VdpVideoMixer;
+
+/**
+ * \brief Create a VdpVideoMixer.
+ * \param[in] device The device that will contain the mixer.
+ * \param[in] feature_count The number of features to request.
+ * \param[in] features The list of features to request.
+ * \param[in] parameter_count The number of parameters to set.
+ * \param[in] parameters The list of parameters to set.
+ * \param[in] parameter_values The values for the parameters. Note that each
+ * entry in the value array is a pointer to the actual value. In other
+ * words, the values themselves are not cast to "void *" and passed
+ * "inside" the array.
+ * \param[out] mixer The new mixer's handle.
+ * \return VdpStatus The completion status of the operation.
+ *
+ * Initially, all requested features will be disabled. They can
+ * be enabled using \ref VdpVideoMixerSetFeatureEnables.
+ *
+ * Initially, all attributes will have default values. Values
+ * can be changed using \ref VdpVideoMixerSetAttributeValues.
+ */
+typedef VdpStatus VdpVideoMixerCreate(
+ VdpDevice device,
+ // The set of features to request
+ uint32_t feature_count,
+ VdpVideoMixerFeature const * features,
+ // The parameters used during creation
+ uint32_t parameter_count,
+ VdpVideoMixerParameter const * parameters,
+ void const * const * parameter_values,
+ /* output parameters follow */
+ VdpVideoMixer * mixer
+);
+
+/**
+ * \brief Enable or disable features.
+ * \param[in] mixer The mixer to manipulate.
+ * \param[in] feature_count The number of features to
+ * enable/disable.
+ * \param[in] features The list of features to enable/disable.
+ * \param[in] feature_enables The list of new feature enable
+ * values.
+ * \return VdpStatus The completion status of the operation.
+ */
+typedef VdpStatus VdpVideoMixerSetFeatureEnables(
+ VdpVideoMixer mixer,
+ uint32_t feature_count,
+ VdpVideoMixerFeature const * features,
+ VdpBool const * feature_enables
+);
+
+/**
+ * \brief Set attribute values
+ * \param[in] mixer The mixer to manipulate.
+ * \param[in] attribute_count The number of attributes to set.
+ * \param[in] attributes The list of attributes to set.
+ * \param[in] attribute_values The values for the attributes. Note that each
+ * entry in the value array is a pointer to the actual value. In other
+ * words, the values themselves are not cast to "void *" and passed
+ * "inside" the array. A NULL pointer requests that the default value be
+ * set for that attribute.
+ * \return VdpStatus The completion status of the operation.
+ */
+typedef VdpStatus VdpVideoMixerSetAttributeValues(
+ VdpVideoMixer mixer,
+ uint32_t attribute_count,
+ VdpVideoMixerAttribute const * attributes,
+ void const * const * attribute_values
+);
+
+/**
+ * \brief Retrieve whether features were requested at creation
+ * time.
+ * \param[in] mixer The mixer to query.
+ * \param[in] feature_count The number of features to query.
+ * \param[in] features The list of features to query.
+ * \param[out] feature_supported A list of values indicating
+ * whether the feature was requested, and hence is
+ * available.
+ * \return VdpStatus The completion status of the operation.
+ */
+typedef VdpStatus VdpVideoMixerGetFeatureSupport(
+ VdpVideoMixer mixer,
+ uint32_t feature_count,
+ VdpVideoMixerFeature const * features,
+ /* output parameters follow */
+ VdpBool * feature_supports
+);
+
+/**
+ * \brief Retrieve whether features are enabled.
+ * \param[in] mixer The mixer to manipulate.
+ * \param[in] feature_count The number of features to query.
+ * \param[in] features The list of features to query.
+ * \param[out] feature_enabled A list of values indicating
+ * whether the feature is enabled.
+ * \return VdpStatus The completion status of the operation.
+ */
+typedef VdpStatus VdpVideoMixerGetFeatureEnables(
+ VdpVideoMixer mixer,
+ uint32_t feature_count,
+ VdpVideoMixerFeature const * features,
+ /* output parameters follow */
+ VdpBool * feature_enables
+);
+
+/**
+ * \brief Retrieve parameter values given at creation time.
+ * \param[in] mixer The mixer to manipulate.
+ * \param[in] parameter_count The number of parameters to query.
+ * \param[in] parameters The list of parameters to query.
+ * \param[out] parameter_values The list of current values for
+ * the parameters. Note that each entry in the value array is a pointer to
+ * storage that will receive the actual value. If the attribute's type is
+ * a pointer itself, please closely read the documentation for that
+ * attribute type for any other data passing requirements.
+ * \return VdpStatus The completion status of the operation.
+ */
+typedef VdpStatus VdpVideoMixerGetParameterValues(
+ VdpVideoMixer mixer,
+ uint32_t parameter_count,
+ VdpVideoMixerParameter const * parameters,
+ /* output parameters follow */
+ void * const * parameter_values
+);
+
+/**
+ * \brief Retrieve current attribute values.
+ * \param[in] mixer The mixer to manipulate.
+ * \param[in] attribute_count The number of attributes to query.
+ * \param[in] attributes The list of attributes to query.
+ * \param[out] attribute_values The list of current values for
+ * the attributes. Note that each entry in the value array is a pointer to
+ * storage that will receive the actual value. If the attribute's type is
+ * a pointer itself, please closely read the documentation for that
+ * attribute type for any other data passing requirements.
+ * \return VdpStatus The completion status of the operation.
+ */
+typedef VdpStatus VdpVideoMixerGetAttributeValues(
+ VdpVideoMixer mixer,
+ uint32_t attribute_count,
+ VdpVideoMixerAttribute const * attributes,
+ /* output parameters follow */
+ void * const * attribute_values
+);
+
+/**
+ * \brief Destroy a VdpVideoMixer.
+ * \param[in] device The device to destroy.
+ * \return VdpStatus The completion status of the operation.
+ */
+typedef VdpStatus VdpVideoMixerDestroy(
+ VdpVideoMixer mixer
+);
+
+/**
+ * \hideinitializer
+ * \brief The structure of the picture present in a \ref
+ * VdpVideoSurface "VdpVideoSurface".
+ */
+typedef enum {
+ /**
+ * The picture is a field, and is the top field of the surface.
+ */
+ VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD,
+ /**
+ * The picture is a field, and is the bottom field of the
+ * surface.
+ */
+ VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD,
+ /**
+ * The picture is a frame, and hence is the entire surface.
+ */
+ VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME,
+} VdpVideoMixerPictureStructure;
+
+#define VDP_LAYER_VERSION 0
+
+/**
+ * \brief Definition of an additional \ref VdpOutputSurface
+ * "VdpOutputSurface" layer in the composting model.
+ */
+typedef struct {
+ /**
+ * This field must be filled with VDP_LAYER_VERSION
+ */
+ uint32_t struct_version;
+ /**
+ * The surface to composite from.
+ */
+ VdpOutputSurface source_surface;
+ /**
+ * The sub-rectangle of the source surface to use. If NULL, the
+ * entire source surface will be used.
+ */
+ VdpRect const * source_rect;
+ /**
+ * The sub-rectangle of the destination surface to map
+ * this layer into. This rectangle is relative to the entire
+ * destination surface. This rectangle will be clipped by \ref
+ * VdpVideoMixerRender's \b destination_rect. If NULL, the
+ * destination rectangle will be sized to match the source
+ * rectangle, and will be located at the origin.
+ */
+ VdpRect const * destination_rect;
+} VdpLayer;
+
+/**
+ * \brief Perform a video post-processing and compositing
+ * operation.
+ * \param[in] mixer The mixer object that will perform the
+ * mixing/rendering operation.
+ * \param[in] background_surface A background image. If set to any value other
+ * than VDP_INVALID_HANDLE, the specific surface will be used instead of
+ * the background color as the first layer in the mixer's compositing
+ * process.
+ * \param[in] background_source_rect When background_surface is specified,
+ * this parameter indicates the portion of background_surface that will
+ * be used as the background layer. The specified region will be
+ * extracted and scaled to match the size of destination_rect. If NULL,
+ * the entire background_surface will be used.
+ * \param[in] current_picture_structure The picture structure of
+ * the field/frame to be processed. This field/frame is
+ * presented in the \b video_surface_current parameter. If
+ * frame, then all \b video_surface_* parameters are
+ * assumed to be frames. If field, then all
+ * video_surface_* parameters are assumed to be fields,
+ * with alternating top/bottom-ness derived from
+ * video_surface_current.
+ * \param[in] video_surfaces_past_count The number of provided
+ * fields/frames prior to the current picture.
+ * \param[in] video_surfaces_past The fields/frames prior to the
+ * current field/frame. Note that array index 0 is the
+ * field/frame temporally nearest to the current
+ * field/frame, with increasing array indices used for
+ * older frames. Unavailable entries may be set to
+ * \ref VDP_INVALID_HANDLE.
+ * \param[in] video_surface_current The field/frame to be
+ * processed.
+ * \param[in] video_surfaces_future_count The number of provided
+ * fields/frames following the current picture.
+ * \param[in] video_surfaces_future The fields/frames that
+ * follow the current field/frame. Note that array index 0
+ * is the field/frame temporally nearest to the current
+ * field/frame, with increasing array indices used for
+ * newer frames. Unavailable entries may be set to \ref
+ * VDP_INVALID_HANDLE.
+ * \param[in] video_source_rect The sub-rectangle of the source
+ * video surface to extract and process. If NULL, the
+ * entire surface will be used.
+ * \param[in] destination_surface
+ * \param[in] destination_rect The sub-rectangle of the
+ * destination surface to modify. Note that rectangle clips
+ * all other actions.
+ * \param[in] destination_video_rect The sub-rectangle of the
+ * destination surface that will contain the processed
+ * video. This rectangle is relative to the entire
+ * destination surface. This rectangle is clipped by \b
+ * destination_rect. If NULL, the destination rectangle
+ * will be sized to match the source rectangle, and will
+ * be located at the origin.
+ * \param[in] layer_count The number of additional layers to
+ * composite above the video.
+ * \param[in] layers The array of additional layers to composite
+ * above the video.
+ * \return VdpStatus The completion status of the operation.
+ *
+ * For a complete discussion of how to use this API, please see
+ * \ref video_mixer_usage.
+ */
+typedef VdpStatus VdpVideoMixerRender(
+ VdpVideoMixer mixer,
+ VdpOutputSurface background_surface,
+ VdpRect const * background_source_rect,
+ VdpVideoMixerPictureStructure current_picture_structure,
+ uint32_t video_surface_past_count,
+ VdpVideoSurface const * video_surface_past,
+ VdpVideoSurface video_surface_current,
+ uint32_t video_surface_future_count,
+ VdpVideoSurface const * video_surface_future,
+ VdpRect const * video_source_rect,
+ VdpOutputSurface destination_surface,
+ VdpRect const * destination_rect,
+ VdpRect const * destination_video_rect,
+ uint32_t layer_count,
+ VdpLayer const * layers
+);
+
+/*@}*/
+
+/**
+ * \defgroup VdpPresentationQueue VdpPresentationQueue; Video \
+ * presentation (display) object
+ *
+ * The VdpPresentationQueue manages a queue of surfaces and
+ * associated timestamps. For each surface in the queue, once
+ * the associated timestamp is reached, the surface is displayed
+ * to the user. This timestamp-based approach yields high
+ * quality video delivery.
+ *
+ * The exact location of the displayed content is Window System
+ * specific. For this reason, the \ref api_winsys provides an
+ * API to create a \ref VdpPresentationQueueTarget object (e.g.
+ * via \ref VdpPresentationQueueTargetCreateX11) which
+ * encapsulates this information.
+ *
+ * Note that the presentation queue performs no scaling of
+ * surfaces to match the display target's size, aspect ratio,
+ * etc.
+ *
+ * Surfaces that are too large to fit into the display target
+ * will be clipped. Surfaces that are too small to fill the
+ * display target will be aligned to the top-left corner of the
+ * display target, with the balance of the display target being
+ * filled with a constant configurable "background" color.
+ *
+ * Note that the presentation queue operates in a manner that is
+ * semantically equivalent to an overlay surface, with any
+ * required color key painting hidden internally. However,
+ * implementations are free to use whatever semantically
+ * equivalent technique they wish. Note that implementations
+ * that actually use color-keyed overlays will typically use
+ * the "background" color as the overlay color key value, so
+ * this color should be chosen with care.
+ *
+ * @{
+ */
+
+/**
+ * \brief The representation of a point in time.
+ *
+ * VdpTime timestamps are intended to be a high-precision timing
+ * system, potentially independent from any other time domain in
+ * the system.
+ *
+ * Time is represented in units of nanoseconds. The origin
+ * (i.e. the time represented by a value of 0) is implementation
+ * dependent.
+ */
+typedef uint64_t VdpTime;
+
+/**
+ * \brief An opaque handle representing the location where
+ * video will be presented.
+ *
+ * VdpPresentationQueueTarget are created using a \ref api_winsys
+ * specific API, such as \ref
+ * VdpPresentationQueueTargetCreateX11.
+ */
+typedef uint32_t VdpPresentationQueueTarget;
+
+/**
+ * \brief Destroy a VdpPresentationQueueTarget.
+ * \param[in] presentation_queue_target The target to destroy.
+ * \return VdpStatus The completion status of the operation.
+ */
+typedef VdpStatus VdpPresentationQueueTargetDestroy(
+ VdpPresentationQueueTarget presentation_queue_target
+);
+
+/**
+ * \brief An opaque handle representing a presentation queue
+ * object.
+ */
+typedef uint32_t VdpPresentationQueue;
+
+/**
+ * \brief Create a VdpPresentationQueue.
+ * \param[in] device The device that will contain the queue.
+ * \param[in] presentation_queue_target The location to display
+ * the content.
+ * \param[out] presentation_queue The new queue's handle.
+ * \return VdpStatus The completion status of the operation.
+ *
+ * Note: The initial value for the background color will be set to
+ * an implementation-defined value.
+ */
+typedef VdpStatus VdpPresentationQueueCreate(
+ VdpDevice device,
+ VdpPresentationQueueTarget presentation_queue_target,
+ /* output parameters follow */
+ VdpPresentationQueue * presentation_queue
+);
+
+/**
+ * \brief Destroy a VdpPresentationQueue.
+ * \param[in] presentation_queue The queue to destroy.
+ * \return VdpStatus The completion status of the operation.
+ */
+typedef VdpStatus VdpPresentationQueueDestroy(
+ VdpPresentationQueue presentation_queue
+);
+
+/**
+ * \brief Configure the background color setting.
+ * \param[in] presentation_queue The queue to manipulate.
+ * \param[in] background_color The new background color.
+ *
+ * Note: Implementations may choose whether to apply the
+ * new background color value immediately, or defer it until
+ * the next surface is presented.
+ */
+typedef VdpStatus VdpPresentationQueueSetBackgroundColor(
+ VdpPresentationQueue presentation_queue,
+ VdpColor * const background_color
+);
+
+/**
+ * \brief Retrieve the current background color setting.
+ * \param[in] presentation_queue The queue to query.
+ * \param[out] background_color The current background color.
+ */
+typedef VdpStatus VdpPresentationQueueGetBackgroundColor(
+ VdpPresentationQueue presentation_queue,
+ VdpColor * background_color
+);
+
+/**
+ * \brief Retrieve the presentation queue's "current" time.
+ * \param[in] presentation_queue The queue to query.
+ * \param[out] current_time The current time, which may
+ * represent a point between display VSYNC events.
+ * \return VdpStatus The completion status of the operation.
+ */
+typedef VdpStatus VdpPresentationQueueGetTime(
+ VdpPresentationQueue presentation_queue,
+ /* output parameters follow */
+ VdpTime * current_time
+);
+
+/**
+ * \brief Enter a surface into the presentation queue.
+ * \param[in] presentation_queue The queue to query.
+ * \param[in] surface The surface to enter into the queue.
+ * \param[in] clip_width If set to a non-zero value, the presentation queue
+ * will display only clip_width pixels of the surface (anchored to the
+ * top-left corner of the surface.
+ * \param[in] clip_height If set to a non-zero value, the presentation queue
+ * will display only clip_height lines of the surface (anchored to the
+ * top-left corner of the surface.
+ * \param[in] earliest_presentation_time The timestamp
+ * associated with the surface. The presentation queue
+ * will not display the surface until the presentation
+ * queue's current time is at least this value.
+ * \return VdpStatus The completion status of the operation.
+ *
+ * Applications may choose to allow resizing of the presentation queue target
+ * (which may be e.g. a regular Window when using an X11-based
+ * implementation).
+ *
+ * \b clip_width and \b clip_height may be used to limit the size of the
+ * displayed region of a surface, in order to match the specific region that
+ * was rendered to.
+ *
+ * In turn, this allows the application to allocate over-sized (e.g.
+ * screen-sized) surfaces, but render to a region that matches the current
+ * size of the video window.
+ *
+ * Using this technique, an application's response to window resizing may
+ * simply be to render to, and display, a different region of the surface,
+ * rather than de-/re-allocation of surfaces to match the updated window size.
+ */
+typedef VdpStatus VdpPresentationQueueDisplay(
+ VdpPresentationQueue presentation_queue,
+ VdpOutputSurface surface,
+ uint32_t clip_width,
+ uint32_t clip_height,
+ VdpTime earliest_presentation_time
+);
+
+/**
+ * \brief Wait for a surface to finish being displayed.
+ * \param[in] presentation_queue The queue to query.
+ * \param[in] surface The surface to wait for.
+ * \param[out] first_presentation_time The timestamp of the
+ * VSYNC at which this surface was first displayed. Note
+ * that 0 means the surface was never displayed.
+ * \return VdpStatus The completion status of the operation.
+ *
+ * Note that this API will block indefinitely if queried about
+ * the surface most recently added to a presentation queue,
+ * since there is no other surface that could possibly replace
+ * the queried surface.
+ */
+typedef VdpStatus VdpPresentationQueueBlockUntilSurfaceIdle(
+ VdpPresentationQueue presentation_queue,
+ VdpOutputSurface surface,
+ /* output parameters follow */
+ VdpTime * first_presentation_time
+);
+
+/**
+ * \hideinitializer
+ * \brief The status of a surface within a presentation queue.
+ */
+typedef enum {
+ /** The surface is no queued or currently visible. */
+ VDP_PRESENTATION_QUEUE_STATUS_IDLE,
+ /** The surface is in the queue, and not currently visible. */
+ VDP_PRESENTATION_QUEUE_STATUS_QUEUED,
+ /** The surface is the currently visible surface. */
+ VDP_PRESENTATION_QUEUE_STATUS_VISIBLE,
+} VdpPresentationQueueStatus;
+
+/**
+ * \brief Poll the current queue status of a surface.
+ * \param[in] presentation_queue The queue to query.
+ * \param[in] surface The surface to query.
+ * \param[out] status The current status of the surface within
+ * the queue.
+ * \param[out] first_presentation_time The timestamp of the
+ * VSYNC at which this surface was first displayed. Note
+ * that 0 means the surface was never displayed.
+ * \return VdpStatus The completion status of the operation.
+ */
+typedef VdpStatus VdpPresentationQueueQuerySurfaceStatus(
+ VdpPresentationQueue presentation_queue,
+ VdpOutputSurface surface,
+ /* output parameters follow */
+ VdpPresentationQueueStatus * status,
+ VdpTime * first_presentation_time
+);
+
+/*@}*/
+
+/**
+ * \defgroup display_preemption Display Preemption
+ *
+ * The Window System may operate within a frame-work (such as
+ * Linux's VT switching) where the display is shared between the
+ * Window System (e.g. X) and some other output mechanism (e.g.
+ * the VT.) Given this scenario, the Window System's control of
+ * the display could be preempted, and restored, at any time.
+ *
+ * VDPAU does not mandate that implementations hide such
+ * preemptions from VDPAU client applications; doing so may
+ * impose extreme burdens upon VDPAU implementations. Equally,
+ * however, implementations are free to hide such preemptions
+ * from client applications.
+ *
+ * VDPAU allows implementations to inform the client application
+ * when such a preemption has occurred, and then refuse to
+ * continue further operation.
+ *
+ * Similarly, some form of fatal hardware error could prevent further
+ * operation of the VDPAU implementation, without a complete
+ * re-initialization.
+ *
+ * The following discusses the behavior of implementations that
+ * choose not to hide preemption from client applications.
+ *
+ * When preemption occurs, VDPAU internally destroys all
+ * objects; the client application need not do this. However, if
+ * the client application wishes to continue operation, it must
+ * recreate all objects that it uses. It is probable that this
+ * recreation will not succeed until the display ownership is
+ * restored to the Window System.
+ *
+ * Once preemption has occurred, all VDPAU entry points will
+ * return the specific error code \ref
+ * VDP_STATUS_DISPLAY_PREEMPTED.
+ *
+ * VDPAU client applications may also be notified of such
+ * preemptions and fatal errors via a callback. See \ref
+ * VdpPreemptionCallbackRegister for more details.
+ *
+ * @{
+ */
+
+/**
+ * \brief A callback to notify the client application that a
+ * device's display has been preempted.
+ * \param[in] device The device that had its display preempted.
+ * \param[in] context The client-supplied callback context
+ * information.
+ * \return void No return value
+ */
+typedef void VdpPreemptionCallback(
+ VdpDevice device,
+ void * context
+);
+
+/**
+ * \brief Configure the display preemption callback.
+ * \param[in] device The device to be monitored for preemption.
+ * \param[in] callback The client application's callback
+ * function. If NULL, the callback is unregistered.
+ * \param[in] context The client-supplied callback context
+ * information. This information will be passed to the
+ * callback function if/when invoked.
+ * \return VdpStatus The completion status of the operation.
+ */
+typedef VdpStatus VdpPreemptionCallbackRegister(
+ VdpDevice device,
+ VdpPreemptionCallback callback,
+ void * context
+);
+
+/*@}*/
+
+/**
+ * \defgroup get_proc_address Entry Point Retrieval
+ *
+ * In order to facilitate multiple implementations of VDPAU
+ * co-existing within a single process, all functionality is
+ * available via function pointers. The mechanism to retrieve
+ * those function pointers is described below.
+ *
+ * @{
+ */
+
+/**
+ * \brief A type suitable for \ref VdpGetProcAddress
+ * "VdpGetProcAddress"'s \b function_id parameter.
+ */
+typedef uint32_t VdpFuncId;
+
+/** \hideinitializer */
+#define VDP_FUNC_ID_GET_ERROR_STRING (VdpFuncId)0
+/** \hideinitializer */
+#define VDP_FUNC_ID_GET_PROC_ADDRESS (VdpFuncId)1
+/** \hideinitializer */
+#define VDP_FUNC_ID_GET_API_VERSION (VdpFuncId)2
+/** \hideinitializer */
+#define VDP_FUNC_ID_GET_INFORMATION_STRING (VdpFuncId)4
+/** \hideinitializer */
+#define VDP_FUNC_ID_DEVICE_DESTROY (VdpFuncId)5
+/** \hideinitializer */
+#define VDP_FUNC_ID_GENERATE_CSC_MATRIX (VdpFuncId)6
+/** \hideinitializer */
+#define VDP_FUNC_ID_VIDEO_SURFACE_QUERY_CAPABILITIES (VdpFuncId)7
+/** \hideinitializer */
+#define VDP_FUNC_ID_VIDEO_SURFACE_QUERY_GET_PUT_BITS_Y_CB_CR_CAPABILITIES (VdpFuncId)8
+/** \hideinitializer */
+#define VDP_FUNC_ID_VIDEO_SURFACE_CREATE (VdpFuncId)9
+/** \hideinitializer */
+#define VDP_FUNC_ID_VIDEO_SURFACE_DESTROY (VdpFuncId)10
+/** \hideinitializer */
+#define VDP_FUNC_ID_VIDEO_SURFACE_GET_PARAMETERS (VdpFuncId)11
+/** \hideinitializer */
+#define VDP_FUNC_ID_VIDEO_SURFACE_GET_BITS_Y_CB_CR (VdpFuncId)12
+/** \hideinitializer */
+#define VDP_FUNC_ID_VIDEO_SURFACE_PUT_BITS_Y_CB_CR (VdpFuncId)13
+/** \hideinitializer */
+#define VDP_FUNC_ID_OUTPUT_SURFACE_QUERY_CAPABILITIES (VdpFuncId)14
+/** \hideinitializer */
+#define VDP_FUNC_ID_OUTPUT_SURFACE_QUERY_GET_PUT_BITS_NATIVE_CAPABILITIES (VdpFuncId)15
+/** \hideinitializer */
+#define VDP_FUNC_ID_OUTPUT_SURFACE_QUERY_PUT_BITS_INDEXED_CAPABILITIES (VdpFuncId)16
+/** \hideinitializer */
+#define VDP_FUNC_ID_OUTPUT_SURFACE_QUERY_PUT_BITS_Y_CB_CR_CAPABILITIES (VdpFuncId)17
+/** \hideinitializer */
+#define VDP_FUNC_ID_OUTPUT_SURFACE_CREATE (VdpFuncId)18
+/** \hideinitializer */
+#define VDP_FUNC_ID_OUTPUT_SURFACE_DESTROY (VdpFuncId)19
+/** \hideinitializer */
+#define VDP_FUNC_ID_OUTPUT_SURFACE_GET_PARAMETERS (VdpFuncId)20
+/** \hideinitializer */
+#define VDP_FUNC_ID_OUTPUT_SURFACE_GET_BITS_NATIVE (VdpFuncId)21
+/** \hideinitializer */
+#define VDP_FUNC_ID_OUTPUT_SURFACE_PUT_BITS_NATIVE (VdpFuncId)22
+/** \hideinitializer */
+#define VDP_FUNC_ID_OUTPUT_SURFACE_PUT_BITS_INDEXED (VdpFuncId)23
+/** \hideinitializer */
+#define VDP_FUNC_ID_OUTPUT_SURFACE_PUT_BITS_Y_CB_CR (VdpFuncId)24
+/** \hideinitializer */
+#define VDP_FUNC_ID_BITMAP_SURFACE_QUERY_CAPABILITIES (VdpFuncId)25
+/** \hideinitializer */
+#define VDP_FUNC_ID_BITMAP_SURFACE_CREATE (VdpFuncId)26
+/** \hideinitializer */
+#define VDP_FUNC_ID_BITMAP_SURFACE_DESTROY (VdpFuncId)27
+/** \hideinitializer */
+#define VDP_FUNC_ID_BITMAP_SURFACE_GET_PARAMETERS (VdpFuncId)28
+/** \hideinitializer */
+#define VDP_FUNC_ID_BITMAP_SURFACE_PUT_BITS_NATIVE (VdpFuncId)29
+/** \hideinitializer */
+#define VDP_FUNC_ID_OUTPUT_SURFACE_RENDER_OUTPUT_SURFACE (VdpFuncId)33
+/** \hideinitializer */
+#define VDP_FUNC_ID_OUTPUT_SURFACE_RENDER_BITMAP_SURFACE (VdpFuncId)34
+/** \hideinitializer */
+#define VDP_FUNC_ID_OUTPUT_SURFACE_RENDER_VIDEO_SURFACE_LUMA (VdpFuncId)35
+/** \hideinitializer */
+#define VDP_FUNC_ID_DECODER_QUERY_CAPABILITIES (VdpFuncId)36
+/** \hideinitializer */
+#define VDP_FUNC_ID_DECODER_CREATE (VdpFuncId)37
+/** \hideinitializer */
+#define VDP_FUNC_ID_DECODER_DESTROY (VdpFuncId)38
+/** \hideinitializer */
+#define VDP_FUNC_ID_DECODER_GET_PARAMETERS (VdpFuncId)39
+/** \hideinitializer */
+#define VDP_FUNC_ID_DECODER_RENDER (VdpFuncId)40
+/** \hideinitializer */
+#define VDP_FUNC_ID_VIDEO_MIXER_QUERY_FEATURE_SUPPORT (VdpFuncId)41
+/** \hideinitializer */
+#define VDP_FUNC_ID_VIDEO_MIXER_QUERY_PARAMETER_SUPPORT (VdpFuncId)42
+/** \hideinitializer */
+#define VDP_FUNC_ID_VIDEO_MIXER_QUERY_ATTRIBUTE_SUPPORT (VdpFuncId)43
+/** \hideinitializer */
+#define VDP_FUNC_ID_VIDEO_MIXER_QUERY_PARAMETER_VALUE_RANGE (VdpFuncId)44
+/** \hideinitializer */
+#define VDP_FUNC_ID_VIDEO_MIXER_QUERY_ATTRIBUTE_VALUE_RANGE (VdpFuncId)45
+/** \hideinitializer */
+#define VDP_FUNC_ID_VIDEO_MIXER_CREATE (VdpFuncId)46
+/** \hideinitializer */
+#define VDP_FUNC_ID_VIDEO_MIXER_SET_FEATURE_ENABLES (VdpFuncId)47
+/** \hideinitializer */
+#define VDP_FUNC_ID_VIDEO_MIXER_SET_ATTRIBUTE_VALUES (VdpFuncId)48
+/** \hideinitializer */
+#define VDP_FUNC_ID_VIDEO_MIXER_GET_FEATURE_SUPPORT (VdpFuncId)49
+/** \hideinitializer */
+#define VDP_FUNC_ID_VIDEO_MIXER_GET_FEATURE_ENABLES (VdpFuncId)50
+/** \hideinitializer */
+#define VDP_FUNC_ID_VIDEO_MIXER_GET_PARAMETER_VALUES (VdpFuncId)51
+/** \hideinitializer */
+#define VDP_FUNC_ID_VIDEO_MIXER_GET_ATTRIBUTE_VALUES (VdpFuncId)52
+/** \hideinitializer */
+#define VDP_FUNC_ID_VIDEO_MIXER_DESTROY (VdpFuncId)53
+/** \hideinitializer */
+#define VDP_FUNC_ID_VIDEO_MIXER_RENDER (VdpFuncId)54
+/** \hideinitializer */
+#define VDP_FUNC_ID_PRESENTATION_QUEUE_TARGET_DESTROY (VdpFuncId)55
+/** \hideinitializer */
+#define VDP_FUNC_ID_PRESENTATION_QUEUE_CREATE (VdpFuncId)56
+/** \hideinitializer */
+#define VDP_FUNC_ID_PRESENTATION_QUEUE_DESTROY (VdpFuncId)57
+/** \hideinitializer */
+#define VDP_FUNC_ID_PRESENTATION_QUEUE_SET_BACKGROUND_COLOR (VdpFuncId)58
+/** \hideinitializer */
+#define VDP_FUNC_ID_PRESENTATION_QUEUE_GET_BACKGROUND_COLOR (VdpFuncId)59
+/** \hideinitializer */
+#define VDP_FUNC_ID_PRESENTATION_QUEUE_GET_TIME (VdpFuncId)62
+/** \hideinitializer */
+#define VDP_FUNC_ID_PRESENTATION_QUEUE_DISPLAY (VdpFuncId)63
+/** \hideinitializer */
+#define VDP_FUNC_ID_PRESENTATION_QUEUE_BLOCK_UNTIL_SURFACE_IDLE (VdpFuncId)64
+/** \hideinitializer */
+#define VDP_FUNC_ID_PRESENTATION_QUEUE_QUERY_SURFACE_STATUS (VdpFuncId)65
+/** \hideinitializer */
+#define VDP_FUNC_ID_PREEMPTION_CALLBACK_REGISTER (VdpFuncId)66
+
+#define VDP_FUNC_ID_BASE_WINSYS 0x1000
+
+/**
+ * \brief Retrieve a VDPAU function pointer.
+ * \param[in] device The device that the function will operate
+ * against.
+ * \param[in] function_id The specific function to retrieve.
+ * \param[out] function_pointer The actual pointer for the
+ * application to call.
+ * \return VdpStatus The completion status of the operation.
+ */
+typedef VdpStatus VdpGetProcAddress(
+ VdpDevice device,
+ VdpFuncId function_id,
+ /* output parameters follow */
+ void * * function_pointer
+);
+
+/*@}*/
+/*@}*/
+
+/**
+ * \defgroup api_winsys Window System Integration Layer
+ *
+ * The set of VDPAU functionality specific to an individual
+ * Windowing System.
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/include/vdpau/vdpau_x11.h b/include/vdpau/vdpau_x11.h
new file mode 100644
index 0000000..d56ae1c
--- /dev/null
+++ b/include/vdpau/vdpau_x11.h
@@ -0,0 +1,174 @@
+/*
+ * This source file is documented using Doxygen markup.
+ * See http://www.stack.nl/~dimitri/doxygen/
+ */
+
+/*
+ * This copyright notice applies to this header file:
+ *
+ * Copyright (c) 2008 NVIDIA Corporation
+ *
+ * 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.
+ */
+
+/**
+ * \file vdpau_x11.h
+ * \brief X11 Window System Integration Layer
+ *
+ * This file contains the \ref api_winsys_x11 "X11 Window System
+ * Integration Layer".
+ */
+
+#ifndef _VDPAU_X11_H
+#define _VDPAU_X11_H
+
+#include <X11/Xlib.h>
+#include "vdpau.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \ingroup api_winsys
+ * @{
+ */
+
+/**
+ * \defgroup api_winsys_x11 X11 Window System Integration Layer
+ *
+ * The set of VDPAU functionality specific to usage with the X
+ * Window System.
+ *
+ * \section Driver Library Layout
+ *
+ * An X11-oriented VDPAU installation consists of the following
+ * components:
+ *
+ * - Header files. These files are located in the standard
+ * system header file path.
+ * - \c vdpau/vdpau.h
+ * - \c vdpau/vdpau_x11.h
+ * - The VDPAU wrapper library. These files are located in the
+ * standard system (possibly X11-specific) library path.
+ * - \c libvdpau.so.1 (runtime)
+ * - \c libvdpau.so (development)
+ * - Back-end driver files. These files are located in the
+ * standard system (possibly X11-specific) library path.
+ * - \c libvdpau_\%s.so
+ * For example:
+ * - \c libvdpau_nvidia.so
+ * - \c libvdpau_intel.so
+ * - \c libvdpau_ati.so
+ *
+ * The VDPAU wrapper library implements just one function; \ref
+ * vdp_device_create_x11. The wrapper will implement this function
+ * by dynamically loading the appropriate back-end driver file
+ * mentioned above. Long-term, the wrapper will use a
+ * VDPAU-specific X extension to determine which back-end driver
+ * to load. Currently, the wrapper library hard-codes the driver
+ * name as "nvidia", although this can be overridden using the
+ * environment variable VDPAU_DRIVER.
+ *
+ * The back-end driver is expected to implement a function named
+ * \b vdp_imp_device_create_x11. The wrapper will call this function to
+ * actually implement the \ref vdp_device_create_x11 application call.
+ *
+ * Note that it is theoretically possible for an application to
+ * create multiple \ref VdpDevice "VdpDevice" objects. In this
+ * case, the wrapper library may load multiple back-end drivers
+ * into the same application, and/or invoke a specific back-end
+ * driver's \b VdpImpDeviceCreateX11 multiple times. The wrapper
+ * libray imposes no policy regarding whether the application
+ * may instantiate multiple \ref VdpDevice "VdpDevice" objects for
+ * the same display and/or screen. However, back-end drivers are
+ * free to limit the number of \ref VdpDevice "VdpDevice" objects
+ * as required by their implementation.
+ *
+ * @{
+ */
+
+/**
+ * \brief Create a VdpDevice object for use with X11.
+ * \param[in] display The X Display that the VdpDevice VdpDevice
+ * will operate against.
+ * \param[in] screen The X screen that the VdpDevice will operate
+ * against.
+ * \param[out] device The new device's handle.
+ * \param[out] get_proc_address The get_proc_address entry point
+ * to use with this device.
+ * \return VdpStatus The completion status of the operation.
+ */
+typedef VdpStatus VdpDeviceCreateX11(
+ Display * display,
+ int screen,
+ /* output parameters follow */
+ VdpDevice * device,
+ VdpGetProcAddress * * get_proc_address
+);
+
+/**
+ * \brief Create a VdpDevice object for use with X11.
+ * This is an actual symbol of type \ref VdpDeviceCreateX11
+ *
+ */
+VdpDeviceCreateX11 vdp_device_create_x11;
+
+/**
+ * \brief Create a VdpPresentationQueueTarget for use with X11.
+ * \param[in] device The device that will contain the queue
+ * target.
+ * \param[in] drawable The X11 Drawable that the presentation
+ * queue will present into.
+ * \param[out] target The new queue target's handle.
+ * \return VdpStatus The completion status of the operation.
+ *
+ * Note: VDPAU expects to own the entire drawable for the duration of time
+ * that the presentation queue target exists. In particular,
+ * implementations may choose to manipulate client-visible X11 window state
+ * as required. As such, it is recommended that applications create a
+ * dedicated window for the presentation queue target, as a child
+ * (grand-child, ...) of their top-level application window.
+ *
+ * Applications may also create child-windows of the presentation queue
+ * target, which will cover any presented video in the normal fashion. VDPAU
+ * implementations will not manipulate such child windows in any fashion.
+ */
+typedef VdpStatus VdpPresentationQueueTargetCreateX11(
+ VdpDevice device,
+ Drawable drawable,
+ /* output parameters follow */
+ VdpPresentationQueueTarget * target
+);
+
+/** \hideinitializer */
+#define VDP_FUNC_ID_PRESENTATION_QUEUE_TARGET_CREATE_X11 (VdpFuncId)(VDP_FUNC_ID_BASE_WINSYS + 0)
+
+/*@}*/
+/*@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/src/vdpau_wrapper.c b/src/vdpau_wrapper.c
new file mode 100644
index 0000000..9ce69ed
--- /dev/null
+++ b/src/vdpau_wrapper.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2008-2009 NVIDIA, Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ */
+
+#include <dlfcn.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "../include/vdpau/vdpau_x11.h"
+
+typedef void SetDllHandle(
+ void * driver_dll_handle
+);
+
+#if DEBUG
+
+static void _vdp_wrapper_error_breakpoint(char const * file, int line, char const * function)
+{
+ fprintf(stderr, "VDPAU wrapper: Error detected at %s:%d %s()\n", file, line, function);
+}
+
+#define _VDP_ERROR_BREAKPOINT() _vdp_wrapper_error_breakpoint(__FILE__, __LINE__, __FUNCTION__)
+
+#else
+
+#define _VDP_ERROR_BREAKPOINT()
+
+#endif
+
+#define DRIVER_LIB_FORMAT "libvdpau_%s.so"
+
+VdpStatus vdp_device_create_x11(
+ Display * display,
+ int screen,
+ /* output parameters follow */
+ VdpDevice * device,
+ VdpGetProcAddress * * get_proc_address
+)
+{
+ char const * vdpau_driver;
+ char * vdpau_driver_lib;
+ void * backend_dll;
+ char const * vdpau_trace;
+ char const * func_name;
+
+ VdpDeviceCreateX11 * vdp_imp_device_create_x11;
+
+ /* FIXME: Determine driver name using an X extension */
+ vdpau_driver = getenv("VDPAU_DRIVER");
+ if (!vdpau_driver) {
+ vdpau_driver = "nvidia";
+ }
+
+ vdpau_driver_lib = malloc(strlen(DRIVER_LIB_FORMAT) + strlen(vdpau_driver) + 1);
+ if (!vdpau_driver_lib) {
+ _VDP_ERROR_BREAKPOINT();
+ return VDP_STATUS_RESOURCES;
+ }
+ sprintf(vdpau_driver_lib, DRIVER_LIB_FORMAT, vdpau_driver);
+
+ backend_dll = dlopen(vdpau_driver_lib, RTLD_NOW | RTLD_GLOBAL);
+ free(vdpau_driver_lib);
+ if (!backend_dll) {
+ _VDP_ERROR_BREAKPOINT();
+ return VDP_STATUS_NO_IMPLEMENTATION;
+ }
+
+ vdpau_trace = getenv("VDPAU_TRACE");
+ if (vdpau_trace && atoi(vdpau_trace)) {
+ void * trace_dll;
+ SetDllHandle * set_dll_handle;
+
+ trace_dll = dlopen("libvdpau_trace.so", RTLD_NOW | RTLD_GLOBAL);
+ if (!trace_dll) {
+ _VDP_ERROR_BREAKPOINT();
+ return VDP_STATUS_NO_IMPLEMENTATION;
+ }
+
+ set_dll_handle = (SetDllHandle*)dlsym(
+ trace_dll,
+ "vdp_trace_set_backend_handle"
+ );
+ if (!set_dll_handle) {
+ _VDP_ERROR_BREAKPOINT();
+ return VDP_STATUS_NO_IMPLEMENTATION;
+ }
+
+ set_dll_handle(backend_dll);
+
+ backend_dll = trace_dll;
+
+ func_name = "vdp_trace_device_create_x11";
+ }
+ else {
+ func_name = "vdp_imp_device_create_x11";
+ }
+
+ vdp_imp_device_create_x11 = (VdpDeviceCreateX11*)dlsym(
+ backend_dll,
+ func_name
+ );
+ if (!vdp_imp_device_create_x11) {
+ _VDP_ERROR_BREAKPOINT();
+ return VDP_STATUS_NO_IMPLEMENTATION;
+ }
+
+ return vdp_imp_device_create_x11(
+ display,
+ screen,
+ device,
+ get_proc_address
+ );
+}
+
diff --git a/trace/vdpau_trace.cpp b/trace/vdpau_trace.cpp
new file mode 100644
index 0000000..ae43973
--- /dev/null
+++ b/trace/vdpau_trace.cpp
@@ -0,0 +1,4293 @@
+/*
+ * Copyright (c) 2008-2009 NVIDIA, Corporation
+ *
+ * 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 (including the next
+ * paragraph) 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.
+ */
+
+#define __STDC_FORMAT_MACROS
+#define __STDC_LIMIT_MACROS
+#include <inttypes.h>
+
+#include <dlfcn.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <vdpau/vdpau_x11.h>
+
+#define _VDP_TRACE_ARSIZE(_x_) ((sizeof (_x_)) / (sizeof ((_x_)[0])))
+
+#if DEBUG
+
+static void _vdp_trace_error_breakpoint(char const * file, int line, char const * function)
+{
+ fprintf(stderr, "VDPAU trace:: Error detected at %s:%d %s()\n", file, line, function);
+}
+
+#define _VDP_TRACE_ERROR_BREAKPOINT() _vdp_trace_error_breakpoint(__FILE__, __LINE__, __FUNCTION__)
+
+#else
+
+#define _VDP_TRACE_ERROR_BREAKPOINT()
+
+#endif
+
+#define LEVEL_PARAMS 1
+#define LEVEL_DATA 2
+
+struct _VdpCapData {
+ void * dll;
+
+ int level;
+ FILE * fp;
+
+ VdpDevice vdp_device;
+ VdpGetProcAddress * vdp_get_proc_address;
+
+ VdpGetErrorString * vdp_get_error_string;
+ VdpGetApiVersion * vdp_get_api_version;
+ VdpGetInformationString * vdp_get_information_string;
+ VdpDeviceDestroy * vdp_device_destroy;
+ VdpGenerateCSCMatrix * vdp_generate_csc_matrix;
+ VdpVideoSurfaceQueryCapabilities * vdp_video_surface_query_capabilities;
+ VdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities * vdp_video_surface_query_get_put_bits_y_cb_cr_capabilities;
+ VdpVideoSurfaceCreate * vdp_video_surface_create;
+ VdpVideoSurfaceDestroy * vdp_video_surface_destroy;
+ VdpVideoSurfaceGetParameters * vdp_video_surface_get_parameters;
+ VdpVideoSurfaceGetBitsYCbCr * vdp_video_surface_get_bits_y_cb_cr;
+ VdpVideoSurfacePutBitsYCbCr * vdp_video_surface_put_bits_y_cb_cr;
+ VdpOutputSurfaceQueryCapabilities * vdp_output_surface_query_capabilities;
+ VdpOutputSurfaceQueryGetPutBitsNativeCapabilities * vdp_output_surface_query_get_put_bits_native_capabilities;
+ VdpOutputSurfaceQueryPutBitsIndexedCapabilities * vdp_output_surface_query_put_bits_indexed_capabilities;
+ VdpOutputSurfaceQueryPutBitsYCbCrCapabilities * vdp_output_surface_query_put_bits_y_cb_cr_capabilities;
+ VdpOutputSurfaceCreate * vdp_output_surface_create;
+ VdpOutputSurfaceDestroy * vdp_output_surface_destroy;
+ VdpOutputSurfaceGetParameters * vdp_output_surface_get_parameters;
+ VdpOutputSurfaceGetBitsNative * vdp_output_surface_get_bits_native;
+ VdpOutputSurfacePutBitsNative * vdp_output_surface_put_bits_native;
+ VdpOutputSurfacePutBitsIndexed * vdp_output_surface_put_bits_indexed;
+ VdpOutputSurfacePutBitsYCbCr * vdp_output_surface_put_bits_y_cb_cr;
+ VdpBitmapSurfaceQueryCapabilities * vdp_bitmap_surface_query_capabilities;
+ VdpBitmapSurfaceCreate * vdp_bitmap_surface_create;
+ VdpBitmapSurfaceDestroy * vdp_bitmap_surface_destroy;
+ VdpBitmapSurfaceGetParameters * vdp_bitmap_surface_get_parameters;
+ VdpBitmapSurfacePutBitsNative * vdp_bitmap_surface_put_bits_native;
+ VdpOutputSurfaceRenderOutputSurface * vdp_output_surface_render_output_surface;
+ VdpOutputSurfaceRenderBitmapSurface * vdp_output_surface_render_bitmap_surface;
+ VdpDecoderQueryCapabilities * vdp_decoder_query_capabilities;
+ VdpDecoderCreate * vdp_decoder_create;
+ VdpDecoderDestroy * vdp_decoder_destroy;
+ VdpDecoderGetParameters * vdp_decoder_get_parameters;
+ VdpDecoderRender * vdp_decoder_render;
+ VdpVideoMixerQueryFeatureSupport * vdp_video_mixer_query_feature_support;
+ VdpVideoMixerQueryParameterSupport * vdp_video_mixer_query_parameter_support;
+ VdpVideoMixerQueryAttributeSupport * vdp_video_mixer_query_attribute_support;
+ VdpVideoMixerQueryParameterValueRange * vdp_video_mixer_query_parameter_value_range;
+ VdpVideoMixerQueryAttributeValueRange * vdp_video_mixer_query_attribute_value_range;
+ VdpVideoMixerCreate * vdp_video_mixer_create;
+ VdpVideoMixerSetFeatureEnables * vdp_video_mixer_set_feature_enables;
+ VdpVideoMixerSetAttributeValues * vdp_video_mixer_set_attribute_values;
+ VdpVideoMixerGetFeatureSupport * vdp_video_mixer_get_feature_support;
+ VdpVideoMixerGetFeatureEnables * vdp_video_mixer_get_feature_enables;
+ VdpVideoMixerGetParameterValues * vdp_video_mixer_get_parameter_values;
+ VdpVideoMixerGetAttributeValues * vdp_video_mixer_get_attribute_values;
+ VdpVideoMixerDestroy * vdp_video_mixer_destroy;
+ VdpVideoMixerRender * vdp_video_mixer_render;
+ VdpPresentationQueueTargetDestroy * vdp_presentation_queue_target_destroy;
+ VdpPresentationQueueCreate * vdp_presentation_queue_create;
+ VdpPresentationQueueDestroy * vdp_presentation_queue_destroy;
+ VdpPresentationQueueSetBackgroundColor * vdp_presentation_queue_set_background_color;
+ VdpPresentationQueueGetBackgroundColor * vdp_presentation_queue_get_background_color;
+ VdpPresentationQueueGetTime * vdp_presentation_queue_get_time;
+ VdpPresentationQueueDisplay * vdp_presentation_queue_display;
+ VdpPresentationQueueBlockUntilSurfaceIdle * vdp_presentation_queue_block_until_surface_idle;
+ VdpPresentationQueueQuerySurfaceStatus * vdp_presentation_queue_query_surface_status;
+ VdpPreemptionCallbackRegister * vdp_preemption_callback_register;
+ VdpPresentationQueueTargetCreateX11 * vdp_presentation_queue_target_create_x11;
+};
+
+static _VdpCapData _vdp_cap_data;
+
+template<class T> static inline T const delta(T const & a, T const & b)
+{
+ if (a < b) {
+ return b - a;
+ }
+ else {
+ return a - b;
+ }
+}
+
+static void _vdp_cap_dump_procamp(VdpProcamp * procamp)
+{
+ if (!procamp) {
+ fprintf(_vdp_cap_data.fp, "NULL");
+ return;
+ }
+
+ fprintf(
+ _vdp_cap_data.fp,
+ "{(ver=%d)%s %f, %f, %f, %f}",
+ procamp->struct_version,
+ (procamp->struct_version > 0)
+ ? "(unsupported; cannot dump all fields)"
+ : "",
+ procamp->brightness,
+ procamp->contrast,
+ procamp->saturation,
+ procamp->hue
+ );
+}
+
+static void _vdp_cap_dump_color(
+ VdpColor const * color
+)
+{
+ if (!color) {
+ fputs("NULL", _vdp_cap_data.fp);
+ return;
+ }
+
+ fprintf(
+ _vdp_cap_data.fp,
+ "{%f, %f, %f, %f}",
+ color->red,
+ color->green,
+ color->blue,
+ color->alpha
+ );
+}
+
+static void _vdp_cap_dump_point(
+ VdpPoint const * point
+)
+{
+ if (!point) {
+ fprintf(_vdp_cap_data.fp, "NULL");
+ return;
+ }
+
+ fprintf(
+ _vdp_cap_data.fp,
+ "{%u, %u}",
+ point->x,
+ point->y
+ );
+}
+
+static void _vdp_cap_dump_rect(
+ VdpRect const * rect
+)
+{
+ if (!rect) {
+ fprintf(_vdp_cap_data.fp, "NULL");
+ return;
+ }
+
+ fprintf(
+ _vdp_cap_data.fp,
+ "{%u, %u, %u, %u}",
+ rect->x0,
+ rect->y0,
+ rect->x1,
+ rect->y1
+ );
+}
+
+static void _vdp_cap_dump_csc_matrix(
+ VdpCSCMatrix const * matrix
+)
+{
+ if (!matrix) {
+ fprintf(_vdp_cap_data.fp, "NULL");
+ return;
+ }
+
+ fprintf(
+ _vdp_cap_data.fp,
+ "{{%f, %f, %f, %f}, {%f, %f, %f, %f}, {%f, %f, %f, %f}}",
+ (*matrix)[0][0],
+ (*matrix)[0][1],
+ (*matrix)[0][2],
+ (*matrix)[0][3],
+ (*matrix)[1][0],
+ (*matrix)[1][1],
+ (*matrix)[1][2],
+ (*matrix)[1][3],
+ (*matrix)[2][0],
+ (*matrix)[2][1],
+ (*matrix)[2][2],
+ (*matrix)[2][3]
+ );
+}
+
+static void _vdp_cap_dump_blend_state(
+ VdpOutputSurfaceRenderBlendState const * blend_state
+)
+{
+ if (!blend_state) {
+ fprintf(_vdp_cap_data.fp, "NULL");
+ return;
+ }
+
+ fprintf(
+ _vdp_cap_data.fp,
+ "{(ver=%d)%s %u, %u, %u, %u, %u, %u, ",
+ blend_state->struct_version,
+ (blend_state->struct_version > 0)
+ ? "(unsupported; cannot dump all fields)"
+ : "",
+ blend_state->blend_factor_source_color,
+ blend_state->blend_factor_destination_color,
+ blend_state->blend_factor_source_alpha,
+ blend_state->blend_factor_destination_alpha,
+ blend_state->blend_equation_color,
+ blend_state->blend_equation_alpha
+ );
+ _vdp_cap_dump_color(&(blend_state->blend_constant));
+ fputs("}", _vdp_cap_data.fp);
+}
+
+static void _vdp_cap_dump_picture_info(
+ VdpDecoderProfile profile,
+ VdpPictureInfo const * picture_info
+)
+{
+ VdpPictureInfoMPEG1Or2 const * picture_info_mpeg1or2;
+
+ switch (profile) {
+ case VDP_DECODER_PROFILE_MPEG1:
+ case VDP_DECODER_PROFILE_MPEG2_SIMPLE:
+ case VDP_DECODER_PROFILE_MPEG2_MAIN:
+ picture_info_mpeg1or2 = (VdpPictureInfoMPEG1Or2 const *)picture_info;
+
+ fprintf(
+ _vdp_cap_data.fp,
+ "{%u, %u, %u, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, {{%d, %d}, {%d, %d}}, {",
+ picture_info_mpeg1or2->forward_reference,
+ picture_info_mpeg1or2->backward_reference,
+ picture_info_mpeg1or2->slice_count,
+ picture_info_mpeg1or2->picture_structure,
+ picture_info_mpeg1or2->picture_coding_type,
+ picture_info_mpeg1or2->intra_dc_precision,
+ picture_info_mpeg1or2->frame_pred_frame_dct,
+ picture_info_mpeg1or2->concealment_motion_vectors,
+ picture_info_mpeg1or2->intra_vlc_format,
+ picture_info_mpeg1or2->alternate_scan,
+ picture_info_mpeg1or2->q_scale_type,
+ picture_info_mpeg1or2->top_field_first,
+ picture_info_mpeg1or2->full_pel_forward_vector,
+ picture_info_mpeg1or2->full_pel_backward_vector,
+ picture_info_mpeg1or2->f_code[0][0],
+ picture_info_mpeg1or2->f_code[0][1],
+ picture_info_mpeg1or2->f_code[1][0],
+ picture_info_mpeg1or2->f_code[1][1]
+ );
+ for (uint32_t i = 0; i < _VDP_TRACE_ARSIZE(picture_info_mpeg1or2->intra_quantizer_matrix); ++i) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%s%d",
+ (i == 0) ? "" : ", ",
+ picture_info_mpeg1or2->intra_quantizer_matrix[i]
+ );
+ }
+ fputs("}, {", _vdp_cap_data.fp);
+ for (uint32_t i = 0; i < _VDP_TRACE_ARSIZE(picture_info_mpeg1or2->non_intra_quantizer_matrix); ++i) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%s%d",
+ (i == 0) ? "" : ", ",
+ picture_info_mpeg1or2->non_intra_quantizer_matrix[i]
+ );
+ }
+ fputs("}}", _vdp_cap_data.fp);
+ break;
+ case VDP_DECODER_PROFILE_H264_BASELINE:
+ case VDP_DECODER_PROFILE_H264_MAIN:
+ case VDP_DECODER_PROFILE_H264_HIGH:
+ case VDP_DECODER_PROFILE_VC1_SIMPLE:
+ case VDP_DECODER_PROFILE_VC1_MAIN:
+ case VDP_DECODER_PROFILE_VC1_ADVANCED:
+ // FIXME: Dump all the other types too.
+ // For now, just deliberately fall through
+ default:
+ fputs("{...}", _vdp_cap_data.fp);
+ break;
+ }
+}
+
+static void _vdp_cap_dump_video_mixer_parameter_value(
+ VdpVideoMixerParameter parameter,
+ void const * value
+)
+{
+ switch (parameter) {
+ case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH:
+ case VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT:
+ case VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE:
+ case VDP_VIDEO_MIXER_PARAMETER_LAYERS:
+ if (!value) {
+ fputs("???", _vdp_cap_data.fp);
+ }
+ else {
+ fprintf(_vdp_cap_data.fp, "%u", *(uint32_t const *)value);
+ }
+ break;
+ default:
+ fputs("???", _vdp_cap_data.fp);
+ break;
+ }
+}
+
+static void _vdp_cap_dump_video_mixer_attribute_value(
+ VdpVideoMixerAttribute attribute,
+ void const * value,
+ bool get_operation
+)
+{
+ if (!value) {
+ fputs("NULL", _vdp_cap_data.fp);
+ return;
+ }
+
+ switch (attribute) {
+ case VDP_VIDEO_MIXER_ATTRIBUTE_BACKGROUND_COLOR:
+ _vdp_cap_dump_color((VdpColor const *)value);
+ break;
+ case VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX:
+ {
+ // We don't really need/want to cast away the const here,
+ // but the buggy compiler thinks we are, even when we don't.
+ // The const_cast tells it to quit complaining.
+ VdpCSCMatrix * ptr;
+
+ // For some objects, the "default" value is a NULL pointer.
+ // So, VdpVideoMixerGetAttributeValues expects a double pointer to
+ // the value, so it can either fill in the value, or NULL out the
+ // pointer.
+ if (get_operation) {
+ VdpCSCMatrix * * dptr = (VdpCSCMatrix * *)const_cast<void *>(value);
+ if (!dptr) {
+ return;
+ }
+ ptr = *dptr;
+ }
+ else {
+ ptr = (VdpCSCMatrix *)const_cast<void *>(value);
+ }
+ _vdp_cap_dump_csc_matrix(ptr);
+ }
+ break;
+ case VDP_VIDEO_MIXER_ATTRIBUTE_NOISE_REDUCTION_LEVEL:
+ case VDP_VIDEO_MIXER_ATTRIBUTE_SHARPNESS_LEVEL:
+ case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MIN_LUMA:
+ case VDP_VIDEO_MIXER_ATTRIBUTE_LUMA_KEY_MAX_LUMA:
+ fprintf(_vdp_cap_data.fp, "%f", *(float const *)value);
+ break;
+ default:
+ fputs("???", _vdp_cap_data.fp);
+ break;
+ }
+}
+
+static void _vdp_cap_dump_uint8_t_stream(
+ uint32_t count,
+ uint8_t const * values
+)
+{
+ if (!values) {
+ fputs("NULL", _vdp_cap_data.fp);
+ return;
+ }
+
+ fputs("{", _vdp_cap_data.fp);
+ while (count) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%02x",
+ values[0]
+ );
+
+ --count;
+ ++values;
+ }
+ fputs("}", _vdp_cap_data.fp);
+}
+
+static void _vdp_cap_dump_uint32_t_stream(
+ uint32_t count,
+ uint32_t const * values
+)
+{
+ if (!values) {
+ fputs("NULL", _vdp_cap_data.fp);
+ return;
+ }
+
+ fputs("{", _vdp_cap_data.fp);
+ while (count) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%08x%s",
+ values[0],
+ (count > 1) ? " " : ""
+ );
+
+ --count;
+ ++values;
+ }
+ fputs("}", _vdp_cap_data.fp);
+}
+
+struct _VdpcapPlane {
+ void const * data;
+ uint32_t pitch;
+ uint32_t item_count;
+ uint32_t item_size;
+ uint32_t lines;
+};
+
+typedef void _VdpcapPlaneDumper(uint32_t count, void const * values);
+
+static void _vdp_cap_dump_plane_list(
+ uint32_t plane_count,
+ _VdpcapPlane const * planes
+)
+{
+ if (!planes) {
+ fputs("NULL", _vdp_cap_data.fp);
+ return;
+ }
+
+ fputs("{", _vdp_cap_data.fp);
+ while (plane_count) {
+ uint32_t lines = planes[0].lines;
+
+ _VdpcapPlaneDumper * dumper;
+ if (planes[0].item_size == 4) {
+ dumper = (_VdpcapPlaneDumper*)_vdp_cap_dump_uint32_t_stream;
+ }
+ else {
+ dumper = (_VdpcapPlaneDumper*)_vdp_cap_dump_uint8_t_stream;
+ }
+
+ fputs("{", _vdp_cap_data.fp);
+ uint8_t const * ptr = (uint8_t const *)planes[0].data;
+ while (lines) {
+ dumper(planes[0].item_count, ptr);
+ if (lines > 1) {
+ fputs(", ", _vdp_cap_data.fp);
+ }
+
+ ptr += planes[0].pitch;
+ --lines;
+ }
+ fputs("}", _vdp_cap_data.fp);
+
+ if (plane_count > 1) {
+ fputs(", ", _vdp_cap_data.fp);
+ }
+
+ --plane_count;
+ ++planes;
+ }
+ fputs("}", _vdp_cap_data.fp);
+}
+
+static bool _vdp_cap_init_planes_for_ycbcr_format(
+ uint32_t * plane_count,
+ _VdpcapPlane * planes,
+ VdpYCbCrFormat format,
+ uint32_t region_width,
+ uint32_t region_height
+)
+{
+ switch (format) {
+ case VDP_YCBCR_FORMAT_NV12:
+ if (*plane_count < 2) {
+ return false;
+ }
+ *plane_count = 2;
+ planes[0].item_size = 1;
+ planes[0].item_count = region_width;
+ planes[0].lines = region_height;
+ planes[1].item_size = 1;
+ planes[1].item_count = region_width;
+ planes[1].lines = region_height / 2;
+ break;
+ case VDP_YCBCR_FORMAT_YV12:
+ if (*plane_count < 3) {
+ return false;
+ }
+ *plane_count = 3;
+ planes[0].item_size = 1;
+ planes[0].item_count = region_width;
+ planes[0].lines = region_height;
+ planes[1].item_size = 1;
+ planes[1].item_count = region_width / 2;
+ planes[1].lines = region_height / 2;
+ planes[2].item_size = 1;
+ planes[2].item_count = region_width / 2;
+ planes[2].lines = region_height / 2;
+ break;
+ case VDP_YCBCR_FORMAT_UYVY:
+ case VDP_YCBCR_FORMAT_YUYV:
+ if (*plane_count < 1) {
+ return false;
+ }
+ *plane_count = 1;
+ planes[0].item_size = 1;
+ planes[0].item_count = region_width * 2;
+ planes[0].lines = region_height;
+ break;
+ case VDP_YCBCR_FORMAT_Y8U8V8A8:
+ case VDP_YCBCR_FORMAT_V8U8Y8A8:
+ if (*plane_count < 1) {
+ return false;
+ }
+ *plane_count = 1;
+ planes[0].item_size = 4;
+ planes[0].item_count = region_width;
+ planes[0].lines = region_height;
+ break;
+ default:
+ return false;
+ }
+
+ return true;
+}
+
+static bool _vdp_cap_init_planes_for_rgba_format(
+ uint32_t * plane_count,
+ _VdpcapPlane * planes,
+ VdpRGBAFormat format,
+ uint32_t region_width,
+ uint32_t region_height
+)
+{
+ switch (format) {
+ case VDP_RGBA_FORMAT_B8G8R8A8:
+ case VDP_RGBA_FORMAT_R8G8B8A8:
+ case VDP_RGBA_FORMAT_R10G10B10A2:
+ case VDP_RGBA_FORMAT_B10G10R10A2:
+ if (*plane_count < 1) {
+ return false;
+ }
+ *plane_count = 1;
+ planes[0].item_size = 4;
+ break;
+ case VDP_RGBA_FORMAT_A8:
+ if (*plane_count < 1) {
+ return false;
+ }
+ *plane_count = 1;
+ planes[0].item_size = 1;
+ break;
+ default:
+ return false;
+ }
+ planes[0].item_count = region_width;
+ planes[0].lines = region_height;
+
+ return true;
+}
+
+static bool _vdp_cap_init_planes_for_indexed_format(
+ uint32_t * plane_count,
+ _VdpcapPlane * planes,
+ VdpIndexedFormat format,
+ uint32_t region_width,
+ uint32_t region_height
+)
+{
+ uint32_t width_multiplier;
+
+ switch (format) {
+ case VDP_INDEXED_FORMAT_A4I4:
+ case VDP_INDEXED_FORMAT_I4A4:
+ width_multiplier = 1;
+ break;
+ case VDP_INDEXED_FORMAT_A8I8:
+ case VDP_INDEXED_FORMAT_I8A8:
+ width_multiplier = 2;
+ break;
+ default:
+ return false;
+ }
+
+ if (*plane_count < 1) {
+ return false;
+ }
+ *plane_count = 1;
+ planes[0].item_size = 1;
+ planes[0].item_count = region_width * width_multiplier;
+ planes[0].lines = region_height;
+
+ return true;
+}
+
+static bool _vdp_cap_init_planes_adapt_format_bits_ycbcr(
+ uint32_t * plane_count,
+ _VdpcapPlane * planes,
+ uint32_t surface_format,
+ uint32_t bits_format,
+ uint32_t region_width,
+ uint32_t region_height
+)
+{
+ return _vdp_cap_init_planes_for_ycbcr_format(
+ plane_count,
+ planes,
+ bits_format,
+ region_width,
+ region_height
+ );
+}
+
+static bool _vdp_cap_init_planes_adapt_format_surface_rgba(
+ uint32_t * plane_count,
+ _VdpcapPlane * planes,
+ uint32_t surface_format,
+ uint32_t bits_format,
+ uint32_t region_width,
+ uint32_t region_height
+)
+{
+ return _vdp_cap_init_planes_for_rgba_format(
+ plane_count,
+ planes,
+ surface_format,
+ region_width,
+ region_height
+ );
+}
+
+static bool _vdp_cap_init_planes_adapt_format_bits_indexed(
+ uint32_t * plane_count,
+ _VdpcapPlane * planes,
+ uint32_t surface_format,
+ uint32_t bits_format,
+ uint32_t region_width,
+ uint32_t region_height
+)
+{
+ return _vdp_cap_init_planes_for_indexed_format(
+ plane_count,
+ planes,
+ bits_format,
+ region_width,
+ region_height
+ );
+}
+
+bool _vdp_cap_init_planes_adapt_surface_video(
+ uint32_t surface,
+ uint32_t * surface_format,
+ uint32_t * width,
+ uint32_t * height
+)
+{
+ VdpStatus ret;
+
+ VdpChromaType chroma_type;
+ ret = _vdp_cap_data.vdp_video_surface_get_parameters(
+ surface,
+ &chroma_type,
+ width,
+ height
+ );
+ if (ret != VDP_STATUS_OK) {
+ return false;
+ }
+
+ *surface_format = chroma_type;
+
+ return true;
+}
+
+bool _vdp_cap_init_planes_adapt_surface_output(
+ uint32_t surface,
+ uint32_t * surface_format,
+ uint32_t * width,
+ uint32_t * height
+)
+{
+ VdpStatus ret;
+
+ VdpRGBAFormat rgba_format;
+ ret = _vdp_cap_data.vdp_output_surface_get_parameters(
+ surface,
+ &rgba_format,
+ width,
+ height
+ );
+ if (ret != VDP_STATUS_OK) {
+ return false;
+ }
+
+ *surface_format = rgba_format;
+
+ return true;
+}
+
+bool _vdp_cap_init_planes_adapt_surface_bitmap(
+ uint32_t surface,
+ uint32_t * surface_format,
+ uint32_t * width,
+ uint32_t * height
+)
+{
+ VdpStatus ret;
+
+ VdpRGBAFormat rgba_format;
+ VdpBool frequently_accessed;
+ ret = _vdp_cap_data.vdp_bitmap_surface_get_parameters(
+ surface,
+ &rgba_format,
+ width,
+ height,
+ &frequently_accessed
+ );
+ if (ret != VDP_STATUS_OK) {
+ return false;
+ }
+
+ *surface_format = rgba_format;
+
+ return true;
+}
+
+typedef bool _Vdpcap_Init_Planes_Adapt_Format(
+ uint32_t * plane_count,
+ _VdpcapPlane * planes,
+ uint32_t surface_format,
+ uint32_t bits_format,
+ uint32_t region_width,
+ uint32_t region_height
+);
+
+typedef bool _Vdpcap_Init_Planes_Adapt_Surface(
+ uint32_t surface,
+ uint32_t * surface_format,
+ uint32_t * width,
+ uint32_t * height
+);
+
+static bool _vdp_cap_init_planes(
+ uint32_t surface,
+ void const * const * source_data,
+ uint32_t const * source_pitches,
+ VdpRect const * destination_rect,
+ uint32_t * plane_count,
+ _VdpcapPlane * planes,
+ _Vdpcap_Init_Planes_Adapt_Surface * adapt_surface,
+ _Vdpcap_Init_Planes_Adapt_Format * adapt_format,
+ uint32_t adapt_format_bits_format
+)
+{
+ bool ok;
+
+ if (!source_data || !source_pitches) {
+ return false;
+ }
+
+ if (_vdp_cap_data.level < LEVEL_PARAMS) {
+ return false;
+ }
+
+ uint32_t surface_format;
+ uint32_t width;
+ uint32_t height;
+ ok = adapt_surface(
+ surface,
+ &surface_format,
+ &width,
+ &height
+ );
+ if (!ok) {
+ return false;
+ }
+
+ if (destination_rect) {
+ width = delta<uint32_t>(destination_rect->x0, destination_rect->x1);
+ height = delta<uint32_t>(destination_rect->y0, destination_rect->y1);
+ }
+
+ ok = adapt_format(
+ plane_count,
+ planes,
+ surface_format,
+ adapt_format_bits_format,
+ width,
+ height
+ );
+ if (!ok) {
+ return false;
+ }
+
+ for (uint32_t i = 0; i < *plane_count; ++i) {
+ planes[i].data = source_data[i];
+ planes[i].pitch = source_pitches[i];
+ }
+
+ return true;
+}
+
+static void _vdp_cap_dump_bool_list(
+ uint32_t count,
+ VdpBool const * values
+)
+{
+ if (!values) {
+ fputs("NULL", _vdp_cap_data.fp);
+ return;
+ }
+
+ fputs("{", _vdp_cap_data.fp);
+ while (count) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%d%s",
+ (int)values[0],
+ (count > 1) ? ", " : ""
+ );
+
+ --count;
+ ++values;
+ }
+ fputs("}", _vdp_cap_data.fp);
+}
+
+static void _vdp_cap_dump_void_pointer_list(
+ uint32_t count,
+ void const * const * values,
+ bool zero_count_question_marks
+)
+{
+ if (!values) {
+ fputs("NULL", _vdp_cap_data.fp);
+ return;
+ }
+
+ fputs("{", _vdp_cap_data.fp);
+ if (!count && zero_count_question_marks) {
+ fputs("???", _vdp_cap_data.fp);
+ }
+ while (count) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%p%s",
+ values[0],
+ (count > 1) ? ", " : ""
+ );
+
+ --count;
+ ++values;
+ }
+ fputs("}", _vdp_cap_data.fp);
+}
+
+static void _vdp_cap_dump_uint32_t_list(
+ uint32_t count,
+ uint32_t const * values,
+ bool zero_count_question_marks
+)
+{
+ if (!values) {
+ fputs("NULL", _vdp_cap_data.fp);
+ return;
+ }
+
+ fputs("{", _vdp_cap_data.fp);
+ if (!count && zero_count_question_marks) {
+ fputs("???", _vdp_cap_data.fp);
+ }
+ while (count) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u%s",
+ values[0],
+ (count > 1) ? ", " : ""
+ );
+
+ --count;
+ ++values;
+ }
+ fputs("}", _vdp_cap_data.fp);
+}
+
+static void _vdp_cap_dump_color_list(
+ uint32_t count,
+ VdpColor const * colors
+)
+{
+ if (!colors) {
+ fputs("NULL", _vdp_cap_data.fp);
+ return;
+ }
+
+ fputs("{", _vdp_cap_data.fp);
+ while (count) {
+ _vdp_cap_dump_color(&colors[0]);
+ fputs(
+ (count > 1) ? ", " : "",
+ _vdp_cap_data.fp
+ );
+
+ --count;
+ ++colors;
+ }
+ fputs("}", _vdp_cap_data.fp);
+}
+
+static void _vdp_cap_dump_color_table(
+ VdpIndexedFormat indexed_format,
+ VdpColorTableFormat format,
+ void const * table
+)
+{
+ if (!table) {
+ fprintf(_vdp_cap_data.fp, "NULL");
+ return;
+ }
+
+ uint32_t count;
+ switch (indexed_format) {
+ case VDP_INDEXED_FORMAT_A4I4:
+ case VDP_INDEXED_FORMAT_I4A4:
+ count = 1 << 4;
+ break;
+ case VDP_INDEXED_FORMAT_A8I8:
+ case VDP_INDEXED_FORMAT_I8A8:
+ count = 1 << 8;
+ break;
+ default:
+ fprintf(_vdp_cap_data.fp, "???");
+ return;
+ }
+
+ switch (format) {
+ case VDP_COLOR_TABLE_FORMAT_B8G8R8X8:
+ break;
+ default:
+ fprintf(_vdp_cap_data.fp, "???");
+ return;
+ }
+
+ _vdp_cap_dump_uint32_t_list(
+ count,
+ (uint32_t const *)table,
+ true
+ );
+}
+
+static void _vdp_cap_dump_bitstream_buffer_list(
+ uint32_t count,
+ VdpBitstreamBuffer const * buffers
+)
+{
+ if (!buffers) {
+ fputs("NULL", _vdp_cap_data.fp);
+ return;
+ }
+
+ fputs("{", _vdp_cap_data.fp);
+ while (count) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "{(ver %d)%s %u, ",
+ buffers[0].struct_version,
+ (buffers[0].struct_version > 0)
+ ? "(unsupported; cannot dump all fields)"
+ : "",
+ buffers[0].bitstream_bytes
+ );
+ if (_vdp_cap_data.level >= LEVEL_DATA) {
+ uint8_t * ptr = (uint8_t * )buffers[0].bitstream;
+ for (uint32_t i = 0; i < buffers[0].bitstream_bytes; ++i) {
+ fprintf(_vdp_cap_data.fp, "%02x ", ptr[i]);
+ }
+ }
+ else {
+ fputs("...", _vdp_cap_data.fp);
+ }
+ fputs(
+ (count > 1) ? "}, " : "}",
+ _vdp_cap_data.fp
+ );
+
+ --count;
+ ++buffers;
+ }
+ fputs("}", _vdp_cap_data.fp);
+}
+
+static void _vdp_cap_dump_video_mixer_feature_list(
+ uint32_t feature_count,
+ VdpVideoMixerFeature const * features
+)
+{
+ _vdp_cap_dump_uint32_t_list(
+ feature_count,
+ features,
+ false
+ );
+}
+
+static void _vdp_cap_dump_video_mixer_parameter_list(
+ uint32_t parameter_count,
+ VdpVideoMixerParameter const * parameters
+)
+{
+ _vdp_cap_dump_uint32_t_list(
+ parameter_count,
+ parameters,
+ false
+ );
+}
+
+static void _vdp_cap_dump_video_mixer_attribute_list(
+ uint32_t attribute_count,
+ VdpVideoMixerAttribute const * attributes
+)
+{
+ _vdp_cap_dump_uint32_t_list(
+ attribute_count,
+ attributes,
+ false
+ );
+}
+
+static void _vdp_cap_dump_video_mixer_parameter_value_list(
+ uint32_t parameter_count,
+ VdpVideoMixerParameter const * parameters,
+ void const * const * parameter_values
+)
+{
+ if (!parameters || !parameter_values) {
+ fputs("NULL", _vdp_cap_data.fp);
+ return;
+ }
+
+ fputs("{", _vdp_cap_data.fp);
+ while (parameter_count) {
+ _vdp_cap_dump_video_mixer_parameter_value(parameters[0], parameter_values[0]);
+ fputs((parameter_count > 1) ? ", " : "", _vdp_cap_data.fp);
+
+ --parameter_count;
+ ++parameters;
+ ++parameter_values;
+ }
+ fputs("}", _vdp_cap_data.fp);
+}
+
+static void _vdp_cap_dump_video_mixer_attribute_value_list(
+ uint32_t attribute_count,
+ VdpVideoMixerAttribute const * attributes,
+ void const * const * attribute_values,
+ bool get_operation
+)
+{
+ if (!attributes || !attribute_values) {
+ fputs("NULL", _vdp_cap_data.fp);
+ return;
+ }
+
+ fputs("{", _vdp_cap_data.fp);
+ while (attribute_count) {
+ _vdp_cap_dump_video_mixer_attribute_value(
+ attributes[0],
+ attribute_values[0],
+ get_operation
+ );
+ fputs((attribute_count > 1) ? ", " : "", _vdp_cap_data.fp);
+
+ --attribute_count;
+ ++attributes;
+ ++attribute_values;
+ }
+ fputs("}", _vdp_cap_data.fp);
+}
+
+static void _vdp_cap_dump_layers_list(
+ uint32_t layer_count,
+ VdpLayer const * layers
+)
+{
+ if (!layers) {
+ fputs("NULL", _vdp_cap_data.fp);
+ return;
+ }
+
+ fputs("{", _vdp_cap_data.fp);
+ while (layer_count) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "{(ver %d)%s %u,",
+ layers[0].struct_version,
+ (layers[0].struct_version > 0)
+ ? "(unsupported; cannot dump all fields)"
+ : "",
+ layers[0].source_surface
+ );
+
+ _vdp_cap_dump_rect(layers[0].source_rect);
+ fputs(", ", _vdp_cap_data.fp);
+ _vdp_cap_dump_rect(layers[0].destination_rect);
+
+ fputs((layer_count > 1) ? "}, " : "}", _vdp_cap_data.fp);
+
+ --layer_count;
+ ++layers;
+ }
+ fputs("}", _vdp_cap_data.fp);
+}
+
+static char const * _vdp_cap_get_error_string(
+ VdpStatus status
+)
+{
+ char const * ret;
+
+ fputs("vdp_get_error_string(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%d",
+ status
+ );
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_get_error_string(
+ status
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ if (ret) {
+ fprintf(_vdp_cap_data.fp, " -> '%s'\n", ret);
+ }
+ else {
+ fprintf(_vdp_cap_data.fp, " -> NULL\n");
+ }
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_get_api_version(
+ /* output parameters follow */
+ uint32_t * api_version
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_get_api_version(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%s",
+ api_version ? "-" : "NULL"
+ );
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_get_api_version(
+ api_version
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d", ret);
+ if (ret == VDP_STATUS_OK) {
+ fprintf(
+ _vdp_cap_data.fp,
+ ", %u",
+ *api_version
+ );
+ }
+ fputs("\n", _vdp_cap_data.fp);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_get_information_string(
+ /* output parameters follow */
+ char const * * information_string
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_get_information_string(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%s",
+ information_string ? "-" : "NULL"
+ );
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_get_information_string(
+ information_string
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d", ret);
+ if (ret == VDP_STATUS_OK) {
+ fprintf(_vdp_cap_data.fp, ", \"%s\"", *information_string);
+ }
+ fputs("\n", _vdp_cap_data.fp);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_device_destroy(
+ VdpDevice device
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_device_destroy(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u",
+ device
+ );
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_device_destroy(
+ device
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d\n", ret);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_generate_csc_matrix(
+ VdpProcamp * procamp,
+ VdpColorStandard standard,
+ /* output parameters follow */
+ VdpCSCMatrix * csc_matrix
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_generate_csc_matrix(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ _vdp_cap_dump_procamp(procamp);
+ fprintf(
+ _vdp_cap_data.fp,
+ ", %u, %s",
+ standard,
+ csc_matrix ? "-" : "NULL"
+ );
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_generate_csc_matrix(
+ procamp,
+ standard,
+ csc_matrix
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d", ret);
+ if (ret == VDP_STATUS_OK) {
+ fputs(", ", _vdp_cap_data.fp);
+ _vdp_cap_dump_csc_matrix(csc_matrix);
+ }
+ fputs("\n", _vdp_cap_data.fp);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_video_surface_query_capabilities(
+ VdpDevice device,
+ VdpChromaType surface_chroma_type,
+ /* output parameters follow */
+ VdpBool * is_supported,
+ uint32_t * max_width,
+ uint32_t * max_height
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_video_surface_query_capabilities(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u, %u, %s, %s, %s",
+ device,
+ surface_chroma_type,
+ is_supported ? "-" : "NULL",
+ max_width ? "-" : "NULL",
+ max_height ? "-" : "NULL"
+ );
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_video_surface_query_capabilities(
+ device,
+ surface_chroma_type,
+ is_supported,
+ max_width,
+ max_height
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d", ret);
+ if (ret == VDP_STATUS_OK) {
+ fprintf(
+ _vdp_cap_data.fp,
+ ", %d, %u, %u",
+ *is_supported,
+ *max_width,
+ *max_height
+ );
+ }
+ fputs("\n", _vdp_cap_data.fp);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_video_surface_query_get_put_bits_y_cb_cr_capabilities(
+ VdpDevice device,
+ VdpChromaType surface_chroma_type,
+ VdpYCbCrFormat bits_ycbcr_format,
+ /* output parameters follow */
+ VdpBool * is_supported
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_video_surface_query_get_put_bits_y_cb_cr_capabilities(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u, %u, %u, %s",
+ device,
+ surface_chroma_type,
+ bits_ycbcr_format,
+ is_supported ? "-" : "NULL"
+ );
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_video_surface_query_get_put_bits_y_cb_cr_capabilities(
+ device,
+ surface_chroma_type,
+ bits_ycbcr_format,
+ is_supported
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d", ret);
+ if (ret == VDP_STATUS_OK) {
+ fprintf(
+ _vdp_cap_data.fp,
+ ", %d",
+ *is_supported
+ );
+ }
+ fputs("\n", _vdp_cap_data.fp);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_video_surface_create(
+ VdpDevice device,
+ VdpChromaType chroma_type,
+ uint32_t width,
+ uint32_t height,
+ /* output parameters follow */
+ VdpVideoSurface * surface
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_video_surface_create(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u, %u, %u, %u, %s",
+ device,
+ chroma_type,
+ width,
+ height,
+ surface ? "-" : "NULL"
+ );
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_video_surface_create(
+ device,
+ chroma_type,
+ width,
+ height,
+ surface
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d", ret);
+ if (ret == VDP_STATUS_OK) {
+ fprintf(
+ _vdp_cap_data.fp,
+ ", %u",
+ *surface
+ );
+ }
+ fputs("\n", _vdp_cap_data.fp);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_video_surface_destroy(
+ VdpVideoSurface surface
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_video_surface_destroy(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u",
+ surface
+ );
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_video_surface_destroy(
+ surface
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d\n", ret);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_video_surface_get_parameters(
+ VdpVideoSurface surface,
+ /* output parameters follow */
+ VdpChromaType * chroma_type,
+ uint32_t * width,
+ uint32_t * height
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_video_surface_get_parameters(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u, %s, %s, %s",
+ surface,
+ chroma_type ? "-" : "NULL",
+ width ? "-" : "NULL",
+ height ? "-" : "NULL"
+ );
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_video_surface_get_parameters(
+ surface,
+ chroma_type,
+ width,
+ height
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d", ret);
+ if (ret == VDP_STATUS_OK) {
+ fprintf(
+ _vdp_cap_data.fp,
+ ", %u, %u, %u",
+ *chroma_type,
+ *width,
+ *height
+ );
+ }
+ fputs("\n", _vdp_cap_data.fp);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_video_surface_get_bits_y_cb_cr(
+ VdpVideoSurface surface,
+ VdpYCbCrFormat destination_ycbcr_format,
+ void * const * destination_data,
+ uint32_t const * destination_pitches
+)
+{
+ VdpStatus ret;
+
+ _VdpcapPlane planes[3];
+ uint32_t plane_count = _VDP_TRACE_ARSIZE(planes);
+ bool dump_data = _vdp_cap_init_planes(
+ surface,
+ destination_data,
+ destination_pitches,
+ 0,
+ &plane_count,
+ planes,
+ _vdp_cap_init_planes_adapt_surface_video,
+ _vdp_cap_init_planes_adapt_format_bits_ycbcr,
+ destination_ycbcr_format
+ );
+ if (!dump_data) {
+ plane_count = 0;
+ }
+
+ fputs("vdp_video_surface_get_bits_y_cb_cr(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u, %u, ",
+ surface,
+ destination_ycbcr_format
+ );
+ _vdp_cap_dump_void_pointer_list(plane_count, destination_data, true);
+ fputs(", ", _vdp_cap_data.fp);
+ _vdp_cap_dump_uint32_t_list(plane_count, destination_pitches, true);
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_video_surface_get_bits_y_cb_cr(
+ surface,
+ destination_ycbcr_format,
+ destination_data,
+ destination_pitches
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d\n", ret);
+ }
+ if (_vdp_cap_data.level >= LEVEL_DATA) {
+ fputs(" ... Data: ", _vdp_cap_data.fp);
+ if (dump_data) {
+ _vdp_cap_dump_plane_list(plane_count, planes);
+ }
+ else {
+ fputs("???", _vdp_cap_data.fp);
+ }
+ fputs("\n", _vdp_cap_data.fp);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_video_surface_put_bits_y_cb_cr(
+ VdpVideoSurface surface,
+ VdpYCbCrFormat source_ycbcr_format,
+ void const * const * source_data,
+ uint32_t const * source_pitches
+)
+{
+ VdpStatus ret;
+
+ _VdpcapPlane planes[3];
+ uint32_t plane_count = _VDP_TRACE_ARSIZE(planes);
+ bool dump_data = _vdp_cap_init_planes(
+ surface,
+ source_data,
+ source_pitches,
+ 0,
+ &plane_count,
+ planes,
+ _vdp_cap_init_planes_adapt_surface_video,
+ _vdp_cap_init_planes_adapt_format_bits_ycbcr,
+ source_ycbcr_format
+ );
+ if (!dump_data) {
+ plane_count = 0;
+ }
+
+ fputs("vdp_video_surface_put_bits_y_cb_cr(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u, %u, ",
+ surface,
+ source_ycbcr_format
+ );
+ _vdp_cap_dump_void_pointer_list(plane_count, source_data, true);
+ fputs(", ", _vdp_cap_data.fp);
+ _vdp_cap_dump_uint32_t_list(plane_count, source_pitches, true);
+ fputs(", ", _vdp_cap_data.fp);
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_DATA) {
+ fputs(" ... Data: ", _vdp_cap_data.fp);
+ if (dump_data) {
+ _vdp_cap_dump_plane_list(plane_count, planes);
+ }
+ else {
+ fputs("???", _vdp_cap_data.fp);
+ }
+ fputs("\n", _vdp_cap_data.fp);
+ }
+
+ ret = _vdp_cap_data.vdp_video_surface_put_bits_y_cb_cr(
+ surface,
+ source_ycbcr_format,
+ source_data,
+ source_pitches
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d\n", ret);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_output_surface_query_capabilities(
+ VdpDevice device,
+ VdpRGBAFormat surface_rgba_format,
+ /* output parameters follow */
+ VdpBool * is_supported,
+ uint32_t * max_width,
+ uint32_t * max_height
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_output_surface_query_capabilities(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u, %u, %s, %s, %s",
+ device,
+ surface_rgba_format,
+ is_supported ? "-" : "NULL",
+ max_width ? "-" : "NULL",
+ max_height ? "-" : "NULL"
+ );
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_output_surface_query_capabilities(
+ device,
+ surface_rgba_format,
+ is_supported,
+ max_width,
+ max_height
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d", ret);
+ if (ret == VDP_STATUS_OK) {
+ fprintf(
+ _vdp_cap_data.fp,
+ ", %d, %u, %u",
+ *is_supported,
+ *max_width,
+ *max_height
+ );
+ }
+ fputs("\n", _vdp_cap_data.fp);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_output_surface_query_get_put_bits_native_capabilities(
+ VdpDevice device,
+ VdpRGBAFormat surface_rgba_format,
+ /* output parameters follow */
+ VdpBool * is_supported
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_output_surface_query_get_put_bits_native_capabilities(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u, %u, %s",
+ device,
+ surface_rgba_format,
+ is_supported ? "-" : "NULL"
+ );
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_output_surface_query_get_put_bits_native_capabilities(
+ device,
+ surface_rgba_format,
+ is_supported
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d", ret);
+ if (ret == VDP_STATUS_OK) {
+ fprintf(
+ _vdp_cap_data.fp,
+ ", %d",
+ *is_supported
+ );
+ }
+ fputs("\n", _vdp_cap_data.fp);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_output_surface_query_put_bits_indexed_capabilities(
+ VdpDevice device,
+ VdpRGBAFormat surface_rgba_format,
+ VdpIndexedFormat bits_indexed_format,
+ VdpColorTableFormat color_table_format,
+ /* output parameters follow */
+ VdpBool * is_supported
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_output_surface_query_put_bits_indexed_capabilities(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u, %u, %u, %u, %s",
+ device,
+ surface_rgba_format,
+ bits_indexed_format,
+ color_table_format,
+ is_supported ? "-" : "NULL"
+ );
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_output_surface_query_put_bits_indexed_capabilities(
+ device,
+ surface_rgba_format,
+ bits_indexed_format,
+ color_table_format,
+ is_supported
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d", ret);
+ if (ret == VDP_STATUS_OK) {
+ fprintf(
+ _vdp_cap_data.fp,
+ ", %d",
+ *is_supported
+ );
+ }
+ fputs("\n", _vdp_cap_data.fp);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_output_surface_query_put_bits_y_cb_cr_capabilities(
+ VdpDevice device,
+ VdpRGBAFormat surface_rgba_format,
+ VdpYCbCrFormat bits_ycbcr_format,
+ /* output parameters follow */
+ VdpBool * is_supported
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_output_surface_query_put_bits_y_cb_cr_capabilities(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u, %u, %u, %s",
+ device,
+ surface_rgba_format,
+ bits_ycbcr_format,
+ is_supported ? "-" : "NULL"
+ );
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_output_surface_query_put_bits_y_cb_cr_capabilities(
+ device,
+ surface_rgba_format,
+ bits_ycbcr_format,
+ is_supported
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d", ret);
+ if (ret == VDP_STATUS_OK) {
+ fprintf(
+ _vdp_cap_data.fp,
+ ", %d",
+ *is_supported
+ );
+ }
+ fputs("\n", _vdp_cap_data.fp);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_output_surface_create(
+ VdpDevice device,
+ VdpRGBAFormat rgba_format,
+ uint32_t width,
+ uint32_t height,
+ /* output parameters follow */
+ VdpOutputSurface * surface
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_output_surface_create(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u, %u, %u, %u, %s",
+ device,
+ rgba_format,
+ width,
+ height,
+ surface ? "-" : "NULL"
+ );
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_output_surface_create(
+ device,
+ rgba_format,
+ width,
+ height,
+ surface
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d", ret);
+ if (ret == VDP_STATUS_OK) {
+ fprintf(
+ _vdp_cap_data.fp,
+ ", %u",
+ *surface
+ );
+ }
+ fputs("\n", _vdp_cap_data.fp);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_output_surface_destroy(
+ VdpOutputSurface surface
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_output_surface_destroy(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u",
+ surface
+ );
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_output_surface_destroy(
+ surface
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d\n", ret);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_output_surface_get_parameters(
+ VdpOutputSurface surface,
+ /* output parameters follow */
+ VdpRGBAFormat * rgba_format,
+ uint32_t * width,
+ uint32_t * height
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_output_surface_get_parameters(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u, %s, %s, %s",
+ surface,
+ rgba_format ? "-" : "NULL",
+ width ? "-" : "NULL",
+ height ? "-" : "NULL"
+ );
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_output_surface_get_parameters(
+ surface,
+ rgba_format,
+ width,
+ height
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d", ret);
+ if (ret == VDP_STATUS_OK) {
+ fprintf(
+ _vdp_cap_data.fp,
+ ", %u, %u, %u",
+ *rgba_format,
+ *width,
+ *height
+ );
+ }
+ fputs("\n", _vdp_cap_data.fp);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_output_surface_get_bits_native(
+ VdpOutputSurface surface,
+ VdpRect const * source_rect,
+ void * const * destination_data,
+ uint32_t const * destination_pitches
+)
+{
+ VdpStatus ret;
+
+ _VdpcapPlane planes[1];
+ uint32_t plane_count = _VDP_TRACE_ARSIZE(planes);
+ bool dump_data = _vdp_cap_init_planes(
+ surface,
+ destination_data,
+ destination_pitches,
+ source_rect,
+ &plane_count,
+ planes,
+ _vdp_cap_init_planes_adapt_surface_output,
+ _vdp_cap_init_planes_adapt_format_surface_rgba,
+ 0
+ );
+ if (!dump_data) {
+ plane_count = 0;
+ }
+
+ fputs("vdp_output_surface_get_bits_native(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u, ",
+ surface
+ );
+ _vdp_cap_dump_rect(source_rect);
+ fputs(", ", _vdp_cap_data.fp);
+ _vdp_cap_dump_void_pointer_list(plane_count, destination_data, true);
+ fputs(", ", _vdp_cap_data.fp);
+ _vdp_cap_dump_uint32_t_list(plane_count, destination_pitches, true);
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_output_surface_get_bits_native(
+ surface,
+ source_rect,
+ destination_data,
+ destination_pitches
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d\n", ret);
+ }
+ if (_vdp_cap_data.level >= LEVEL_DATA) {
+ fputs(" ... Data: ", _vdp_cap_data.fp);
+ if (dump_data) {
+ _vdp_cap_dump_plane_list(plane_count, planes);
+ }
+ else {
+ fputs("???", _vdp_cap_data.fp);
+ }
+ fputs("\n", _vdp_cap_data.fp);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_output_surface_put_bits_native(
+ VdpOutputSurface surface,
+ void const * const * source_data,
+ uint32_t const * source_pitches,
+ VdpRect const * destination_rect
+)
+{
+ VdpStatus ret;
+
+ _VdpcapPlane planes[1];
+ uint32_t plane_count = _VDP_TRACE_ARSIZE(planes);
+ bool dump_data = _vdp_cap_init_planes(
+ surface,
+ source_data,
+ source_pitches,
+ destination_rect,
+ &plane_count,
+ planes,
+ _vdp_cap_init_planes_adapt_surface_output,
+ _vdp_cap_init_planes_adapt_format_surface_rgba,
+ 0
+ );
+ if (!dump_data) {
+ plane_count = 0;
+ }
+
+ fputs("vdp_output_surface_put_bits_native(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u, ",
+ surface
+ );
+ _vdp_cap_dump_void_pointer_list(plane_count, source_data, true);
+ fputs(", ", _vdp_cap_data.fp);
+ _vdp_cap_dump_uint32_t_list(plane_count, source_pitches, true);
+ fputs(", ", _vdp_cap_data.fp);
+ _vdp_cap_dump_rect(destination_rect);
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_DATA) {
+ fputs(" ... Data: ", _vdp_cap_data.fp);
+ if (dump_data) {
+ _vdp_cap_dump_plane_list(plane_count, planes);
+ }
+ else {
+ fputs("???", _vdp_cap_data.fp);
+ }
+ fputs("\n", _vdp_cap_data.fp);
+ }
+
+ ret = _vdp_cap_data.vdp_output_surface_put_bits_native(
+ surface,
+ source_data,
+ source_pitches,
+ destination_rect
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d\n", ret);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_output_surface_put_bits_indexed(
+ VdpOutputSurface surface,
+ VdpIndexedFormat source_indexed_format,
+ void const * const * source_data,
+ uint32_t const * source_pitches,
+ VdpRect const * destination_rect,
+ VdpColorTableFormat color_table_format,
+ void const * color_table
+)
+{
+ VdpStatus ret;
+
+ _VdpcapPlane planes[1];
+ uint32_t plane_count = _VDP_TRACE_ARSIZE(planes);
+ bool dump_data = _vdp_cap_init_planes(
+ surface,
+ source_data,
+ source_pitches,
+ destination_rect,
+ &plane_count,
+ planes,
+ _vdp_cap_init_planes_adapt_surface_output,
+ _vdp_cap_init_planes_adapt_format_bits_indexed,
+ source_indexed_format
+ );
+ if (!dump_data) {
+ plane_count = 0;
+ }
+
+ fputs("vdp_output_surface_put_bits_indexed(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u, %u, ",
+ surface,
+ source_indexed_format
+ );
+ _vdp_cap_dump_void_pointer_list(plane_count, source_data, true);
+ fputs(", ", _vdp_cap_data.fp);
+ _vdp_cap_dump_uint32_t_list(plane_count, source_pitches, true);
+ fputs(", ", _vdp_cap_data.fp);
+ _vdp_cap_dump_rect(destination_rect);
+ fprintf(
+ _vdp_cap_data.fp,
+ ", %u, ",
+ color_table_format
+ );
+ _vdp_cap_dump_color_table(
+ source_indexed_format,
+ color_table_format,
+ color_table
+ );
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_DATA) {
+ fputs(" ... Data: ", _vdp_cap_data.fp);
+ if (dump_data) {
+ _vdp_cap_dump_plane_list(plane_count, planes);
+ }
+ else {
+ fputs("???", _vdp_cap_data.fp);
+ }
+ fputs("\n", _vdp_cap_data.fp);
+ }
+
+ ret = _vdp_cap_data.vdp_output_surface_put_bits_indexed(
+ surface,
+ source_indexed_format,
+ source_data,
+ source_pitches,
+ destination_rect,
+ color_table_format,
+ color_table
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d\n", ret);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_output_surface_put_bits_y_cb_cr(
+ VdpOutputSurface surface,
+ VdpYCbCrFormat source_ycbcr_format,
+ void const * const * source_data,
+ uint32_t const * source_pitches,
+ VdpRect const * destination_rect,
+ VdpCSCMatrix const * csc_matrix
+)
+{
+ VdpStatus ret;
+
+ _VdpcapPlane planes[1];
+ uint32_t plane_count = _VDP_TRACE_ARSIZE(planes);
+ bool dump_data = _vdp_cap_init_planes(
+ surface,
+ source_data,
+ source_pitches,
+ destination_rect,
+ &plane_count,
+ planes,
+ _vdp_cap_init_planes_adapt_surface_output,
+ _vdp_cap_init_planes_adapt_format_bits_ycbcr,
+ source_ycbcr_format
+ );
+ if (!dump_data) {
+ plane_count = 0;
+ }
+
+ fputs("vdp_output_surface_put_bits_y_cb_cr(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u, %u, ",
+ surface,
+ source_ycbcr_format
+ );
+ _vdp_cap_dump_void_pointer_list(plane_count, source_data, true);
+ fputs(", ", _vdp_cap_data.fp);
+ _vdp_cap_dump_uint32_t_list(plane_count, source_pitches, true);
+ fputs(", ", _vdp_cap_data.fp);
+ _vdp_cap_dump_rect(destination_rect);
+ fputs(", ", _vdp_cap_data.fp);
+ _vdp_cap_dump_csc_matrix(csc_matrix);
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_DATA) {
+ fputs(" ... Data: ", _vdp_cap_data.fp);
+ if (dump_data) {
+ _vdp_cap_dump_plane_list(plane_count, planes);
+ }
+ else {
+ fputs("???", _vdp_cap_data.fp);
+ }
+ fputs("\n", _vdp_cap_data.fp);
+ }
+
+ ret = _vdp_cap_data.vdp_output_surface_put_bits_y_cb_cr(
+ surface,
+ source_ycbcr_format,
+ source_data,
+ source_pitches,
+ destination_rect,
+ csc_matrix
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d\n", ret);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_bitmap_surface_query_capabilities(
+ VdpDevice device,
+ VdpRGBAFormat surface_rgba_format,
+ /* output parameters follow */
+ VdpBool * is_supported,
+ uint32_t * max_width,
+ uint32_t * max_height
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_bitmap_surface_query_capabilities(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u, %u, %s, %s, %s",
+ device,
+ surface_rgba_format,
+ is_supported ? "-" : "NULL",
+ max_width ? "-" : "NULL",
+ max_height ? "-" : "NULL"
+ );
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_bitmap_surface_query_capabilities(
+ device,
+ surface_rgba_format,
+ is_supported,
+ max_width,
+ max_height
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d", ret);
+ if (ret == VDP_STATUS_OK) {
+ fprintf(
+ _vdp_cap_data.fp,
+ ", %d, %u, %u",
+ *is_supported,
+ *max_width,
+ *max_height
+ );
+ }
+ fputs("\n", _vdp_cap_data.fp);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_bitmap_surface_create(
+ VdpDevice device,
+ VdpRGBAFormat rgba_format,
+ uint32_t width,
+ uint32_t height,
+ VdpBool frequently_accessed,
+ /* output parameters follow */
+ VdpBitmapSurface * surface
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_bitmap_surface_create(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u, %u, %u, %u, %d, %s",
+ device,
+ rgba_format,
+ width,
+ height,
+ frequently_accessed,
+ surface ? "-" : "NULL"
+ );
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_bitmap_surface_create(
+ device,
+ rgba_format,
+ width,
+ height,
+ frequently_accessed,
+ surface
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d", ret);
+ if (ret == VDP_STATUS_OK) {
+ fprintf(
+ _vdp_cap_data.fp,
+ ", %u",
+ *surface
+ );
+ }
+ fputs("\n", _vdp_cap_data.fp);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_bitmap_surface_destroy(
+ VdpBitmapSurface surface
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_bitmap_surface_destroy(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u",
+ surface
+ );
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_bitmap_surface_destroy(
+ surface
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d\n", ret);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_bitmap_surface_get_parameters(
+ VdpBitmapSurface surface,
+ /* output parameters follow */
+ VdpRGBAFormat * rgba_format,
+ uint32_t * width,
+ uint32_t * height,
+ VdpBool * frequently_accessed
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_bitmap_surface_get_parameters(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u, %s, %s, %s, %s",
+ surface,
+ rgba_format ? "-" : "NULL",
+ width ? "-" : "NULL",
+ height ? "-" : "NULL",
+ frequently_accessed ? "-" : "NULL"
+ );
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_bitmap_surface_get_parameters(
+ surface,
+ rgba_format,
+ width,
+ height,
+ frequently_accessed
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d", ret);
+ if (ret == VDP_STATUS_OK) {
+ fprintf(
+ _vdp_cap_data.fp,
+ ", %u, %u, %u, %d",
+ *rgba_format,
+ *width,
+ *height,
+ *frequently_accessed
+ );
+ }
+ fputs("\n", _vdp_cap_data.fp);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_bitmap_surface_put_bits_native(
+ VdpBitmapSurface surface,
+ void const * const * source_data,
+ uint32_t const * source_pitches,
+ VdpRect const * destination_rect
+)
+{
+ VdpStatus ret;
+
+ _VdpcapPlane planes[1];
+ uint32_t plane_count = _VDP_TRACE_ARSIZE(planes);
+ bool dump_data = _vdp_cap_init_planes(
+ surface,
+ source_data,
+ source_pitches,
+ destination_rect,
+ &plane_count,
+ planes,
+ _vdp_cap_init_planes_adapt_surface_bitmap,
+ _vdp_cap_init_planes_adapt_format_surface_rgba,
+ 0
+ );
+ if (!dump_data) {
+ plane_count = 0;
+ }
+
+ fputs("vdp_bitmap_surface_put_bits_native(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u, ",
+ surface
+ );
+ _vdp_cap_dump_void_pointer_list(plane_count, source_data, true);
+ fputs(", ", _vdp_cap_data.fp);
+ _vdp_cap_dump_uint32_t_list(plane_count, source_pitches, true);
+ fputs(", ", _vdp_cap_data.fp);
+ _vdp_cap_dump_rect(destination_rect);
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_DATA) {
+ fputs(" ... Data: ", _vdp_cap_data.fp);
+ if (dump_data) {
+ _vdp_cap_dump_plane_list(plane_count, planes);
+ }
+ else {
+ fputs("???", _vdp_cap_data.fp);
+ }
+ fputs("\n", _vdp_cap_data.fp);
+ }
+
+ ret = _vdp_cap_data.vdp_bitmap_surface_put_bits_native(
+ surface,
+ source_data,
+ source_pitches,
+ destination_rect
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d\n", ret);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_output_surface_render_output_surface(
+ VdpOutputSurface destination_surface,
+ VdpRect const * destination_rect,
+ VdpOutputSurface source_surface,
+ VdpRect const * source_rect,
+ VdpColor const * colors,
+ VdpOutputSurfaceRenderBlendState const * blend_state,
+ uint32_t flags
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_output_surface_render_output_surface(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u, ",
+ destination_surface
+ );
+ _vdp_cap_dump_rect(destination_rect);
+ fprintf(
+ _vdp_cap_data.fp,
+ ", %u, ",
+ source_surface
+ );
+ _vdp_cap_dump_rect(source_rect);
+ fputs(", ", _vdp_cap_data.fp);
+ _vdp_cap_dump_color_list((flags & VDP_OUTPUT_SURFACE_RENDER_COLOR_PER_VERTEX) ? 4 : 1, colors);
+ fputs(", ", _vdp_cap_data.fp);
+ _vdp_cap_dump_blend_state(blend_state);
+ fprintf(
+ _vdp_cap_data.fp,
+ ", %u",
+ flags
+ );
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_output_surface_render_output_surface(
+ destination_surface,
+ destination_rect,
+ source_surface,
+ source_rect,
+ colors,
+ blend_state,
+ flags
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d\n", ret);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_output_surface_render_bitmap_surface(
+ VdpOutputSurface destination_surface,
+ VdpRect const * destination_rect,
+ VdpBitmapSurface source_surface,
+ VdpRect const * source_rect,
+ VdpColor const * colors,
+ VdpOutputSurfaceRenderBlendState const * blend_state,
+ uint32_t flags
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_output_surface_render_bitmap_surface(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u, ",
+ destination_surface
+ );
+ _vdp_cap_dump_rect(destination_rect);
+ fprintf(
+ _vdp_cap_data.fp,
+ ", %u, ",
+ source_surface
+ );
+ _vdp_cap_dump_rect(source_rect);
+ fputs(", ", _vdp_cap_data.fp);
+ _vdp_cap_dump_color_list((flags & VDP_OUTPUT_SURFACE_RENDER_COLOR_PER_VERTEX) ? 4 : 1, colors);
+ fputs(", ", _vdp_cap_data.fp);
+ _vdp_cap_dump_blend_state(blend_state);
+ fprintf(
+ _vdp_cap_data.fp,
+ ", %u",
+ flags
+ );
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_output_surface_render_bitmap_surface(
+ destination_surface,
+ destination_rect,
+ source_surface,
+ source_rect,
+ colors,
+ blend_state,
+ flags
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d\n", ret);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_decoder_query_capabilities(
+ VdpDevice device,
+ VdpDecoderProfile profile,
+ /* output parameters follow */
+ VdpBool * is_supported,
+ uint32_t * max_level,
+ uint32_t * max_macroblocks,
+ uint32_t * max_width,
+ uint32_t * max_height
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_decoder_query_capabilities(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u, %u, %s, %s, %s, %s, %s",
+ device,
+ profile,
+ is_supported ? "-" : "NULL",
+ max_level ? "-" : "NULL",
+ max_macroblocks ? "-" : "NULL",
+ max_width ? "-" : "NULL",
+ max_height ? "-" : "NULL"
+ );
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_decoder_query_capabilities(
+ device,
+ profile,
+ is_supported,
+ max_level,
+ max_macroblocks,
+ max_width,
+ max_height
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d", ret);
+ if (ret == VDP_STATUS_OK) {
+ fprintf(
+ _vdp_cap_data.fp,
+ ", %d, %u, %u, %u, %u",
+ *is_supported,
+ *max_level,
+ *max_macroblocks,
+ *max_width,
+ *max_height
+ );
+ }
+ fputs("\n", _vdp_cap_data.fp);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_decoder_create(
+ VdpDevice device,
+ VdpDecoderProfile profile,
+ uint32_t width,
+ uint32_t height,
+ uint32_t max_references,
+ /* output parameters follow */
+ VdpDecoder * decoder
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_decoder_create(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u, %u, %u, %u, %u, %s",
+ device,
+ profile,
+ width,
+ height,
+ max_references,
+ decoder ? "-" : "NULL"
+ );
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_decoder_create(
+ device,
+ profile,
+ width,
+ height,
+ max_references,
+ decoder
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d", ret);
+ if (ret == VDP_STATUS_OK) {
+ fprintf(
+ _vdp_cap_data.fp,
+ ", %u",
+ *decoder
+ );
+ }
+ fputs("\n", _vdp_cap_data.fp);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_decoder_destroy(
+ VdpDecoder decoder
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_decoder_destroy(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u",
+ decoder
+ );
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_decoder_destroy(
+ decoder
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d\n", ret);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_decoder_get_parameters(
+ VdpDecoder decoder,
+ /* output parameters follow */
+ VdpDecoderProfile * profile,
+ uint32_t * width,
+ uint32_t * height
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_decoder_get_parameters(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u, %s, %s, %s",
+ decoder,
+ profile ? "-" : "NULL",
+ width ? "-" : "NULL",
+ height ? "-" : "NULL"
+ );
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_decoder_get_parameters(
+ decoder,
+ profile,
+ width,
+ height
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d", ret);
+ if (ret == VDP_STATUS_OK) {
+ fprintf(
+ _vdp_cap_data.fp,
+ ", %u, %u, %u",
+ *profile,
+ *width,
+ *height
+ );
+ }
+ fputs("\n", _vdp_cap_data.fp);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_decoder_render(
+ VdpDecoder decoder,
+ VdpVideoSurface target,
+ VdpPictureInfo const * picture_info,
+ uint32_t bitstream_buffer_count,
+ VdpBitstreamBuffer const * bitstream_buffers
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_decoder_render(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ VdpDecoderProfile profile;
+ uint32_t width;
+ uint32_t height;
+
+ ret = _vdp_cap_data.vdp_decoder_get_parameters(
+ decoder,
+ &profile,
+ &width,
+ &height
+ );
+
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u, %u, ",
+ decoder,
+ target
+ );
+ _vdp_cap_dump_picture_info(profile, picture_info);
+ fprintf(
+ _vdp_cap_data.fp,
+ ", %u, ",
+ bitstream_buffer_count
+ );
+ _vdp_cap_dump_bitstream_buffer_list(bitstream_buffer_count, bitstream_buffers);
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_decoder_render(
+ decoder,
+ target,
+ picture_info,
+ bitstream_buffer_count,
+ bitstream_buffers
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d\n", ret);
+ }
+
+ return ret;
+}
+
+
+static VdpStatus _vdp_cap_video_mixer_query_feature_support(
+ VdpDevice device,
+ VdpVideoMixerFeature feature,
+ /* output parameters follow */
+ VdpBool * is_supported
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_video_mixer_query_feature_support(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u, %u, %s",
+ device,
+ feature,
+ is_supported ? "-" : "NULL"
+ );
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_video_mixer_query_feature_support(
+ device,
+ feature,
+ is_supported
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d", ret);
+ if (ret == VDP_STATUS_OK) {
+ fprintf(_vdp_cap_data.fp, ", %d", *is_supported);
+ }
+ fputs("\n", _vdp_cap_data.fp);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_video_mixer_query_parameter_support(
+ VdpDevice device,
+ VdpVideoMixerParameter parameter,
+ /* output parameters follow */
+ VdpBool * is_supported
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_video_mixer_query_parameter_support(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u, %u, %s",
+ device,
+ parameter,
+ is_supported ? "-" : "NULL"
+ );
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_video_mixer_query_parameter_support(
+ device,
+ parameter,
+ is_supported
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d", ret);
+ if (ret == VDP_STATUS_OK) {
+ fprintf(_vdp_cap_data.fp, ", %d", *is_supported);
+ }
+ fputs("\n", _vdp_cap_data.fp);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_video_mixer_query_attribute_support(
+ VdpDevice device,
+ VdpVideoMixerAttribute attribute,
+ /* output parameters follow */
+ VdpBool * is_supported
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_video_mixer_query_attribute_support(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u, %u, %s",
+ device,
+ attribute,
+ is_supported ? "-" : "NULL"
+ );
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_video_mixer_query_attribute_support(
+ device,
+ attribute,
+ is_supported
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d", ret);
+ if (ret == VDP_STATUS_OK) {
+ fprintf(_vdp_cap_data.fp, ", %d", *is_supported);
+ }
+ fputs("\n", _vdp_cap_data.fp);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_video_mixer_query_parameter_value_range(
+ VdpDevice device,
+ VdpVideoMixerParameter parameter,
+ /* output parameters follow */
+ void * min_value,
+ void * max_value
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_video_mixer_query_parameter_value_range(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u, %u, %s, %s",
+ device,
+ parameter,
+ min_value ? "-" : "NULL",
+ max_value ? "-" : "NULL"
+ );
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_video_mixer_query_parameter_value_range(
+ device,
+ parameter,
+ min_value,
+ max_value
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d", ret);
+ if (ret == VDP_STATUS_OK) {
+ fputs(", ", _vdp_cap_data.fp);
+ _vdp_cap_dump_video_mixer_parameter_value(parameter, min_value);
+ fputs(", ", _vdp_cap_data.fp);
+ _vdp_cap_dump_video_mixer_parameter_value(parameter, max_value);
+ }
+ fputs("\n", _vdp_cap_data.fp);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_video_mixer_query_attribute_value_range(
+ VdpDevice device,
+ VdpVideoMixerAttribute attribute,
+ /* output parameters follow */
+ void * min_value,
+ void * max_value
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_video_mixer_query_attribute_value_range(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u, %u, %s, %s",
+ device,
+ attribute,
+ min_value ? "-" : "NULL",
+ max_value ? "-" : "NULL"
+ );
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_video_mixer_query_attribute_value_range(
+ device,
+ attribute,
+ min_value,
+ max_value
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d", ret);
+ if (ret == VDP_STATUS_OK) {
+ fputs(", ", _vdp_cap_data.fp);
+ _vdp_cap_dump_video_mixer_attribute_value(attribute, min_value, false);
+ fputs(", ", _vdp_cap_data.fp);
+ _vdp_cap_dump_video_mixer_attribute_value(attribute, max_value, false);
+ }
+ fputs("\n", _vdp_cap_data.fp);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_video_mixer_create(
+ VdpDevice device,
+ uint32_t feature_count,
+ VdpVideoMixerFeature const * features,
+ uint32_t parameter_count,
+ VdpVideoMixerParameter const * parameters,
+ void const * const * parameter_values,
+ /* output parameters follow */
+ VdpVideoMixer * mixer
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_video_mixer_create(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, "%u, %u, ", device, feature_count);
+ _vdp_cap_dump_video_mixer_feature_list(feature_count, features);
+ fprintf(_vdp_cap_data.fp, ", %u, ", parameter_count);
+ _vdp_cap_dump_video_mixer_parameter_list(parameter_count, parameters);
+ fputs(", ", _vdp_cap_data.fp);
+ _vdp_cap_dump_video_mixer_parameter_value_list(
+ parameter_count,
+ parameters,
+ parameter_values
+ );
+ fprintf(_vdp_cap_data.fp, ", %s", mixer ? "-" : "NULL");
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_video_mixer_create(
+ device,
+ feature_count,
+ features,
+ parameter_count,
+ parameters,
+ parameter_values,
+ mixer
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d", ret);
+ if (ret == VDP_STATUS_OK) {
+ fprintf(
+ _vdp_cap_data.fp,
+ ", %u",
+ *mixer
+ );
+ }
+ fputs("\n", _vdp_cap_data.fp);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_video_mixer_set_feature_enables(
+ VdpVideoMixer mixer,
+ uint32_t feature_count,
+ VdpVideoMixerFeature const * features,
+ VdpBool const * feature_enables
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_video_mixer_set_feature_enables(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, "%u, %u, ", mixer, feature_count);
+ _vdp_cap_dump_video_mixer_feature_list(feature_count, features);
+ fputs(", ", _vdp_cap_data.fp);
+ _vdp_cap_dump_bool_list(feature_count, feature_enables);
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_video_mixer_set_feature_enables(
+ mixer,
+ feature_count,
+ features,
+ feature_enables
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d\n", ret);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_video_mixer_set_attribute_values(
+ VdpVideoMixer mixer,
+ uint32_t attribute_count,
+ VdpVideoMixerAttribute const * attributes,
+ void const * const * attribute_values
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_video_mixer_set_attribute_values(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, "%u, %u, ", mixer, attribute_count);
+ _vdp_cap_dump_video_mixer_attribute_list(attribute_count, attributes);
+ fputs(", ", _vdp_cap_data.fp);
+ _vdp_cap_dump_video_mixer_attribute_value_list(
+ attribute_count,
+ attributes,
+ attribute_values,
+ false
+ );
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_video_mixer_set_attribute_values(
+ mixer,
+ attribute_count,
+ attributes,
+ attribute_values
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d\n", ret);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_video_mixer_get_feature_support(
+ VdpVideoMixer mixer,
+ uint32_t feature_count,
+ VdpVideoMixerFeature const * features,
+ /* output parameters follow */
+ VdpBool * feature_supports
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_video_mixer_get_feature_support(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, "%u, %u, ", mixer, feature_count);
+ _vdp_cap_dump_video_mixer_feature_list(feature_count, features);
+ fputs(feature_supports ? "-" : "NULL", _vdp_cap_data.fp);
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_video_mixer_get_feature_support(
+ mixer,
+ feature_count,
+ features,
+ feature_supports
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d", ret);
+ if (ret == VDP_STATUS_OK) {
+ fputs(", ", _vdp_cap_data.fp);
+ _vdp_cap_dump_bool_list(feature_count, feature_supports);
+ }
+ fputs("\n", _vdp_cap_data.fp);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_video_mixer_get_feature_enables(
+ VdpVideoMixer mixer,
+ uint32_t feature_count,
+ VdpVideoMixerFeature const * features,
+ /* output parameters follow */
+ VdpBool * feature_enables
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_video_mixer_get_feature_enables(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, "%u, %u, ", mixer, feature_count);
+ _vdp_cap_dump_video_mixer_feature_list(feature_count, features);
+ fprintf(_vdp_cap_data.fp, ", %s", feature_enables ? "-" : "NULL");
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_video_mixer_get_feature_enables(
+ mixer,
+ feature_count,
+ features,
+ feature_enables
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d", ret);
+ if (ret == VDP_STATUS_OK) {
+ fputs(", ", _vdp_cap_data.fp);
+ _vdp_cap_dump_bool_list(feature_count, feature_enables);
+ }
+ fputs("\n", _vdp_cap_data.fp);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_video_mixer_get_parameter_values(
+ VdpVideoMixer mixer,
+ uint32_t parameter_count,
+ VdpVideoMixerParameter const * parameters,
+ /* output parameters follow */
+ void * const * parameter_values
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_video_mixer_get_parameter_values(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, "%u, %u, ", mixer, parameter_count);
+ _vdp_cap_dump_video_mixer_parameter_list(parameter_count, parameters);
+ fprintf(_vdp_cap_data.fp, ", %s", parameter_values ? "-" : "NULL");
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_video_mixer_get_parameter_values(
+ mixer,
+ parameter_count,
+ parameters,
+ parameter_values
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d", ret);
+ if (ret == VDP_STATUS_OK) {
+ fputs(", ", _vdp_cap_data.fp);
+ _vdp_cap_dump_video_mixer_parameter_value_list(
+ parameter_count,
+ parameters,
+ parameter_values
+ );
+ }
+ fputs("\n", _vdp_cap_data.fp);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_video_mixer_get_attribute_values(
+ VdpVideoMixer mixer,
+ uint32_t attribute_count,
+ VdpVideoMixerAttribute const * attributes,
+ /* output parameters follow */
+ void * const * attribute_values
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_video_mixer_get_attribute_values(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, "%u, %u, ", mixer, attribute_count);
+ _vdp_cap_dump_video_mixer_attribute_list(attribute_count, attributes);
+ fprintf(_vdp_cap_data.fp, ", %s", attribute_values ? "-" : "NULL");
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_video_mixer_get_attribute_values(
+ mixer,
+ attribute_count,
+ attributes,
+ attribute_values
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d", ret);
+ if (ret == VDP_STATUS_OK) {
+ fputs(", ", _vdp_cap_data.fp);
+ _vdp_cap_dump_video_mixer_attribute_value_list(
+ attribute_count,
+ attributes,
+ attribute_values,
+ true
+ );
+ }
+ fputs("\n", _vdp_cap_data.fp);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_video_mixer_destroy(
+ VdpVideoMixer mixer
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_video_mixer_destroy(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u",
+ mixer
+ );
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_video_mixer_destroy(
+ mixer
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d\n", ret);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_video_mixer_render(
+ VdpVideoMixer mixer,
+ VdpOutputSurface background_surface,
+ VdpRect const * background_source_rect,
+ VdpVideoMixerPictureStructure current_picture_structure,
+ uint32_t video_surface_past_count,
+ VdpVideoSurface const * video_surface_past,
+ VdpVideoSurface video_surface_current,
+ uint32_t video_surface_future_count,
+ VdpVideoSurface const * video_surface_future,
+ VdpRect const * video_source_rect,
+ VdpOutputSurface destination_surface,
+ VdpRect const * destination_rect,
+ VdpRect const * destination_video_rect,
+ uint32_t layer_count,
+ VdpLayer const * layers
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_video_mixer_render(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u, %u, ",
+ mixer,
+ background_surface
+ );
+ _vdp_cap_dump_rect(background_source_rect);
+ fprintf(
+ _vdp_cap_data.fp,
+ ", %d, %u, ",
+ current_picture_structure,
+ video_surface_past_count
+ );
+ _vdp_cap_dump_uint32_t_list(video_surface_past_count, video_surface_past, false);
+ fprintf(
+ _vdp_cap_data.fp,
+ ", %u, %u, ",
+ video_surface_current,
+ video_surface_future_count
+ );
+ _vdp_cap_dump_uint32_t_list(video_surface_future_count, video_surface_future, false);
+ fputs(", ", _vdp_cap_data.fp);
+ _vdp_cap_dump_rect(video_source_rect);
+ fprintf(
+ _vdp_cap_data.fp,
+ ", %u, ",
+ destination_surface
+ );
+ _vdp_cap_dump_rect(destination_rect);
+ fputs(", ", _vdp_cap_data.fp);
+ _vdp_cap_dump_rect(destination_video_rect);
+ fprintf(
+ _vdp_cap_data.fp,
+ ", %u, ",
+ layer_count
+ );
+ _vdp_cap_dump_layers_list(layer_count, layers);
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_video_mixer_render(
+ mixer,
+ background_surface,
+ background_source_rect,
+ current_picture_structure,
+ video_surface_past_count,
+ video_surface_past,
+ video_surface_current,
+ video_surface_future_count,
+ video_surface_future,
+ video_source_rect,
+ destination_surface,
+ destination_rect,
+ destination_video_rect,
+ layer_count,
+ layers
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d\n", ret);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_presentation_queue_target_destroy(
+ VdpPresentationQueueTarget presentation_queue_target
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_presentation_queue_target_destroy(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u",
+ presentation_queue_target
+ );
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_presentation_queue_target_destroy(
+ presentation_queue_target
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d\n", ret);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_presentation_queue_create(
+ VdpDevice device,
+ VdpPresentationQueueTarget presentation_queue_target,
+ /* output parameters follow */
+ VdpPresentationQueue * presentation_queue
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_presentation_queue_create(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u, %u, %s",
+ device,
+ presentation_queue_target,
+ presentation_queue ? "-" : "NULL"
+ );
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_presentation_queue_create(
+ device,
+ presentation_queue_target,
+ presentation_queue
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d", ret);
+ if (ret == VDP_STATUS_OK) {
+ fprintf(
+ _vdp_cap_data.fp,
+ ", %u",
+ *presentation_queue
+ );
+ }
+ fputs("\n", _vdp_cap_data.fp);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_presentation_queue_destroy(
+ VdpPresentationQueue presentation_queue
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_presentation_queue_destroy(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u",
+ presentation_queue
+ );
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_presentation_queue_destroy(
+ presentation_queue
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d\n", ret);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_presentation_queue_set_background_color(
+ VdpPresentationQueue presentation_queue,
+ VdpColor * const background_color
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_presentation_queue_set_background_color(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u, ",
+ presentation_queue
+ );
+ _vdp_cap_dump_color(background_color);
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_presentation_queue_set_background_color(
+ presentation_queue,
+ background_color
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d\n", ret);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_presentation_queue_get_background_color(
+ VdpPresentationQueue presentation_queue,
+ VdpColor * background_color
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_presentation_queue_get_background_color(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u, %s",
+ presentation_queue,
+ background_color ? "-" : "NULL"
+ );
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_presentation_queue_get_background_color(
+ presentation_queue,
+ background_color
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d", ret);
+ if (ret == VDP_STATUS_OK) {
+ fputs(", ", _vdp_cap_data.fp);
+ _vdp_cap_dump_color(background_color);
+ }
+ fputs("\n", _vdp_cap_data.fp);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_presentation_queue_get_time(
+ VdpPresentationQueue presentation_queue,
+ /* output parameters follow */
+ VdpTime * current_time
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_presentation_queue_get_time(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u, %s",
+ presentation_queue,
+ current_time ? "-" : "NULL"
+ );
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_presentation_queue_get_time(
+ presentation_queue,
+ current_time
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d", ret);
+ if (ret == VDP_STATUS_OK) {
+ fprintf(
+ _vdp_cap_data.fp,
+ ", %" PRIu64,
+ *current_time
+ );
+ }
+ fputs("\n", _vdp_cap_data.fp);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_presentation_queue_display(
+ VdpPresentationQueue presentation_queue,
+ VdpOutputSurface surface,
+ uint32_t clip_width,
+ uint32_t clip_height,
+ VdpTime earliest_presentation_time
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_presentation_queue_display(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u, %u, %u, %u, %" PRIu64,
+ presentation_queue,
+ surface,
+ clip_width,
+ clip_height,
+ earliest_presentation_time
+ );
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_presentation_queue_display(
+ presentation_queue,
+ surface,
+ clip_width,
+ clip_height,
+ earliest_presentation_time
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d\n", ret);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_presentation_queue_block_until_surface_idle(
+ VdpPresentationQueue presentation_queue,
+ VdpOutputSurface surface,
+ /* output parameters follow */
+ VdpTime * first_presentation_time
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_presentation_queue_block_until_surface_idle(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u, %u, %s",
+ presentation_queue,
+ surface,
+ first_presentation_time ? "-" : "NULL"
+ );
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_presentation_queue_block_until_surface_idle(
+ presentation_queue,
+ surface,
+ first_presentation_time
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d", ret);
+ if (ret == VDP_STATUS_OK) {
+ fprintf(
+ _vdp_cap_data.fp,
+ ", %" PRIu64,
+ *first_presentation_time
+ );
+ }
+ fputs("\n", _vdp_cap_data.fp);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_presentation_queue_query_surface_status(
+ VdpPresentationQueue presentation_queue,
+ VdpOutputSurface surface,
+ /* output parameters follow */
+ VdpPresentationQueueStatus * status,
+ VdpTime * first_presentation_time
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_presentation_queue_query_surface_status(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u, %u, %s, %s",
+ presentation_queue,
+ surface,
+ status ? "-" : "NULL",
+ first_presentation_time ? "-" : "NULL"
+ );
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_presentation_queue_query_surface_status(
+ presentation_queue,
+ surface,
+ status,
+ first_presentation_time
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d", ret);
+ if (ret == VDP_STATUS_OK) {
+ fprintf(
+ _vdp_cap_data.fp,
+ ", %d, %" PRIu64,
+ *status,
+ *first_presentation_time
+ );
+ }
+ fputs("\n", _vdp_cap_data.fp);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_preemption_callback_register(
+ VdpDevice device,
+ VdpPreemptionCallback callback,
+ void * context
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_preemption_callback_register(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u, %p, %p",
+ device,
+ callback,
+ context
+ );
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_preemption_callback_register(
+ device,
+ callback,
+ context
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d\n", ret);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_presentation_queue_target_create_x11(
+ VdpDevice device,
+ Drawable drawable,
+ /* output parameters follow */
+ VdpPresentationQueueTarget * target
+)
+{
+ VdpStatus ret;
+
+ fprintf(_vdp_cap_data.fp, "vdp_presentation_queue_target_create_x11(");
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u, %lu, %s",
+ device,
+ drawable,
+ target ? "-" : "NULL"
+ );
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ ret = _vdp_cap_data.vdp_presentation_queue_target_create_x11(
+ device,
+ drawable,
+ target
+ );
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d", ret);
+ if (ret == VDP_STATUS_OK) {
+ fprintf(
+ _vdp_cap_data.fp,
+ ", %u",
+ *target
+ );
+ }
+ fputs("\n", _vdp_cap_data.fp);
+ }
+
+ return ret;
+}
+
+static VdpStatus _vdp_cap_get_proc_address(
+ VdpDevice device,
+ VdpFuncId function_id,
+ /* output parameters follow */
+ void * * function_pointer
+)
+{
+ VdpStatus ret;
+
+ fputs("vdp_get_proc_address(", _vdp_cap_data.fp);
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%u, %u, %s",
+ device,
+ function_id,
+ function_pointer ? "-" : "NULL"
+ );
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ if (device != _vdp_cap_data.vdp_device) {
+ _VDP_TRACE_ERROR_BREAKPOINT();
+ ret = VDP_STATUS_ERROR;
+ }
+ else if (!function_pointer) {
+ _VDP_TRACE_ERROR_BREAKPOINT();
+ ret = VDP_STATUS_ERROR;
+ }
+ else {
+ ret = VDP_STATUS_OK;
+
+ switch (function_id) {
+ case VDP_FUNC_ID_GET_ERROR_STRING:
+ *function_pointer = (void *)&_vdp_cap_get_error_string;
+ break;
+ case VDP_FUNC_ID_GET_PROC_ADDRESS:
+ *function_pointer = (void *)&_vdp_cap_get_proc_address;
+ break;
+ case VDP_FUNC_ID_GET_API_VERSION:
+ *function_pointer = (void *)&_vdp_cap_get_api_version;
+ break;
+ case VDP_FUNC_ID_GET_INFORMATION_STRING:
+ *function_pointer = (void *)&_vdp_cap_get_information_string;
+ break;
+ case VDP_FUNC_ID_DEVICE_DESTROY:
+ *function_pointer = (void *)&_vdp_cap_device_destroy;
+ break;
+ case VDP_FUNC_ID_GENERATE_CSC_MATRIX:
+ *function_pointer = (void *)&_vdp_cap_generate_csc_matrix;
+ break;
+ case VDP_FUNC_ID_VIDEO_SURFACE_QUERY_CAPABILITIES:
+ *function_pointer = (void *)&_vdp_cap_video_surface_query_capabilities;
+ break;
+ case VDP_FUNC_ID_VIDEO_SURFACE_QUERY_GET_PUT_BITS_Y_CB_CR_CAPABILITIES:
+ *function_pointer = (void *)&_vdp_cap_video_surface_query_get_put_bits_y_cb_cr_capabilities;
+ break;
+ case VDP_FUNC_ID_VIDEO_SURFACE_CREATE:
+ *function_pointer = (void *)&_vdp_cap_video_surface_create;
+ break;
+ case VDP_FUNC_ID_VIDEO_SURFACE_DESTROY:
+ *function_pointer = (void *)&_vdp_cap_video_surface_destroy;
+ break;
+ case VDP_FUNC_ID_VIDEO_SURFACE_GET_PARAMETERS:
+ *function_pointer = (void *)&_vdp_cap_video_surface_get_parameters;
+ break;
+ case VDP_FUNC_ID_VIDEO_SURFACE_GET_BITS_Y_CB_CR:
+ *function_pointer = (void *)&_vdp_cap_video_surface_get_bits_y_cb_cr;
+ break;
+ case VDP_FUNC_ID_VIDEO_SURFACE_PUT_BITS_Y_CB_CR:
+ *function_pointer = (void *)&_vdp_cap_video_surface_put_bits_y_cb_cr;
+ break;
+ case VDP_FUNC_ID_OUTPUT_SURFACE_QUERY_CAPABILITIES:
+ *function_pointer = (void *)&_vdp_cap_output_surface_query_capabilities;
+ break;
+ case VDP_FUNC_ID_OUTPUT_SURFACE_QUERY_GET_PUT_BITS_NATIVE_CAPABILITIES:
+ *function_pointer = (void *)&_vdp_cap_output_surface_query_get_put_bits_native_capabilities;
+ break;
+ case VDP_FUNC_ID_OUTPUT_SURFACE_QUERY_PUT_BITS_INDEXED_CAPABILITIES:
+ *function_pointer = (void *)&_vdp_cap_output_surface_query_put_bits_indexed_capabilities;
+ break;
+ case VDP_FUNC_ID_OUTPUT_SURFACE_QUERY_PUT_BITS_Y_CB_CR_CAPABILITIES:
+ *function_pointer = (void *)&_vdp_cap_output_surface_query_put_bits_y_cb_cr_capabilities;
+ break;
+ case VDP_FUNC_ID_OUTPUT_SURFACE_CREATE:
+ *function_pointer = (void *)&_vdp_cap_output_surface_create;
+ break;
+ case VDP_FUNC_ID_OUTPUT_SURFACE_DESTROY:
+ *function_pointer = (void *)&_vdp_cap_output_surface_destroy;
+ break;
+ case VDP_FUNC_ID_OUTPUT_SURFACE_GET_PARAMETERS:
+ *function_pointer = (void *)&_vdp_cap_output_surface_get_parameters;
+ break;
+ case VDP_FUNC_ID_OUTPUT_SURFACE_GET_BITS_NATIVE:
+ *function_pointer = (void *)&_vdp_cap_output_surface_get_bits_native;
+ break;
+ case VDP_FUNC_ID_OUTPUT_SURFACE_PUT_BITS_NATIVE:
+ *function_pointer = (void *)&_vdp_cap_output_surface_put_bits_native;
+ break;
+ case VDP_FUNC_ID_OUTPUT_SURFACE_PUT_BITS_INDEXED:
+ *function_pointer = (void *)&_vdp_cap_output_surface_put_bits_indexed;
+ break;
+ case VDP_FUNC_ID_OUTPUT_SURFACE_PUT_BITS_Y_CB_CR:
+ *function_pointer = (void *)&_vdp_cap_output_surface_put_bits_y_cb_cr;
+ break;
+ case VDP_FUNC_ID_BITMAP_SURFACE_QUERY_CAPABILITIES:
+ *function_pointer = (void *)&_vdp_cap_bitmap_surface_query_capabilities;
+ break;
+ case VDP_FUNC_ID_BITMAP_SURFACE_CREATE:
+ *function_pointer = (void *)&_vdp_cap_bitmap_surface_create;
+ break;
+ case VDP_FUNC_ID_BITMAP_SURFACE_DESTROY:
+ *function_pointer = (void *)&_vdp_cap_bitmap_surface_destroy;
+ break;
+ case VDP_FUNC_ID_BITMAP_SURFACE_GET_PARAMETERS:
+ *function_pointer = (void *)&_vdp_cap_bitmap_surface_get_parameters;
+ break;
+ case VDP_FUNC_ID_BITMAP_SURFACE_PUT_BITS_NATIVE:
+ *function_pointer = (void *)&_vdp_cap_bitmap_surface_put_bits_native;
+ break;
+ case VDP_FUNC_ID_OUTPUT_SURFACE_RENDER_OUTPUT_SURFACE:
+ *function_pointer = (void *)&_vdp_cap_output_surface_render_output_surface;
+ break;
+ case VDP_FUNC_ID_OUTPUT_SURFACE_RENDER_BITMAP_SURFACE:
+ *function_pointer = (void *)&_vdp_cap_output_surface_render_bitmap_surface;
+ break;
+ case VDP_FUNC_ID_DECODER_QUERY_CAPABILITIES:
+ *function_pointer = (void *)&_vdp_cap_decoder_query_capabilities;
+ break;
+ case VDP_FUNC_ID_DECODER_CREATE:
+ *function_pointer = (void *)&_vdp_cap_decoder_create;
+ break;
+ case VDP_FUNC_ID_DECODER_DESTROY:
+ *function_pointer = (void *)&_vdp_cap_decoder_destroy;
+ break;
+ case VDP_FUNC_ID_DECODER_GET_PARAMETERS:
+ *function_pointer = (void *)&_vdp_cap_decoder_get_parameters;
+ break;
+ case VDP_FUNC_ID_DECODER_RENDER:
+ *function_pointer = (void *)&_vdp_cap_decoder_render;
+ break;
+ case VDP_FUNC_ID_VIDEO_MIXER_QUERY_FEATURE_SUPPORT:
+ *function_pointer = (void *)&_vdp_cap_video_mixer_query_feature_support;
+ break;
+ case VDP_FUNC_ID_VIDEO_MIXER_QUERY_PARAMETER_SUPPORT:
+ *function_pointer = (void *)&_vdp_cap_video_mixer_query_parameter_support;
+ break;
+ case VDP_FUNC_ID_VIDEO_MIXER_QUERY_ATTRIBUTE_SUPPORT:
+ *function_pointer = (void *)&_vdp_cap_video_mixer_query_attribute_support;
+ break;
+ case VDP_FUNC_ID_VIDEO_MIXER_QUERY_PARAMETER_VALUE_RANGE:
+ *function_pointer = (void *)&_vdp_cap_video_mixer_query_parameter_value_range;
+ break;
+ case VDP_FUNC_ID_VIDEO_MIXER_QUERY_ATTRIBUTE_VALUE_RANGE:
+ *function_pointer = (void *)&_vdp_cap_video_mixer_query_attribute_value_range;
+ break;
+ case VDP_FUNC_ID_VIDEO_MIXER_CREATE:
+ *function_pointer = (void *)&_vdp_cap_video_mixer_create;
+ break;
+ case VDP_FUNC_ID_VIDEO_MIXER_SET_FEATURE_ENABLES:
+ *function_pointer = (void *)&_vdp_cap_video_mixer_set_feature_enables;
+ break;
+ case VDP_FUNC_ID_VIDEO_MIXER_SET_ATTRIBUTE_VALUES:
+ *function_pointer = (void *)&_vdp_cap_video_mixer_set_attribute_values;
+ break;
+ case VDP_FUNC_ID_VIDEO_MIXER_GET_FEATURE_SUPPORT:
+ *function_pointer = (void *)&_vdp_cap_video_mixer_get_feature_support;
+ break;
+ case VDP_FUNC_ID_VIDEO_MIXER_GET_FEATURE_ENABLES:
+ *function_pointer = (void *)&_vdp_cap_video_mixer_get_feature_enables;
+ break;
+ case VDP_FUNC_ID_VIDEO_MIXER_GET_PARAMETER_VALUES:
+ *function_pointer = (void *)&_vdp_cap_video_mixer_get_parameter_values;
+ break;
+ case VDP_FUNC_ID_VIDEO_MIXER_GET_ATTRIBUTE_VALUES:
+ *function_pointer = (void *)&_vdp_cap_video_mixer_get_attribute_values;
+ break;
+ case VDP_FUNC_ID_VIDEO_MIXER_DESTROY:
+ *function_pointer = (void *)&_vdp_cap_video_mixer_destroy;
+ break;
+ case VDP_FUNC_ID_VIDEO_MIXER_RENDER:
+ *function_pointer = (void *)&_vdp_cap_video_mixer_render;
+ break;
+ case VDP_FUNC_ID_PRESENTATION_QUEUE_TARGET_DESTROY:
+ *function_pointer = (void *)&_vdp_cap_presentation_queue_target_destroy;
+ break;
+ case VDP_FUNC_ID_PRESENTATION_QUEUE_CREATE:
+ *function_pointer = (void *)&_vdp_cap_presentation_queue_create;
+ break;
+ case VDP_FUNC_ID_PRESENTATION_QUEUE_DESTROY:
+ *function_pointer = (void *)&_vdp_cap_presentation_queue_destroy;
+ break;
+ case VDP_FUNC_ID_PRESENTATION_QUEUE_SET_BACKGROUND_COLOR:
+ *function_pointer = (void *)&_vdp_cap_presentation_queue_set_background_color;
+ break;
+ case VDP_FUNC_ID_PRESENTATION_QUEUE_GET_BACKGROUND_COLOR:
+ *function_pointer = (void *)&_vdp_cap_presentation_queue_get_background_color;
+ break;
+ case VDP_FUNC_ID_PRESENTATION_QUEUE_GET_TIME:
+ *function_pointer = (void *)&_vdp_cap_presentation_queue_get_time;
+ break;
+ case VDP_FUNC_ID_PRESENTATION_QUEUE_DISPLAY:
+ *function_pointer = (void *)&_vdp_cap_presentation_queue_display;
+ break;
+ case VDP_FUNC_ID_PRESENTATION_QUEUE_BLOCK_UNTIL_SURFACE_IDLE:
+ *function_pointer = (void *)&_vdp_cap_presentation_queue_block_until_surface_idle;
+ break;
+ case VDP_FUNC_ID_PRESENTATION_QUEUE_QUERY_SURFACE_STATUS:
+ *function_pointer = (void *)&_vdp_cap_presentation_queue_query_surface_status;
+ break;
+ case VDP_FUNC_ID_PREEMPTION_CALLBACK_REGISTER:
+ *function_pointer = (void *)&_vdp_cap_preemption_callback_register;
+ break;
+ case VDP_FUNC_ID_PRESENTATION_QUEUE_TARGET_CREATE_X11:
+ *function_pointer = (void *)&_vdp_cap_presentation_queue_target_create_x11;
+ break;
+ default:
+ fprintf(
+ _vdp_cap_data.fp,
+ "VDPAU capture: Not able to proxy function %d",
+ function_id
+ );
+ ret = _vdp_cap_data.vdp_get_proc_address(device, function_id, function_pointer);
+ break;
+ }
+
+ if ((ret == VDP_STATUS_OK) && !*function_pointer) {
+ ret = VDP_STATUS_INVALID_FUNC_ID;
+ }
+ }
+
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d", ret);
+ if (ret == VDP_STATUS_OK) {
+ fprintf(
+ _vdp_cap_data.fp,
+ ", %p",
+ *function_pointer
+ );
+ }
+ fputs("\n", _vdp_cap_data.fp);
+ }
+
+ return ret;
+}
+
+extern "C" void vdp_trace_set_backend_handle(
+ void * driver_dll_handle
+)
+{
+ _vdp_cap_data.dll = driver_dll_handle;
+}
+
+extern "C" VdpDeviceCreateX11 vdp_trace_device_create_x11;
+
+VdpStatus vdp_trace_device_create_x11(
+ Display * display,
+ int screen,
+ /* output parameters follow */
+ VdpDevice * device,
+ VdpGetProcAddress * * get_proc_address
+)
+{
+ if (!device || !get_proc_address) {
+ _VDP_TRACE_ERROR_BREAKPOINT();
+ return VDP_STATUS_INVALID_POINTER;
+ }
+
+ // For now, the capture library only allows a single VdpDevice
+ // This could probably be fixed by dynamically associating most of
+ // _vdp_cap_data with a VdpDevice handle.
+ if (_vdp_cap_data.fp) {
+ fprintf(_vdp_cap_data.fp,
+ "VDPAU trace: Multiple devices created; "
+ "will return get_proc_address results from the latest only\n"
+ );
+ }
+ else {
+ _vdp_cap_data.level = 0;
+ char const * vdpau_trace = getenv("VDPAU_TRACE");
+ if (vdpau_trace) {
+ _vdp_cap_data.level = atoi(vdpau_trace);
+ }
+
+ _vdp_cap_data.fp = 0;
+ char const * vdpau_trace_file = getenv("VDPAU_TRACE_FILE");
+ if (vdpau_trace_file && strlen(vdpau_trace_file)) {
+ if (vdpau_trace_file[0] == '&') {
+ int fd = atoi(&vdpau_trace_file[1]);
+ _vdp_cap_data.fp = fdopen(fd, "wt");
+ }
+ else {
+ _vdp_cap_data.fp = fopen(vdpau_trace_file, "wt");
+ }
+ if (!_vdp_cap_data.fp) {
+ fprintf(
+ stderr,
+ "VDPAU capture: ERROR: Can't open '%s' for writing, defaulting to stderr\n",
+ vdpau_trace_file
+ );
+ }
+ }
+ if (!_vdp_cap_data.fp) {
+ _vdp_cap_data.fp = stderr;
+ }
+ fprintf(_vdp_cap_data.fp, "VDPAU capture: Enabled\n");
+ }
+
+ fprintf(_vdp_cap_data.fp, "vdp_imp_device_create_x11(");
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(
+ _vdp_cap_data.fp,
+ "%p, %d, %s, %s",
+ display,
+ screen,
+ device ? "-" : "NULL",
+ get_proc_address ? "-" : "NULL"
+ );
+ }
+ fputs(")\n", _vdp_cap_data.fp);
+
+ VdpStatus vdp_st = VDP_STATUS_ERROR;
+
+ VdpDeviceCreateX11 * vdp_imp_device_create_x11;
+ vdp_imp_device_create_x11 = (VdpDeviceCreateX11*)dlsym(
+ _vdp_cap_data.dll,
+ "vdp_imp_device_create_x11"
+ );
+ if (!vdp_imp_device_create_x11) {
+ _VDP_TRACE_ERROR_BREAKPOINT();
+ vdp_st = VDP_STATUS_NO_IMPLEMENTATION;
+ goto done;
+ }
+
+ vdp_st = vdp_imp_device_create_x11(
+ display,
+ screen,
+ &_vdp_cap_data.vdp_device,
+ &_vdp_cap_data.vdp_get_proc_address
+ );
+ if (vdp_st != VDP_STATUS_OK) {
+ _VDP_TRACE_ERROR_BREAKPOINT();
+ goto done;
+ }
+
+ *device = _vdp_cap_data.vdp_device;
+ *get_proc_address = _vdp_cap_get_proc_address;
+
+#define GET_POINTER(_id_, _var_) \
+ vdp_st = _vdp_cap_data.vdp_get_proc_address( \
+ _vdp_cap_data.vdp_device, \
+ (_id_), \
+ (void * *)&_vdp_cap_data._var_ \
+ ); \
+ if (vdp_st != VDP_STATUS_OK) { \
+ _vdp_cap_data._var_ = 0; \
+ }
+
+ GET_POINTER(VDP_FUNC_ID_PREEMPTION_CALLBACK_REGISTER, vdp_preemption_callback_register);
+ GET_POINTER(VDP_FUNC_ID_GET_ERROR_STRING, vdp_get_error_string);
+ GET_POINTER(VDP_FUNC_ID_GET_API_VERSION, vdp_get_api_version);
+ GET_POINTER(VDP_FUNC_ID_GET_INFORMATION_STRING, vdp_get_information_string);
+ GET_POINTER(VDP_FUNC_ID_DEVICE_DESTROY, vdp_device_destroy);
+ GET_POINTER(VDP_FUNC_ID_GENERATE_CSC_MATRIX, vdp_generate_csc_matrix);
+ GET_POINTER(VDP_FUNC_ID_VIDEO_SURFACE_QUERY_CAPABILITIES, vdp_video_surface_query_capabilities);
+ GET_POINTER(VDP_FUNC_ID_VIDEO_SURFACE_QUERY_GET_PUT_BITS_Y_CB_CR_CAPABILITIES, vdp_video_surface_query_get_put_bits_y_cb_cr_capabilities);
+ GET_POINTER(VDP_FUNC_ID_VIDEO_SURFACE_CREATE, vdp_video_surface_create);
+ GET_POINTER(VDP_FUNC_ID_VIDEO_SURFACE_DESTROY, vdp_video_surface_destroy);
+ GET_POINTER(VDP_FUNC_ID_VIDEO_SURFACE_GET_PARAMETERS, vdp_video_surface_get_parameters);
+ GET_POINTER(VDP_FUNC_ID_VIDEO_SURFACE_GET_BITS_Y_CB_CR, vdp_video_surface_get_bits_y_cb_cr);
+ GET_POINTER(VDP_FUNC_ID_VIDEO_SURFACE_PUT_BITS_Y_CB_CR, vdp_video_surface_put_bits_y_cb_cr);
+ GET_POINTER(VDP_FUNC_ID_OUTPUT_SURFACE_QUERY_CAPABILITIES, vdp_output_surface_query_capabilities);
+ GET_POINTER(VDP_FUNC_ID_OUTPUT_SURFACE_QUERY_GET_PUT_BITS_NATIVE_CAPABILITIES, vdp_output_surface_query_get_put_bits_native_capabilities);
+ GET_POINTER(VDP_FUNC_ID_OUTPUT_SURFACE_QUERY_PUT_BITS_INDEXED_CAPABILITIES, vdp_output_surface_query_put_bits_indexed_capabilities);
+ GET_POINTER(VDP_FUNC_ID_OUTPUT_SURFACE_QUERY_PUT_BITS_Y_CB_CR_CAPABILITIES, vdp_output_surface_query_put_bits_y_cb_cr_capabilities);
+ GET_POINTER(VDP_FUNC_ID_OUTPUT_SURFACE_CREATE, vdp_output_surface_create);
+ GET_POINTER(VDP_FUNC_ID_OUTPUT_SURFACE_DESTROY, vdp_output_surface_destroy);
+ GET_POINTER(VDP_FUNC_ID_OUTPUT_SURFACE_GET_PARAMETERS, vdp_output_surface_get_parameters);
+ GET_POINTER(VDP_FUNC_ID_OUTPUT_SURFACE_GET_BITS_NATIVE, vdp_output_surface_get_bits_native);
+ GET_POINTER(VDP_FUNC_ID_OUTPUT_SURFACE_PUT_BITS_NATIVE, vdp_output_surface_put_bits_native);
+ GET_POINTER(VDP_FUNC_ID_OUTPUT_SURFACE_PUT_BITS_INDEXED, vdp_output_surface_put_bits_indexed);
+ GET_POINTER(VDP_FUNC_ID_OUTPUT_SURFACE_PUT_BITS_Y_CB_CR, vdp_output_surface_put_bits_y_cb_cr);
+ GET_POINTER(VDP_FUNC_ID_BITMAP_SURFACE_QUERY_CAPABILITIES, vdp_bitmap_surface_query_capabilities);
+ GET_POINTER(VDP_FUNC_ID_BITMAP_SURFACE_CREATE, vdp_bitmap_surface_create);
+ GET_POINTER(VDP_FUNC_ID_BITMAP_SURFACE_DESTROY, vdp_bitmap_surface_destroy);
+ GET_POINTER(VDP_FUNC_ID_BITMAP_SURFACE_GET_PARAMETERS, vdp_bitmap_surface_get_parameters);
+ GET_POINTER(VDP_FUNC_ID_BITMAP_SURFACE_PUT_BITS_NATIVE, vdp_bitmap_surface_put_bits_native);
+ GET_POINTER(VDP_FUNC_ID_OUTPUT_SURFACE_RENDER_OUTPUT_SURFACE, vdp_output_surface_render_output_surface);
+ GET_POINTER(VDP_FUNC_ID_OUTPUT_SURFACE_RENDER_BITMAP_SURFACE, vdp_output_surface_render_bitmap_surface);
+ GET_POINTER(VDP_FUNC_ID_DECODER_QUERY_CAPABILITIES, vdp_decoder_query_capabilities);
+ GET_POINTER(VDP_FUNC_ID_DECODER_CREATE, vdp_decoder_create);
+ GET_POINTER(VDP_FUNC_ID_DECODER_DESTROY, vdp_decoder_destroy);
+ GET_POINTER(VDP_FUNC_ID_DECODER_GET_PARAMETERS, vdp_decoder_get_parameters);
+ GET_POINTER(VDP_FUNC_ID_DECODER_RENDER, vdp_decoder_render);
+ GET_POINTER(VDP_FUNC_ID_VIDEO_MIXER_QUERY_FEATURE_SUPPORT, vdp_video_mixer_query_feature_support);
+ GET_POINTER(VDP_FUNC_ID_VIDEO_MIXER_QUERY_PARAMETER_SUPPORT, vdp_video_mixer_query_parameter_support);
+ GET_POINTER(VDP_FUNC_ID_VIDEO_MIXER_QUERY_ATTRIBUTE_SUPPORT, vdp_video_mixer_query_attribute_support);
+ GET_POINTER(VDP_FUNC_ID_VIDEO_MIXER_QUERY_PARAMETER_VALUE_RANGE, vdp_video_mixer_query_parameter_value_range);
+ GET_POINTER(VDP_FUNC_ID_VIDEO_MIXER_QUERY_ATTRIBUTE_VALUE_RANGE, vdp_video_mixer_query_attribute_value_range);
+ GET_POINTER(VDP_FUNC_ID_VIDEO_MIXER_CREATE, vdp_video_mixer_create);
+ GET_POINTER(VDP_FUNC_ID_VIDEO_MIXER_SET_FEATURE_ENABLES, vdp_video_mixer_set_feature_enables);
+ GET_POINTER(VDP_FUNC_ID_VIDEO_MIXER_SET_ATTRIBUTE_VALUES, vdp_video_mixer_set_attribute_values);
+ GET_POINTER(VDP_FUNC_ID_VIDEO_MIXER_GET_FEATURE_SUPPORT, vdp_video_mixer_get_feature_support);
+ GET_POINTER(VDP_FUNC_ID_VIDEO_MIXER_GET_FEATURE_ENABLES, vdp_video_mixer_get_feature_enables);
+ GET_POINTER(VDP_FUNC_ID_VIDEO_MIXER_GET_PARAMETER_VALUES, vdp_video_mixer_get_parameter_values);
+ GET_POINTER(VDP_FUNC_ID_VIDEO_MIXER_GET_ATTRIBUTE_VALUES, vdp_video_mixer_get_attribute_values);
+ GET_POINTER(VDP_FUNC_ID_VIDEO_MIXER_DESTROY, vdp_video_mixer_destroy);
+ GET_POINTER(VDP_FUNC_ID_VIDEO_MIXER_RENDER, vdp_video_mixer_render);
+ GET_POINTER(VDP_FUNC_ID_PRESENTATION_QUEUE_TARGET_DESTROY, vdp_presentation_queue_target_destroy);
+ GET_POINTER(VDP_FUNC_ID_PRESENTATION_QUEUE_CREATE, vdp_presentation_queue_create);
+ GET_POINTER(VDP_FUNC_ID_PRESENTATION_QUEUE_DESTROY, vdp_presentation_queue_destroy);
+ GET_POINTER(VDP_FUNC_ID_PRESENTATION_QUEUE_SET_BACKGROUND_COLOR, vdp_presentation_queue_set_background_color);
+ GET_POINTER(VDP_FUNC_ID_PRESENTATION_QUEUE_GET_BACKGROUND_COLOR, vdp_presentation_queue_get_background_color);
+ GET_POINTER(VDP_FUNC_ID_PRESENTATION_QUEUE_GET_TIME, vdp_presentation_queue_get_time);
+ GET_POINTER(VDP_FUNC_ID_PRESENTATION_QUEUE_DISPLAY, vdp_presentation_queue_display);
+ GET_POINTER(VDP_FUNC_ID_PRESENTATION_QUEUE_BLOCK_UNTIL_SURFACE_IDLE, vdp_presentation_queue_block_until_surface_idle);
+ GET_POINTER(VDP_FUNC_ID_PRESENTATION_QUEUE_QUERY_SURFACE_STATUS, vdp_presentation_queue_query_surface_status);
+ GET_POINTER(VDP_FUNC_ID_PREEMPTION_CALLBACK_REGISTER, vdp_preemption_callback_register);
+ GET_POINTER(VDP_FUNC_ID_PRESENTATION_QUEUE_TARGET_CREATE_X11, vdp_presentation_queue_target_create_x11);
+
+ vdp_st = VDP_STATUS_OK;
+
+done:
+ if (_vdp_cap_data.level >= LEVEL_PARAMS) {
+ fprintf(_vdp_cap_data.fp, " -> %d", vdp_st);
+ if (vdp_st == VDP_STATUS_OK) {
+ fprintf(
+ _vdp_cap_data.fp,
+ ", %x, %p",
+ _vdp_cap_data.vdp_device,
+ _vdp_cap_data.vdp_get_proc_address
+ );
+ }
+ fputs("\n", _vdp_cap_data.fp);
+ }
+
+ return vdp_st;
+}
+