XFree86 server 4.x Design (DRAFT) : The XFree86 X Video Extension (Xv) Device Dependent Layer
Previous: DGA Extension
Next: The Loader

## 16. The XFree86 X Video Extension (Xv) Device Dependent Layer

XFree86 offers the X Video Extension which allows clients to treat video as any another primitive and ``Put'' video into drawables. By default, the extension reports no video adaptors as being available since the DDX layer has not been initialized. The driver can initialize the DDX layer by filling out one or more `XF86VideoAdaptorRecs` as described later in this document and passing a list of `XF86VideoAdaptorPtr` pointers to the following function:

> `Bool xf86XVScreenInit(
> ScreenPtr pScreen,
> XF86VideoAdaptorPtr *adaptPtrs,
> int num)`

After doing this, the extension will report video adaptors as being available, providing the data in their respective `XF86VideoAdaptorRecs` was valid. `xf86XVScreenInit()` copies data from the structure passed to it so the driver may free it after the initialization. At the moment, the DDX only supports rendering into Window drawables. Pixmap rendering will be supported after a sufficient survey of suitable hardware is completed.

The `XF86VideoAdaptorRec`:

>     typedef struct {
>     	unsigned int type;
>     	int flags;
>     	char *name;
>     	int nEncodings;
>     	XF86VideoEncodingPtr pEncodings;
>     	int nFormats;
>     	XF86VideoFormatPtr pFormats;
>     	int nPorts;
>     	DevUnion *pPortPrivates;
>     	int nAttributes;
>     	XF86AttributePtr pAttributes;
>     	int nImages;
>     	XF86ImagePtr pImages;
>     	PutVideoFuncPtr PutVideo;
>     	PutStillFuncPtr PutStill;
>     	GetVideoFuncPtr GetVideo;
>     	GetStillFuncPtr GetStill;
>     	StopVideoFuncPtr StopVideo;
>     	SetPortAttributeFuncPtr SetPortAttribute;
>     	GetPortAttributeFuncPtr GetPortAttribute;
>     	QueryBestSizeFuncPtr QueryBestSize;
>     	PutImageFuncPtr PutImage;
>     	QueryImageAttributesFuncPtr QueryImageAttributes;
>     } XF86VideoAdaptorRec, *XF86VideoAdaptorPtr;

> Each adaptor will have its own XF86VideoAdaptorRec. The fields are as follows:

> `type`

> > This can be any of the following flags OR'd together.

> > `XvInputMask` `XvOutputMask`

> > > These refer to the target drawable and are similar to a Window's class. `XvInputMask` indicates that the adaptor can put video into a drawable. `XvOutputMask` indicates that the adaptor can get video from a drawable.

> > `XvVideoMask` `XvStillMask` `XvImageMask`

> > > These indicate that the adaptor supports video, still or image primitives respectively.

> > `XvWindowMask` `XvPixmapMask`

> > > These indicate the types of drawables the adaptor is capable of rendering into. At the moment, Pixmap rendering is not supported and the `XvPixmapMask` flag is ignored.

> `flags`

> > Currently, the following flags are defined:

> > `VIDEO_NO_CLIPPING`

> > > This indicates that the video adaptor does not support clipping. The driver will never receive ``Put'' requests where less than the entire area determined by `drw_x`, `drw_y`, `drw_w` and `drw_h` is visible. This flag does not apply to ``Get'' requests. Hardware that is incapable of clipping ``Gets'' may punt or get the extents of the clipping region passed to it.

> > `VIDEO_INVERT_CLIPLIST`

> > > This indicates that the video driver requires the clip list to contain the regions which are obscured rather than the regions which are are visible.

> > `VIDEO_OVERLAID_STILLS`

> > > Implementing PutStill for hardware that does video as an overlay can be awkward since it's unclear how long to leave the video up for. When this flag is set, StopVideo will be called whenever the destination gets clipped or moved so that the still can be left up until then.

> > `VIDEO_OVERLAID_IMAGES`

> > > Same as `VIDEO_OVERLAID_STILLS` but for images.

> > `VIDEO_CLIP_TO_VIEWPORT`

> > > Indicates that the clip region passed to the driver functions should be clipped to the visible portion of the screen in the case where the viewport is smaller than the virtual desktop.

> `name`

> > The name of the adaptor.

> `nEncodings
> pEncodings`

