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"
40fc0a5e21d77ae2f082fd19dd2295e84f6fb7bd3bChristian König#include "vl/vl_winsys.h"
41b48676672592271597d07e5ece79cf4d3ffbe04bChristian König
42e44c85637a3298918e292e9ddba812856cf92924Younes Manton#include "xvmc_private.h"
43c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton
44e44c85637a3298918e292e9ddba812856cf92924Younes Mantonstatic void
45d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian KönigMacroBlocksToPipe(XvMCContextPrivate *context,
46d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König                  XvMCSurfacePrivate *surface,
4734e5ae5aed8187e0f6395dee2985091cea3a6df6Christian König                  unsigned int xvmc_picture_structure,
484d057864d0d523c241e40ad675487276789e3b36Christian König                  const XvMCMacroBlock *xvmc_mb,
49e44c85637a3298918e292e9ddba812856cf92924Younes Manton                  const XvMCBlockArray *xvmc_blocks,
50d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König                  struct pipe_mpeg12_macroblock *mb,
512e6274fc3b123e7de695038054b5cbd20b11559aChristian König                  unsigned int num_macroblocks)
52e44c85637a3298918e292e9ddba812856cf92924Younes Manton{
53d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König   unsigned int i, j, k;
54e44c85637a3298918e292e9ddba812856cf92924Younes Manton
554d057864d0d523c241e40ad675487276789e3b36Christian König   assert(xvmc_mb);
56e44c85637a3298918e292e9ddba812856cf92924Younes Manton   assert(xvmc_blocks);
57e44c85637a3298918e292e9ddba812856cf92924Younes Manton   assert(num_macroblocks);
58e44c85637a3298918e292e9ddba812856cf92924Younes Manton
59d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König   for (; num_macroblocks > 0; --num_macroblocks) {
60d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König      mb->base.codec = PIPE_VIDEO_CODEC_MPEG12;
61d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König      mb->x = xvmc_mb->x;
62d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König      mb->y = xvmc_mb->y;
63d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König      mb->macroblock_type = xvmc_mb->macroblock_type;
64e44c85637a3298918e292e9ddba812856cf92924Younes Manton
65d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König      switch (xvmc_picture_structure) {
66d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König      case XVMC_FRAME_PICTURE:
67d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König         mb->macroblock_modes.bits.frame_motion_type = xvmc_mb->motion_type;
68d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König         mb->macroblock_modes.bits.field_motion_type = 0;
69d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König         break;
707a5390b06fea99f85ab47d40d8dc40e40e0f2ab8Christian König
71d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König      case XVMC_TOP_FIELD:
72d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König      case XVMC_BOTTOM_FIELD:
73d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König         mb->macroblock_modes.bits.frame_motion_type = 0;
74d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König         mb->macroblock_modes.bits.field_motion_type = xvmc_mb->motion_type;
75d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König         break;
76e44c85637a3298918e292e9ddba812856cf92924Younes Manton
77d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König      default:
78d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König         assert(0);
79b7acf83d523563cde613fe805bd8edaa02f64b53Christian König      }
80e44c85637a3298918e292e9ddba812856cf92924Younes Manton
81d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König      mb->macroblock_modes.bits.dct_type = xvmc_mb->dct_type;
82d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König      mb->motion_vertical_field_select = xvmc_mb->motion_vertical_field_select;
83d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König
84d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König      for (i = 0; i < 2; ++i)
85d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König         for (j = 0; j < 2; ++j)
86d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König            for (k = 0; k < 2; ++k)
87d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König               mb->PMV[i][j][k] = xvmc_mb->PMV[i][j][k];
88d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König
89d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König      mb->coded_block_pattern = xvmc_mb->coded_block_pattern;
90d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König      mb->blocks = xvmc_blocks->blocks + xvmc_mb->index * BLOCK_SIZE_SAMPLES;
91d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König      mb->num_skipped_macroblocks = 0;
92d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König
93e44c85637a3298918e292e9ddba812856cf92924Younes Manton      ++xvmc_mb;
94d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König      ++mb;
95e44c85637a3298918e292e9ddba812856cf92924Younes Manton   }
96e44c85637a3298918e292e9ddba812856cf92924Younes Manton}
976858dd50c9b696c1c6044f5a403000f9d20b286bYounes Manton
98884cb79edfefb1133229a002f41b4d370d717a7eChristian Königstatic void
998ea416f35de0c664ef47b71841756758f22d7faaChristian KönigGetPictureDescription(XvMCSurfacePrivate *surface, struct pipe_mpeg12_picture_desc *desc)
100884cb79edfefb1133229a002f41b4d370d717a7eChristian König{
1011d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König   unsigned i, num_refs = 0;
1021d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König
1038ea416f35de0c664ef47b71841756758f22d7faaChristian König   assert(surface && desc);
1041d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König
1058ea416f35de0c664ef47b71841756758f22d7faaChristian König   memset(desc, 0, sizeof(*desc));
1068ea416f35de0c664ef47b71841756758f22d7faaChristian König   desc->base.profile = PIPE_VIDEO_PROFILE_MPEG1;
1078ea416f35de0c664ef47b71841756758f22d7faaChristian König   desc->picture_structure = surface->picture_structure;
1081d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König   for (i = 0; i < 2; ++i) {
109d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König      if (surface->ref[i]) {
110d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König         XvMCSurfacePrivate *ref = surface->ref[i]->privData;
1111d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König
1121d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König         if (ref)
1138ea416f35de0c664ef47b71841756758f22d7faaChristian König            desc->ref[num_refs++] = ref->video_buffer;
1141d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König      }
1151d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König   }
1161d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König}
1171d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König
1181d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian Königstatic void
1191d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian KönigRecursiveEndFrame(XvMCSurfacePrivate *surface)
1201d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König{
121d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   XvMCContextPrivate *context_priv;
122d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König   unsigned i;
123884cb79edfefb1133229a002f41b4d370d717a7eChristian König
124884cb79edfefb1133229a002f41b4d370d717a7eChristian König   assert(surface);
125884cb79edfefb1133229a002f41b4d370d717a7eChristian König
126d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   context_priv = surface->context->privData;
127d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König
1283e92b4fd14b731bd6984aafd220059e27948aea8Christian König   for ( i = 0; i < 2; ++i ) {
129d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König      if (surface->ref[i]) {
130d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König         XvMCSurface *ref = surface->ref[i];
131884cb79edfefb1133229a002f41b4d370d717a7eChristian König
132884cb79edfefb1133229a002f41b4d370d717a7eChristian König         assert(ref);
133884cb79edfefb1133229a002f41b4d370d717a7eChristian König
134d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König         surface->ref[i] = NULL;
1351d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König         RecursiveEndFrame(ref->privData);
136d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König         surface->ref[i] = ref;
137884cb79edfefb1133229a002f41b4d370d717a7eChristian König      }
138884cb79edfefb1133229a002f41b4d370d717a7eChristian König   }
139884cb79edfefb1133229a002f41b4d370d717a7eChristian König
140a09754c15fc48e5fed347f478a301a02ee69fe8cMaarten Lankhorst   if (surface->picture_structure) {
1418ea416f35de0c664ef47b71841756758f22d7faaChristian König      struct pipe_mpeg12_picture_desc desc;
1428ea416f35de0c664ef47b71841756758f22d7faaChristian König      GetPictureDescription(surface, &desc);
143a09754c15fc48e5fed347f478a301a02ee69fe8cMaarten Lankhorst      surface->picture_structure = 0;
1441d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König
1451d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König      for (i = 0; i < 2; ++i)
146d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König         surface->ref[i] = NULL;
1471d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König
1488ea416f35de0c664ef47b71841756758f22d7faaChristian König      context_priv->decoder->end_frame(context_priv->decoder, surface->video_buffer, &desc.base);
149884cb79edfefb1133229a002f41b4d370d717a7eChristian König   }
150884cb79edfefb1133229a002f41b4d370d717a7eChristian König}
151884cb79edfefb1133229a002f41b4d370d717a7eChristian König
1523107b54b011c7ceef2b314632bdcf0b87c5e4d36Younes MantonPUBLIC
153e44c85637a3298918e292e9ddba812856cf92924Younes MantonStatus XvMCCreateSurface(Display *dpy, XvMCContext *context, XvMCSurface *surface)
154e44c85637a3298918e292e9ddba812856cf92924Younes Manton{
155e44c85637a3298918e292e9ddba812856cf92924Younes Manton   XvMCContextPrivate *context_priv;
1564e837f557bf5f5afb286e1f2244ed69c0092c2d6Christian König   struct pipe_context *pipe;
157e44c85637a3298918e292e9ddba812856cf92924Younes Manton   XvMCSurfacePrivate *surface_priv;
158e027759336bf49e3f568bd73b9e5f26d56ef6f83Christian König   struct pipe_video_buffer tmpl;
159e44c85637a3298918e292e9ddba812856cf92924Younes Manton
1608580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton   XVMC_MSG(XVMC_TRACE, "[XvMC] Creating surface %p.\n", surface);
1618580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton
162e44c85637a3298918e292e9ddba812856cf92924Younes Manton   assert(dpy);
163e44c85637a3298918e292e9ddba812856cf92924Younes Manton
164e44c85637a3298918e292e9ddba812856cf92924Younes Manton   if (!context)
165e44c85637a3298918e292e9ddba812856cf92924Younes Manton      return XvMCBadContext;
166e44c85637a3298918e292e9ddba812856cf92924Younes Manton   if (!surface)
167e44c85637a3298918e292e9ddba812856cf92924Younes Manton      return XvMCBadSurface;
168e44c85637a3298918e292e9ddba812856cf92924Younes Manton
169e44c85637a3298918e292e9ddba812856cf92924Younes Manton   context_priv = context->privData;
1701448e829e86981e6144410ba6a3d0f16357fb2b3Christian König   pipe = context_priv->pipe;
171e44c85637a3298918e292e9ddba812856cf92924Younes Manton
172e44c85637a3298918e292e9ddba812856cf92924Younes Manton   surface_priv = CALLOC(1, sizeof(XvMCSurfacePrivate));
173e44c85637a3298918e292e9ddba812856cf92924Younes Manton   if (!surface_priv)
174e44c85637a3298918e292e9ddba812856cf92924Younes Manton      return BadAlloc;
175e44c85637a3298918e292e9ddba812856cf92924Younes Manton
176e027759336bf49e3f568bd73b9e5f26d56ef6f83Christian König   memset(&tmpl, 0, sizeof(tmpl));
1779d9afcb5bac2931d4b8e6d1aa571e941c5110c90Christian König   tmpl.buffer_format = pipe->screen->get_video_param
1789d9afcb5bac2931d4b8e6d1aa571e941c5110c90Christian König   (
1799d9afcb5bac2931d4b8e6d1aa571e941c5110c90Christian König      pipe->screen,
1809d9afcb5bac2931d4b8e6d1aa571e941c5110c90Christian König      PIPE_VIDEO_PROFILE_MPEG2_MAIN,
1819d9afcb5bac2931d4b8e6d1aa571e941c5110c90Christian König      PIPE_VIDEO_CAP_PREFERED_FORMAT
1829d9afcb5bac2931d4b8e6d1aa571e941c5110c90Christian König   );
183e027759336bf49e3f568bd73b9e5f26d56ef6f83Christian König   tmpl.chroma_format = context_priv->decoder->chroma_format;
184e027759336bf49e3f568bd73b9e5f26d56ef6f83Christian König   tmpl.width = context_priv->decoder->width;
185e027759336bf49e3f568bd73b9e5f26d56ef6f83Christian König   tmpl.height = context_priv->decoder->height;
18614f47d164d198e6aabce7348d9574c8253134708Christian König   tmpl.interlaced = pipe->screen->get_video_param
18714f47d164d198e6aabce7348d9574c8253134708Christian König   (
18814f47d164d198e6aabce7348d9574c8253134708Christian König      pipe->screen,
18914f47d164d198e6aabce7348d9574c8253134708Christian König      PIPE_VIDEO_PROFILE_MPEG2_MAIN,
19014f47d164d198e6aabce7348d9574c8253134708Christian König      PIPE_VIDEO_CAP_PREFERS_INTERLACED
19114f47d164d198e6aabce7348d9574c8253134708Christian König   );
192e027759336bf49e3f568bd73b9e5f26d56ef6f83Christian König
193e027759336bf49e3f568bd73b9e5f26d56ef6f83Christian König   surface_priv->video_buffer = pipe->create_video_buffer(pipe, &tmpl);
194e44c85637a3298918e292e9ddba812856cf92924Younes Manton   surface_priv->context = context;
195e44c85637a3298918e292e9ddba812856cf92924Younes Manton
196e44c85637a3298918e292e9ddba812856cf92924Younes Manton   surface->surface_id = XAllocID(dpy);
197e44c85637a3298918e292e9ddba812856cf92924Younes Manton   surface->context_id = context->context_id;
198e44c85637a3298918e292e9ddba812856cf92924Younes Manton   surface->surface_type_id = context->surface_type_id;
199e44c85637a3298918e292e9ddba812856cf92924Younes Manton   surface->width = context->width;
200e44c85637a3298918e292e9ddba812856cf92924Younes Manton   surface->height = context->height;
201e44c85637a3298918e292e9ddba812856cf92924Younes Manton   surface->privData = surface_priv;
202e44c85637a3298918e292e9ddba812856cf92924Younes Manton
203e44c85637a3298918e292e9ddba812856cf92924Younes Manton   SyncHandle();
204e44c85637a3298918e292e9ddba812856cf92924Younes Manton
2058580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton   XVMC_MSG(XVMC_TRACE, "[XvMC] Surface %p created.\n", surface);
2068580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton
207e44c85637a3298918e292e9ddba812856cf92924Younes Manton   return Success;
208c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton}
209c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton
2103107b54b011c7ceef2b314632bdcf0b87c5e4d36Younes MantonPUBLIC
211e44c85637a3298918e292e9ddba812856cf92924Younes MantonStatus XvMCRenderSurface(Display *dpy, XvMCContext *context, unsigned int picture_structure,
212e44c85637a3298918e292e9ddba812856cf92924Younes Manton                         XvMCSurface *target_surface, XvMCSurface *past_surface, XvMCSurface *future_surface,
213e44c85637a3298918e292e9ddba812856cf92924Younes Manton                         unsigned int flags, unsigned int num_macroblocks, unsigned int first_macroblock,
214e44c85637a3298918e292e9ddba812856cf92924Younes Manton                         XvMCMacroBlockArray *macroblocks, XvMCBlockArray *blocks
215c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton)
216c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton{
217d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König   struct pipe_mpeg12_macroblock mb[num_macroblocks];
2181d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König   struct pipe_video_decoder *decoder;
2198ea416f35de0c664ef47b71841756758f22d7faaChristian König   struct pipe_mpeg12_picture_desc desc;
2204d057864d0d523c241e40ad675487276789e3b36Christian König
2211d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König   XvMCContextPrivate *context_priv;
222e44c85637a3298918e292e9ddba812856cf92924Younes Manton   XvMCSurfacePrivate *target_surface_priv;
223e44c85637a3298918e292e9ddba812856cf92924Younes Manton   XvMCSurfacePrivate *past_surface_priv;
224e44c85637a3298918e292e9ddba812856cf92924Younes Manton   XvMCSurfacePrivate *future_surface_priv;
2254d057864d0d523c241e40ad675487276789e3b36Christian König   XvMCMacroBlock *xvmc_mb;
2264d057864d0d523c241e40ad675487276789e3b36Christian König
227e6176ce3719e6c6e88d31ae7307154386e83553bChristian König   XVMC_MSG(XVMC_TRACE, "[XvMC] Rendering to surface %p, with past %p and future %p\n",
228e6176ce3719e6c6e88d31ae7307154386e83553bChristian König            target_surface, past_surface, future_surface);
2298580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton
230e44c85637a3298918e292e9ddba812856cf92924Younes Manton   assert(dpy);
231e44c85637a3298918e292e9ddba812856cf92924Younes Manton
232e44c85637a3298918e292e9ddba812856cf92924Younes Manton   if (!context || !context->privData)
233e44c85637a3298918e292e9ddba812856cf92924Younes Manton      return XvMCBadContext;
234e44c85637a3298918e292e9ddba812856cf92924Younes Manton   if (!target_surface || !target_surface->privData)
235e44c85637a3298918e292e9ddba812856cf92924Younes Manton      return XvMCBadSurface;
236e44c85637a3298918e292e9ddba812856cf92924Younes Manton
237e44c85637a3298918e292e9ddba812856cf92924Younes Manton   if (picture_structure != XVMC_TOP_FIELD &&
238e44c85637a3298918e292e9ddba812856cf92924Younes Manton       picture_structure != XVMC_BOTTOM_FIELD &&
239e44c85637a3298918e292e9ddba812856cf92924Younes Manton       picture_structure != XVMC_FRAME_PICTURE)
240e44c85637a3298918e292e9ddba812856cf92924Younes Manton      return BadValue;
241e44c85637a3298918e292e9ddba812856cf92924Younes Manton   /* Bkwd pred equivalent to fwd (past && !future) */
242e44c85637a3298918e292e9ddba812856cf92924Younes Manton   if (future_surface && !past_surface)
243e44c85637a3298918e292e9ddba812856cf92924Younes Manton      return BadMatch;
244e44c85637a3298918e292e9ddba812856cf92924Younes Manton
245e44c85637a3298918e292e9ddba812856cf92924Younes Manton   assert(context->context_id == target_surface->context_id);
246e44c85637a3298918e292e9ddba812856cf92924Younes Manton   assert(!past_surface || context->context_id == past_surface->context_id);
247e44c85637a3298918e292e9ddba812856cf92924Younes Manton   assert(!future_surface || context->context_id == future_surface->context_id);
248e44c85637a3298918e292e9ddba812856cf92924Younes Manton
249e44c85637a3298918e292e9ddba812856cf92924Younes Manton   assert(macroblocks);
250e44c85637a3298918e292e9ddba812856cf92924Younes Manton   assert(blocks);
251e44c85637a3298918e292e9ddba812856cf92924Younes Manton
252e44c85637a3298918e292e9ddba812856cf92924Younes Manton   assert(macroblocks->context_id == context->context_id);
253e44c85637a3298918e292e9ddba812856cf92924Younes Manton   assert(blocks->context_id == context->context_id);
254e44c85637a3298918e292e9ddba812856cf92924Younes Manton
255e44c85637a3298918e292e9ddba812856cf92924Younes Manton   assert(flags == 0 || flags == XVMC_SECOND_FIELD);
256e44c85637a3298918e292e9ddba812856cf92924Younes Manton
2571d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König   context_priv = context->privData;
2581d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König   decoder = context_priv->decoder;
2591d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König
260e44c85637a3298918e292e9ddba812856cf92924Younes Manton   target_surface_priv = target_surface->privData;
261e44c85637a3298918e292e9ddba812856cf92924Younes Manton   past_surface_priv = past_surface ? past_surface->privData : NULL;
262e44c85637a3298918e292e9ddba812856cf92924Younes Manton   future_surface_priv = future_surface ? future_surface->privData : NULL;
263e44c85637a3298918e292e9ddba812856cf92924Younes Manton
264e44c85637a3298918e292e9ddba812856cf92924Younes Manton   assert(target_surface_priv->context == context);
265e44c85637a3298918e292e9ddba812856cf92924Younes Manton   assert(!past_surface || past_surface_priv->context == context);
266e44c85637a3298918e292e9ddba812856cf92924Younes Manton   assert(!future_surface || future_surface_priv->context == context);
267e44c85637a3298918e292e9ddba812856cf92924Younes Manton
2681d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König   // call end frame on all referenced frames
269884cb79edfefb1133229a002f41b4d370d717a7eChristian König   if (past_surface)
2701d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König      RecursiveEndFrame(past_surface->privData);
271884cb79edfefb1133229a002f41b4d370d717a7eChristian König
272884cb79edfefb1133229a002f41b4d370d717a7eChristian König   if (future_surface)
2731d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König      RecursiveEndFrame(future_surface->privData);
274e44c85637a3298918e292e9ddba812856cf92924Younes Manton
2754d057864d0d523c241e40ad675487276789e3b36Christian König   xvmc_mb = macroblocks->macro_blocks + first_macroblock;
2764d057864d0d523c241e40ad675487276789e3b36Christian König
277ce6f8331fa520bc464a9fa50c18fe57678dd0a24Christian König   /* If the surface we're rendering hasn't changed the ref frames shouldn't change. */
278a09754c15fc48e5fed347f478a301a02ee69fe8cMaarten Lankhorst   if (target_surface_priv->picture_structure > 0 && (
279a09754c15fc48e5fed347f478a301a02ee69fe8cMaarten Lankhorst       target_surface_priv->picture_structure != picture_structure ||
280d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König       target_surface_priv->ref[0] != past_surface ||
281d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König       target_surface_priv->ref[1] != future_surface ||
2824d057864d0d523c241e40ad675487276789e3b36Christian König       (xvmc_mb->x == 0 && xvmc_mb->y == 0))) {
283ce6f8331fa520bc464a9fa50c18fe57678dd0a24Christian König
2841d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König      // If they change anyway we must assume that the current frame is ended
2851d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König      RecursiveEndFrame(target_surface_priv);
286ce6f8331fa520bc464a9fa50c18fe57678dd0a24Christian König   }
287ce6f8331fa520bc464a9fa50c18fe57678dd0a24Christian König
288d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König   target_surface_priv->ref[0] = past_surface;
289d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König   target_surface_priv->ref[1] = future_surface;
2901d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König
291a09754c15fc48e5fed347f478a301a02ee69fe8cMaarten Lankhorst   if (target_surface_priv->picture_structure)
2928ea416f35de0c664ef47b71841756758f22d7faaChristian König      GetPictureDescription(target_surface_priv, &desc);
293a09754c15fc48e5fed347f478a301a02ee69fe8cMaarten Lankhorst   else {
294a09754c15fc48e5fed347f478a301a02ee69fe8cMaarten Lankhorst      target_surface_priv->picture_structure = picture_structure;
2958ea416f35de0c664ef47b71841756758f22d7faaChristian König      GetPictureDescription(target_surface_priv, &desc);
2968ea416f35de0c664ef47b71841756758f22d7faaChristian König      decoder->begin_frame(decoder, target_surface_priv->video_buffer, &desc.base);
297884cb79edfefb1133229a002f41b4d370d717a7eChristian König   }
298ce6f8331fa520bc464a9fa50c18fe57678dd0a24Christian König
299d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König   MacroBlocksToPipe(context_priv, target_surface_priv, picture_structure,
300d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König                     xvmc_mb, blocks, mb, num_macroblocks);
301d3770d6229d95e9beb67358ae2b2c8824ed3ae58Christian König
3028ea416f35de0c664ef47b71841756758f22d7faaChristian König   context_priv->decoder->decode_macroblock(context_priv->decoder,
3038ea416f35de0c664ef47b71841756758f22d7faaChristian König                                            target_surface_priv->video_buffer,
3048ea416f35de0c664ef47b71841756758f22d7faaChristian König                                            &desc.base,
3058ea416f35de0c664ef47b71841756758f22d7faaChristian König                                            &mb[0].base, num_macroblocks);
306e44c85637a3298918e292e9ddba812856cf92924Younes Manton
3078580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton   XVMC_MSG(XVMC_TRACE, "[XvMC] Submitted surface %p for rendering.\n", target_surface);
3088580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton
309e44c85637a3298918e292e9ddba812856cf92924Younes Manton   return Success;
310c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton}
311c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton
3123107b54b011c7ceef2b314632bdcf0b87c5e4d36Younes MantonPUBLIC
313e44c85637a3298918e292e9ddba812856cf92924Younes MantonStatus XvMCFlushSurface(Display *dpy, XvMCSurface *surface)
314c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton{
315d52d51ab8ae1240f77b6c18c3e99be4bf4868037Younes Manton   assert(dpy);
3166858dd50c9b696c1c6044f5a403000f9d20b286bYounes Manton
317d52d51ab8ae1240f77b6c18c3e99be4bf4868037Younes Manton   if (!surface)
318d52d51ab8ae1240f77b6c18c3e99be4bf4868037Younes Manton      return XvMCBadSurface;
3196858dd50c9b696c1c6044f5a403000f9d20b286bYounes Manton
320884cb79edfefb1133229a002f41b4d370d717a7eChristian König   // don't call flush here, because this is usually
321884cb79edfefb1133229a002f41b4d370d717a7eChristian König   // called once for every slice instead of every frame
322884cb79edfefb1133229a002f41b4d370d717a7eChristian König
323e6176ce3719e6c6e88d31ae7307154386e83553bChristian König   XVMC_MSG(XVMC_TRACE, "[XvMC] Flushing surface %p\n", surface);
324e6176ce3719e6c6e88d31ae7307154386e83553bChristian König
325e44c85637a3298918e292e9ddba812856cf92924Younes Manton   return Success;
326c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton}
327c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton
3283107b54b011c7ceef2b314632bdcf0b87c5e4d36Younes MantonPUBLIC
329e44c85637a3298918e292e9ddba812856cf92924Younes MantonStatus XvMCSyncSurface(Display *dpy, XvMCSurface *surface)
330c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton{
331d52d51ab8ae1240f77b6c18c3e99be4bf4868037Younes Manton   assert(dpy);
3326858dd50c9b696c1c6044f5a403000f9d20b286bYounes Manton
333d52d51ab8ae1240f77b6c18c3e99be4bf4868037Younes Manton   if (!surface)
334d52d51ab8ae1240f77b6c18c3e99be4bf4868037Younes Manton      return XvMCBadSurface;
3356858dd50c9b696c1c6044f5a403000f9d20b286bYounes Manton
336e6176ce3719e6c6e88d31ae7307154386e83553bChristian König   XVMC_MSG(XVMC_TRACE, "[XvMC] Syncing surface %p\n", surface);
337e6176ce3719e6c6e88d31ae7307154386e83553bChristian König
338e44c85637a3298918e292e9ddba812856cf92924Younes Manton   return Success;
339c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton}
340c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton
3413107b54b011c7ceef2b314632bdcf0b87c5e4d36Younes MantonPUBLIC
342e44c85637a3298918e292e9ddba812856cf92924Younes MantonStatus XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable,
343e44c85637a3298918e292e9ddba812856cf92924Younes Manton                      short srcx, short srcy, unsigned short srcw, unsigned short srch,
344e44c85637a3298918e292e9ddba812856cf92924Younes Manton                      short destx, short desty, unsigned short destw, unsigned short desth,
345e44c85637a3298918e292e9ddba812856cf92924Younes Manton                      int flags)
346c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton{
3479cff90534389c2aad9b58ff04b1a5d624e3d0bdbChristian König   static int dump_window = -1;
3489cff90534389c2aad9b58ff04b1a5d624e3d0bdbChristian König
349ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König   struct pipe_context *pipe;
350bd5fd67a3e3cda4b7676dd4745fc5d5524709210Christian König   struct vl_compositor *compositor;
35132c4381d4a0479b3d9bfe305ce701be6b5ac8e18Christian König   struct vl_compositor_state *cstate;
352e5f78a74f8294ee02015552db664dae1e7da9f47Christian König
353e44c85637a3298918e292e9ddba812856cf92924Younes Manton   XvMCSurfacePrivate *surface_priv;
354e44c85637a3298918e292e9ddba812856cf92924Younes Manton   XvMCContextPrivate *context_priv;
35580468464897682b8e10aeab310f20fdd7ddc6cb4Younes Manton   XvMCSubpicturePrivate *subpicture_priv;
356e44c85637a3298918e292e9ddba812856cf92924Younes Manton   XvMCContext *context;
357d645dc65b6c5e7d46538e98208a703f0f7a5d20bChristian König   struct u_rect src_rect = {srcx, srcx + srcw, srcy, srcy + srch};
358d645dc65b6c5e7d46538e98208a703f0f7a5d20bChristian König   struct u_rect dst_rect = {destx, destx + destw, desty, desty + desth};
359e44c85637a3298918e292e9ddba812856cf92924Younes Manton
360f56784f9d0922163d59d7e1dff74c1970b86ba2cChristian König   struct pipe_resource *tex;
361f56784f9d0922163d59d7e1dff74c1970b86ba2cChristian König   struct pipe_surface surf_templ, *surf;
362c14c84f383309ee0fdf007c0d3e968c38f3af86eChristian König   struct u_rect *dirty_area;
363f56784f9d0922163d59d7e1dff74c1970b86ba2cChristian König
3648580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton   XVMC_MSG(XVMC_TRACE, "[XvMC] Displaying surface %p.\n", surface);
3658580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton
366e44c85637a3298918e292e9ddba812856cf92924Younes Manton   assert(dpy);
367e44c85637a3298918e292e9ddba812856cf92924Younes Manton
368e44c85637a3298918e292e9ddba812856cf92924Younes Manton   if (!surface || !surface->privData)
369e44c85637a3298918e292e9ddba812856cf92924Younes Manton      return XvMCBadSurface;
370e44c85637a3298918e292e9ddba812856cf92924Younes Manton
3710e59cd33e6a38567801c7da541e4caffbd6cccd3Younes Manton   surface_priv = surface->privData;
3720e59cd33e6a38567801c7da541e4caffbd6cccd3Younes Manton   context = surface_priv->context;
3730e59cd33e6a38567801c7da541e4caffbd6cccd3Younes Manton   context_priv = context->privData;
3740e59cd33e6a38567801c7da541e4caffbd6cccd3Younes Manton
375221e1b7ababe67efe80f38f8ab2236be5cacfddfChristian König   assert(flags == XVMC_TOP_FIELD || flags == XVMC_BOTTOM_FIELD || flags == XVMC_FRAME_PICTURE);
376221e1b7ababe67efe80f38f8ab2236be5cacfddfChristian König   assert(srcx + srcw - 1 < surface->width);
377221e1b7ababe67efe80f38f8ab2236be5cacfddfChristian König   assert(srcy + srch - 1 < surface->height);
378221e1b7ababe67efe80f38f8ab2236be5cacfddfChristian König
379221e1b7ababe67efe80f38f8ab2236be5cacfddfChristian König   subpicture_priv = surface_priv->subpicture ? surface_priv->subpicture->privData : NULL;
3801448e829e86981e6144410ba6a3d0f16357fb2b3Christian König   pipe = context_priv->pipe;
381bd5fd67a3e3cda4b7676dd4745fc5d5524709210Christian König   compositor = &context_priv->compositor;
38232c4381d4a0479b3d9bfe305ce701be6b5ac8e18Christian König   cstate = &context_priv->cstate;
383221e1b7ababe67efe80f38f8ab2236be5cacfddfChristian König
384f56784f9d0922163d59d7e1dff74c1970b86ba2cChristian König   tex = vl_screen_texture_from_drawable(context_priv->vscreen, drawable);
385c14c84f383309ee0fdf007c0d3e968c38f3af86eChristian König   dirty_area = vl_screen_get_dirty_area(context_priv->vscreen);
386c14c84f383309ee0fdf007c0d3e968c38f3af86eChristian König
387f56784f9d0922163d59d7e1dff74c1970b86ba2cChristian König   memset(&surf_templ, 0, sizeof(surf_templ));
388f56784f9d0922163d59d7e1dff74c1970b86ba2cChristian König   surf_templ.format = tex->format;
389f56784f9d0922163d59d7e1dff74c1970b86ba2cChristian König   surf_templ.usage = PIPE_BIND_RENDER_TARGET;
390f56784f9d0922163d59d7e1dff74c1970b86ba2cChristian König   surf = pipe->create_surface(pipe, tex, &surf_templ);
391f3f212acf0d2fc25d3b6bd70dd1f346d97a9b25dChristian König
392f56784f9d0922163d59d7e1dff74c1970b86ba2cChristian König   if (!surf)
393e44c85637a3298918e292e9ddba812856cf92924Younes Manton      return BadDrawable;
394e44c85637a3298918e292e9ddba812856cf92924Younes Manton
395e44c85637a3298918e292e9ddba812856cf92924Younes Manton   /*
396e44c85637a3298918e292e9ddba812856cf92924Younes Manton    * Some apps (mplayer) hit these asserts because they call
397e44c85637a3298918e292e9ddba812856cf92924Younes Manton    * this function after the window has been resized by the WM
398e44c85637a3298918e292e9ddba812856cf92924Younes Manton    * but before they've handled the corresponding XEvent and
399e44c85637a3298918e292e9ddba812856cf92924Younes Manton    * know about the new dimensions. The output should be clipped
400e44c85637a3298918e292e9ddba812856cf92924Younes Manton    * until the app updates destw and desth.
401e44c85637a3298918e292e9ddba812856cf92924Younes Manton    */
402e44c85637a3298918e292e9ddba812856cf92924Younes Manton   /*
4036414952efe3b53fd33d73d592da74975a1075330Younes Manton   assert(destx + destw - 1 < drawable_surface->width);
4046414952efe3b53fd33d73d592da74975a1075330Younes Manton   assert(desty + desth - 1 < drawable_surface->height);
405e44c85637a3298918e292e9ddba812856cf92924Younes Manton    */
406e44c85637a3298918e292e9ddba812856cf92924Younes Manton
4071d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König   RecursiveEndFrame(surface_priv);
4081d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König
4091d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König   context_priv->decoder->flush(context_priv->decoder);
410e5f78a74f8294ee02015552db664dae1e7da9f47Christian König
41132c4381d4a0479b3d9bfe305ce701be6b5ac8e18Christian König   vl_compositor_clear_layers(cstate);
41232c4381d4a0479b3d9bfe305ce701be6b5ac8e18Christian König   vl_compositor_set_buffer_layer(cstate, compositor, 0, surface_priv->video_buffer,
41337f97e1753af20a7161f61e99cb203b214e00641Christian König                                  &src_rect, NULL, VL_COMPOSITOR_WEAVE);
414e44c85637a3298918e292e9ddba812856cf92924Younes Manton
41580468464897682b8e10aeab310f20fdd7ddc6cb4Younes Manton   if (subpicture_priv) {
41680468464897682b8e10aeab310f20fdd7ddc6cb4Younes Manton      XVMC_MSG(XVMC_TRACE, "[XvMC] Surface %p has subpicture %p.\n", surface, surface_priv->subpicture);
41780468464897682b8e10aeab310f20fdd7ddc6cb4Younes Manton
41880468464897682b8e10aeab310f20fdd7ddc6cb4Younes Manton      assert(subpicture_priv->surface == surface);
419efaf024f8c7c1000af06e54a85378818d55c5160Christian König
420e5f78a74f8294ee02015552db664dae1e7da9f47Christian König      if (subpicture_priv->palette)
42132c4381d4a0479b3d9bfe305ce701be6b5ac8e18Christian König         vl_compositor_set_palette_layer(cstate, compositor, 1, subpicture_priv->sampler, subpicture_priv->palette,
4224f37636afb5adc299ecbe497209702a47039580cChristian König                                         &subpicture_priv->src_rect, &subpicture_priv->dst_rect, true);
423e5f78a74f8294ee02015552db664dae1e7da9f47Christian König      else
42432c4381d4a0479b3d9bfe305ce701be6b5ac8e18Christian König         vl_compositor_set_rgba_layer(cstate, compositor, 1, subpicture_priv->sampler,
425b90727bb241e4a04158d34aad078cb18e478fea7Christian König                                      &subpicture_priv->src_rect, &subpicture_priv->dst_rect, NULL);
42680468464897682b8e10aeab310f20fdd7ddc6cb4Younes Manton
42780468464897682b8e10aeab310f20fdd7ddc6cb4Younes Manton      surface_priv->subpicture = NULL;
42880468464897682b8e10aeab310f20fdd7ddc6cb4Younes Manton      subpicture_priv->surface = NULL;
42980468464897682b8e10aeab310f20fdd7ddc6cb4Younes Manton   }
43080468464897682b8e10aeab310f20fdd7ddc6cb4Younes Manton
431104ac0066394f8246d18c833bca4bcce271b5eefChristian König   // Workaround for r600g, there seems to be a bug in the fence refcounting code
432ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König   pipe->screen->fence_reference(pipe->screen, &surface_priv->fence, NULL);
433104ac0066394f8246d18c833bca4bcce271b5eefChristian König
43474a4e9089488e7f341d21053bbf2d4aa52b99b70Christian König   vl_compositor_set_layer_dst_area(cstate, 0, &dst_rect);
43574a4e9089488e7f341d21053bbf2d4aa52b99b70Christian König   vl_compositor_set_layer_dst_area(cstate, 1, &dst_rect);
43632c4381d4a0479b3d9bfe305ce701be6b5ac8e18Christian König   vl_compositor_render(cstate, compositor, surf, dirty_area);
437dcf8ee7d6ac89bb2a9d608618a51604a3c78fe96Christian König
4380d082390d903e0a6908e1d444e762a23de14174aChristian König   pipe->flush(pipe, &surface_priv->fence);
439e44c85637a3298918e292e9ddba812856cf92924Younes Manton
44080468464897682b8e10aeab310f20fdd7ddc6cb4Younes Manton   XVMC_MSG(XVMC_TRACE, "[XvMC] Submitted surface %p for display. Pushing to front buffer.\n", surface);
44180468464897682b8e10aeab310f20fdd7ddc6cb4Younes Manton
442ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König   pipe->screen->flush_frontbuffer
443e44c85637a3298918e292e9ddba812856cf92924Younes Manton   (
444f56784f9d0922163d59d7e1dff74c1970b86ba2cChristian König      pipe->screen, tex, 0, 0,
4451448e829e86981e6144410ba6a3d0f16357fb2b3Christian König      vl_screen_get_private(context_priv->vscreen)
446e44c85637a3298918e292e9ddba812856cf92924Younes Manton   );
447e44c85637a3298918e292e9ddba812856cf92924Younes Manton
4489cff90534389c2aad9b58ff04b1a5d624e3d0bdbChristian König   if(dump_window == -1) {
4499cff90534389c2aad9b58ff04b1a5d624e3d0bdbChristian König      dump_window = debug_get_num_option("XVMC_DUMP", 0);
4509cff90534389c2aad9b58ff04b1a5d624e3d0bdbChristian König   }
4519cff90534389c2aad9b58ff04b1a5d624e3d0bdbChristian König
4529cff90534389c2aad9b58ff04b1a5d624e3d0bdbChristian König   if(dump_window) {
4539cff90534389c2aad9b58ff04b1a5d624e3d0bdbChristian König      static unsigned int framenum = 0;
4549cff90534389c2aad9b58ff04b1a5d624e3d0bdbChristian König      char cmd[256];
45587e81a3e9db1a30f6f31e6e91aeb5acfdc8b589fChristian König
4569cff90534389c2aad9b58ff04b1a5d624e3d0bdbChristian König      sprintf(cmd, "xwd -id %d -out xvmc_frame_%08d.xwd", (int)drawable, ++framenum);
45787e81a3e9db1a30f6f31e6e91aeb5acfdc8b589fChristian König      if (system(cmd) != 0)
45887e81a3e9db1a30f6f31e6e91aeb5acfdc8b589fChristian König         XVMC_MSG(XVMC_ERR, "[XvMC] Dumping surface %p failed.\n", surface);
4599cff90534389c2aad9b58ff04b1a5d624e3d0bdbChristian König   }
4609cff90534389c2aad9b58ff04b1a5d624e3d0bdbChristian König
46180468464897682b8e10aeab310f20fdd7ddc6cb4Younes Manton   XVMC_MSG(XVMC_TRACE, "[XvMC] Pushed surface %p to front buffer.\n", surface);
4628580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton
463e44c85637a3298918e292e9ddba812856cf92924Younes Manton   return Success;
464c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton}
465c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton
4663107b54b011c7ceef2b314632bdcf0b87c5e4d36Younes MantonPUBLIC
467e44c85637a3298918e292e9ddba812856cf92924Younes MantonStatus XvMCGetSurfaceStatus(Display *dpy, XvMCSurface *surface, int *status)
468c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton{
469ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König   struct pipe_context *pipe;
470104ac0066394f8246d18c833bca4bcce271b5eefChristian König   XvMCSurfacePrivate *surface_priv;
471104ac0066394f8246d18c833bca4bcce271b5eefChristian König   XvMCContextPrivate *context_priv;
472104ac0066394f8246d18c833bca4bcce271b5eefChristian König
473d52d51ab8ae1240f77b6c18c3e99be4bf4868037Younes Manton   assert(dpy);
474d52d51ab8ae1240f77b6c18c3e99be4bf4868037Younes Manton
475d52d51ab8ae1240f77b6c18c3e99be4bf4868037Younes Manton   if (!surface)
476d52d51ab8ae1240f77b6c18c3e99be4bf4868037Younes Manton      return XvMCBadSurface;
477d52d51ab8ae1240f77b6c18c3e99be4bf4868037Younes Manton
478d52d51ab8ae1240f77b6c18c3e99be4bf4868037Younes Manton   assert(status);
479d52d51ab8ae1240f77b6c18c3e99be4bf4868037Younes Manton
480104ac0066394f8246d18c833bca4bcce271b5eefChristian König   surface_priv = surface->privData;
481104ac0066394f8246d18c833bca4bcce271b5eefChristian König   context_priv = surface_priv->context->privData;
4821448e829e86981e6144410ba6a3d0f16357fb2b3Christian König   pipe = context_priv->pipe;
483104ac0066394f8246d18c833bca4bcce271b5eefChristian König
484e44c85637a3298918e292e9ddba812856cf92924Younes Manton   *status = 0;
485d52d51ab8ae1240f77b6c18c3e99be4bf4868037Younes Manton
486104ac0066394f8246d18c833bca4bcce271b5eefChristian König   if (surface_priv->fence)
487ea78480029450c019287c2a94d7c42a6a1d12dc3Christian König      if (!pipe->screen->fence_signalled(pipe->screen, surface_priv->fence))
488104ac0066394f8246d18c833bca4bcce271b5eefChristian König         *status |= XVMC_RENDERING;
489104ac0066394f8246d18c833bca4bcce271b5eefChristian König
490e44c85637a3298918e292e9ddba812856cf92924Younes Manton   return Success;
491c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton}
492c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton
4933107b54b011c7ceef2b314632bdcf0b87c5e4d36Younes MantonPUBLIC
494e44c85637a3298918e292e9ddba812856cf92924Younes MantonStatus XvMCDestroySurface(Display *dpy, XvMCSurface *surface)
495c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton{
496e44c85637a3298918e292e9ddba812856cf92924Younes Manton   XvMCSurfacePrivate *surface_priv;
4971d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König   XvMCContextPrivate *context_priv;
4981d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König
4998580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton   XVMC_MSG(XVMC_TRACE, "[XvMC] Destroying surface %p.\n", surface);
5008580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton
501e44c85637a3298918e292e9ddba812856cf92924Younes Manton   assert(dpy);
5026858dd50c9b696c1c6044f5a403000f9d20b286bYounes Manton
503e44c85637a3298918e292e9ddba812856cf92924Younes Manton   if (!surface || !surface->privData)
504e44c85637a3298918e292e9ddba812856cf92924Younes Manton      return XvMCBadSurface;
5056858dd50c9b696c1c6044f5a403000f9d20b286bYounes Manton
506e44c85637a3298918e292e9ddba812856cf92924Younes Manton   surface_priv = surface->privData;
5071d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König   context_priv = surface_priv->context->privData;
508dcf8ee7d6ac89bb2a9d608618a51604a3c78fe96Christian König
509a09754c15fc48e5fed347f478a301a02ee69fe8cMaarten Lankhorst   if (surface_priv->picture_structure) {
5108ea416f35de0c664ef47b71841756758f22d7faaChristian König      struct pipe_mpeg12_picture_desc desc;
5118ea416f35de0c664ef47b71841756758f22d7faaChristian König      GetPictureDescription(surface_priv, &desc);
5128ea416f35de0c664ef47b71841756758f22d7faaChristian König      context_priv->decoder->end_frame(context_priv->decoder, surface_priv->video_buffer, &desc.base);
5131d1d038c85ebb37f1da4540f092563e8ecab7dfbChristian König   }
514d9ad3aa3b9647f1ede2568600978af956ff32fffChristian König   surface_priv->video_buffer->destroy(surface_priv->video_buffer);
515e44c85637a3298918e292e9ddba812856cf92924Younes Manton   FREE(surface_priv);
516e44c85637a3298918e292e9ddba812856cf92924Younes Manton   surface->privData = NULL;
5176858dd50c9b696c1c6044f5a403000f9d20b286bYounes Manton
5188580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton   XVMC_MSG(XVMC_TRACE, "[XvMC] Surface %p destroyed.\n", surface);
5198580b7a0eeed3fc29320b2c0a184084e4267661aYounes Manton
520e44c85637a3298918e292e9ddba812856cf92924Younes Manton   return Success;
521c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton}
522c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton
5233107b54b011c7ceef2b314632bdcf0b87c5e4d36Younes MantonPUBLIC
524e44c85637a3298918e292e9ddba812856cf92924Younes MantonStatus XvMCHideSurface(Display *dpy, XvMCSurface *surface)
525c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton{
526e44c85637a3298918e292e9ddba812856cf92924Younes Manton   assert(dpy);
5276858dd50c9b696c1c6044f5a403000f9d20b286bYounes Manton
528e44c85637a3298918e292e9ddba812856cf92924Younes Manton   if (!surface || !surface->privData)
529e44c85637a3298918e292e9ddba812856cf92924Younes Manton      return XvMCBadSurface;
5306858dd50c9b696c1c6044f5a403000f9d20b286bYounes Manton
531e44c85637a3298918e292e9ddba812856cf92924Younes Manton   /* No op, only for overlaid rendering */
5326858dd50c9b696c1c6044f5a403000f9d20b286bYounes Manton
533e44c85637a3298918e292e9ddba812856cf92924Younes Manton   return Success;
534c11a7ec821d41b91a3825c5abfb4687c98b5bf98Younes Manton}
535