st/xorg: Fix include style
[mesa.git] / src / gallium / state_trackers / xorg / xvmc / context.c
index c8a389385a80796e8db10624ffdbd2cd52509a75..172f16cfb6375d639cb70f3711b251a72a337e93 100644 (file)
@@ -1,8 +1,8 @@
 /**************************************************************************
- * 
+ *
  * Copyright 2009 Younes Manton.
  * All Rights Reserved.
- * 
+ *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the
  * "Software"), to deal in the Software without restriction, including
  * distribute, sub license, and/or sell copies of the Software, and to
  * permit persons to whom the Software is furnished to do so, subject to
  * the following conditions:
- * 
+ *
  * The above copyright notice and this permission notice (including the
  * next paragraph) shall be included in all copies or substantial portions
  * of the Software.
- * 
+ *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
+ *
  **************************************************************************/
 
 #include <assert.h>
+
 #include <X11/Xlibint.h>
 #include <X11/extensions/XvMClib.h>
-#include <pipe/p_screen.h>
-#include <pipe/p_video_context.h>
-#include <pipe/p_video_state.h>
-#include <pipe/p_state.h>
-#include <vl_winsys.h>
-#include <util/u_memory.h>
-#include <util/u_debug.h>
-#include <vl/vl_csc.h>
+
+#include "pipe/p_screen.h"
+#include "pipe/p_video_decoder.h"
+#include "pipe/p_video_state.h"
+#include "pipe/p_state.h"
+
+#include "util/u_memory.h"
+
+#include "vl/vl_csc.h"
+#include "vl_winsys.h"
+
 #include "xvmc_private.h"
 
 static Status Validate(Display *dpy, XvPortID port, int surface_type_id,
                        unsigned int width, unsigned int height, int flags,
                        bool *found_port, int *screen, int *chroma_format,
-                       int *mc_type, int *surface_flags)
+                       int *mc_type, int *surface_flags,
+                       unsigned short *subpic_max_w,
+                       unsigned short *subpic_max_h)
 {
    bool found_surface = false;
    XvAdaptorInfo *adaptor_info;
    unsigned int num_adaptors;
    int num_types;
-   unsigned int max_width, max_height;
+   unsigned int max_width = 0, max_height = 0;
    Status ret;
 
    assert(dpy);
@@ -56,6 +62,8 @@ static Status Validate(Display *dpy, XvPortID port, int surface_type_id,
    assert(chroma_format);
    assert(mc_type);
    assert(surface_flags);
+   assert(subpic_max_w);
+   assert(subpic_max_h);
 
    *found_port = false;
 
@@ -89,7 +97,20 @@ static Status Validate(Display *dpy, XvPortID port, int surface_type_id,
                *chroma_format = surface_info[l].chroma_format;
                *mc_type = surface_info[l].mc_type;
                *surface_flags = surface_info[l].flags;
+               *subpic_max_w = surface_info[l].subpicture_max_width;
+               *subpic_max_h = surface_info[l].subpicture_max_height;
                *screen = i;
+
+               XVMC_MSG(XVMC_TRACE, "[XvMC] Found requested context surface format.\n" \
+                                    "[XvMC]   screen=%u, port=%u\n" \
+                                    "[XvMC]   id=0x%08X\n" \
+                                    "[XvMC]   max width=%u, max height=%u\n" \
+                                    "[XvMC]   chroma format=0x%08X\n" \
+                                    "[XvMC]   acceleration level=0x%08X\n" \
+                                    "[XvMC]   flags=0x%08X\n" \
+                                    "[XvMC]   subpicture max width=%u, max height=%u\n",
+                                    i, port, surface_type_id, max_width, max_height, *chroma_format,
+                                    *mc_type, *surface_flags, *subpic_max_w, *subpic_max_h);
             }
 
             XFree(surface_info);
@@ -99,14 +120,23 @@ static Status Validate(Display *dpy, XvPortID port, int surface_type_id,
       XvFreeAdaptorInfo(adaptor_info);
    }
 
-   if (!*found_port)
+   if (!*found_port) {
+      XVMC_MSG(XVMC_ERR, "[XvMC] Could not find a suitable port.\n");
       return XvBadPort;
-   if (!found_surface)
+   }
+   if (!found_surface) {
+      XVMC_MSG(XVMC_ERR, "[XvMC] Could not find a suitable surface.\n");
       return BadMatch;
-   if (width > max_width || height > max_height)
+   }
+   if (width > max_width || height > max_height) {
+      XVMC_MSG(XVMC_ERR, "[XvMC] Requested context dimensions (w=%u,h=%u) too large (max w=%u,h=%u).\n",
+               width, height, max_width, max_height);
       return BadValue;
-   if (flags != XVMC_DIRECT && flags != 0)
+   }
+   if (flags != XVMC_DIRECT && flags != 0) {
+      XVMC_MSG(XVMC_ERR, "[XvMC] Invalid context flags 0x%08X.\n", flags);
       return BadValue;
+   }
 
    return Success;
 }
@@ -121,9 +151,11 @@ static enum pipe_video_profile ProfileToPipe(int xvmc_profile)
       assert(0);
    if (xvmc_profile & XVMC_MPEG_4)
       assert(0);
-       
+
    assert(0);
 
+   XVMC_MSG(XVMC_ERR, "[XvMC] Unrecognized profile 0x%08X.\n", xvmc_profile);
+
    return -1;
 }
 