> > The number of encodings the adaptor is capable of and pointer to the `XF86VideoEncodingRec` array. The `XF86VideoEncodingRec` is described later on. For drivers that only support XvImages there should be an encoding named "XV_IMAGE" and the width and height should specify the maximum size source image supported.

> `nFormats
> pFormats`

> > The number of formats the adaptor is capable of and pointer to the `XF86VideoFormatRec` array. The `XF86VideoFormatRec` is described later on.

> `nPorts
> pPortPrivates`

> > The number of ports is the number of separate data streams which the adaptor can handle simultaneously. If you have more than one port, the adaptor is expected to be able to render into more than one window at a time. `pPortPrivates` is an array of pointers or ints - one for each port. A port's private data will be passed to the driver any time the port is requested to do something like put the video or stop the video. In the case where there may be many ports, this enables the driver to know which port the request is intended for. Most commonly, this will contain a pointer to the data structure containing information about the port. In Xv, all ports on a particular adaptor are expected to be identical in their functionality.

> `nAttributes
> pAttributes`

> > The number of attributes recognized by the adaptor and a pointer to the array of `XF86AttributeRecs`. The `XF86AttributeRec` is described later on.

> `nImages
> pImages`

> > The number of `XF86ImageRecs` supported by the adaptor and a pointer to the array of `XF86ImageRecs`. The `XF86ImageRec` is described later on.

> `PutVideo PutStill GetVideo GetStill StopVideo SetPortAttribute GetPortAttribute QueryBestSize PutImage QueryImageAttributes`

> > These functions define the DDX->driver interface. In each case, the pointer `data` is passed to the driver. This is the port private for that port as described above. All fields are required except under the following conditions:

> > 1. `PutVideo`, `PutStill` and the image routines `PutImage` and `QueryImageAttributes` are not required when the adaptor type does not contain `XvInputMask`.
> > 2. `GetVideo` and `GetStill` are not required when the adaptor type does not contain `XvOutputMask`.
> > 3. `GetVideo` and `PutVideo` are not required when the adaptor type does not contain `XvVideoMask`.
> > 4. `GetStill` and `PutStill` are not required when the adaptor type does not contain `XvStillMask`.
> > 5. `PutImage` and `QueryImageAttributes` are not required when the adaptor type does not contain `XvImageMask`.

> > With the exception of `QueryImageAttributes`, these functions should return `Success` if the operation was completed successfully. They can return `XvBadAlloc` otherwise. `QueryImageAttributes` returns the size of the XvImage queried.

> > If the `VIDEO_NO_CLIPPING` flag is set, the `clipBoxes` may be ignored by the driver. `ClipBoxes` is an `X-Y` banded region identical to those used throughout the server. The clipBoxes represent the visible portions of the area determined by `drw_x`, `drw_y`, `drw_w` and `drw_h` in the Get/Put function. The boxes are in screen coordinates, are guaranteed not to overlap and an empty region will never be passed. If the driver has specified `VIDEO_INVERT_CLIPLIST`, `clipBoxes` will indicate the areas of the primitive which are obscured rather than the areas visible.

> `typedef int (* PutVideoFuncPtr)( ScrnInfoPtr pScrn,
> short vid_x, short vid_y, short drw_x, short drw_y,
> short vid_w, short vid_h, short drw_w, short drw_h,
> RegionPtr clipBoxes, pointer data )`

> > This indicates that the driver should take a subsection `vid_w` by `vid_h` at location `(vid_x,vid_y)` from the video stream and direct it into the rectangle `drw_w` by `drw_h` at location `(drw_x,drw_y)` on the screen, scaling as necessary. Due to the large variations in capabilities of the various hardware expected to be used with this extension, it is not expected that all hardware will be able to do this exactly as described. In that case the driver should just do ``the best it can,'' scaling as closely to the target rectangle as it can without rendering outside of it. In the worst case, the driver can opt to just not turn on the video.

> `typedef int (* PutStillFuncPtr)( ScrnInfoPtr pScrn,
> short vid_x, short vid_y, short drw_x, short drw_y,
> short vid_w, short vid_h, short drw_w, short drw_h,
> RegionPtr clipBoxes, pointer data )`

> > This is same as `PutVideo` except that the driver should place only one frame from the stream on the screen.

> `typedef int (* GetVideoFuncPtr)( ScrnInfoPtr pScrn,
> short vid_x, short vid_y, short drw_x, short drw_y,
> short vid_w, short vid_h, short drw_w, short drw_h,
> RegionPtr clipBoxes, pointer data )`

