context.c revision 8c2bfa34a0d70ab08de44e3b091b3a097abbad97
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"
417ea550621e25f9b2f344b2ed60551ceec91b3fcfKai Wasserbäch#include "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;
193e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton   struct vl_context *vctx;
194e44c85637a3298918e292e9ddba812856cf92924Younes Manton   XvMCContextPrivate *context_priv;
19562db9b21da6ccad6301feae9b90d53d46224c854Younes Manton   float csc[16];
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
239d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   vctx = vl_video_create(vscreen);
240e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton   if (!vctx) {
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
247ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König   context_priv->decoder = vctx->pipe->create_video_decoder
248ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König   (
249ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König      vctx->pipe,
250ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König      ProfileToPipe(mc_type),
251ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König      (mc_type & XVMC_IDCT) ? PIPE_VIDEO_ENTRYPOINT_IDCT : PIPE_VIDEO_ENTRYPOINT_MC,
252ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König      FormatToPipe(chroma_format),
2538c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König      width, height, 2,
2548c2bfa34a0d70ab08de44e3b091b3a097abbad97Christian König      true
255ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König   );
256d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
257d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   if (!context_priv->decoder) {
258d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König      XVMC_MSG(XVMC_ERR, "[XvMC] Could not create VL decoder.\n");
259d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König      vl_video_destroy(vctx);
260d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König      vl_screen_destroy(vscreen);
261d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König      FREE(context_priv);
262d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König      return BadAlloc;
263d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   }
264d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
265bd5fd67a3e3cda4b7676dd4745fc5d5524709210Christian König   if (!vl_compositor_init(&context_priv->compositor, vctx->pipe)) {
266e5f78a74f8294ee02015552db664dae1e7da9f47Christian König      XVMC_MSG(XVMC_ERR, "[XvMC] Could not create VL compositor.\n");
267d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König      context_priv->decoder->destroy(context_priv->decoder);
268e5f78a74f8294ee02015552db664dae1e7da9f47Christian König      vl_video_destroy(vctx);
269e5f78a74f8294ee02015552db664dae1e7da9f47Christian König      vl_screen_destroy(vscreen);
270e5f78a74f8294ee02015552db664dae1e7da9f47Christian König      FREE(context_priv);
271e5f78a74f8294ee02015552db664dae1e7da9f47Christian König      return BadAlloc;
272e5f78a74f8294ee02015552db664dae1e7da9f47Christian König   }
273e5f78a74f8294ee02015552db664dae1e7da9f47Christian König
274c7b65dcaffeb9d0760c8ecad052f4c79297bfc8aChristian König   context_priv->color_standard =
275c7b65dcaffeb9d0760c8ecad052f4c79297bfc8aChristian König      debug_get_bool_option("G3DVL_NO_CSC", FALSE) ?
276c7b65dcaffeb9d0760c8ecad052f4c79297bfc8aChristian König      VL_CSC_COLOR_STANDARD_IDENTITY : VL_CSC_COLOR_STANDARD_BT_601;
277c7b65dcaffeb9d0760c8ecad052f4c79297bfc8aChristian König   context_priv->procamp = vl_default_procamp;
278c7b65dcaffeb9d0760c8ecad052f4c79297bfc8aChristian König
27962db9b21da6ccad6301feae9b90d53d46224c854Younes Manton   vl_csc_get_matrix
28062db9b21da6ccad6301feae9b90d53d46224c854Younes Manton   (
281c7b65dcaffeb9d0760c8ecad052f4c79297bfc8aChristian König      context_priv->color_standard,
282c7b65dcaffeb9d0760c8ecad052f4c79297bfc8aChristian König      &context_priv->procamp, true, csc
28362db9b21da6ccad6301feae9b90d53d46224c854Younes Manton   );
284bd5fd67a3e3cda4b7676dd4745fc5d5524709210Christian König   vl_compositor_set_csc_matrix(&context_priv->compositor, csc);
28562db9b21da6ccad6301feae9b90d53d46224c854Younes Manton
286e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton   context_priv->vctx = vctx;
2875eb822cb6a8fb461ee5b1bd881e0ef1b91c432b5Younes Manton   context_priv->subpicture_max_width = subpic_max_w;
2885eb822cb6a8fb461ee5b1bd881e0ef1b91c432b5Younes Manton   context_priv->subpicture_max_height = subpic_max_h;
289e44c85637a3298918e292e9ddba812856cf92924Younes Manton
290e44c85637a3298918e292e9ddba812856cf92924Younes Manton   context->context_id = XAllocID(dpy);
291e44c85637a3298918e292e9ddba812856cf92924Younes Manton   context->surface_type_id = surface_type_id;
292e44c85637a3298918e292e9ddba812856cf92924Younes Manton   context->width = width;
293e44c85637a3298918e292e9ddba812856cf92924Younes Manton   context->height = height;
294e44c85637a3298918e292e9ddba812856cf92924Younes Manton   context->flags = flags;
295e44c85637a3298918e292e9ddba812856cf92924Younes Manton   context->port = port;
296e44c85637a3298918e292e9ddba812856cf92924Younes Manton   context->privData = context_priv;
297e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton
298e44c85637a3298918e292e9ddba812856cf92924Younes Manton   SyncHandle();
299e44c85637a3298918e292e9ddba812856cf92924Younes Manton
3008580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton   XVMC_MSG(XVMC_TRACE, "[XvMC] Context %p created.\n", context);
3018580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton
302e44c85637a3298918e292e9ddba812856cf92924Younes Manton   return Success;
303c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton}
304c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton
3053107b54b011c7ceef2b314632bdcf0b87c5e4d36Younes MantonPUBLIC
306e44c85637a3298918e292e9ddba812856cf92924Younes MantonStatus XvMCDestroyContext(Display *dpy, XvMCContext *context)
307c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton{
308e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton   struct vl_screen *vscreen;
309e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton   struct vl_context *vctx;
310e44c85637a3298918e292e9ddba812856cf92924Younes Manton   XvMCContextPrivate *context_priv;
3116858dd50c9b696c1c6044f5a403000f9d20b286bYounes Manton
3128580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton   XVMC_MSG(XVMC_TRACE, "[XvMC] Destroying context %p.\n", context);
3138580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton
314e44c85637a3298918e292e9ddba812856cf92924Younes Manton   assert(dpy);
315c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton
316e44c85637a3298918e292e9ddba812856cf92924Younes Manton   if (!context || !context->privData)
317e44c85637a3298918e292e9ddba812856cf92924Younes Manton      return XvMCBadContext;
31890bd0e338d315c426c2d0255331610055023739eYounes Manton
319e44c85637a3298918e292e9ddba812856cf92924Younes Manton   context_priv = context->privData;
320e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton   vctx = context_priv->vctx;
321e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton   vscreen = vctx->vscreen;
322f3f212acf0d2fc25d3b6bd70dd1f346d97a9b25dChristian König   pipe_surface_reference(&context_priv->drawable_surface, NULL);
323d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   context_priv->decoder->destroy(context_priv->decoder);
324bd5fd67a3e3cda4b7676dd4745fc5d5524709210Christian König   vl_compositor_cleanup(&context_priv->compositor);
325e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton   vl_video_destroy(vctx);
326e60a8e4fcf2b4073a5fc2d9ec1de5a6ca6c7b9feYounes Manton   vl_screen_destroy(vscreen);
327e44c85637a3298918e292e9ddba812856cf92924Younes Manton   FREE(context_priv);
328e44c85637a3298918e292e9ddba812856cf92924Younes Manton   context->privData = NULL;
32990bd0e338d315c426c2d0255331610055023739eYounes Manton
3308580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton   XVMC_MSG(XVMC_TRACE, "[XvMC] Context %p destroyed.\n", context);
3318580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton
332e44c85637a3298918e292e9ddba812856cf92924Younes Manton   return Success;
33390bd0e338d315c426c2d0255331610055023739eYounes Manton}
334