@@ -140,30 +172,38 @@ static enum pipe_video_chroma_format FormatToPipe(int xvmc_format)
          assert(0);
    }
 
+   XVMC_MSG(XVMC_ERR, "[XvMC] Unrecognized format 0x%08X.\n", xvmc_format);
+
    return -1;
 }
 
+PUBLIC
 Status XvMCCreateContext(Display *dpy, XvPortID port, int surface_type_id,
                          int width, int height, int flags, XvMCContext *context)
 {
    bool found_port;
-   int scrn;
-   int chroma_format;
-   int mc_type;
-   int surface_flags;
+   int scrn = 0;
+   int chroma_format = 0;
+   int mc_type = 0;
+   int surface_flags = 0;
+   unsigned short subpic_max_w = 0;
+   unsigned short subpic_max_h = 0;
    Status ret;
-   struct pipe_screen *screen;
-   struct pipe_video_context *vpipe;
+   struct vl_screen *vscreen;
+   struct vl_context *vctx;
    XvMCContextPrivate *context_priv;
    float csc[16];
 
+   XVMC_MSG(XVMC_TRACE, "[XvMC] Creating context %p.\n", context);
+
    assert(dpy);
 
    if (!context)
       return XvMCBadContext;
 
    ret = Validate(dpy, port, surface_type_id, width, height, flags,
-                  &found_port, &scrn, &chroma_format, &mc_type, &surface_flags);
+                  &found_port, &scrn, &chroma_format, &mc_type, &surface_flags,
+                  &subpic_max_w, &subpic_max_h);
 
    /* Success and XvBadPort have the same value */
    if (ret != Success || !found_port)
