xorg_xv.c revision 4969d014e5d55985119874c8db7cb98154185802
1#include "xorg_tracker.h"
2
3#include <xf86xv.h>
4#include <X11/extensions/Xv.h>
5#include <fourcc.h>
6
7/*XXX get these from pipe's texture limits */
8#define IMAGE_MAX_WIDTH		2048
9#define IMAGE_MAX_HEIGHT	2048
10
11#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
12
13static Atom xvBrightness, xvContrast;
14
15#define NUM_TEXTURED_ATTRIBUTES 2
16static XF86AttributeRec TexturedAttributes[NUM_TEXTURED_ATTRIBUTES] = {
17   {XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"},
18   {XvSettable | XvGettable, 0, 255, "XV_CONTRAST"}
19};
20
21#define NUM_FORMATS 3
22static XF86VideoFormatRec Formats[NUM_FORMATS] = {
23   {15, TrueColor}, {16, TrueColor}, {24, TrueColor}
24};
25
26static XF86VideoEncodingRec DummyEncoding[1] = {
27   {
28      0,
29      "XV_IMAGE",
30      IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT,
31      {1, 1}
32   }
33};
34
35#define NUM_IMAGES 2
36static XF86ImageRec Images[NUM_IMAGES] = {
37   XVIMAGE_UYVY,
38   XVIMAGE_YUY2,
39};
40
41struct xorg_xv_port_priv {
42   RegionRec clip;
43
44   int brightness;
45   int contrast;
46};
47
48
49static void
50stop_video(ScrnInfoPtr pScrn, pointer data, Bool shutdown)
51{
52   struct xorg_xv_port_priv *priv = (struct xorg_xv_port_priv *)data;
53
54   REGION_EMPTY(pScrn->pScreen, &priv->clip);
55}
56
57static int
58set_port_attribute(ScrnInfoPtr pScrn,
59                   Atom attribute, INT32 value, pointer data)
60{
61   struct xorg_xv_port_priv *priv = (struct xorg_xv_port_priv *)data;
62
63   if (attribute == xvBrightness) {
64      if ((value < -128) || (value > 127))
65         return BadValue;
66      priv->brightness = value;
67   } else if (attribute == xvContrast) {
68      if ((value < 0) || (value > 255))
69         return BadValue;
70      priv->contrast = value;
71   } else
72      return BadMatch;
73
74   return Success;
75}
76
77static int
78get_port_attribute(ScrnInfoPtr pScrn,
79                   Atom attribute, INT32 * value, pointer data)
80{
81   struct xorg_xv_port_priv *priv = (struct xorg_xv_port_priv *)data;
82
83   if (attribute == xvBrightness)
84      *value = priv->brightness;
85   else if (attribute == xvContrast)
86      *value = priv->contrast;
87   else
88      return BadMatch;
89
90   return Success;
91}
92
93static void
94query_best_size(ScrnInfoPtr pScrn,
95                Bool motion,
96                short vid_w, short vid_h,
97                short drw_w, short drw_h,
98                unsigned int *p_w, unsigned int *p_h, pointer data)
99{
100   if (vid_w > (drw_w << 1))
101      drw_w = vid_w >> 1;
102   if (vid_h > (drw_h << 1))
103      drw_h = vid_h >> 1;
104
105   *p_w = drw_w;
106   *p_h = drw_h;
107}
108
109static int
110put_image(ScrnInfoPtr pScrn,
111          short src_x, short src_y,
112          short drw_x, short drw_y,
113          short src_w, short src_h,
114          short drw_w, short drw_h,
115          int id, unsigned char *buf,
116          short width, short height,
117          Bool sync, RegionPtr clipBoxes, pointer data,
118          DrawablePtr pDraw)
119{
120   return 0;
121}
122
123static int
124query_image_attributes(ScrnInfoPtr pScrn,
125                       int id,
126                       unsigned short *w, unsigned short *h,
127                       int *pitches, int *offsets)
128{
129   int size;
130
131   if (*w > IMAGE_MAX_WIDTH)
132      *w = IMAGE_MAX_WIDTH;
133   if (*h > IMAGE_MAX_HEIGHT)
134      *h = IMAGE_MAX_HEIGHT;
135
136   *w = (*w + 1) & ~1;
137   if (offsets)
138      offsets[0] = 0;
139
140   switch (id) {
141   case FOURCC_UYVY:
142   case FOURCC_YUY2:
143   default:
144      size = *w << 1;
145      if (pitches)
146	 pitches[0] = size;
147      size *= *h;
148      break;
149   }
150
151   return size;
152}
153
154static struct xorg_xv_port_priv *
155port_priv_create(ScreenPtr pScreen)
156{
157   /*ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];*/
158   /*modesettingPtr ms = modesettingPTR(pScrn);*/
159   struct xorg_xv_port_priv *priv = NULL;
160
161   priv = calloc(1, sizeof(struct xorg_xv_port_priv));
162
163   if (!priv)
164      return NULL;
165
166   REGION_NULL(pScreen, &priv->clip);
167
168   return priv;
169}
170
171static XF86VideoAdaptorPtr
172xorg_setup_textured_adapter(ScreenPtr pScreen)
173{
174   /*ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];*/
175   /*modesettingPtr ms = modesettingPTR(pScrn);*/
176   XF86VideoAdaptorPtr adapt;
177   XF86AttributePtr attrs;
178   DevUnion *dev_unions;
179   int nports = 16, i;
180   int nattributes;
181
182   nattributes = NUM_TEXTURED_ATTRIBUTES;
183
184   adapt = calloc(1, sizeof(XF86VideoAdaptorRec));
185   dev_unions = calloc(nports, sizeof(DevUnion));
186   attrs = calloc(nattributes, sizeof(XF86AttributeRec));
187   if (adapt == NULL || dev_unions == NULL || attrs == NULL) {
188      free(adapt);
189      free(dev_unions);
190      free(attrs);
191      return NULL;
192   }
193
194   adapt->type = XvWindowMask | XvInputMask | XvImageMask;
195   adapt->flags = 0;
196   adapt->name = "Gallium3D Textured Video";
197   adapt->nEncodings = 1;
198   adapt->pEncodings = DummyEncoding;
199   adapt->nFormats = NUM_FORMATS;
200   adapt->pFormats = Formats;
201   adapt->nPorts = 0;
202   adapt->pPortPrivates = dev_unions;
203   adapt->nAttributes = nattributes;
204   adapt->pAttributes = attrs;
205   memcpy(attrs, TexturedAttributes, nattributes * sizeof(XF86AttributeRec));
206   adapt->nImages = NUM_IMAGES;
207   adapt->pImages = Images;
208   adapt->PutVideo = NULL;
209   adapt->PutStill = NULL;
210   adapt->GetVideo = NULL;
211   adapt->GetStill = NULL;
212   adapt->StopVideo = stop_video;
213   adapt->SetPortAttribute = set_port_attribute;
214   adapt->GetPortAttribute = get_port_attribute;
215   adapt->QueryBestSize = query_best_size;
216   adapt->PutImage = put_image;
217   adapt->QueryImageAttributes = query_image_attributes;
218
219   for (i = 0; i < nports; i++) {
220      struct xorg_xv_port_priv *priv =
221         port_priv_create(pScreen);
222
223      adapt->pPortPrivates[i].ptr = (pointer) (priv);
224      adapt->nPorts++;
225   }
226
227   return adapt;
228}
229
230void
231xorg_init_video(ScreenPtr pScreen)
232{
233   ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
234   /*modesettingPtr ms = modesettingPTR(pScrn);*/
235   XF86VideoAdaptorPtr *adaptors, *new_adaptors = NULL;
236   XF86VideoAdaptorPtr textured_adapter;
237   int num_adaptors;
238
239   num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors);
240   new_adaptors = malloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr *));
241   if (new_adaptors == NULL)
242      return;
243
244   memcpy(new_adaptors, adaptors, num_adaptors * sizeof(XF86VideoAdaptorPtr));
245   adaptors = new_adaptors;
246
247   /* Add the adaptors supported by our hardware.  First, set up the atoms
248    * that will be used by both output adaptors.
249    */
250   xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
251   xvContrast = MAKE_ATOM("XV_CONTRAST");
252
253   textured_adapter = xorg_setup_textured_adapter(pScreen);
254
255   debug_assert(textured_adapter);
256
257   if (textured_adapter) {
258      adaptors[num_adaptors++] = textured_adapter;
259   }
260
261   if (num_adaptors) {
262      xf86XVScreenInit(pScreen, adaptors, num_adaptors);
263   } else {
264      xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
265                 "Disabling Xv because no adaptors could be initialized.\n");
266   }
267
268   free(adaptors);
269}
270