1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/**************************************************************************
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2009 Younes Manton.
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * All Rights Reserved.
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Software"), to deal in the Software without restriction, including
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * without limitation the rights to use, copy, modify, merge, publish,
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * distribute, sub license, and/or sell copies of the Software, and to
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * permit persons to whom the Software is furnished to do so, subject to
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the following conditions:
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * next paragraph) shall be included in all copies or substantial portions
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of the Software.
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org *
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org **************************************************************************/
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <assert.h>
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <X11/Xlibint.h>
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <X11/extensions/XvMClib.h>
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_screen.h"
34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_video_decoder.h"
35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_video_state.h"
36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_state.h"
37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_memory.h"
39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "vl/vl_csc.h"
41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "vl/vl_winsys.h"
42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "xvmc_private.h"
44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic Status Validate(Display *dpy, XvPortID port, int surface_type_id,
46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       unsigned int width, unsigned int height, int flags,
47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       bool *found_port, int *screen, int *chroma_format,
48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       int *mc_type, int *surface_flags,
49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       unsigned short *subpic_max_w,
50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                       unsigned short *subpic_max_h)
51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   bool found_surface = false;
53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   XvAdaptorInfo *adaptor_info;
54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned int num_adaptors;
55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int num_types;
56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned int max_width = 0, max_height = 0;
57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   Status ret;
58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(dpy);
60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(found_port);
61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(screen);
62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(chroma_format);
63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(mc_type);
64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(surface_flags);
65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(subpic_max_w);
66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(subpic_max_h);
67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   *found_port = false;
69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   for (unsigned int i = 0; i < XScreenCount(dpy); ++i) {
71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      ret = XvQueryAdaptors(dpy, XRootWindow(dpy, i), &num_adaptors, &adaptor_info);
72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      if (ret != Success)
73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return ret;
74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      for (unsigned int j = 0; j < num_adaptors && !*found_port; ++j) {
76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         for (unsigned int k = 0; k < adaptor_info[j].num_ports && !*found_port; ++k) {
77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            XvMCSurfaceInfo *surface_info;
78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (adaptor_info[j].base_id + k != port)
80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               continue;
81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            *found_port = true;
83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            surface_info = XvMCListSurfaceTypes(dpy, adaptor_info[j].base_id, &num_types);
85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            if (!surface_info) {
86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               XvFreeAdaptorInfo(adaptor_info);
87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               return BadAlloc;
88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            for (unsigned int l = 0; l < num_types && !found_surface; ++l) {
91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               if (surface_info[l].surface_type_id != surface_type_id)
92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  continue;
93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               found_surface = true;
95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               max_width = surface_info[l].max_width;
96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               max_height = surface_info[l].max_height;
97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               *chroma_format = surface_info[l].chroma_format;
98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               *mc_type = surface_info[l].mc_type;
99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               *surface_flags = surface_info[l].flags;
100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               *subpic_max_w = surface_info[l].subpicture_max_width;
101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               *subpic_max_h = surface_info[l].subpicture_max_height;
102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               *screen = i;
103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               XVMC_MSG(XVMC_TRACE, "[XvMC] Found requested context surface format.\n" \
105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    "[XvMC]   screen=%u, port=%u\n" \
106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    "[XvMC]   id=0x%08X\n" \
107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    "[XvMC]   max width=%u, max height=%u\n" \
108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    "[XvMC]   chroma format=0x%08X\n" \
109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    "[XvMC]   acceleration level=0x%08X\n" \
110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    "[XvMC]   flags=0x%08X\n" \
111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    "[XvMC]   subpicture max width=%u, max height=%u\n",
112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    i, port, surface_type_id, max_width, max_height, *chroma_format,
113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                                    *mc_type, *surface_flags, *subpic_max_w, *subpic_max_h);
114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            }
115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org            XFree(surface_info);
117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         }
118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      }
119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      XvFreeAdaptorInfo(adaptor_info);
121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!*found_port) {
124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      XVMC_MSG(XVMC_ERR, "[XvMC] Could not find a suitable port.\n");
125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return XvBadPort;
126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!found_surface) {
128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      XVMC_MSG(XVMC_ERR, "[XvMC] Could not find a suitable surface.\n");
129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return BadMatch;
130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (width > max_width || height > max_height) {
132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      XVMC_MSG(XVMC_ERR, "[XvMC] Requested context dimensions (w=%u,h=%u) too large (max w=%u,h=%u).\n",
133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org               width, height, max_width, max_height);
134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return BadValue;
135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (flags != XVMC_DIRECT && flags != 0) {
137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      XVMC_MSG(XVMC_ERR, "[XvMC] Invalid context flags 0x%08X.\n", flags);
138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return BadValue;
139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return Success;
142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic enum pipe_video_profile ProfileToPipe(int xvmc_profile)
145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (xvmc_profile & XVMC_MPEG_1)
147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(0);
148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (xvmc_profile & XVMC_MPEG_2)
149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return PIPE_VIDEO_PROFILE_MPEG2_MAIN;
150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (xvmc_profile & XVMC_H263)
151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(0);
152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (xvmc_profile & XVMC_MPEG_4)
153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      assert(0);
154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(0);
156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   XVMC_MSG(XVMC_ERR, "[XvMC] Unrecognized profile 0x%08X.\n", xvmc_profile);
158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return -1;
160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic enum pipe_video_chroma_format FormatToPipe(int xvmc_format)
163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   switch (xvmc_format) {
165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case XVMC_CHROMA_FORMAT_420:
166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return PIPE_VIDEO_CHROMA_FORMAT_420;
167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case XVMC_CHROMA_FORMAT_422:
168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return PIPE_VIDEO_CHROMA_FORMAT_422;
169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      case XVMC_CHROMA_FORMAT_444:
170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         return PIPE_VIDEO_CHROMA_FORMAT_444;
171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      default:
172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org         assert(0);
173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   XVMC_MSG(XVMC_ERR, "[XvMC] Unrecognized format 0x%08X.\n", xvmc_format);
176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return -1;
178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgPUBLIC
181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgStatus XvMCCreateContext(Display *dpy, XvPortID port, int surface_type_id,
182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                         int width, int height, int flags, XvMCContext *context)
183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   bool found_port;
185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int scrn = 0;
186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int chroma_format = 0;
187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int mc_type = 0;
188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   int surface_flags = 0;
189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned short subpic_max_w = 0;
190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   unsigned short subpic_max_h = 0;
191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   Status ret;
192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct vl_screen *vscreen;
193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   struct pipe_context *pipe;
194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   XvMCContextPrivate *context_priv;
195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   vl_csc_matrix csc;
196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   XVMC_MSG(XVMC_TRACE, "[XvMC] Creating context %p.\n", context);
198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(dpy);
200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!context)
202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return XvMCBadContext;
203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   ret = Validate(dpy, port, surface_type_id, width, height, flags,
205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  &found_port, &scrn, &chroma_format, &mc_type, &surface_flags,
206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org                  &subpic_max_w, &subpic_max_h);
207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* Success and XvBadPort have the same value */
209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (ret != Success || !found_port)
210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return ret;
211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* XXX: Current limits */
213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (chroma_format != XVMC_CHROMA_FORMAT_420) {
214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      XVMC_MSG(XVMC_ERR, "[XvMC] Cannot decode requested surface type. Unsupported chroma format.\n");
215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return BadImplementation;
216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if ((mc_type & ~XVMC_IDCT) != (XVMC_MOCOMP | XVMC_MPEG_2)) {
218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      XVMC_MSG(XVMC_ERR, "[XvMC] Cannot decode requested surface type. Non-MPEG2/Mocomp/iDCT acceleration unsupported.\n");
219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return BadImplementation;
220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (surface_flags & XVMC_INTRA_UNSIGNED) {
222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      XVMC_MSG(XVMC_ERR, "[XvMC] Cannot decode requested surface type. Unsigned intra unsupported.\n");
223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return BadImplementation;
224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   context_priv = CALLOC(1, sizeof(XvMCContextPrivate));
227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!context_priv)
228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return BadAlloc;
229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   /* TODO: Reuse screen if process creates another context */
231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   vscreen = vl_screen_create(dpy, scrn);
232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!vscreen) {
234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      XVMC_MSG(XVMC_ERR, "[XvMC] Could not create VL screen.\n");
235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      FREE(context_priv);
236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return BadAlloc;
237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   pipe = vscreen->pscreen->context_create(vscreen->pscreen, vscreen);
240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!pipe) {
241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      XVMC_MSG(XVMC_ERR, "[XvMC] Could not create VL context.\n");
242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      vl_screen_destroy(vscreen);
243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      FREE(context_priv);
244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return BadAlloc;
245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   context_priv->decoder = pipe->create_video_decoder
248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (
249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pipe, ProfileToPipe(mc_type),
250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      (mc_type & XVMC_IDCT) ? PIPE_VIDEO_ENTRYPOINT_IDCT : PIPE_VIDEO_ENTRYPOINT_MC,
251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      FormatToPipe(chroma_format),
252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      width, height, 2,
253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      true
254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   );
255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!context_priv->decoder) {
257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      XVMC_MSG(XVMC_ERR, "[XvMC] Could not create VL decoder.\n");
258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pipe->destroy(pipe);
259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      vl_screen_destroy(vscreen);
260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      FREE(context_priv);
261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return BadAlloc;
262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!vl_compositor_init(&context_priv->compositor, pipe)) {
265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      XVMC_MSG(XVMC_ERR, "[XvMC] Could not create VL compositor.\n");
266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      context_priv->decoder->destroy(context_priv->decoder);
267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pipe->destroy(pipe);
268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      vl_screen_destroy(vscreen);
269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      FREE(context_priv);
270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return BadAlloc;
271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!vl_compositor_init_state(&context_priv->cstate, pipe)) {
274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      XVMC_MSG(XVMC_ERR, "[XvMC] Could not create VL compositor state.\n");
275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      vl_compositor_cleanup(&context_priv->compositor);
276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      context_priv->decoder->destroy(context_priv->decoder);
277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      pipe->destroy(pipe);
278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      vl_screen_destroy(vscreen);
279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      FREE(context_priv);
280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return BadAlloc;
281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   }
282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   context_priv->color_standard =
285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      debug_get_bool_option("G3DVL_NO_CSC", FALSE) ?
286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      VL_CSC_COLOR_STANDARD_IDENTITY : VL_CSC_COLOR_STANDARD_BT_601;
287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   context_priv->procamp = vl_default_procamp;
288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   vl_csc_get_matrix
290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   (
291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      context_priv->color_standard,
292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      &context_priv->procamp, true, &csc
293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   );
294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   vl_compositor_set_csc_matrix(&context_priv->cstate, (const vl_csc_matrix *)&csc);
295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   context_priv->vscreen = vscreen;
297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   context_priv->pipe = pipe;
298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   context_priv->subpicture_max_width = subpic_max_w;
299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   context_priv->subpicture_max_height = subpic_max_h;
300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   context->context_id = XAllocID(dpy);
302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   context->surface_type_id = surface_type_id;
303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   context->width = width;
304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   context->height = height;
305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   context->flags = flags;
306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   context->port = port;
307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   context->privData = context_priv;
308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   SyncHandle();
310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   XVMC_MSG(XVMC_TRACE, "[XvMC] Context %p created.\n", context);
312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return Success;
314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgPUBLIC
317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgStatus XvMCDestroyContext(Display *dpy, XvMCContext *context)
318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{
319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   XvMCContextPrivate *context_priv;
320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   XVMC_MSG(XVMC_TRACE, "[XvMC] Destroying context %p.\n", context);
322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   assert(dpy);
324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   if (!context || !context->privData)
326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return XvMCBadContext;
327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   context_priv = context->privData;
329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   context_priv->decoder->destroy(context_priv->decoder);
330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   vl_compositor_cleanup_state(&context_priv->cstate);
331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   vl_compositor_cleanup(&context_priv->compositor);
332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   context_priv->pipe->destroy(context_priv->pipe);
333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   vl_screen_destroy(context_priv->vscreen);
334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   FREE(context_priv);
335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   context->privData = NULL;
336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   XVMC_MSG(XVMC_TRACE, "[XvMC] Context %p destroyed.\n", context);
338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org   return Success;
340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
341