@@ -171,15 +211,15 @@ Status XvMCCreateContext(Display *dpy, XvPortID port, int surface_type_id,
 
    /* XXX: Current limits */
    if (chroma_format != XVMC_CHROMA_FORMAT_420) {
-      debug_printf("[XvMCg3dvl] Cannot decode requested surface type. Unsupported chroma format.\n");
+      XVMC_MSG(XVMC_ERR, "[XvMC] Cannot decode requested surface type. Unsupported chroma format.\n");
       return BadImplementation;
    }
-   if (mc_type != (XVMC_MOCOMP | XVMC_MPEG_2)) {
-      debug_printf("[XvMCg3dvl] Cannot decode requested surface type. Non-MPEG2/Mocomp acceleration unsupported.\n");
+   if ((mc_type & ~XVMC_IDCT) != (XVMC_MOCOMP | XVMC_MPEG_2)) {
+      XVMC_MSG(XVMC_ERR, "[XvMC] Cannot decode requested surface type. Non-MPEG2/Mocomp/iDCT acceleration unsupported.\n");
       return BadImplementation;
    }
-   if (!(surface_flags & XVMC_INTRA_UNSIGNED)) {
-      debug_printf("[XvMCg3dvl] Cannot decode requested surface type. Signed intra unsupported.\n");
+   if (surface_flags & XVMC_INTRA_UNSIGNED) {
+      XVMC_MSG(XVMC_ERR, "[XvMC] Cannot decode requested surface type. Unsigned intra unsupported.\n");
       return BadImplementation;
    }
 
@@ -188,32 +228,63 @@ Status XvMCCreateContext(Display *dpy, XvPortID port, int surface_type_id,
       return BadAlloc;
 
    /* TODO: Reuse screen if process creates another context */
-   screen = vl_screen_create(dpy, scrn);
+   vscreen = vl_screen_create(dpy, scrn);
 
-   if (!screen) {
+   if (!vscreen) {
+      XVMC_MSG(XVMC_ERR, "[XvMC] Could not create VL screen.\n");
       FREE(context_priv);
       return BadAlloc;
    }
 
-   vpipe = vl_video_create(dpy, scrn, screen, ProfileToPipe(mc_type),
-                           FormatToPipe(chroma_format), width, height);
+   vctx = vl_video_create(vscreen);
+   if (!vctx) {
+      XVMC_MSG(XVMC_ERR, "[XvMC] Could not create VL context.\n");
+      vl_screen_destroy(vscreen);
+      FREE(context_priv);
+      return BadAlloc;
+   }
+
+   context_priv->decoder = vctx->pipe->create_video_decoder
+   (
+      vctx->pipe,
+      ProfileToPipe(mc_type),
+      (mc_type & XVMC_IDCT) ? PIPE_VIDEO_ENTRYPOINT_IDCT : PIPE_VIDEO_ENTRYPOINT_MC,
+      FormatToPipe(chroma_format),
+      width, height
+   );
+
+   if (!context_priv->decoder) {
+      XVMC_MSG(XVMC_ERR, "[XvMC] Could not create VL decoder.\n");
+      vl_video_destroy(vctx);
+      vl_screen_destroy(vscreen);
+      FREE(context_priv);
+      return BadAlloc;
+   }
 
-   if (!vpipe) {
-      screen->destroy(screen);
+   if (!vl_compositor_init(&context_priv->compositor, vctx->pipe)) {
+      XVMC_MSG(XVMC_ERR, "[XvMC] Could not create VL compositor.\n");
+      context_priv->decoder->destroy(context_priv->decoder);
+      vl_video_destroy(vctx);
+      vl_screen_destroy(vscreen);
       FREE(context_priv);
       return BadAlloc;
    }
 
-   /* TODO: Define some Xv attribs to allow users to specify color standard, procamp */
+   context_priv->color_standard =
+      debug_get_bool_option("G3DVL_NO_CSC", FALSE) ?
+      VL_CSC_COLOR_STANDARD_IDENTITY : VL_CSC_COLOR_STANDARD_BT_601;
+   context_priv->procamp = vl_default_procamp;
+
    vl_csc_get_matrix
    (
-      debug_get_bool_option("G3DVL_NO_CSC", FALSE) ?
-      VL_CSC_COLOR_STANDARD_IDENTITY : VL_CSC_COLOR_STANDARD_BT_601,
-      NULL, true, csc
+      context_priv->color_standard,
+      &context_priv->procamp, true, csc
    );
-   vpipe->set_csc_matrix(vpipe, csc);
+   vl_compositor_set_csc_matrix(&context_priv->compositor, csc);
 
-   context_priv->vpipe = vpipe;
+   context_priv->vctx = vctx;
+   context_priv->subpicture_max_width = subpic_max_w;
+   context_priv->subpicture_max_height = subpic_max_h;
 
    context->context_id = XAllocID(dpy);
    context->surface_type_id = surface_type_id;
@@ -222,31 +293,40 @@ Status XvMCCreateContext(Display *dpy, XvPortID port, int surface_type_id,
    context->flags = flags;
    context->port = port;
    context->privData = context_priv;
-       
+
    SyncHandle();
 
+   XVMC_MSG(XVMC_TRACE, "[XvMC] Context %p created.\n", context);
+
    return Success;
 }
 
+PUBLIC
 Status XvMCDestroyContext(Display *dpy, XvMCContext *context)
 {
-   struct pipe_screen *screen;
-   struct pipe_video_context *vpipe;
+   struct vl_screen *vscreen;
+   struct vl_context *vctx;
    XvMCContextPrivate *context_priv;
 
+   XVMC_MSG(XVMC_TRACE, "[XvMC] Destroying context %p.\n", context);
+
    assert(dpy);
 
    if (!context || !context->privData)
       return XvMCBadContext;
 
    context_priv = context->privData;
-   vpipe = context_priv->vpipe;
-   pipe_surface_reference(&context_priv->backbuffer, NULL);
-   screen = vpipe->screen;
-   vpipe->destroy(vpipe);
-   screen->destroy(screen);
+   vctx = context_priv->vctx;
+   vscreen = vctx->vscreen;
+   pipe_surface_reference(&context_priv->drawable_surface, NULL);
+   context_priv->decoder->destroy(context_priv->decoder);
+   vl_compositor_cleanup(&context_priv->compositor);
+   vl_video_destroy(vctx);
+   vl_screen_destroy(vscreen);
    FREE(context_priv);
    context->privData = NULL;
 
+   XVMC_MSG(XVMC_TRACE, "[XvMC] Context %p destroyed.\n", context);
+
    return Success;
 }