surface.c revision 9d9afcb5bac2931d4b8e6d1aa571e941c5110c90
1fcb595c04f9ee275eae49b7bb7c61246671f5ce2Younes Manton/**************************************************************************
2cbb7226a4b457a3ebc94592660f22324c8e7cfccYounes Manton *
3fcb595c04f9ee275eae49b7bb7c61246671f5ce2Younes Manton * Copyright 2009 Younes Manton.
4fcb595c04f9ee275eae49b7bb7c61246671f5ce2Younes Manton * All Rights Reserved.
5cbb7226a4b457a3ebc94592660f22324c8e7cfccYounes 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:
13cbb7226a4b457a3ebc94592660f22324c8e7cfccYounes 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.
17cbb7226a4b457a3ebc94592660f22324c8e7cfccYounes 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.
25cbb7226a4b457a3ebc94592660f22324c8e7cfccYounes Manton *
26fcb595c04f9ee275eae49b7bb7c61246671f5ce2Younes Manton **************************************************************************/
27fcb595c04f9ee275eae49b7bb7c61246671f5ce2Younes Manton
28c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton#include <assert.h>
299cff90534389c2aad9b58ff04b1a5d624e3d0bdbChristian König#include <stdio.h>
30b48676672592271597d07e5ece79cf4d3ffbe04bChristian König
312ef8c60e558938686196bf8ff4d22fd57903bf4cCooper Yuan#include <X11/Xlibint.h>
32b48676672592271597d07e5ece79cf4d3ffbe04bChristian König
337ea550621e25f9b2f344b2ed60551ceec91b3fcfKai Wasserbäch#include "pipe/p_video_decoder.h"
347ea550621e25f9b2f344b2ed60551ceec91b3fcfKai Wasserbäch#include "pipe/p_video_state.h"
357ea550621e25f9b2f344b2ed60551ceec91b3fcfKai Wasserbäch#include "pipe/p_state.h"
36b48676672592271597d07e5ece79cf4d3ffbe04bChristian König
377ea550621e25f9b2f344b2ed60551ceec91b3fcfKai Wasserbäch#include "util/u_inlines.h"
387ea550621e25f9b2f344b2ed60551ceec91b3fcfKai Wasserbäch#include "util/u_memory.h"
397ea550621e25f9b2f344b2ed60551ceec91b3fcfKai Wasserbäch#include "util/u_math.h"
40b48676672592271597d07e5ece79cf4d3ffbe04bChristian König
417ea550621e25f9b2f344b2ed60551ceec91b3fcfKai Wasserbäch#include "vl_winsys.h"
42b48676672592271597d07e5ece79cf4d3ffbe04bChristian König
43e44c85637a3298918e292e9ddba812856cf92924Younes Manton#include "xvmc_private.h"
44c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton
45e44c85637a3298918e292e9ddba812856cf92924Younes Mantonstatic void
46d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian KönigMacroBlocksToPipe(XvMCContextPrivate *context,
47d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König                  XvMCSurfacePrivate *surface,
4834e5ae5aed8187e0f6395dee2985091cea3a6df6Christian König                  unsigned int xvmc_picture_structure,
494d057864d0d523c241e40ad675487276789e3b36Christian König                  const XvMCMacroBlock *xvmc_mb,
50e44c85637a3298918e292e9ddba812856cf92924Younes Manton                  const XvMCBlockArray *xvmc_blocks,
51d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König                  struct pipe_mpeg12_macroblock *mb,
522e6274fc3b123e7de695038054b5cbd20b11559aChristian König                  unsigned int num_macroblocks)
53e44c85637a3298918e292e9ddba812856cf92924Younes Manton{
54d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König   unsigned int i, j, k;
55e44c85637a3298918e292e9ddba812856cf92924Younes Manton
564d057864d0d523c241e40ad675487276789e3b36Christian König   assert(xvmc_mb);
57e44c85637a3298918e292e9ddba812856cf92924Younes Manton   assert(xvmc_blocks);
58e44c85637a3298918e292e9ddba812856cf92924Younes Manton   assert(num_macroblocks);
59e44c85637a3298918e292e9ddba812856cf92924Younes Manton
60d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König   for (; num_macroblocks > 0; --num_macroblocks) {
61d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König      mb->base.codec = PIPE_VIDEO_CODEC_MPEG12;
62d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König      mb->x = xvmc_mb->x;
63d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König      mb->y = xvmc_mb->y;
64d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König      mb->macroblock_type = xvmc_mb->macroblock_type;
65e44c85637a3298918e292e9ddba812856cf92924Younes Manton
66d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König      switch (xvmc_picture_structure) {
67d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König      case XVMC_FRAME_PICTURE:
68d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König         mb->macroblock_modes.bits.frame_motion_type = xvmc_mb->motion_type;
69d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König         mb->macroblock_modes.bits.field_motion_type = 0;
70d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König         break;
717a5390b06fea99f85ab47d40d8dc40e40e0f2ab8Christian König
72d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König      case XVMC_TOP_FIELD:
73d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König      case XVMC_BOTTOM_FIELD:
74d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König         mb->macroblock_modes.bits.frame_motion_type = 0;
75d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König         mb->macroblock_modes.bits.field_motion_type = xvmc_mb->motion_type;
76d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König         break;
77e44c85637a3298918e292e9ddba812856cf92924Younes Manton
78d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König      default:
79d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König         assert(0);
80b7acf83d523563cde613fe805bd8edaa02f64b53Christian König      }
81e44c85637a3298918e292e9ddba812856cf92924Younes Manton
82d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König      mb->macroblock_modes.bits.dct_type = xvmc_mb->dct_type;
83d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König      mb->motion_vertical_field_select = xvmc_mb->motion_vertical_field_select;
84d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König
85d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König      for (i = 0; i < 2; ++i)
86d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König         for (j = 0; j < 2; ++j)
87d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König            for (k = 0; k < 2; ++k)
88d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König               mb->PMV[i][j][k] = xvmc_mb->PMV[i][j][k];
89d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König
90d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König      mb->coded_block_pattern = xvmc_mb->coded_block_pattern;
91d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König      mb->blocks = xvmc_blocks->blocks + xvmc_mb->index * BLOCK_SIZE_SAMPLES;
92d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König      mb->num_skipped_macroblocks = 0;
93d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König
94e44c85637a3298918e292e9ddba812856cf92924Younes Manton      ++xvmc_mb;
95d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König      ++mb;
96e44c85637a3298918e292e9ddba812856cf92924Younes Manton   }
97e44c85637a3298918e292e9ddba812856cf92924Younes Manton}
986858dd50c9b696c1c6044f5a403000f9d20b286bYounes Manton
99884cb79edfefb1133229a002f41b4d370d717a7eChristian Königstatic void
1008ea416f35de0c664ef47b71841756758f22d7faaChristian KönigGetPictureDescription(XvMCSurfacePrivate *surface, struct pipe_mpeg12_picture_desc *desc)
101884cb79edfefb1133229a002f41b4d370d717a7eChristian König{
1021d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König   unsigned i, num_refs = 0;
1031d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König
1048ea416f35de0c664ef47b71841756758f22d7faaChristian König   assert(surface && desc);
1051d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König
1068ea416f35de0c664ef47b71841756758f22d7faaChristian König   memset(desc, 0, sizeof(*desc));
1078ea416f35de0c664ef47b71841756758f22d7faaChristian König   desc->base.profile = PIPE_VIDEO_PROFILE_MPEG1;
1088ea416f35de0c664ef47b71841756758f22d7faaChristian König   desc->picture_structure = surface->picture_structure;
1091d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König   for (i = 0; i < 2; ++i) {
110d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König      if (surface->ref[i]) {
111d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König         XvMCSurfacePrivate *ref = surface->ref[i]->privData;
1121d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König
1131d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König         if (ref)
1148ea416f35de0c664ef47b71841756758f22d7faaChristian König            desc->ref[num_refs++] = ref->video_buffer;
1151d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König      }
1161d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König   }
1171d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König}
1181d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König
1191d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian Königstatic void
1201d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian KönigRecursiveEndFrame(XvMCSurfacePrivate *surface)
1211d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König{
122d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   XvMCContextPrivate *context_priv;
123d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König   unsigned i;
124884cb79edfefb1133229a002f41b4d370d717a7eChristian König
125884cb79edfefb1133229a002f41b4d370d717a7eChristian König   assert(surface);
126884cb79edfefb1133229a002f41b4d370d717a7eChristian König
127d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   context_priv = surface->context->privData;
128d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
1293e92b4fd14b731bd6984aafd220059e27948aea8Christian König   for ( i = 0; i < 2; ++i ) {
130d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König      if (surface->ref[i]) {
131d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König         XvMCSurface *ref = surface->ref[i];
132884cb79edfefb1133229a002f41b4d370d717a7eChristian König
133884cb79edfefb1133229a002f41b4d370d717a7eChristian König         assert(ref);
134884cb79edfefb1133229a002f41b4d370d717a7eChristian König
135d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König         surface->ref[i] = NULL;
1361d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König         RecursiveEndFrame(ref->privData);
137d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König         surface->ref[i] = ref;
138884cb79edfefb1133229a002f41b4d370d717a7eChristian König      }
139884cb79edfefb1133229a002f41b4d370d717a7eChristian König   }
140884cb79edfefb1133229a002f41b4d370d717a7eChristian König
141a09754c15fc48e5fed347f478a301a02ee69fe8cMaarten Lankhorst   if (surface->picture_structure) {
1428ea416f35de0c664ef47b71841756758f22d7faaChristian König      struct pipe_mpeg12_picture_desc desc;
1438ea416f35de0c664ef47b71841756758f22d7faaChristian König      GetPictureDescription(surface, &desc);
144a09754c15fc48e5fed347f478a301a02ee69fe8cMaarten Lankhorst      surface->picture_structure = 0;
1451d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König
1461d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König      for (i = 0; i < 2; ++i)
147d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König         surface->ref[i] = NULL;
1481d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König
1498ea416f35de0c664ef47b71841756758f22d7faaChristian König      context_priv->decoder->end_frame(context_priv->decoder, surface->video_buffer, &desc.base);
150884cb79edfefb1133229a002f41b4d370d717a7eChristian König   }
151884cb79edfefb1133229a002f41b4d370d717a7eChristian König}
152884cb79edfefb1133229a002f41b4d370d717a7eChristian König
1533107b54b011c7ceef2b314632bdcf0b87c5e4d36Younes MantonPUBLIC
154e44c85637a3298918e292e9ddba812856cf92924Younes MantonStatus XvMCCreateSurface(Display *dpy, XvMCContext *context, XvMCSurface *surface)
155e44c85637a3298918e292e9ddba812856cf92924Younes Manton{
156e44c85637a3298918e292e9ddba812856cf92924Younes Manton   XvMCContextPrivate *context_priv;
1574e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König   struct pipe_context *pipe;
158e44c85637a3298918e292e9ddba812856cf92924Younes Manton   XvMCSurfacePrivate *surface_priv;
159e027759336bf49e3f568bd73b9e5f26d56ef6f83Christian König   struct pipe_video_buffer tmpl;
160e44c85637a3298918e292e9ddba812856cf92924Younes Manton
1618580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton   XVMC_MSG(XVMC_TRACE, "[XvMC] Creating surface %p.\n", surface);
1628580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton
163e44c85637a3298918e292e9ddba812856cf92924Younes Manton   assert(dpy);
164e44c85637a3298918e292e9ddba812856cf92924Younes Manton
165e44c85637a3298918e292e9ddba812856cf92924Younes Manton   if (!context)
166e44c85637a3298918e292e9ddba812856cf92924Younes Manton      return XvMCBadContext;
167e44c85637a3298918e292e9ddba812856cf92924Younes Manton   if (!surface)
168e44c85637a3298918e292e9ddba812856cf92924Younes Manton      return XvMCBadSurface;
169e44c85637a3298918e292e9ddba812856cf92924Younes Manton
170e44c85637a3298918e292e9ddba812856cf92924Younes Manton   context_priv = context->privData;
1714e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König   pipe = context_priv->vctx->pipe;
172e44c85637a3298918e292e9ddba812856cf92924Younes Manton
173e44c85637a3298918e292e9ddba812856cf92924Younes Manton   surface_priv = CALLOC(1, sizeof(XvMCSurfacePrivate));
174e44c85637a3298918e292e9ddba812856cf92924Younes Manton   if (!surface_priv)
175e44c85637a3298918e292e9ddba812856cf92924Younes Manton      return BadAlloc;
176e44c85637a3298918e292e9ddba812856cf92924Younes Manton
177e027759336bf49e3f568bd73b9e5f26d56ef6f83Christian König   memset(&tmpl, 0, sizeof(tmpl));
1789d9afcb5bac2931d4b8e6d1aa571e941c5110c90Christian König   tmpl.buffer_format = pipe->screen->get_video_param
1799d9afcb5bac2931d4b8e6d1aa571e941c5110c90Christian König   (
1809d9afcb5bac2931d4b8e6d1aa571e941c5110c90Christian König      pipe->screen,
1819d9afcb5bac2931d4b8e6d1aa571e941c5110c90Christian König      PIPE_VIDEO_PROFILE_MPEG2_MAIN,
1829d9afcb5bac2931d4b8e6d1aa571e941c5110c90Christian König      PIPE_VIDEO_CAP_PREFERED_FORMAT
1839d9afcb5bac2931d4b8e6d1aa571e941c5110c90Christian König   );
184e027759336bf49e3f568bd73b9e5f26d56ef6f83Christian König   tmpl.chroma_format = context_priv->decoder->chroma_format;
185e027759336bf49e3f568bd73b9e5f26d56ef6f83Christian König   tmpl.width = context_priv->decoder->width;
186e027759336bf49e3f568bd73b9e5f26d56ef6f83Christian König   tmpl.height = context_priv->decoder->height;
187e027759336bf49e3f568bd73b9e5f26d56ef6f83Christian König
188e027759336bf49e3f568bd73b9e5f26d56ef6f83Christian König   surface_priv->video_buffer = pipe->create_video_buffer(pipe, &tmpl);
189e44c85637a3298918e292e9ddba812856cf92924Younes Manton   surface_priv->context = context;
190e44c85637a3298918e292e9ddba812856cf92924Younes Manton
191e44c85637a3298918e292e9ddba812856cf92924Younes Manton   surface->surface_id = XAllocID(dpy);
192e44c85637a3298918e292e9ddba812856cf92924Younes Manton   surface->context_id = context->context_id;
193e44c85637a3298918e292e9ddba812856cf92924Younes Manton   surface->surface_type_id = context->surface_type_id;
194e44c85637a3298918e292e9ddba812856cf92924Younes Manton   surface->width = context->width;
195e44c85637a3298918e292e9ddba812856cf92924Younes Manton   surface->height = context->height;
196e44c85637a3298918e292e9ddba812856cf92924Younes Manton   surface->privData = surface_priv;
197e44c85637a3298918e292e9ddba812856cf92924Younes Manton
198e44c85637a3298918e292e9ddba812856cf92924Younes Manton   SyncHandle();
199e44c85637a3298918e292e9ddba812856cf92924Younes Manton
2008580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton   XVMC_MSG(XVMC_TRACE, "[XvMC] Surface %p created.\n", surface);
2018580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton
202e44c85637a3298918e292e9ddba812856cf92924Younes Manton   return Success;
203c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton}
204c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton
2053107b54b011c7ceef2b314632bdcf0b87c5e4d36Younes MantonPUBLIC
206e44c85637a3298918e292e9ddba812856cf92924Younes MantonStatus XvMCRenderSurface(Display *dpy, XvMCContext *context, unsigned int picture_structure,
207e44c85637a3298918e292e9ddba812856cf92924Younes Manton                         XvMCSurface *target_surface, XvMCSurface *past_surface, XvMCSurface *future_surface,
208e44c85637a3298918e292e9ddba812856cf92924Younes Manton                         unsigned int flags, unsigned int num_macroblocks, unsigned int first_macroblock,
209e44c85637a3298918e292e9ddba812856cf92924Younes Manton                         XvMCMacroBlockArray *macroblocks, XvMCBlockArray *blocks
210c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton)
211c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton{
212d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König   struct pipe_mpeg12_macroblock mb[num_macroblocks];
2131d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König   struct pipe_video_decoder *decoder;
2148ea416f35de0c664ef47b71841756758f22d7faaChristian König   struct pipe_mpeg12_picture_desc desc;
2154d057864d0d523c241e40ad675487276789e3b36Christian König
2161d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König   XvMCContextPrivate *context_priv;
217e44c85637a3298918e292e9ddba812856cf92924Younes Manton   XvMCSurfacePrivate *target_surface_priv;
218e44c85637a3298918e292e9ddba812856cf92924Younes Manton   XvMCSurfacePrivate *past_surface_priv;
219e44c85637a3298918e292e9ddba812856cf92924Younes Manton   XvMCSurfacePrivate *future_surface_priv;
2204d057864d0d523c241e40ad675487276789e3b36Christian König   XvMCMacroBlock *xvmc_mb;
2214d057864d0d523c241e40ad675487276789e3b36Christian König
222e6176ce3719e6c6e88d31ae7307154386e83553bChristian König   XVMC_MSG(XVMC_TRACE, "[XvMC] Rendering to surface %p, with past %p and future %p\n",
223e6176ce3719e6c6e88d31ae7307154386e83553bChristian König            target_surface, past_surface, future_surface);
2248580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton
225e44c85637a3298918e292e9ddba812856cf92924Younes Manton   assert(dpy);
226e44c85637a3298918e292e9ddba812856cf92924Younes Manton
227e44c85637a3298918e292e9ddba812856cf92924Younes Manton   if (!context || !context->privData)
228e44c85637a3298918e292e9ddba812856cf92924Younes Manton      return XvMCBadContext;
229e44c85637a3298918e292e9ddba812856cf92924Younes Manton   if (!target_surface || !target_surface->privData)
230e44c85637a3298918e292e9ddba812856cf92924Younes Manton      return XvMCBadSurface;
231e44c85637a3298918e292e9ddba812856cf92924Younes Manton
232e44c85637a3298918e292e9ddba812856cf92924Younes Manton   if (picture_structure != XVMC_TOP_FIELD &&
233e44c85637a3298918e292e9ddba812856cf92924Younes Manton       picture_structure != XVMC_BOTTOM_FIELD &&
234e44c85637a3298918e292e9ddba812856cf92924Younes Manton       picture_structure != XVMC_FRAME_PICTURE)
235e44c85637a3298918e292e9ddba812856cf92924Younes Manton      return BadValue;
236e44c85637a3298918e292e9ddba812856cf92924Younes Manton   /* Bkwd pred equivalent to fwd (past && !future) */
237e44c85637a3298918e292e9ddba812856cf92924Younes Manton   if (future_surface && !past_surface)
238e44c85637a3298918e292e9ddba812856cf92924Younes Manton      return BadMatch;
239e44c85637a3298918e292e9ddba812856cf92924Younes Manton
240e44c85637a3298918e292e9ddba812856cf92924Younes Manton   assert(context->context_id == target_surface->context_id);
241e44c85637a3298918e292e9ddba812856cf92924Younes Manton   assert(!past_surface || context->context_id == past_surface->context_id);
242e44c85637a3298918e292e9ddba812856cf92924Younes Manton   assert(!future_surface || context->context_id == future_surface->context_id);
243e44c85637a3298918e292e9ddba812856cf92924Younes Manton
244e44c85637a3298918e292e9ddba812856cf92924Younes Manton   assert(macroblocks);
245e44c85637a3298918e292e9ddba812856cf92924Younes Manton   assert(blocks);
246e44c85637a3298918e292e9ddba812856cf92924Younes Manton
247e44c85637a3298918e292e9ddba812856cf92924Younes Manton   assert(macroblocks->context_id == context->context_id);
248e44c85637a3298918e292e9ddba812856cf92924Younes Manton   assert(blocks->context_id == context->context_id);
249e44c85637a3298918e292e9ddba812856cf92924Younes Manton
250e44c85637a3298918e292e9ddba812856cf92924Younes Manton   assert(flags == 0 || flags == XVMC_SECOND_FIELD);
251e44c85637a3298918e292e9ddba812856cf92924Younes Manton
2521d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König   context_priv = context->privData;
2531d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König   decoder = context_priv->decoder;
2541d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König
255e44c85637a3298918e292e9ddba812856cf92924Younes Manton   target_surface_priv = target_surface->privData;
256e44c85637a3298918e292e9ddba812856cf92924Younes Manton   past_surface_priv = past_surface ? past_surface->privData : NULL;
257e44c85637a3298918e292e9ddba812856cf92924Younes Manton   future_surface_priv = future_surface ? future_surface->privData : NULL;
258e44c85637a3298918e292e9ddba812856cf92924Younes Manton
259e44c85637a3298918e292e9ddba812856cf92924Younes Manton   assert(target_surface_priv->context == context);
260e44c85637a3298918e292e9ddba812856cf92924Younes Manton   assert(!past_surface || past_surface_priv->context == context);
261e44c85637a3298918e292e9ddba812856cf92924Younes Manton   assert(!future_surface || future_surface_priv->context == context);
262e44c85637a3298918e292e9ddba812856cf92924Younes Manton
2631d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König   // call end frame on all referenced frames
264884cb79edfefb1133229a002f41b4d370d717a7eChristian König   if (past_surface)
2651d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König      RecursiveEndFrame(past_surface->privData);
266884cb79edfefb1133229a002f41b4d370d717a7eChristian König
267884cb79edfefb1133229a002f41b4d370d717a7eChristian König   if (future_surface)
2681d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König      RecursiveEndFrame(future_surface->privData);
269e44c85637a3298918e292e9ddba812856cf92924Younes Manton
2704d057864d0d523c241e40ad675487276789e3b36Christian König   xvmc_mb = macroblocks->macro_blocks + first_macroblock;
2714d057864d0d523c241e40ad675487276789e3b36Christian König
272ce6f8331fa520bc464a9fa50c18fe57678dd0a24Christian König   /* If the surface we're rendering hasn't changed the ref frames shouldn't change. */
273a09754c15fc48e5fed347f478a301a02ee69fe8cMaarten Lankhorst   if (target_surface_priv->picture_structure > 0 && (
274a09754c15fc48e5fed347f478a301a02ee69fe8cMaarten Lankhorst       target_surface_priv->picture_structure != picture_structure ||
275d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König       target_surface_priv->ref[0] != past_surface ||
276d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König       target_surface_priv->ref[1] != future_surface ||
2774d057864d0d523c241e40ad675487276789e3b36Christian König       (xvmc_mb->x == 0 && xvmc_mb->y == 0))) {
278ce6f8331fa520bc464a9fa50c18fe57678dd0a24Christian König
2791d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König      // If they change anyway we must assume that the current frame is ended
2801d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König      RecursiveEndFrame(target_surface_priv);
281ce6f8331fa520bc464a9fa50c18fe57678dd0a24Christian König   }
282ce6f8331fa520bc464a9fa50c18fe57678dd0a24Christian König
283d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König   target_surface_priv->ref[0] = past_surface;
284d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König   target_surface_priv->ref[1] = future_surface;
2851d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König
286a09754c15fc48e5fed347f478a301a02ee69fe8cMaarten Lankhorst   if (target_surface_priv->picture_structure)
2878ea416f35de0c664ef47b71841756758f22d7faaChristian König      GetPictureDescription(target_surface_priv, &desc);
288a09754c15fc48e5fed347f478a301a02ee69fe8cMaarten Lankhorst   else {
289a09754c15fc48e5fed347f478a301a02ee69fe8cMaarten Lankhorst      target_surface_priv->picture_structure = picture_structure;
2908ea416f35de0c664ef47b71841756758f22d7faaChristian König      GetPictureDescription(target_surface_priv, &desc);
2918ea416f35de0c664ef47b71841756758f22d7faaChristian König      decoder->begin_frame(decoder, target_surface_priv->video_buffer, &desc.base);
292884cb79edfefb1133229a002f41b4d370d717a7eChristian König   }
293ce6f8331fa520bc464a9fa50c18fe57678dd0a24Christian König
294d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König   MacroBlocksToPipe(context_priv, target_surface_priv, picture_structure,
295d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König                     xvmc_mb, blocks, mb, num_macroblocks);
296d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König
2978ea416f35de0c664ef47b71841756758f22d7faaChristian König   context_priv->decoder->decode_macroblock(context_priv->decoder,
2988ea416f35de0c664ef47b71841756758f22d7faaChristian König                                            target_surface_priv->video_buffer,
2998ea416f35de0c664ef47b71841756758f22d7faaChristian König                                            &desc.base,
3008ea416f35de0c664ef47b71841756758f22d7faaChristian König                                            &mb[0].base, num_macroblocks);
301e44c85637a3298918e292e9ddba812856cf92924Younes Manton
3028580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton   XVMC_MSG(XVMC_TRACE, "[XvMC] Submitted surface %p for rendering.\n", target_surface);
3038580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton
304e44c85637a3298918e292e9ddba812856cf92924Younes Manton   return Success;
305c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton}
306c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton
3073107b54b011c7ceef2b314632bdcf0b87c5e4d36Younes MantonPUBLIC
308e44c85637a3298918e292e9ddba812856cf92924Younes MantonStatus XvMCFlushSurface(Display *dpy, XvMCSurface *surface)
309c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton{
310d52d51ab8ae1240f77b6c18c3e99be4bf4868037Younes Manton   assert(dpy);
3116858dd50c9b696c1c6044f5a403000f9d20b286bYounes Manton
312d52d51ab8ae1240f77b6c18c3e99be4bf4868037Younes Manton   if (!surface)
313d52d51ab8ae1240f77b6c18c3e99be4bf4868037Younes Manton      return XvMCBadSurface;
3146858dd50c9b696c1c6044f5a403000f9d20b286bYounes Manton
315884cb79edfefb1133229a002f41b4d370d717a7eChristian König   // don't call flush here, because this is usually
316884cb79edfefb1133229a002f41b4d370d717a7eChristian König   // called once for every slice instead of every frame
317884cb79edfefb1133229a002f41b4d370d717a7eChristian König
318e6176ce3719e6c6e88d31ae7307154386e83553bChristian König   XVMC_MSG(XVMC_TRACE, "[XvMC] Flushing surface %p\n", surface);
319e6176ce3719e6c6e88d31ae7307154386e83553bChristian König
320e44c85637a3298918e292e9ddba812856cf92924Younes Manton   return Success;
321c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton}
322c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton
3233107b54b011c7ceef2b314632bdcf0b87c5e4d36Younes MantonPUBLIC
324e44c85637a3298918e292e9ddba812856cf92924Younes MantonStatus XvMCSyncSurface(Display *dpy, XvMCSurface *surface)
325c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton{
326d52d51ab8ae1240f77b6c18c3e99be4bf4868037Younes Manton   assert(dpy);
3276858dd50c9b696c1c6044f5a403000f9d20b286bYounes Manton
328d52d51ab8ae1240f77b6c18c3e99be4bf4868037Younes Manton   if (!surface)
329d52d51ab8ae1240f77b6c18c3e99be4bf4868037Younes Manton      return XvMCBadSurface;
3306858dd50c9b696c1c6044f5a403000f9d20b286bYounes Manton
331e6176ce3719e6c6e88d31ae7307154386e83553bChristian König   XVMC_MSG(XVMC_TRACE, "[XvMC] Syncing surface %p\n", surface);
332e6176ce3719e6c6e88d31ae7307154386e83553bChristian König
333e44c85637a3298918e292e9ddba812856cf92924Younes Manton   return Success;
334c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton}
335c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton
3363107b54b011c7ceef2b314632bdcf0b87c5e4d36Younes MantonPUBLIC
337e44c85637a3298918e292e9ddba812856cf92924Younes MantonStatus XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable,
338e44c85637a3298918e292e9ddba812856cf92924Younes Manton                      short srcx, short srcy, unsigned short srcw, unsigned short srch,
339e44c85637a3298918e292e9ddba812856cf92924Younes Manton                      short destx, short desty, unsigned short destw, unsigned short desth,
340e44c85637a3298918e292e9ddba812856cf92924Younes Manton                      int flags)
341c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton{
3429cff90534389c2aad9b58ff04b1a5d624e3d0bdbChristian König   static int dump_window = -1;
3439cff90534389c2aad9b58ff04b1a5d624e3d0bdbChristian König
344ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König   struct pipe_context *pipe;
345bd5fd67a3e3cda4b7676dd4745fc5d5524709210Christian König   struct vl_compositor *compositor;
346e5f78a74f8294ee02015552db664dae1e7da9f47Christian König
347e44c85637a3298918e292e9ddba812856cf92924Younes Manton   XvMCSurfacePrivate *surface_priv;
348e44c85637a3298918e292e9ddba812856cf92924Younes Manton   XvMCContextPrivate *context_priv;
34980468464897682b8e10aeab310f20fdd7ddc6cb4Younes Manton   XvMCSubpicturePrivate *subpicture_priv;
350e44c85637a3298918e292e9ddba812856cf92924Younes Manton   XvMCContext *context;
351e44c85637a3298918e292e9ddba812856cf92924Younes Manton   struct pipe_video_rect src_rect = {srcx, srcy, srcw, srch};
352e44c85637a3298918e292e9ddba812856cf92924Younes Manton   struct pipe_video_rect dst_rect = {destx, desty, destw, desth};
353e44c85637a3298918e292e9ddba812856cf92924Younes Manton
3548580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton   XVMC_MSG(XVMC_TRACE, "[XvMC] Displaying surface %p.\n", surface);
3558580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton
356e44c85637a3298918e292e9ddba812856cf92924Younes Manton   assert(dpy);
357e44c85637a3298918e292e9ddba812856cf92924Younes Manton
358e44c85637a3298918e292e9ddba812856cf92924Younes Manton   if (!surface || !surface->privData)
359e44c85637a3298918e292e9ddba812856cf92924Younes Manton      return XvMCBadSurface;
360e44c85637a3298918e292e9ddba812856cf92924Younes Manton
3610e59cd33e6a38567801c7da541e4caffbd6cccd3Younes Manton   surface_priv = surface->privData;
3620e59cd33e6a38567801c7da541e4caffbd6cccd3Younes Manton   context = surface_priv->context;
3630e59cd33e6a38567801c7da541e4caffbd6cccd3Younes Manton   context_priv = context->privData;
3640e59cd33e6a38567801c7da541e4caffbd6cccd3Younes Manton
365221e1b7ababe67efe80f38f8ab2236be5cacfddfChristian König   assert(flags == XVMC_TOP_FIELD || flags == XVMC_BOTTOM_FIELD || flags == XVMC_FRAME_PICTURE);
366221e1b7ababe67efe80f38f8ab2236be5cacfddfChristian König   assert(srcx + srcw - 1 < surface->width);
367221e1b7ababe67efe80f38f8ab2236be5cacfddfChristian König   assert(srcy + srch - 1 < surface->height);
368221e1b7ababe67efe80f38f8ab2236be5cacfddfChristian König
369221e1b7ababe67efe80f38f8ab2236be5cacfddfChristian König   subpicture_priv = surface_priv->subpicture ? surface_priv->subpicture->privData : NULL;
370ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König   pipe = context_priv->vctx->pipe;
371bd5fd67a3e3cda4b7676dd4745fc5d5524709210Christian König   compositor = &context_priv->compositor;
372221e1b7ababe67efe80f38f8ab2236be5cacfddfChristian König
373f3f212acf0d2fc25d3b6bd70dd1f346d97a9b25dChristian König   if (!context_priv->drawable_surface ||
374f3f212acf0d2fc25d3b6bd70dd1f346d97a9b25dChristian König       context_priv->dst_rect.x != dst_rect.x || context_priv->dst_rect.y != dst_rect.y ||
375f3f212acf0d2fc25d3b6bd70dd1f346d97a9b25dChristian König       context_priv->dst_rect.w != dst_rect.w || context_priv->dst_rect.h != dst_rect.h) {
376f3f212acf0d2fc25d3b6bd70dd1f346d97a9b25dChristian König
377df5e0b9435c869f88234a69db9bfe97342b027d4Christian König      pipe_surface_reference(&context_priv->drawable_surface, NULL);
378f3f212acf0d2fc25d3b6bd70dd1f346d97a9b25dChristian König      context_priv->drawable_surface = vl_drawable_surface_get(context_priv->vctx, drawable);
379f3f212acf0d2fc25d3b6bd70dd1f346d97a9b25dChristian König      context_priv->dst_rect = dst_rect;
380167b1b32c5ff30d514253072ce54513112c03d4dChristian König      vl_compositor_reset_dirty_area(&context_priv->dirty_area);
381f3f212acf0d2fc25d3b6bd70dd1f346d97a9b25dChristian König   }
382f3f212acf0d2fc25d3b6bd70dd1f346d97a9b25dChristian König
383f3f212acf0d2fc25d3b6bd70dd1f346d97a9b25dChristian König   if (!context_priv->drawable_surface)
384e44c85637a3298918e292e9ddba812856cf92924Younes Manton      return BadDrawable;
385e44c85637a3298918e292e9ddba812856cf92924Younes Manton
386e44c85637a3298918e292e9ddba812856cf92924Younes Manton   /*
387e44c85637a3298918e292e9ddba812856cf92924Younes Manton    * Some apps (mplayer) hit these asserts because they call
388e44c85637a3298918e292e9ddba812856cf92924Younes Manton    * this function after the window has been resized by the WM
389e44c85637a3298918e292e9ddba812856cf92924Younes Manton    * but before they've handled the corresponding XEvent and
390e44c85637a3298918e292e9ddba812856cf92924Younes Manton    * know about the new dimensions. The output should be clipped
391e44c85637a3298918e292e9ddba812856cf92924Younes Manton    * until the app updates destw and desth.
392e44c85637a3298918e292e9ddba812856cf92924Younes Manton    */
393e44c85637a3298918e292e9ddba812856cf92924Younes Manton   /*
3946414952efe3b53fd33d73d592da74975a1075330Younes Manton   assert(destx + destw - 1 < drawable_surface->width);
3956414952efe3b53fd33d73d592da74975a1075330Younes Manton   assert(desty + desth - 1 < drawable_surface->height);
396e44c85637a3298918e292e9ddba812856cf92924Younes Manton    */
397e44c85637a3298918e292e9ddba812856cf92924Younes Manton
3981d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König   RecursiveEndFrame(surface_priv);
3991d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König
4001d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König   context_priv->decoder->flush(context_priv->decoder);
401e5f78a74f8294ee02015552db664dae1e7da9f47Christian König
402bd5fd67a3e3cda4b7676dd4745fc5d5524709210Christian König   vl_compositor_clear_layers(compositor);
403bd5fd67a3e3cda4b7676dd4745fc5d5524709210Christian König   vl_compositor_set_buffer_layer(compositor, 0, surface_priv->video_buffer, &src_rect, NULL);
404e44c85637a3298918e292e9ddba812856cf92924Younes Manton
40580468464897682b8e10aeab310f20fdd7ddc6cb4Younes Manton   if (subpicture_priv) {
40680468464897682b8e10aeab310f20fdd7ddc6cb4Younes Manton      XVMC_MSG(XVMC_TRACE, "[XvMC] Surface %p has subpicture %p.\n", surface, surface_priv->subpicture);
40780468464897682b8e10aeab310f20fdd7ddc6cb4Younes Manton
40880468464897682b8e10aeab310f20fdd7ddc6cb4Younes Manton      assert(subpicture_priv->surface == surface);
409efaf024f8c7c1000af06e54a85378818d55c5160Christian König
410e5f78a74f8294ee02015552db664dae1e7da9f47Christian König      if (subpicture_priv->palette)
411bd5fd67a3e3cda4b7676dd4745fc5d5524709210Christian König         vl_compositor_set_palette_layer(compositor, 1, subpicture_priv->sampler, subpicture_priv->palette,
4124f37636afb5adc299ecbe497209702a47039580cChristian König                                         &subpicture_priv->src_rect, &subpicture_priv->dst_rect, true);
413e5f78a74f8294ee02015552db664dae1e7da9f47Christian König      else
414bd5fd67a3e3cda4b7676dd4745fc5d5524709210Christian König         vl_compositor_set_rgba_layer(compositor, 1, subpicture_priv->sampler,
415bd5fd67a3e3cda4b7676dd4745fc5d5524709210Christian König                                      &subpicture_priv->src_rect, &subpicture_priv->dst_rect);
41680468464897682b8e10aeab310f20fdd7ddc6cb4Younes Manton
41780468464897682b8e10aeab310f20fdd7ddc6cb4Younes Manton      surface_priv->subpicture = NULL;
41880468464897682b8e10aeab310f20fdd7ddc6cb4Younes Manton      subpicture_priv->surface = NULL;
41980468464897682b8e10aeab310f20fdd7ddc6cb4Younes Manton   }
42080468464897682b8e10aeab310f20fdd7ddc6cb4Younes Manton
421104ac0066394f8246d18c833bca4bcce271b5eefChristian König   // Workaround for r600g, there seems to be a bug in the fence refcounting code
422ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König   pipe->screen->fence_reference(pipe->screen, &surface_priv->fence, NULL);
423104ac0066394f8246d18c833bca4bcce271b5eefChristian König
424167b1b32c5ff30d514253072ce54513112c03d4dChristian König   vl_compositor_render(compositor, context_priv->drawable_surface, &dst_rect, NULL, &context_priv->dirty_area);
4250d082390d903e0a6908e1d444e762a23de14174aChristian König
4260d082390d903e0a6908e1d444e762a23de14174aChristian König   pipe->flush(pipe, &surface_priv->fence);
427e44c85637a3298918e292e9ddba812856cf92924Younes Manton
42880468464897682b8e10aeab310f20fdd7ddc6cb4Younes Manton   XVMC_MSG(XVMC_TRACE, "[XvMC] Submitted surface %p for display. Pushing to front buffer.\n", surface);
42980468464897682b8e10aeab310f20fdd7ddc6cb4Younes Manton
430ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König   pipe->screen->flush_frontbuffer
431e44c85637a3298918e292e9ddba812856cf92924Younes Manton   (
432ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König      pipe->screen,
433f3f212acf0d2fc25d3b6bd70dd1f346d97a9b25dChristian König      context_priv->drawable_surface->texture,
434772b25e1f366edc857e77b8c1ccdc5297d82cc41Christian König      0, 0,
435f3f212acf0d2fc25d3b6bd70dd1f346d97a9b25dChristian König      vl_contextprivate_get(context_priv->vctx, context_priv->drawable_surface)
436e44c85637a3298918e292e9ddba812856cf92924Younes Manton   );
437e44c85637a3298918e292e9ddba812856cf92924Younes Manton
4389cff90534389c2aad9b58ff04b1a5d624e3d0bdbChristian König   if(dump_window == -1) {
4399cff90534389c2aad9b58ff04b1a5d624e3d0bdbChristian König      dump_window = debug_get_num_option("XVMC_DUMP", 0);
4409cff90534389c2aad9b58ff04b1a5d624e3d0bdbChristian König   }
4419cff90534389c2aad9b58ff04b1a5d624e3d0bdbChristian König
4429cff90534389c2aad9b58ff04b1a5d624e3d0bdbChristian König   if(dump_window) {
4439cff90534389c2aad9b58ff04b1a5d624e3d0bdbChristian König      static unsigned int framenum = 0;
4449cff90534389c2aad9b58ff04b1a5d624e3d0bdbChristian König      char cmd[256];
44587e81a3e9db1a30f6f31e6e91aeb5acfdc8b589fChristian König
4469cff90534389c2aad9b58ff04b1a5d624e3d0bdbChristian König      sprintf(cmd, "xwd -id %d -out xvmc_frame_%08d.xwd", (int)drawable, ++framenum);
44787e81a3e9db1a30f6f31e6e91aeb5acfdc8b589fChristian König      if (system(cmd) != 0)
44887e81a3e9db1a30f6f31e6e91aeb5acfdc8b589fChristian König         XVMC_MSG(XVMC_ERR, "[XvMC] Dumping surface %p failed.\n", surface);
4499cff90534389c2aad9b58ff04b1a5d624e3d0bdbChristian König   }
4509cff90534389c2aad9b58ff04b1a5d624e3d0bdbChristian König
45180468464897682b8e10aeab310f20fdd7ddc6cb4Younes Manton   XVMC_MSG(XVMC_TRACE, "[XvMC] Pushed surface %p to front buffer.\n", surface);
4528580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton
453e44c85637a3298918e292e9ddba812856cf92924Younes Manton   return Success;
454c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton}
455c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton
4563107b54b011c7ceef2b314632bdcf0b87c5e4d36Younes MantonPUBLIC
457e44c85637a3298918e292e9ddba812856cf92924Younes MantonStatus XvMCGetSurfaceStatus(Display *dpy, XvMCSurface *surface, int *status)
458c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton{
459ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König   struct pipe_context *pipe;
460104ac0066394f8246d18c833bca4bcce271b5eefChristian König   XvMCSurfacePrivate *surface_priv;
461104ac0066394f8246d18c833bca4bcce271b5eefChristian König   XvMCContextPrivate *context_priv;
462104ac0066394f8246d18c833bca4bcce271b5eefChristian König
463d52d51ab8ae1240f77b6c18c3e99be4bf4868037Younes Manton   assert(dpy);
464d52d51ab8ae1240f77b6c18c3e99be4bf4868037Younes Manton
465d52d51ab8ae1240f77b6c18c3e99be4bf4868037Younes Manton   if (!surface)
466d52d51ab8ae1240f77b6c18c3e99be4bf4868037Younes Manton      return XvMCBadSurface;
467d52d51ab8ae1240f77b6c18c3e99be4bf4868037Younes Manton
468d52d51ab8ae1240f77b6c18c3e99be4bf4868037Younes Manton   assert(status);
469d52d51ab8ae1240f77b6c18c3e99be4bf4868037Younes Manton
470104ac0066394f8246d18c833bca4bcce271b5eefChristian König   surface_priv = surface->privData;
471104ac0066394f8246d18c833bca4bcce271b5eefChristian König   context_priv = surface_priv->context->privData;
472ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König   pipe = context_priv->vctx->pipe;
473104ac0066394f8246d18c833bca4bcce271b5eefChristian König
474e44c85637a3298918e292e9ddba812856cf92924Younes Manton   *status = 0;
475d52d51ab8ae1240f77b6c18c3e99be4bf4868037Younes Manton
476104ac0066394f8246d18c833bca4bcce271b5eefChristian König   if (surface_priv->fence)
477ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König      if (!pipe->screen->fence_signalled(pipe->screen, surface_priv->fence))
478104ac0066394f8246d18c833bca4bcce271b5eefChristian König         *status |= XVMC_RENDERING;
479104ac0066394f8246d18c833bca4bcce271b5eefChristian König
480e44c85637a3298918e292e9ddba812856cf92924Younes Manton   return Success;
481c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton}
482c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton
4833107b54b011c7ceef2b314632bdcf0b87c5e4d36Younes MantonPUBLIC
484e44c85637a3298918e292e9ddba812856cf92924Younes MantonStatus XvMCDestroySurface(Display *dpy, XvMCSurface *surface)
485c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton{
486e44c85637a3298918e292e9ddba812856cf92924Younes Manton   XvMCSurfacePrivate *surface_priv;
4871d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König   XvMCContextPrivate *context_priv;
4881d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König
4898580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton   XVMC_MSG(XVMC_TRACE, "[XvMC] Destroying surface %p.\n", surface);
4908580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton
491e44c85637a3298918e292e9ddba812856cf92924Younes Manton   assert(dpy);
4926858dd50c9b696c1c6044f5a403000f9d20b286bYounes Manton
493e44c85637a3298918e292e9ddba812856cf92924Younes Manton   if (!surface || !surface->privData)
494e44c85637a3298918e292e9ddba812856cf92924Younes Manton      return XvMCBadSurface;
4956858dd50c9b696c1c6044f5a403000f9d20b286bYounes Manton
496e44c85637a3298918e292e9ddba812856cf92924Younes Manton   surface_priv = surface->privData;
4971d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König   context_priv = surface_priv->context->privData;
498df5e0b9435c869f88234a69db9bfe97342b027d4Christian König
499a09754c15fc48e5fed347f478a301a02ee69fe8cMaarten Lankhorst   if (surface_priv->picture_structure) {
5008ea416f35de0c664ef47b71841756758f22d7faaChristian König      struct pipe_mpeg12_picture_desc desc;
5018ea416f35de0c664ef47b71841756758f22d7faaChristian König      GetPictureDescription(surface_priv, &desc);
5028ea416f35de0c664ef47b71841756758f22d7faaChristian König      context_priv->decoder->end_frame(context_priv->decoder, surface_priv->video_buffer, &desc.base);
5031d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König   }
504d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   surface_priv->video_buffer->destroy(surface_priv->video_buffer);
505e44c85637a3298918e292e9ddba812856cf92924Younes Manton   FREE(surface_priv);
506e44c85637a3298918e292e9ddba812856cf92924Younes Manton   surface->privData = NULL;
5076858dd50c9b696c1c6044f5a403000f9d20b286bYounes Manton
5088580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton   XVMC_MSG(XVMC_TRACE, "[XvMC] Surface %p destroyed.\n", surface);
5098580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton
510e44c85637a3298918e292e9ddba812856cf92924Younes Manton   return Success;
511c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton}
512c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton
5133107b54b011c7ceef2b314632bdcf0b87c5e4d36Younes MantonPUBLIC
514e44c85637a3298918e292e9ddba812856cf92924Younes MantonStatus XvMCHideSurface(Display *dpy, XvMCSurface *surface)
515c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton{
516e44c85637a3298918e292e9ddba812856cf92924Younes Manton   assert(dpy);
5176858dd50c9b696c1c6044f5a403000f9d20b286bYounes Manton
518e44c85637a3298918e292e9ddba812856cf92924Younes Manton   if (!surface || !surface->privData)
519e44c85637a3298918e292e9ddba812856cf92924Younes Manton      return XvMCBadSurface;
5206858dd50c9b696c1c6044f5a403000f9d20b286bYounes Manton
521e44c85637a3298918e292e9ddba812856cf92924Younes Manton   /* No op, only for overlaid rendering */
5226858dd50c9b696c1c6044f5a403000f9d20b286bYounes Manton
523e44c85637a3298918e292e9ddba812856cf92924Younes Manton   return Success;
524c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton}
525