22eadc1889b327efa56fc6666480dfdafe602b6b
[mesa.git] / src / libXvMC / context.c
1 #include <assert.h>
2 #include <X11/Xlib.h>
3 #include <X11/extensions/XvMClib.h>
4 #include <vl_context.h>
5 #include <xsp_winsys.h>
6
7 static Status Validate(Display *display, XvPortID port, int surface_type_id, unsigned int width, unsigned int height, int flags, int *chroma_format)
8 {
9 unsigned int found_port = 0;
10 unsigned int found_surface = 0;
11 XvAdaptorInfo *adaptor_info;
12 unsigned int num_adaptors;
13 int num_types;
14 unsigned int max_width, max_height;
15 Status ret;
16 unsigned int i, j, k;
17
18 assert(display && chroma_format);
19
20 ret = XvQueryAdaptors(display, XDefaultRootWindow(display), &num_adaptors, &adaptor_info);
21 if (ret != Success)
22 return ret;
23
24 /* Scan through all adaptors looking for this port and surface */
25 for (i = 0; i < num_adaptors && !found_port; ++i)
26 {
27 /* Scan through all ports of this adaptor looking for our port */
28 for (j = 0; j < adaptor_info[i].num_ports && !found_port; ++j)
29 {
30 /* If this is our port, scan through all its surfaces looking for our surface */
31 if (adaptor_info[i].base_id + j == port)
32 {
33 XvMCSurfaceInfo *surface_info;
34
35 found_port = 1;
36 surface_info = XvMCListSurfaceTypes(display, adaptor_info[i].base_id, &num_types);
37
38 if (surface_info)
39 {
40 for (k = 0; k < num_types && !found_surface; ++k)
41 {
42 if (surface_info[k].surface_type_id == surface_type_id)
43 {
44 found_surface = 1;
45 max_width = surface_info[k].max_width;
46 max_height = surface_info[k].max_height;
47 *chroma_format = surface_info[k].chroma_format;
48 }
49 }
50
51 XFree(surface_info);
52 }
53 else
54 {
55 XvFreeAdaptorInfo(adaptor_info);
56 return BadAlloc;
57 }
58 }
59 }
60 }
61
62 XvFreeAdaptorInfo(adaptor_info);
63
64 if (!found_port)
65 return XvBadPort;
66 if (!found_surface)
67 return BadMatch;
68 if (width > max_width || height > max_height)
69 return BadValue;
70 if (flags != XVMC_DIRECT && flags != 0)
71 return BadValue;
72
73 return Success;
74 }
75
76 static enum VL_FORMAT FormatToVL(int xvmc_format)
77 {
78 enum VL_FORMAT vl_format;
79
80 switch (xvmc_format)
81 {
82 case XVMC_CHROMA_FORMAT_420:
83 {
84 vl_format = VL_FORMAT_YCBCR_420;
85 break;
86 }
87 case XVMC_CHROMA_FORMAT_422:
88 {
89 vl_format = VL_FORMAT_YCBCR_422;
90 break;
91 }
92 case XVMC_CHROMA_FORMAT_444:
93 {
94 vl_format = VL_FORMAT_YCBCR_444;
95 break;
96 }
97 default:
98 assert(0);
99 }
100
101 return vl_format;
102 }
103
104 Status XvMCCreateContext(Display *display, XvPortID port, int surface_type_id, int width, int height, int flags, XvMCContext *context)
105 {
106 int chroma_format;
107 Status ret;
108 struct VL_CONTEXT *vl_ctx;
109 struct pipe_context *pipe;
110
111 assert(display);
112
113 if (!context)
114 return XvMCBadContext;
115
116 ret = Validate(display, port, surface_type_id, width, height, flags, &chroma_format);
117 if (ret != Success)
118 return ret;
119
120 pipe = create_pipe_context(display);
121
122 assert(pipe);
123
124 vlCreateContext(display, pipe, width, height, FormatToVL(chroma_format), &vl_ctx);
125
126 context->context_id = XAllocID(display);
127 context->surface_type_id = surface_type_id;
128 context->width = width;
129 context->height = height;
130 context->flags = flags;
131 context->port = port;
132 context->privData = vl_ctx;
133
134 return Success;
135 }
136
137 Status XvMCDestroyContext(Display *display, XvMCContext *context)
138 {
139 struct VL_CONTEXT *vl_ctx;
140 struct pipe_context *pipe;
141
142 assert(display);
143
144 if (!context)
145 return XvMCBadContext;
146
147 vl_ctx = context->privData;
148
149 assert(display == vl_ctx->display);
150
151 pipe = vl_ctx->pipe;
152 vlDestroyContext(vl_ctx);
153 destroy_pipe_context(pipe);
154
155 return Success;
156 }
157
158 /* XXX: The following are here temporarily, need to be implemented in the DDX driver */
159 /* TODO: Figure out which of these need to be in DDX, which are better off in DDX, which can stay */
160
161 Bool XvMCQueryExtension(Display *display, int *event_base, int *err_base)
162 {
163 *event_base = 0;
164 *err_base = 0;
165
166 return True;
167 }
168
169 Status XvMCQueryVersion(Display *display, int *major, int *minor)
170 {
171 *major = 1;
172 *minor = 0;
173
174 return Success;
175 }
176
177 XvMCSurfaceInfo* XvMCListSurfaceTypes(Display *display, XvPortID port, int *num)
178 {
179 XvMCSurfaceInfo *surface_info = calloc(1, sizeof(XvMCSurfaceInfo));
180
181 *num = 1;
182
183 surface_info->chroma_format = XVMC_CHROMA_FORMAT_420;
184 surface_info->max_width = 2048;
185 surface_info->max_height = 2048;
186 surface_info->mc_type = XVMC_IDCT | XVMC_MPEG_2;
187 surface_info->surface_type_id = 123; /* FIXME: XAllocID(display)*/;
188 surface_info->flags |= XVMC_INTRA_UNSIGNED;
189
190 return surface_info;
191 }
192
193 XvImageFormatValues* XvMCListSubpictureTypes(Display* display, XvPortID port, int surface_type_id, int *count_return)
194 {
195 /* TODO */
196 *count_return = 0;
197
198 return NULL;
199 }
200