1fcb595c04f9ee275eae49b7bb7c61246671f5ce2Younes Manton/**************************************************************************
2e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton *
3fcb595c04f9ee275eae49b7bb7c61246671f5ce2Younes Manton * Copyright 2009 Younes Manton.
4fcb595c04f9ee275eae49b7bb7c61246671f5ce2Younes Manton * All Rights Reserved.
5e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton *
6fcb595c04f9ee275eae49b7bb7c61246671f5ce2Younes Manton * Permission is hereby granted, free of charge, to any person obtaining a
7fcb595c04f9ee275eae49b7bb7c61246671f5ce2Younes Manton * copy of this software and associated documentation files (the
8fcb595c04f9ee275eae49b7bb7c61246671f5ce2Younes Manton * "Software"), to deal in the Software without restriction, including
9fcb595c04f9ee275eae49b7bb7c61246671f5ce2Younes Manton * without limitation the rights to use, copy, modify, merge, publish,
10fcb595c04f9ee275eae49b7bb7c61246671f5ce2Younes Manton * distribute, sub license, and/or sell copies of the Software, and to
11fcb595c04f9ee275eae49b7bb7c61246671f5ce2Younes Manton * permit persons to whom the Software is furnished to do so, subject to
12fcb595c04f9ee275eae49b7bb7c61246671f5ce2Younes Manton * the following conditions:
13e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton *
14fcb595c04f9ee275eae49b7bb7c61246671f5ce2Younes Manton * The above copyright notice and this permission notice (including the
15fcb595c04f9ee275eae49b7bb7c61246671f5ce2Younes Manton * next paragraph) shall be included in all copies or substantial portions
16fcb595c04f9ee275eae49b7bb7c61246671f5ce2Younes Manton * of the Software.
17e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton *
18fcb595c04f9ee275eae49b7bb7c61246671f5ce2Younes Manton * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19fcb595c04f9ee275eae49b7bb7c61246671f5ce2Younes Manton * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20fcb595c04f9ee275eae49b7bb7c61246671f5ce2Younes Manton * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21fcb595c04f9ee275eae49b7bb7c61246671f5ce2Younes Manton * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22fcb595c04f9ee275eae49b7bb7c61246671f5ce2Younes Manton * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23fcb595c04f9ee275eae49b7bb7c61246671f5ce2Younes Manton * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24fcb595c04f9ee275eae49b7bb7c61246671f5ce2Younes Manton * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton *
26fcb595c04f9ee275eae49b7bb7c61246671f5ce2Younes Manton **************************************************************************/
27fcb595c04f9ee275eae49b7bb7c61246671f5ce2Younes Manton
28c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton#include <assert.h>
29b48676672592271597d07e5ece79cf4d3ffbe04bChristian König
302ef8c60e558938686196bf8ff4d22fd57903bf4cCooper Yuan#include <X11/Xlibint.h>
31e44c85637a3298918e292e9ddba812856cf92924Younes Manton#include <X11/extensions/XvMClib.h>
32b48676672592271597d07e5ece79cf4d3ffbe04bChristian König
337ea550621e25f9b2f344b2ed60551ceec91b3fcfKai Wasserbäch#include "pipe/p_screen.h"
347ea550621e25f9b2f344b2ed60551ceec91b3fcfKai Wasserbäch#include "pipe/p_video_decoder.h"
357ea550621e25f9b2f344b2ed60551ceec91b3fcfKai Wasserbäch#include "pipe/p_video_state.h"
367ea550621e25f9b2f344b2ed60551ceec91b3fcfKai Wasserbäch#include "pipe/p_state.h"
37b48676672592271597d07e5ece79cf4d3ffbe04bChristian König
387ea550621e25f9b2f344b2ed60551ceec91b3fcfKai Wasserbäch#include "util/u_memory.h"
39b48676672592271597d07e5ece79cf4d3ffbe04bChristian König
407ea550621e25f9b2f344b2ed60551ceec91b3fcfKai Wasserbäch#include "vl/vl_csc.h"
41fc0a5e21d77ae2f082fd19dd2295e84f6fb7bd3bChristian König#include "vl/vl_winsys.h"
42b48676672592271597d07e5ece79cf4d3ffbe04bChristian König
43e44c85637a3298918e292e9ddba812856cf92924Younes Manton#include "xvmc_private.h"
44c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton
45e44c85637a3298918e292e9ddba812856cf92924Younes Mantonstatic Status Validate(Display *dpy, XvPortID port, int surface_type_id,
46e44c85637a3298918e292e9ddba812856cf92924Younes Manton                       unsigned int width, unsigned int height, int flags,
4770c44073ad3f333ed40c5c297a934a359c839e94Younes Manton                       bool *found_port, int *screen, int *chroma_format,
485eb822cb6a8fb461ee5b1bd881e0ef1b91c432b5Younes Manton                       int *mc_type, int *surface_flags,
495eb822cb6a8fb461ee5b1bd881e0ef1b91c432b5Younes Manton                       unsigned short *subpic_max_w,
505eb822cb6a8fb461ee5b1bd881e0ef1b91c432b5Younes Manton                       unsigned short *subpic_max_h)
51c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton{
52e44c85637a3298918e292e9ddba812856cf92924Younes Manton   bool found_surface = false;
53e44c85637a3298918e292e9ddba812856cf92924Younes Manton   XvAdaptorInfo *adaptor_info;
54e44c85637a3298918e292e9ddba812856cf92924Younes Manton   unsigned int num_adaptors;
55e44c85637a3298918e292e9ddba812856cf92924Younes Manton   int num_types;
568b02f9e67b83e40019d6b07b9a035ba5d5042688Christian König   unsigned int max_width = 0, max_height = 0;
57e44c85637a3298918e292e9ddba812856cf92924Younes Manton   Status ret;
58e44c85637a3298918e292e9ddba812856cf92924Younes Manton
59e44c85637a3298918e292e9ddba812856cf92924Younes Manton   assert(dpy);
60e44c85637a3298918e292e9ddba812856cf92924Younes Manton   assert(found_port);
61e44c85637a3298918e292e9ddba812856cf92924Younes Manton   assert(screen);
62e44c85637a3298918e292e9ddba812856cf92924Younes Manton   assert(chroma_format);
63e44c85637a3298918e292e9ddba812856cf92924Younes Manton   assert(mc_type);
6470c44073ad3f333ed40c5c297a934a359c839e94Younes Manton   assert(surface_flags);
655eb822cb6a8fb461ee5b1bd881e0ef1b91c432b5Younes Manton   assert(subpic_max_w);
665eb822cb6a8fb461ee5b1bd881e0ef1b91c432b5Younes Manton   assert(subpic_max_h);
67e44c85637a3298918e292e9ddba812856cf92924Younes Manton
68e44c85637a3298918e292e9ddba812856cf92924Younes Manton   *found_port = false;
69e44c85637a3298918e292e9ddba812856cf92924Younes Manton
70d52d51ab8ae1240f77b6c18c3e99be4bf4868037Younes Manton   for (unsigned int i = 0; i < XScreenCount(dpy); ++i) {
71e44c85637a3298918e292e9ddba812856cf92924Younes Manton      ret = XvQueryAdaptors(dpy, XRootWindow(dpy, i), &num_adaptors, &adaptor_info);
72e44c85637a3298918e292e9ddba812856cf92924Younes Manton      if (ret != Success)
73e44c85637a3298918e292e9ddba812856cf92924Younes Manton         return ret;
74e44c85637a3298918e292e9ddba812856cf92924Younes Manton
75d52d51ab8ae1240f77b6c18c3e99be4bf4868037Younes Manton      for (unsigned int j = 0; j < num_adaptors && !*found_port; ++j) {
76d52d51ab8ae1240f77b6c18c3e99be4bf4868037Younes Manton         for (unsigned int k = 0; k < adaptor_info[j].num_ports && !*found_port; ++k) {
77e44c85637a3298918e292e9ddba812856cf92924Younes Manton            XvMCSurfaceInfo *surface_info;
78e44c85637a3298918e292e9ddba812856cf92924Younes Manton
79e44c85637a3298918e292e9ddba812856cf92924Younes Manton            if (adaptor_info[j].base_id + k != port)
80e44c85637a3298918e292e9ddba812856cf92924Younes Manton               continue;
81e44c85637a3298918e292e9ddba812856cf92924Younes Manton
82e44c85637a3298918e292e9ddba812856cf92924Younes Manton            *found_port = true;
83e44c85637a3298918e292e9ddba812856cf92924Younes Manton
84e44c85637a3298918e292e9ddba812856cf92924Younes Manton            surface_info = XvMCListSurfaceTypes(dpy, adaptor_info[j].base_id, &num_types);
85d52d51ab8ae1240f77b6c18c3e99be4bf4868037Younes Manton            if (!surface_info) {
86e44c85637a3298918e292e9ddba812856cf92924Younes Manton               XvFreeAdaptorInfo(adaptor_info);
87e44c85637a3298918e292e9ddba812856cf92924Younes Manton               return BadAlloc;
88e44c85637a3298918e292e9ddba812856cf92924Younes Manton            }
89e44c85637a3298918e292e9ddba812856cf92924Younes Manton
90d52d51ab8ae1240f77b6c18c3e99be4bf4868037Younes Manton            for (unsigned int l = 0; l < num_types && !found_surface; ++l) {
91e44c85637a3298918e292e9ddba812856cf92924Younes Manton               if (surface_info[l].surface_type_id != surface_type_id)
92e44c85637a3298918e292e9ddba812856cf92924Younes Manton                  continue;
93e44c85637a3298918e292e9ddba812856cf92924Younes Manton
94e44c85637a3298918e292e9ddba812856cf92924Younes Manton               found_surface = true;
95e44c85637a3298918e292e9ddba812856cf92924Younes Manton               max_width = surface_info[l].max_width;
96e44c85637a3298918e292e9ddba812856cf92924Younes Manton               max_height = surface_info[l].max_height;
97e44c85637a3298918e292e9ddba812856cf92924Younes Manton               *chroma_format = surface_info[l].chroma_format;
98e44c85637a3298918e292e9ddba812856cf92924Younes Manton               *mc_type = surface_info[l].mc_type;
9970c44073ad3f333ed40c5c297a934a359c839e94Younes Manton               *surface_flags = surface_info[l].flags;
1005eb822cb6a8fb461ee5b1bd881e0ef1b91c432b5Younes Manton               *subpic_max_w = surface_info[l].subpicture_max_width;
1015eb822cb6a8fb461ee5b1bd881e0ef1b91c432b5Younes Manton               *subpic_max_h = surface_info[l].subpicture_max_height;
102e44c85637a3298918e292e9ddba812856cf92924Younes Manton               *screen = i;
1038580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton
1045eb822cb6a8fb461ee5b1bd881e0ef1b91c432b5Younes Manton               XVMC_MSG(XVMC_TRACE, "[XvMC] Found requested context surface format.\n" \
1058580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton                                    "[XvMC]   screen=%u, port=%u\n" \
1065eb822cb6a8fb461ee5b1bd881e0ef1b91c432b5Younes Manton                                    "[XvMC]   id=0x%08X\n" \
1078580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton                                    "[XvMC]   max width=%u, max height=%u\n" \
1088580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton                                    "[XvMC]   chroma format=0x%08X\n" \
1098580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton                                    "[XvMC]   acceleration level=0x%08X\n" \
1105eb822cb6a8fb461ee5b1bd881e0ef1b91c432b5Younes Manton                                    "[XvMC]   flags=0x%08X\n" \
1115eb822cb6a8fb461ee5b1bd881e0ef1b91c432b5Younes Manton                                    "[XvMC]   subpicture max width=%u, max height=%u\n",
1125eb822cb6a8fb461ee5b1bd881e0ef1b91c432b5Younes Manton                                    i, port, surface_type_id, max_width, max_height, *chroma_format,
1135eb822cb6a8fb461ee5b1bd881e0ef1b91c432b5Younes Manton                                    *mc_type, *surface_flags, *subpic_max_w, *subpic_max_h);
114e44c85637a3298918e292e9ddba812856cf92924Younes Manton            }
115e44c85637a3298918e292e9ddba812856cf92924Younes Manton
116d52d51ab8ae1240f77b6c18c3e99be4bf4868037Younes Manton            XFree(surface_info);
117e44c85637a3298918e292e9ddba812856cf92924Younes Manton         }
118e44c85637a3298918e292e9ddba812856cf92924Younes Manton      }
119e44c85637a3298918e292e9ddba812856cf92924Younes Manton
120e44c85637a3298918e292e9ddba812856cf92924Younes Manton      XvFreeAdaptorInfo(adaptor_info);
121e44c85637a3298918e292e9ddba812856cf92924Younes Manton   }
122e44c85637a3298918e292e9ddba812856cf92924Younes Manton
1238580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton   if (!*found_port) {
1248580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton      XVMC_MSG(XVMC_ERR, "[XvMC] Could not find a suitable port.\n");
125e44c85637a3298918e292e9ddba812856cf92924Younes Manton      return XvBadPort;
1268580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton   }
1278580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton   if (!found_surface) {
1288580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton      XVMC_MSG(XVMC_ERR, "[XvMC] Could not find a suitable surface.\n");
129e44c85637a3298918e292e9ddba812856cf92924Younes Manton      return BadMatch;
1308580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton   }
1318580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton   if (width > max_width || height > max_height) {
1328580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton      XVMC_MSG(XVMC_ERR, "[XvMC] Requested context dimensions (w=%u,h=%u) too large (max w=%u,h=%u).\n",
1338580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton               width, height, max_width, max_height);
134e44c85637a3298918e292e9ddba812856cf92924Younes Manton      return BadValue;
1358580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton   }
1368580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton   if (flags != XVMC_DIRECT && flags != 0) {
1378580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton      XVMC_MSG(XVMC_ERR, "[XvMC] Invalid context flags 0x%08X.\n", flags);
138e44c85637a3298918e292e9ddba812856cf92924Younes Manton      return BadValue;
1398580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton   }
140e44c85637a3298918e292e9ddba812856cf92924Younes Manton
141e44c85637a3298918e292e9ddba812856cf92924Younes Manton   return Success;
142c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton}
143c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton
144e44c85637a3298918e292e9ddba812856cf92924Younes Mantonstatic enum pipe_video_profile ProfileToPipe(int xvmc_profile)
1456858dd50c9b696c1c6044f5a403000f9d20b286bYounes Manton{
146e44c85637a3298918e292e9ddba812856cf92924Younes Manton   if (xvmc_profile & XVMC_MPEG_1)
147e44c85637a3298918e292e9ddba812856cf92924Younes Manton      assert(0);
148e44c85637a3298918e292e9ddba812856cf92924Younes Manton   if (xvmc_profile & XVMC_MPEG_2)
149e44c85637a3298918e292e9ddba812856cf92924Younes Manton      return PIPE_VIDEO_PROFILE_MPEG2_MAIN;
150e44c85637a3298918e292e9ddba812856cf92924Younes Manton   if (xvmc_profile & XVMC_H263)
151e44c85637a3298918e292e9ddba812856cf92924Younes Manton      assert(0);
152e44c85637a3298918e292e9ddba812856cf92924Younes Manton   if (xvmc_profile & XVMC_MPEG_4)
153e44c85637a3298918e292e9ddba812856cf92924Younes Manton      assert(0);
154e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton
155e44c85637a3298918e292e9ddba812856cf92924Younes Manton   assert(0);
156e44c85637a3298918e292e9ddba812856cf92924Younes Manton
1578580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton   XVMC_MSG(XVMC_ERR, "[XvMC] Unrecognized profile 0x%08X.\n", xvmc_profile);
1588580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton
159e44c85637a3298918e292e9ddba812856cf92924Younes Manton   return -1;
1606858dd50c9b696c1c6044f5a403000f9d20b286bYounes Manton}
1616858dd50c9b696c1c6044f5a403000f9d20b286bYounes Manton
162e44c85637a3298918e292e9ddba812856cf92924Younes Mantonstatic enum pipe_video_chroma_format FormatToPipe(int xvmc_format)
1636858dd50c9b696c1c6044f5a403000f9d20b286bYounes Manton{
164d52d51ab8ae1240f77b6c18c3e99be4bf4868037Younes Manton   switch (xvmc_format) {
165e44c85637a3298918e292e9ddba812856cf92924Younes Manton      case XVMC_CHROMA_FORMAT_420:
166e44c85637a3298918e292e9ddba812856cf92924Younes Manton         return PIPE_VIDEO_CHROMA_FORMAT_420;
167e44c85637a3298918e292e9ddba812856cf92924Younes Manton      case XVMC_CHROMA_FORMAT_422:
168e44c85637a3298918e292e9ddba812856cf92924Younes Manton         return PIPE_VIDEO_CHROMA_FORMAT_422;
169e44c85637a3298918e292e9ddba812856cf92924Younes Manton      case XVMC_CHROMA_FORMAT_444:
170e44c85637a3298918e292e9ddba812856cf92924Younes Manton         return PIPE_VIDEO_CHROMA_FORMAT_444;
171e44c85637a3298918e292e9ddba812856cf92924Younes Manton      default:
172e44c85637a3298918e292e9ddba812856cf92924Younes Manton         assert(0);
173e44c85637a3298918e292e9ddba812856cf92924Younes Manton   }
174e44c85637a3298918e292e9ddba812856cf92924Younes Manton
1758580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton   XVMC_MSG(XVMC_ERR, "[XvMC] Unrecognized format 0x%08X.\n", xvmc_format);
1768580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton
177e44c85637a3298918e292e9ddba812856cf92924Younes Manton   return -1;
1786858dd50c9b696c1c6044f5a403000f9d20b286bYounes Manton}
1796858dd50c9b696c1c6044f5a403000f9d20b286bYounes Manton
1803107b54b011c7ceef2b314632bdcf0b87c5e4d36Younes MantonPUBLIC
181e44c85637a3298918e292e9ddba812856cf92924Younes MantonStatus XvMCCreateContext(Display *dpy, XvPortID port, int surface_type_id,
182e44c85637a3298918e292e9ddba812856cf92924Younes Manton                         int width, int height, int flags, XvMCContext *context)
183c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton{
184e44c85637a3298918e292e9ddba812856cf92924Younes Manton   bool found_port;
1853d40d4f391e2fc319a03d8f171a2cfb9daf250c8Christian König   int scrn = 0;
1863d40d4f391e2fc319a03d8f171a2cfb9daf250c8Christian König   int chroma_format = 0;
1873d40d4f391e2fc319a03d8f171a2cfb9daf250c8Christian König   int mc_type = 0;
1883d40d4f391e2fc319a03d8f171a2cfb9daf250c8Christian König   int surface_flags = 0;
1893d40d4f391e2fc319a03d8f171a2cfb9daf250c8Christian König   unsigned short subpic_max_w = 0;
1903d40d4f391e2fc319a03d8f171a2cfb9daf250c8Christian König   unsigned short subpic_max_h = 0;
191e44c85637a3298918e292e9ddba812856cf92924Younes Manton   Status ret;
192e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton   struct vl_screen *vscreen;
1931448e829e86981e6144410ba6a3d0f16357fb2b3Christian König   struct pipe_context *pipe;
194e44c85637a3298918e292e9ddba812856cf92924Younes Manton   XvMCContextPrivate *context_priv;
19514766f820069ca987543918bce96410c481e5d20Christian König   vl_csc_matrix csc;
196e44c85637a3298918e292e9ddba812856cf92924Younes Manton
1978580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton   XVMC_MSG(XVMC_TRACE, "[XvMC] Creating context %p.\n", context);
1988580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton
199e44c85637a3298918e292e9ddba812856cf92924Younes Manton   assert(dpy);
200e44c85637a3298918e292e9ddba812856cf92924Younes Manton
201e44c85637a3298918e292e9ddba812856cf92924Younes Manton   if (!context)
202e44c85637a3298918e292e9ddba812856cf92924Younes Manton      return XvMCBadContext;
203e44c85637a3298918e292e9ddba812856cf92924Younes Manton
204e44c85637a3298918e292e9ddba812856cf92924Younes Manton   ret = Validate(dpy, port, surface_type_id, width, height, flags,
2055eb822cb6a8fb461ee5b1bd881e0ef1b91c432b5Younes Manton                  &found_port, &scrn, &chroma_format, &mc_type, &surface_flags,
2065eb822cb6a8fb461ee5b1bd881e0ef1b91c432b5Younes Manton                  &subpic_max_w, &subpic_max_h);
207e44c85637a3298918e292e9ddba812856cf92924Younes Manton
208e44c85637a3298918e292e9ddba812856cf92924Younes Manton   /* Success and XvBadPort have the same value */
209e44c85637a3298918e292e9ddba812856cf92924Younes Manton   if (ret != Success || !found_port)
210e44c85637a3298918e292e9ddba812856cf92924Younes Manton      return ret;
211e44c85637a3298918e292e9ddba812856cf92924Younes Manton
21270c44073ad3f333ed40c5c297a934a359c839e94Younes Manton   /* XXX: Current limits */
21370c44073ad3f333ed40c5c297a934a359c839e94Younes Manton   if (chroma_format != XVMC_CHROMA_FORMAT_420) {
2148580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton      XVMC_MSG(XVMC_ERR, "[XvMC] Cannot decode requested surface type. Unsupported chroma format.\n");
21570c44073ad3f333ed40c5c297a934a359c839e94Younes Manton      return BadImplementation;
21670c44073ad3f333ed40c5c297a934a359c839e94Younes Manton   }
217fcdf50f74befad8d89eb3f9cdfd88b82d1daa98cChristian König   if ((mc_type & ~XVMC_IDCT) != (XVMC_MOCOMP | XVMC_MPEG_2)) {
21842c7291d2cb50c2bd94dd9346a8402a24303d66dChristian König      XVMC_MSG(XVMC_ERR, "[XvMC] Cannot decode requested surface type. Non-MPEG2/Mocomp/iDCT acceleration unsupported.\n");
21970c44073ad3f333ed40c5c297a934a359c839e94Younes Manton      return BadImplementation;
22070c44073ad3f333ed40c5c297a934a359c839e94Younes Manton   }
2213cbe27a9888b94d1ab24b5e76ebd7563a7d8c6b8Christian König   if (surface_flags & XVMC_INTRA_UNSIGNED) {
2223cbe27a9888b94d1ab24b5e76ebd7563a7d8c6b8Christian König      XVMC_MSG(XVMC_ERR, "[XvMC] Cannot decode requested surface type. Unsigned intra unsupported.\n");
22370c44073ad3f333ed40c5c297a934a359c839e94Younes Manton      return BadImplementation;
22470c44073ad3f333ed40c5c297a934a359c839e94Younes Manton   }
22570c44073ad3f333ed40c5c297a934a359c839e94Younes Manton
226e44c85637a3298918e292e9ddba812856cf92924Younes Manton   context_priv = CALLOC(1, sizeof(XvMCContextPrivate));
227e44c85637a3298918e292e9ddba812856cf92924Younes Manton   if (!context_priv)
228e44c85637a3298918e292e9ddba812856cf92924Younes Manton      return BadAlloc;
229e44c85637a3298918e292e9ddba812856cf92924Younes Manton
230e44c85637a3298918e292e9ddba812856cf92924Younes Manton   /* TODO: Reuse screen if process creates another context */
231e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton   vscreen = vl_screen_create(dpy, scrn);
232e44c85637a3298918e292e9ddba812856cf92924Younes Manton
233e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton   if (!vscreen) {
2348580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton      XVMC_MSG(XVMC_ERR, "[XvMC] Could not create VL screen.\n");
235e44c85637a3298918e292e9ddba812856cf92924Younes Manton      FREE(context_priv);
236e44c85637a3298918e292e9ddba812856cf92924Younes Manton      return BadAlloc;
237e44c85637a3298918e292e9ddba812856cf92924Younes Manton   }
238e44c85637a3298918e292e9ddba812856cf92924Younes Manton
2391448e829e86981e6144410ba6a3d0f16357fb2b3Christian König   pipe = vscreen->pscreen->context_create(vscreen->pscreen, vscreen);
2401448e829e86981e6144410ba6a3d0f16357fb2b3Christian König   if (!pipe) {
2418580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton      XVMC_MSG(XVMC_ERR, "[XvMC] Could not create VL context.\n");
242e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton      vl_screen_destroy(vscreen);
243e44c85637a3298918e292e9ddba812856cf92924Younes Manton      FREE(context_priv);
244e44c85637a3298918e292e9ddba812856cf92924Younes Manton      return BadAlloc;
245e44c85637a3298918e292e9ddba812856cf92924Younes Manton   }
246e44c85637a3298918e292e9ddba812856cf92924Younes Manton
2471448e829e86981e6144410ba6a3d0f16357fb2b3Christian König   context_priv->decoder = pipe->create_video_decoder
248ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König   (
2491448e829e86981e6144410ba6a3d0f16357fb2b3Christian König      pipe, ProfileToPipe(mc_type),
250ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König      (mc_type & XVMC_IDCT) ? PIPE_VIDEO_ENTRYPOINT_IDCT : PIPE_VIDEO_ENTRYPOINT_MC,
251ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König      FormatToPipe(chroma_format),
2528c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König      width, height, 2,
2538c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König      true
254ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König   );
255d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
256d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   if (!context_priv->decoder) {
257d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König      XVMC_MSG(XVMC_ERR, "[XvMC] Could not create VL decoder.\n");
2581448e829e86981e6144410ba6a3d0f16357fb2b3Christian König      pipe->destroy(pipe);
259d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König      vl_screen_destroy(vscreen);
260d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König      FREE(context_priv);
261d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König      return BadAlloc;
262d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   }
263d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
2641448e829e86981e6144410ba6a3d0f16357fb2b3Christian König   if (!vl_compositor_init(&context_priv->compositor, pipe)) {
265e5f78a74f8294ee02015552db664dae1e7da9f47Christian König      XVMC_MSG(XVMC_ERR, "[XvMC] Could not create VL compositor.\n");
266d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König      context_priv->decoder->destroy(context_priv->decoder);
2671448e829e86981e6144410ba6a3d0f16357fb2b3Christian König      pipe->destroy(pipe);
268e5f78a74f8294ee02015552db664dae1e7da9f47Christian König      vl_screen_destroy(vscreen);
269e5f78a74f8294ee02015552db664dae1e7da9f47Christian König      FREE(context_priv);
270e5f78a74f8294ee02015552db664dae1e7da9f47Christian König      return BadAlloc;
271e5f78a74f8294ee02015552db664dae1e7da9f47Christian König   }
272e5f78a74f8294ee02015552db664dae1e7da9f47Christian König
27332c4381d4a0479b3d9bfe305ce701be6b5ac8e18Christian König   if (!vl_compositor_init_state(&context_priv->cstate, pipe)) {
27432c4381d4a0479b3d9bfe305ce701be6b5ac8e18Christian König      XVMC_MSG(XVMC_ERR, "[XvMC] Could not create VL compositor state.\n");
27532c4381d4a0479b3d9bfe305ce701be6b5ac8e18Christian König      vl_compositor_cleanup(&context_priv->compositor);
27632c4381d4a0479b3d9bfe305ce701be6b5ac8e18Christian König      context_priv->decoder->destroy(context_priv->decoder);
27732c4381d4a0479b3d9bfe305ce701be6b5ac8e18Christian König      pipe->destroy(pipe);
27832c4381d4a0479b3d9bfe305ce701be6b5ac8e18Christian König      vl_screen_destroy(vscreen);
27932c4381d4a0479b3d9bfe305ce701be6b5ac8e18Christian König      FREE(context_priv);
28032c4381d4a0479b3d9bfe305ce701be6b5ac8e18Christian König      return BadAlloc;
28132c4381d4a0479b3d9bfe305ce701be6b5ac8e18Christian König   }
28232c4381d4a0479b3d9bfe305ce701be6b5ac8e18Christian König
28332c4381d4a0479b3d9bfe305ce701be6b5ac8e18Christian König
284c7b65dcaffeb9d0760c8ecad052f4c79297bfc8aChristian König   context_priv->color_standard =
285c7b65dcaffeb9d0760c8ecad052f4c79297bfc8aChristian König      debug_get_bool_option("G3DVL_NO_CSC", FALSE) ?
286c7b65dcaffeb9d0760c8ecad052f4c79297bfc8aChristian König      VL_CSC_COLOR_STANDARD_IDENTITY : VL_CSC_COLOR_STANDARD_BT_601;
287c7b65dcaffeb9d0760c8ecad052f4c79297bfc8aChristian König   context_priv->procamp = vl_default_procamp;
288c7b65dcaffeb9d0760c8ecad052f4c79297bfc8aChristian König
28962db9b21da6ccad6301feae9b90d53d46224c854Younes Manton   vl_csc_get_matrix
29062db9b21da6ccad6301feae9b90d53d46224c854Younes Manton   (
291c7b65dcaffeb9d0760c8ecad052f4c79297bfc8aChristian König      context_priv->color_standard,
29214766f820069ca987543918bce96410c481e5d20Christian König      &context_priv->procamp, true, &csc
29362db9b21da6ccad6301feae9b90d53d46224c854Younes Manton   );
29414766f820069ca987543918bce96410c481e5d20Christian König   vl_compositor_set_csc_matrix(&context_priv->cstate, (const vl_csc_matrix *)&csc);
29562db9b21da6ccad6301feae9b90d53d46224c854Younes Manton
2961448e829e86981e6144410ba6a3d0f16357fb2b3Christian König   context_priv->vscreen = vscreen;
2971448e829e86981e6144410ba6a3d0f16357fb2b3Christian König   context_priv->pipe = pipe;
2985eb822cb6a8fb461ee5b1bd881e0ef1b91c432b5Younes Manton   context_priv->subpicture_max_width = subpic_max_w;
2995eb822cb6a8fb461ee5b1bd881e0ef1b91c432b5Younes Manton   context_priv->subpicture_max_height = subpic_max_h;
300e44c85637a3298918e292e9ddba812856cf92924Younes Manton
301e44c85637a3298918e292e9ddba812856cf92924Younes Manton   context->context_id = XAllocID(dpy);
302e44c85637a3298918e292e9ddba812856cf92924Younes Manton   context->surface_type_id = surface_type_id;
303e44c85637a3298918e292e9ddba812856cf92924Younes Manton   context->width = width;
304e44c85637a3298918e292e9ddba812856cf92924Younes Manton   context->height = height;
305e44c85637a3298918e292e9ddba812856cf92924Younes Manton   context->flags = flags;
306e44c85637a3298918e292e9ddba812856cf92924Younes Manton   context->port = port;
307e44c85637a3298918e292e9ddba812856cf92924Younes Manton   context->privData = context_priv;
308e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton
309e44c85637a3298918e292e9ddba812856cf92924Younes Manton   SyncHandle();
310e44c85637a3298918e292e9ddba812856cf92924Younes Manton
3118580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton   XVMC_MSG(XVMC_TRACE, "[XvMC] Context %p created.\n", context);
3128580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton
313e44c85637a3298918e292e9ddba812856cf92924Younes Manton   return Success;
314c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton}
315c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton
3163107b54b011c7ceef2b314632bdcf0b87c5e4d36Younes MantonPUBLIC
317e44c85637a3298918e292e9ddba812856cf92924Younes MantonStatus XvMCDestroyContext(Display *dpy, XvMCContext *context)
318c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton{
319e44c85637a3298918e292e9ddba812856cf92924Younes Manton   XvMCContextPrivate *context_priv;
3206858dd50c9b696c1c6044f5a403000f9d20b286bYounes Manton
3218580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton   XVMC_MSG(XVMC_TRACE, "[XvMC] Destroying context %p.\n", context);
3228580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton
323e44c85637a3298918e292e9ddba812856cf92924Younes Manton   assert(dpy);
324c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton
325e44c85637a3298918e292e9ddba812856cf92924Younes Manton   if (!context || !context->privData)
326e44c85637a3298918e292e9ddba812856cf92924Younes Manton      return XvMCBadContext;
32790bd0e338d315c426c2d0255331610055023739eYounes Manton
328e44c85637a3298918e292e9ddba812856cf92924Younes Manton   context_priv = context->privData;
329d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   context_priv->decoder->destroy(context_priv->decoder);
33032c4381d4a0479b3d9bfe305ce701be6b5ac8e18Christian König   vl_compositor_cleanup_state(&context_priv->cstate);
331bd5fd67a3e3cda4b7676dd4745fc5d5524709210Christian König   vl_compositor_cleanup(&context_priv->compositor);
3321448e829e86981e6144410ba6a3d0f16357fb2b3Christian König   context_priv->pipe->destroy(context_priv->pipe);
3331448e829e86981e6144410ba6a3d0f16357fb2b3Christian König   vl_screen_destroy(context_priv->vscreen);
334e44c85637a3298918e292e9ddba812856cf92924Younes Manton   FREE(context_priv);
335e44c85637a3298918e292e9ddba812856cf92924Younes Manton   context->privData = NULL;
33690bd0e338d315c426c2d0255331610055023739eYounes Manton
3378580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton   XVMC_MSG(XVMC_TRACE, "[XvMC] Context %p destroyed.\n", context);
3388580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton
339e44c85637a3298918e292e9ddba812856cf92924Younes Manton   return Success;
34090bd0e338d315c426c2d0255331610055023739eYounes Manton}
341