#include <assert.h>
#include <X11/Xlibint.h>
+#include <vl_winsys.h>
#include <pipe/p_video_context.h>
#include <pipe/p_video_state.h>
#include <pipe/p_state.h>
+#include <util/u_inlines.h>
#include <util/u_memory.h>
#include "xvmc_private.h"
assert(0);
+ XVMC_MSG(XVMC_ERR, "[XvMC] Unrecognized mb type 0x%08X.\n", xvmc_mb_type);
+
return -1;
}
assert(0);
}
+ XVMC_MSG(XVMC_ERR, "[XvMC] Unrecognized picture type 0x%08X.\n", xvmc_pic);
+
return -1;
}
{
switch (xvmc_motion_type) {
case XVMC_PREDICTION_FRAME:
- return xvmc_dct_type == XVMC_DCT_TYPE_FIELD ?
- PIPE_MPEG12_MOTION_TYPE_16x8 : PIPE_MPEG12_MOTION_TYPE_FRAME;
+ if (xvmc_dct_type == XVMC_DCT_TYPE_FIELD)
+ return PIPE_MPEG12_MOTION_TYPE_16x8;
+ else if (xvmc_dct_type == XVMC_DCT_TYPE_FRAME)
+ return PIPE_MPEG12_MOTION_TYPE_FRAME;
+ break;
case XVMC_PREDICTION_FIELD:
return PIPE_MPEG12_MOTION_TYPE_FIELD;
case XVMC_PREDICTION_DUAL_PRIME:
assert(0);
}
+ XVMC_MSG(XVMC_ERR, "[XvMC] Unrecognized motion type 0x%08X (with DCT type 0x%08X).\n", xvmc_motion_type, xvmc_dct_type);
+
return -1;
}
static bool
-CreateOrResizeBackBuffer(struct pipe_video_context *vpipe, unsigned int width, unsigned int height,
+CreateOrResizeBackBuffer(struct vl_context *vctx, unsigned int width, unsigned int height,
struct pipe_surface **backbuffer)
{
+ struct pipe_video_context *vpipe;
struct pipe_texture template;
struct pipe_texture *tex;
- assert(vpipe);
+ assert(vctx);
+
+ vpipe = vctx->vpipe;
if (*backbuffer) {
if ((*backbuffer)->width != width || (*backbuffer)->height != height)
memset(&template, 0, sizeof(struct pipe_texture));
template.target = PIPE_TEXTURE_2D;
- /* XXX: Needs to match the drawable's format? */
- template.format = PIPE_FORMAT_B8G8R8X8_UNORM;
+ template.format = vctx->vscreen->format;
template.last_level = 0;
template.width0 = width;
template.height0 = height;
/* Clear the backbuffer in case the video doesn't cover the whole window */
/* FIXME: Need to clear every time a frame moves and leaves dirty rects */
- vpipe->clear_surface(vpipe, 0, 0, width, height, 0, *backbuffer);
+ vpipe->surface_fill(vpipe, *backbuffer, 0, 0, width, height, 0);
return true;
}
static void
-MacroBlocksToPipe(const XvMCMacroBlockArray *xvmc_macroblocks,
+MacroBlocksToPipe(struct pipe_screen *screen,
+ const XvMCMacroBlockArray *xvmc_macroblocks,
const XvMCBlockArray *xvmc_blocks,
unsigned int first_macroblock,
unsigned int num_macroblocks,
pipe_macroblocks->pmv[j][k][l] = xvmc_mb->PMV[j][k][l];
pipe_macroblocks->cbp = xvmc_mb->coded_block_pattern;
- pipe_macroblocks->blocks = xvmc_blocks->blocks + xvmc_mb->index * BLOCK_SIZE_SAMPLES;
+ pipe_macroblocks->blocks = pipe_user_buffer_create(screen, xvmc_blocks->blocks + xvmc_mb->index * BLOCK_SIZE_SAMPLES,
+ BLOCK_SIZE_BYTES);
++pipe_macroblocks;
++xvmc_mb;
XvMCSurfacePrivate *surface_priv;
struct pipe_video_surface *vsfc;
+ XVMC_MSG(XVMC_TRACE, "[XvMC] Creating surface %p.\n", surface);
+
assert(dpy);
if (!context)
return XvMCBadSurface;
context_priv = context->privData;
- vpipe = context_priv->vpipe;
+ vpipe = context_priv->vctx->vpipe;
surface_priv = CALLOC(1, sizeof(XvMCSurfacePrivate));
if (!surface_priv)
return BadAlloc;
+ assert(vpipe->screen->video_surface_create);
vsfc = vpipe->screen->video_surface_create(vpipe->screen, vpipe->chroma_format,
vpipe->width, vpipe->height);
if (!vsfc) {
SyncHandle();
+ XVMC_MSG(XVMC_TRACE, "[XvMC] Surface %p created.\n", surface);
+
return Success;
}
XvMCSurfacePrivate *past_surface_priv;
XvMCSurfacePrivate *future_surface_priv;
struct pipe_mpeg12_macroblock pipe_macroblocks[num_macroblocks];
+ unsigned int i;
+
+ XVMC_MSG(XVMC_TRACE, "[XvMC] Rendering to surface %p.\n", target_surface);
assert(dpy);
assert(!future_surface || future_surface_priv->context == context);
context_priv = context->privData;
- vpipe = context_priv->vpipe;
+ vpipe = context_priv->vctx->vpipe;
t_vsfc = target_surface_priv->pipe_vsfc;
p_vsfc = past_surface ? past_surface_priv->pipe_vsfc : NULL;
f_vsfc = future_surface ? future_surface_priv->pipe_vsfc : NULL;
- MacroBlocksToPipe(macroblocks, blocks, first_macroblock,
+ MacroBlocksToPipe(vpipe->screen, macroblocks, blocks, first_macroblock,
num_macroblocks, pipe_macroblocks);
vpipe->set_decode_target(vpipe, t_vsfc);
vpipe->decode_macroblocks(vpipe, p_vsfc, f_vsfc, num_macroblocks,
&pipe_macroblocks->base, target_surface_priv->render_fence);
+ for (i = 0; i < num_macroblocks; ++i)
+ vpipe->screen->buffer_destroy(pipe_macroblocks[i].blocks);
+
+ XVMC_MSG(XVMC_TRACE, "[XvMC] Submitted surface %p for rendering.\n", target_surface);
+
return Success;
}
struct pipe_video_context *vpipe;
XvMCSurfacePrivate *surface_priv;
XvMCContextPrivate *context_priv;
+ XvMCSubpicturePrivate *subpicture_priv;
XvMCContext *context;
struct pipe_video_rect src_rect = {srcx, srcy, srcw, srch};
struct pipe_video_rect dst_rect = {destx, desty, destw, desth};
+ XVMC_MSG(XVMC_TRACE, "[XvMC] Displaying surface %p.\n", surface);
+
assert(dpy);
if (!surface || !surface->privData)
surface_priv = surface->privData;
context = surface_priv->context;
context_priv = context->privData;
- vpipe = context_priv->vpipe;
+ subpicture_priv = surface_priv->subpicture ? surface_priv->subpicture->privData : NULL;
+ vpipe = context_priv->vctx->vpipe;
- if (!CreateOrResizeBackBuffer(vpipe, width, height, &context_priv->backbuffer))
+ if (!CreateOrResizeBackBuffer(context_priv->vctx, width, height, &context_priv->backbuffer))
return BadAlloc;
+ if (subpicture_priv) {
+ struct pipe_video_rect src_rect = {surface_priv->subx, surface_priv->suby, surface_priv->subw, surface_priv->subh};
+ struct pipe_video_rect dst_rect = {surface_priv->surfx, surface_priv->surfy, surface_priv->surfw, surface_priv->surfh};
+ struct pipe_video_rect *src_rects[1] = {&src_rect};
+ struct pipe_video_rect *dst_rects[1] = {&dst_rect};
+
+ XVMC_MSG(XVMC_TRACE, "[XvMC] Surface %p has subpicture %p.\n", surface, surface_priv->subpicture);
+
+ assert(subpicture_priv->surface == surface);
+ vpipe->set_picture_layers(vpipe, &subpicture_priv->sfc->texture, &src_rects, &dst_rects, 1);
+
+ surface_priv->subpicture = NULL;
+ subpicture_priv->surface = NULL;
+ }
+ else
+ vpipe->set_picture_layers(vpipe, NULL, NULL, NULL, 0);
+
vpipe->render_picture(vpipe, surface_priv->pipe_vsfc, PictureToPipe(flags), &src_rect,
context_priv->backbuffer, &dst_rect, surface_priv->disp_fence);
- vl_video_bind_drawable(vpipe, drawable);
-
+ XVMC_MSG(XVMC_TRACE, "[XvMC] Submitted surface %p for display. Pushing to front buffer.\n", surface);
+
+ vl_video_bind_drawable(context_priv->vctx, drawable);
+
vpipe->screen->flush_frontbuffer
(
vpipe->screen,
vpipe->priv
);
+ XVMC_MSG(XVMC_TRACE, "[XvMC] Pushed surface %p to front buffer.\n", surface);
+
return Success;
}
{
XvMCSurfacePrivate *surface_priv;
+ XVMC_MSG(XVMC_TRACE, "[XvMC] Destroying surface %p.\n", surface);
+
assert(dpy);
if (!surface || !surface->privData)
FREE(surface_priv);
surface->privData = NULL;
+ XVMC_MSG(XVMC_TRACE, "[XvMC] Surface %p destroyed.\n", surface);
+
return Success;
}