> > This is same as `PutVideo` except that the driver gets video from the screen and outputs it. The driver should do the best it can to get the requested dimensions correct without reading from an area larger than requested.

> `typedef int (* GetStillFuncPtr)( ScrnInfoPtr pScrn,
> short vid_x, short vid_y, short drw_x, short drw_y,
> short vid_w, short vid_h, short drw_w, short drw_h,
> RegionPtr clipBoxes, pointer data )`

> > This is the same as `GetVideo` except that the driver should place only one frame from the screen into the output stream.

> `typedef void (* StopVideoFuncPtr)(ScrnInfoPtr pScrn,
> pointer data, Bool cleanup)`

> > This indicates the driver should stop displaying the video. This is used to stop both input and output video. The `cleanup` field indicates that the video is being stopped because the client requested it to stop or because the server is exiting the current VT. In that case the driver should deallocate any offscreen memory areas (if there are any) being used to put the video to the screen. If `cleanup` is not set, the video is being stopped temporarily due to clipping or moving of the window, etc... and video will likely be restarted soon so the driver should not deallocate any offscreen areas associated with that port.

> `typedef int (* SetPortAttributeFuncPtr)(ScrnInfoPtr pScrn,
> Atom attribute,INT32 value, pointer data)`

> `typedef int (* GetPortAttributeFuncPtr)(ScrnInfoPtr pScrn,
> Atom attribute,INT32 *value, pointer data)`

> > A port may have particular attributes such as hue, saturation, brightness or contrast. Xv clients set and get these attribute values by sending attribute strings (Atoms) to the server. Such requests end up at these driver functions. It is recommended that the driver provide at least the following attributes mentioned in the Xv client library docs:

> > > `XV_ENCODING
> > > XV_HUE
> > > XV_SATURATION
> > > XV_BRIGHTNESS
> > > XV_CONTRAST`

> > but the driver may recognize as many atoms as it wishes. If a requested attribute is unknown by the driver it should return `BadMatch`. `XV_ENCODING` is the attribute intended to let the client specify which video encoding the particular port should be using (see the description of `XF86VideoEncodingRec` below). If the requested encoding is unsupported, the driver should return `XvBadEncoding`. If the value lies outside the advertised range `BadValue` may be returned. `Success` should be returned otherwise.

> `typedef void (* QueryBestSizeFuncPtr)(ScrnInfoPtr pScrn,
> Bool motion, short vid_w, short vid_h,
> short drw_w, short drw_h,
> unsigned int *p_w, unsigned int *p_h, pointer data)`

> > `QueryBestSize` provides the client with a way to query what the destination dimensions would end up being if they were to request that an area `vid_w` by `vid_h` from the video stream be scaled to rectangle of `drw_w` by `drw_h` on the screen. Since it is not expected that all hardware will be able to get the target dimensions exactly, it is important that the driver provide this function.

> `typedef int (* PutImageFuncPtr)( ScrnInfoPtr pScrn,
> short src_x, short src_y, short drw_x, short drw_y,
> short src_w, short src_h, short drw_w, short drw_h,
> int image, char *buf, short width, short height,
> Bool sync, RegionPtr clipBoxes, pointer data )`

> > This is similar to `PutStill` except that the source of the video is not a port but the data stored in a system memory buffer at `buf`. The data is in the format indicated by the `image` descriptor and represents a source of size `width` by `height`. If `sync` is TRUE the driver should not return from this function until it is through reading the data from `buf`. Returning when `sync` is TRUE indicates that it is safe for the data at `buf` to be replaced, freed, or modified.

> `typedef int (* QueryImageAttributesFuncPtr)( ScrnInfoPtr pScrn,
> int image, short *width, short *height,
> int *pitches, int *offsets)`

> > This function is called to let the driver specify how data for a particular `image` of size `width` by `height` should be stored. Sometimes only the size and corrected width and height are needed. In that case `pitches` and `offsets` are NULL. The size of the memory required for the image is returned by this function. The `width` and `height` of the requested image can be altered by the driver to reflect format limitations (such as component sampling periods that are larger than one). If `pitches` and `offsets` are not NULL, these will be arrays with as many elements in them as there are planes in the `image` format. The driver should specify the pitch (in bytes) of each scanline in the particular plane as well as the offset to that plane (in bytes) from the beginning of the image.

The XF86VideoEncodingRec:

>     typedef struct {
>     	int id;
>     	char *name;
>     	unsigned short width, height;
>     	XvRationalRec rate;
>     } XF86VideoEncodingRec, *XF86VideoEncodingPtr;

> The `XF86VideoEncodingRec` specifies what encodings the adaptor can support. Most of this data is just informational and for the client's benefit, and is what will be reported by `XvQueryEncodings`. The `id` field is expected to be a unique identifier to allow the client to request a certain encoding via the `XV_ENCODING` attribute string.

The XF86VideoFormatRec:

>     typedef struct {
>     	char  depth;
>     	short class;
>     } XF86VideoFormatRec, *XF86VideoFormatPtr;

> This specifies what visuals the video is viewable in. `depth` is the depth of the visual (not bpp). `class` is the visual class such as `TrueColor`, `DirectColor` or `PseudoColor`. Initialization of an adaptor will fail if none of the visuals on that screen are supported.

The XF86AttributeRec:

>     typedef struct {
>     	int   flags;
>     	int   min_value;
>     	int   max_value;
>     	char  *name;
>     } XF86AttributeListRec, *XF86AttributeListPtr;

> Each adaptor may have an array of these advertising the attributes for its ports. Currently defined flags are `XvGettable` and `XvSettable` which may be OR'd together indicating that attribute is ``gettable'' or ``settable'' by the client. The `min` and `max` field specify the valid range for the value. `Name` is a text string describing the attribute by name.

The XF86ImageRec:

>     typedef struct {
>     	int id;
>     	int type;
>     	int byte_order;
>     	char guid[16];
>     	int bits_per_pixel;
>     	int format;
>     	int num_planes;

>     	/* for RGB formats */
>     	int depth;
>     	unsigned int red_mask;
>     	unsigned int green_mask;
>     	unsigned int blue_mask;

>     	/* for YUV formats */
>     	unsigned int y_sample_bits;
>     	unsigned int u_sample_bits;
>     	unsigned int v_sample_bits;
>     	unsigned int horz_y_period;
>     	unsigned int horz_u_period;
>     	unsigned int horz_v_period;
>     	unsigned int vert_y_period;
>     	unsigned int vert_u_period;
>     	unsigned int vert_v_period;
>     	char component_order[32];
>     	int scanline_order;
>     } XF86ImageRec, *XF86ImagePtr;

> XF86ImageRec describes how video source data is laid out in memory. The fields are as follows:

> `id`

> > This is a unique descriptor for the format. It is often good to set this value to the FOURCC for the format when applicable.

> `type`

> > This is `XvRGB` or `XvYUV`.

> `byte_order`

> > This is `LSBFirst` or `MSBFirst`.

> `guid`

> > This is the Globally Unique IDentifier for the format. When not applicable, all characters should be NULL.

> `bits_per_pixel`

> > The number of bits taken up (but not necessarily used) by each pixel. Note that for some planar formats which have fractional bits per pixel (such as IF09) this number may be rounded _down_.

> `format`

> > This is `XvPlanar` or `XvPacked`.

> `num_planes`

> > The number of planes in planar formats. This should be set to one for packed formats.

> `depth`

> > The significant bits per pixel in RGB formats (analgous to the depth of a pixmap format).

> `red_mask` `green_mask` `blue_mask`

> > The red, green and blue bitmasks for packed RGB formats.

> `y_sample_bits` `u_sample_bits` `v_sample_bits`

> > The y, u and v sample sizes (in bits).

> `horz_y_period` `horz_u_period` `horz_v_period`

> > The y, u and v sampling periods in the horizontal direction.

> `vert_y_period` `vert_u_period` `vert_v_period`

> > The y, u and v sampling periods in the vertical direction.

> `component_order`

> > Uppercase ascii characters representing the order that samples are stored within packed formats. For planar formats this represents the ordering of the planes. Unused characters in the 32 byte string should be set to NULL.

> `scanline_order`

> > This is `XvTopToBottom` or `XvBottomToTop`.

> Since some formats (particular some planar YUV formats) may not be completely defined by the parameters above, the guid, when available, should provide the most accurate description of the format.

XFree86 server 4.x Design (DRAFT) : The XFree86 X Video Extension (Xv) Device Dependent Layer
Previous: DGA Extension
Next: The Loader