g3dvl: Implement XvMC using pipe_video_context.
This commit is contained in:
parent
f547472bfa
commit
e44c85637a
|
@ -0,0 +1,11 @@
|
|||
TOP = ../../../..
|
||||
include $(TOP)/configs/current
|
||||
|
||||
SUBDIRS = $(GALLIUM_WINSYS_DIRS)
|
||||
|
||||
default install clean:
|
||||
@for dir in $(SUBDIRS) ; do \
|
||||
if [ -d $$dir ] ; then \
|
||||
(cd $$dir && $(MAKE) $@) || exit 1; \
|
||||
fi \
|
||||
done
|
|
@ -2,13 +2,22 @@
|
|||
#define vl_winsys_h
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <pipe/p_defines.h>
|
||||
#include <pipe/p_format.h>
|
||||
|
||||
struct pipe_context;
|
||||
struct pipe_screen;
|
||||
struct pipe_video_context;
|
||||
|
||||
struct pipe_context* create_pipe_context(Display *display, int screen);
|
||||
int destroy_pipe_context(struct pipe_context *pipe);
|
||||
int bind_pipe_drawable(struct pipe_context *pipe, Drawable drawable);
|
||||
int unbind_pipe_drawable(struct pipe_context *pipe);
|
||||
struct pipe_screen*
|
||||
vl_screen_create(Display *display, int screen);
|
||||
|
||||
struct pipe_video_context*
|
||||
vl_video_create(struct pipe_screen *screen,
|
||||
enum pipe_video_profile profile,
|
||||
enum pipe_video_chroma_format chroma_format,
|
||||
unsigned width, unsigned height);
|
||||
|
||||
Drawable
|
||||
vl_video_bind_drawable(struct pipe_video_context *vpipe, Drawable drawable);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
# This makefile produces a "stand-alone" libXvMCg3dvl.so which is
|
||||
# based on Xlib (no DRI HW acceleration)
|
||||
|
||||
TOP = ../../../../..
|
||||
include $(TOP)/configs/current
|
||||
|
||||
XVMC_MAJOR = 1
|
||||
XVMC_MINOR = 0
|
||||
XVMC_LIB = XvMCg3dvl
|
||||
XVMC_LIB_NAME = lib$(XVMC_LIB).so
|
||||
XVMC_LIB_DEPS = $(EXTRA_LIB_PATH) -lXvMC -lXv -lX11 -lm
|
||||
|
||||
INCLUDES = -I$(TOP)/src/gallium/include \
|
||||
-I$(TOP)/src/gallium/auxiliary \
|
||||
-I$(TOP)/src/gallium/drivers \
|
||||
-I$(TOP)/src/gallium/winsys/g3dvl
|
||||
|
||||
DEFINES += -DGALLIUM_SOFTPIPE \
|
||||
-DGALLIUM_TRACE
|
||||
|
||||
SOURCES = xsp_winsys.c
|
||||
|
||||
# XXX: Hack, if we include libXvMCapi.a in LIBS none of the symbols are
|
||||
# pulled in by the linker because xsp_winsys.c doesn't refer to them
|
||||
OBJECTS = $(SOURCES:.c=.o) $(TOP)/src/xvmc/*.o
|
||||
|
||||
LIBS = $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
|
||||
$(TOP)/src/gallium/auxiliary/vl/libvl.a \
|
||||
$(TOP)/src/gallium/auxiliary/tgsi/libtgsi.a \
|
||||
$(TOP)/src/gallium/auxiliary/draw/libdraw.a \
|
||||
$(TOP)/src/gallium/auxiliary/translate/libtranslate.a \
|
||||
$(TOP)/src/gallium/auxiliary/cso_cache/libcso_cache.a \
|
||||
$(TOP)/src/gallium/auxiliary/rtasm/librtasm.a \
|
||||
$(TOP)/src/gallium/auxiliary/util/libutil.a
|
||||
|
||||
.c.o:
|
||||
$(CC) -c $(INCLUDES) $(DEFINES) $(CFLAGS) $< -o $@
|
||||
|
||||
.S.o:
|
||||
$(CC) -c $(INCLUDES) $(DEFINES) $(CFLAGS) $< -o $@
|
||||
|
||||
.PHONY: default $(TOP)/$(LIB_DIR)/gallium clean
|
||||
|
||||
default: depend $(TOP)/$(LIB_DIR)/gallium $(TOP)/$(LIB_DIR)/gallium/$(XVMC_LIB_NAME)
|
||||
|
||||
$(TOP)/$(LIB_DIR)/gallium:
|
||||
@mkdir -p $(TOP)/$(LIB_DIR)/gallium
|
||||
|
||||
# Make the libXvMCg3dvl.so library
|
||||
$(TOP)/$(LIB_DIR)/gallium/$(XVMC_LIB_NAME): $(OBJECTS) $(LIBS) Makefile
|
||||
$(MKLIB) -o $(XVMC_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \
|
||||
-major $(XVMC_MAJOR) -minor $(XVMC_MINOR) $(MKLIB_OPTIONS) \
|
||||
-install $(TOP)/$(LIB_DIR)/gallium -id $(INSTALL_LIB_DIR)/lib$(XVMC_LIB).1.dylib \
|
||||
$(XVMC_LIB_DEPS) $(OBJECTS) $(LIBS)
|
||||
|
||||
depend: $(SOURCES) Makefile
|
||||
$(RM) depend
|
||||
touch depend
|
||||
$(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDES) $(SOURCES)
|
||||
|
||||
#install: default
|
||||
# $(INSTALL) -d $(INSTALL_DIR)/include/GL
|
||||
# $(INSTALL) -d $(INSTALL_DIR)/$(LIB_DIR)
|
||||
# $(INSTALL) -m 644 $(TOP)/include/GL/*.h $(INSTALL_DIR)/include/GL
|
||||
# @if [ -e $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) ]; then \
|
||||
# $(INSTALL) $(TOP)/$(LIB_DIR)/libGL* $(INSTALL_DIR)/$(LIB_DIR); \
|
||||
# fi
|
||||
|
||||
clean: Makefile
|
||||
$(RM) $(TOP)/$(LIB_DIR)/gallium/$(XVMC_LIB_NAME)
|
||||
$(RM) *.o *~
|
||||
$(RM) depend depend.bak
|
||||
|
||||
-include depend
|
|
@ -0,0 +1,307 @@
|
|||
#include <vl_winsys.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <pipe/internal/p_winsys_screen.h>
|
||||
#include <pipe/p_state.h>
|
||||
#include <pipe/p_inlines.h>
|
||||
#include <util/u_memory.h>
|
||||
#include <util/u_math.h>
|
||||
#include <softpipe/sp_winsys.h>
|
||||
#include <softpipe/sp_video_context.h>
|
||||
#include <softpipe/sp_texture.h>
|
||||
|
||||
/* pipe_winsys implementation */
|
||||
|
||||
struct xsp_pipe_winsys
|
||||
{
|
||||
struct pipe_winsys base;
|
||||
Display *display;
|
||||
int screen;
|
||||
XImage *fbimage;
|
||||
};
|
||||
|
||||
struct xsp_context
|
||||
{
|
||||
Drawable drawable;
|
||||
|
||||
void (*pipe_destroy)(struct pipe_video_context *vpipe);
|
||||
};
|
||||
|
||||
struct xsp_buffer
|
||||
{
|
||||
struct pipe_buffer base;
|
||||
boolean is_user_buffer;
|
||||
void *data;
|
||||
void *mapped_data;
|
||||
};
|
||||
|
||||
static struct pipe_buffer* xsp_buffer_create(struct pipe_winsys *pws, unsigned alignment, unsigned usage, unsigned size)
|
||||
{
|
||||
struct xsp_buffer *buffer;
|
||||
|
||||
assert(pws);
|
||||
|
||||
buffer = calloc(1, sizeof(struct xsp_buffer));
|
||||
pipe_reference_init(&buffer->base.reference, 1);
|
||||
buffer->base.alignment = alignment;
|
||||
buffer->base.usage = usage;
|
||||
buffer->base.size = size;
|
||||
buffer->data = align_malloc(size, alignment);
|
||||
|
||||
return (struct pipe_buffer*)buffer;
|
||||
}
|
||||
|
||||
static struct pipe_buffer* xsp_user_buffer_create(struct pipe_winsys *pws, void *data, unsigned size)
|
||||
{
|
||||
struct xsp_buffer *buffer;
|
||||
|
||||
assert(pws);
|
||||
|
||||
buffer = calloc(1, sizeof(struct xsp_buffer));
|
||||
pipe_reference_init(&buffer->base.reference, 1);
|
||||
buffer->base.size = size;
|
||||
buffer->is_user_buffer = TRUE;
|
||||
buffer->data = data;
|
||||
|
||||
return (struct pipe_buffer*)buffer;
|
||||
}
|
||||
|
||||
static void* xsp_buffer_map(struct pipe_winsys *pws, struct pipe_buffer *buffer, unsigned flags)
|
||||
{
|
||||
struct xsp_buffer *xsp_buf = (struct xsp_buffer*)buffer;
|
||||
|
||||
assert(pws);
|
||||
assert(buffer);
|
||||
|
||||
xsp_buf->mapped_data = xsp_buf->data;
|
||||
|
||||
return xsp_buf->mapped_data;
|
||||
}
|
||||
|
||||
static void xsp_buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buffer)
|
||||
{
|
||||
struct xsp_buffer *xsp_buf = (struct xsp_buffer*)buffer;
|
||||
|
||||
assert(pws);
|
||||
assert(buffer);
|
||||
|
||||
xsp_buf->mapped_data = NULL;
|
||||
}
|
||||
|
||||
static void xsp_buffer_destroy(struct pipe_buffer *buffer)
|
||||
{
|
||||
struct xsp_buffer *xsp_buf = (struct xsp_buffer*)buffer;
|
||||
|
||||
assert(buffer);
|
||||
|
||||
if (!xsp_buf->is_user_buffer)
|
||||
align_free(xsp_buf->data);
|
||||
|
||||
free(xsp_buf);
|
||||
}
|
||||
|
||||
static struct pipe_buffer* xsp_surface_buffer_create
|
||||
(
|
||||
struct pipe_winsys *pws,
|
||||
unsigned width,
|
||||
unsigned height,
|
||||
enum pipe_format format,
|
||||
unsigned usage,
|
||||
unsigned tex_usage,
|
||||
unsigned *stride
|
||||
)
|
||||
{
|
||||
const unsigned int ALIGNMENT = 1;
|
||||
struct pipe_format_block block;
|
||||
unsigned nblocksx, nblocksy;
|
||||
|
||||
pf_get_block(format, &block);
|
||||
nblocksx = pf_get_nblocksx(&block, width);
|
||||
nblocksy = pf_get_nblocksy(&block, height);
|
||||
*stride = align(nblocksx * block.size, ALIGNMENT);
|
||||
|
||||
return pws->buffer_create(pws, ALIGNMENT,
|
||||
usage,
|
||||
*stride * nblocksy);
|
||||
}
|
||||
|
||||
static void xsp_fence_reference(struct pipe_winsys *pws, struct pipe_fence_handle **ptr, struct pipe_fence_handle *fence)
|
||||
{
|
||||
assert(pws);
|
||||
assert(ptr);
|
||||
assert(fence);
|
||||
}
|
||||
|
||||
static int xsp_fence_signalled(struct pipe_winsys *pws, struct pipe_fence_handle *fence, unsigned flag)
|
||||
{
|
||||
assert(pws);
|
||||
assert(fence);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xsp_fence_finish(struct pipe_winsys *pws, struct pipe_fence_handle *fence, unsigned flag)
|
||||
{
|
||||
assert(pws);
|
||||
assert(fence);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void xsp_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surface, void *context_private)
|
||||
{
|
||||
struct xsp_pipe_winsys *xsp_winsys;
|
||||
struct xsp_context *xsp_context;
|
||||
|
||||
assert(pws);
|
||||
assert(surface);
|
||||
assert(context_private);
|
||||
|
||||
xsp_winsys = (struct xsp_pipe_winsys*)pws;
|
||||
xsp_context = (struct xsp_context*)context_private;
|
||||
xsp_winsys->fbimage->width = surface->width;
|
||||
xsp_winsys->fbimage->height = surface->height;
|
||||
xsp_winsys->fbimage->bytes_per_line = surface->width * (xsp_winsys->fbimage->bits_per_pixel >> 3);
|
||||
xsp_winsys->fbimage->data = (char*)((struct xsp_buffer *)softpipe_texture(surface->texture)->buffer)->data + surface->offset;
|
||||
|
||||
XPutImage
|
||||
(
|
||||
xsp_winsys->display, xsp_context->drawable,
|
||||
XDefaultGC(xsp_winsys->display, xsp_winsys->screen),
|
||||
xsp_winsys->fbimage, 0, 0, 0, 0,
|
||||
surface->width, surface->height
|
||||
);
|
||||
XFlush(xsp_winsys->display);
|
||||
}
|
||||
|
||||
static const char* xsp_get_name(struct pipe_winsys *pws)
|
||||
{
|
||||
assert(pws);
|
||||
return "X11 SoftPipe";
|
||||
}
|
||||
|
||||
static void xsp_destroy(struct pipe_winsys *pws)
|
||||
{
|
||||
struct xsp_pipe_winsys *xsp_winsys = (struct xsp_pipe_winsys*)pws;
|
||||
|
||||
assert(pws);
|
||||
|
||||
/* XDestroyImage() wants to free the data as well */
|
||||
xsp_winsys->fbimage->data = NULL;
|
||||
|
||||
XDestroyImage(xsp_winsys->fbimage);
|
||||
FREE(xsp_winsys);
|
||||
}
|
||||
|
||||
/* Called through pipe_video_context::destroy() */
|
||||
static void xsp_pipe_destroy(struct pipe_video_context *vpipe)
|
||||
{
|
||||
struct xsp_context *xsp_context;
|
||||
|
||||
assert(vpipe);
|
||||
|
||||
xsp_context = vpipe->priv;
|
||||
|
||||
/* Call the original destroy */
|
||||
xsp_context->pipe_destroy(vpipe);
|
||||
|
||||
FREE(xsp_context);
|
||||
}
|
||||
|
||||
/* Show starts here */
|
||||
|
||||
Drawable
|
||||
vl_video_bind_drawable(struct pipe_video_context *vpipe, Drawable drawable)
|
||||
{
|
||||
struct xsp_context *xsp_context;
|
||||
Drawable old_drawable;
|
||||
|
||||
assert(vpipe);
|
||||
|
||||
xsp_context = vpipe->priv;
|
||||
old_drawable = xsp_context->drawable;
|
||||
xsp_context->drawable = drawable;
|
||||
|
||||
return old_drawable;
|
||||
}
|
||||
|
||||
struct pipe_screen*
|
||||
vl_screen_create(Display *display, int screen)
|
||||
{
|
||||
struct xsp_pipe_winsys *xsp_winsys;
|
||||
|
||||
assert(display);
|
||||
|
||||
xsp_winsys = CALLOC_STRUCT(xsp_pipe_winsys);
|
||||
if (!xsp_winsys)
|
||||
return NULL;
|
||||
|
||||
xsp_winsys->base.buffer_create = xsp_buffer_create;
|
||||
xsp_winsys->base.user_buffer_create = xsp_user_buffer_create;
|
||||
xsp_winsys->base.buffer_map = xsp_buffer_map;
|
||||
xsp_winsys->base.buffer_unmap = xsp_buffer_unmap;
|
||||
xsp_winsys->base.buffer_destroy = xsp_buffer_destroy;
|
||||
xsp_winsys->base.surface_buffer_create = xsp_surface_buffer_create;
|
||||
xsp_winsys->base.fence_reference = xsp_fence_reference;
|
||||
xsp_winsys->base.fence_signalled = xsp_fence_signalled;
|
||||
xsp_winsys->base.fence_finish = xsp_fence_finish;
|
||||
xsp_winsys->base.flush_frontbuffer = xsp_flush_frontbuffer;
|
||||
xsp_winsys->base.get_name = xsp_get_name;
|
||||
xsp_winsys->base.destroy = xsp_destroy;
|
||||
xsp_winsys->display = display;
|
||||
xsp_winsys->screen = screen;
|
||||
xsp_winsys->fbimage = XCreateImage
|
||||
(
|
||||
display,
|
||||
XDefaultVisual(display, screen),
|
||||
XDefaultDepth(display, screen),
|
||||
ZPixmap,
|
||||
0,
|
||||
NULL,
|
||||
0, /* Don't know the width and height until flush_frontbuffer */
|
||||
0,
|
||||
32,
|
||||
0
|
||||
);
|
||||
|
||||
if (!xsp_winsys->fbimage)
|
||||
{
|
||||
FREE(xsp_winsys);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
XInitImage(xsp_winsys->fbimage);
|
||||
|
||||
return softpipe_create_screen(&xsp_winsys->base);
|
||||
}
|
||||
|
||||
struct pipe_video_context*
|
||||
vl_video_create(struct pipe_screen *screen,
|
||||
enum pipe_video_profile profile,
|
||||
enum pipe_video_chroma_format chroma_format,
|
||||
unsigned width, unsigned height)
|
||||
{
|
||||
struct pipe_video_context *vpipe;
|
||||
struct xsp_context *xsp_context;
|
||||
|
||||
assert(screen);
|
||||
assert(width && height);
|
||||
|
||||
vpipe = sp_video_create(screen, profile, chroma_format, width, height);
|
||||
if (!vpipe)
|
||||
return NULL;
|
||||
|
||||
xsp_context = CALLOC_STRUCT(xsp_context);
|
||||
if (!xsp_context)
|
||||
{
|
||||
vpipe->destroy(vpipe);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Override this so we can free our xsp_context when the pipe is freed */
|
||||
xsp_context->pipe_destroy = vpipe->destroy;
|
||||
vpipe->destroy = xsp_pipe_destroy;
|
||||
|
||||
vpipe->priv = xsp_context;
|
||||
|
||||
return vpipe;
|
||||
}
|
|
@ -1,73 +1,45 @@
|
|||
TARGET = libXvMCg3dvl.so
|
||||
SONAME = libXvMCg3dvl.so.1
|
||||
GALLIUMDIR = ../gallium
|
||||
TOP = ../..
|
||||
include $(TOP)/configs/current
|
||||
|
||||
OBJECTS = block.o surface.o context.o subpicture.o attributes.o
|
||||
#DEFINES += -DDEFAULT_DRIVER_DIR=\"$(DRI_DRIVER_SEARCH_DIR)\"
|
||||
|
||||
ifeq (${DRIVER}, softpipe)
|
||||
OBJECTS += ${GALLIUMDIR}/winsys/g3dvl/xsp_winsys.o
|
||||
endif
|
||||
SOURCES = block.c \
|
||||
surface.c \
|
||||
context.c \
|
||||
subpicture.c \
|
||||
attributes.c
|
||||
|
||||
CFLAGS += -g -fPIC -Wall -Werror=implicit-function-declaration \
|
||||
-I${GALLIUMDIR}/state_trackers/g3dvl \
|
||||
-I${GALLIUMDIR}/winsys/g3dvl \
|
||||
-I${GALLIUMDIR}/include \
|
||||
-I${GALLIUMDIR}/auxiliary \
|
||||
-I${GALLIUMDIR}/drivers
|
||||
OBJECTS = $(SOURCES:.c=.o)
|
||||
|
||||
ifeq (${DRIVER}, softpipe)
|
||||
LDFLAGS += -L${GALLIUMDIR}/state_trackers/g3dvl \
|
||||
-L${GALLIUMDIR}/drivers/softpipe \
|
||||
-L${GALLIUMDIR}/auxiliary/tgsi \
|
||||
-L${GALLIUMDIR}/auxiliary/draw \
|
||||
-L${GALLIUMDIR}/auxiliary/translate \
|
||||
-L${GALLIUMDIR}/auxiliary/cso_cache \
|
||||
-L${GALLIUMDIR}/auxiliary/util \
|
||||
-L${GALLIUMDIR}/auxiliary/rtasm
|
||||
else
|
||||
LDFLAGS += -L${GALLIUMDIR}/state_trackers/g3dvl \
|
||||
-L${GALLIUMDIR}/winsys/g3dvl/nouveau \
|
||||
-L${GALLIUMDIR}/auxiliary/util
|
||||
endif
|
||||
INCLUDES = -I$(TOP)/src/gallium/include \
|
||||
-I$(TOP)/src/gallium/auxiliary \
|
||||
-I$(TOP)/src/gallium/winsys/g3dvl
|
||||
|
||||
ifeq (${DRIVER}, softpipe)
|
||||
LIBS += -lg3dvl -lsoftpipe -ldraw -ltgsi -ltranslate -lrtasm -lcso_cache -lutil -lm
|
||||
else
|
||||
LIBS += -lg3dvl -lnouveau_dri -lutil
|
||||
endif
|
||||
##### RULES #####
|
||||
|
||||
#############################################
|
||||
.c.o:
|
||||
$(CC) -c $(INCLUDES) $(DEFINES) $(CFLAGS) $< -o $@
|
||||
|
||||
ifeq (${DRIVER}, softpipe)
|
||||
.PHONY = all clean g3dvl
|
||||
else
|
||||
.PHONY = all clean g3dvl nouveau_winsys
|
||||
endif
|
||||
.S.o:
|
||||
$(CC) -c $(INCLUDES) $(DEFINES) $(CFLAGS) $< -o $@
|
||||
|
||||
all: ${TARGET}
|
||||
##### TARGETS #####
|
||||
|
||||
ifeq (${DRIVER}, softpipe)
|
||||
${TARGET}: ${OBJECTS} g3dvl
|
||||
$(CC) ${LDFLAGS} -shared -Wl,-soname,${SONAME} -o $@ ${OBJECTS} ${LIBS}
|
||||
.PHONY: default clean
|
||||
|
||||
g3dvl:
|
||||
cd ${GALLIUMDIR}/state_trackers/g3dvl; ${MAKE}
|
||||
default: depend libXvMCapi.a
|
||||
|
||||
clean:
|
||||
cd ${GALLIUMDIR}/state_trackers/g3dvl; ${MAKE} clean
|
||||
rm -rf ${OBJECTS} ${TARGET}
|
||||
else
|
||||
${TARGET}: ${OBJECTS} g3dvl nouveau_winsys
|
||||
$(CC) ${LDFLAGS} -shared -Wl,-soname,${SONAME} -o $@ ${OBJECTS} ${LIBS}
|
||||
libXvMCapi.a: $(OBJECTS) Makefile
|
||||
$(MKLIB) -o XvMCapi $(MKLIB_OPTIONS) -static $(OBJECTS)
|
||||
|
||||
g3dvl:
|
||||
cd ${GALLIUMDIR}/state_trackers/g3dvl; ${MAKE}
|
||||
depend: $(SOURCES) Makefile
|
||||
$(RM) depend
|
||||
touch depend
|
||||
$(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDES) $(SOURCES)
|
||||
|
||||
nouveau_winsys:
|
||||
cd ${GALLIUMDIR}/winsys/g3dvl/nouveau; ${MAKE}
|
||||
clean: Makefile
|
||||
$(RM) libXvMCapi.a
|
||||
$(RM) *.o *~
|
||||
$(RM) depend depend.bak
|
||||
|
||||
clean:
|
||||
cd ${GALLIUMDIR}/state_trackers/g3dvl; ${MAKE} clean
|
||||
cd ${GALLIUMDIR}/winsys/g3dvl/nouveau; ${MAKE} clean
|
||||
rm -rf ${OBJECTS} ${TARGET}
|
||||
endif
|
||||
-include depend
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
Import('*')
|
||||
|
||||
if env['platform'] not in ['linux']:
|
||||
Return()
|
||||
|
||||
env = env.Clone()
|
||||
|
||||
env.AppendUnique(CPPPATH = [
|
||||
'#/src/gallium/winsys/g3dvl',
|
||||
])
|
||||
|
||||
XvMCapi = env.StaticLibrary(
|
||||
target = 'XvMCapi',
|
||||
source = [
|
||||
'block.c',
|
||||
'surface.c',
|
||||
'context.c',
|
||||
'subpicture.c',
|
||||
'attributes.c',
|
||||
],
|
||||
)
|
|
@ -1,20 +1,19 @@
|
|||
#include <assert.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/Xvlib.h>
|
||||
#include <X11/extensions/XvMC.h>
|
||||
#include <X11/extensions/XvMClib.h>
|
||||
|
||||
XvAttribute* XvMCQueryAttributes(Display *display, XvMCContext *context, int *number)
|
||||
XvAttribute* XvMCQueryAttributes(Display *dpy, XvMCContext *context, int *number)
|
||||
{
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Status XvMCSetAttribute(Display *display, XvMCContext *context, Atom attribute, int value)
|
||||
Status XvMCSetAttribute(Display *dpy, XvMCContext *context, Atom attribute, int value)
|
||||
{
|
||||
return BadImplementation;
|
||||
return BadImplementation;
|
||||
}
|
||||
|
||||
Status XvMCGetAttribute(Display *display, XvMCContext *context, Atom attribute, int *value)
|
||||
Status XvMCGetAttribute(Display *dpy, XvMCContext *context, Atom attribute, int *value)
|
||||
{
|
||||
return BadImplementation;
|
||||
return BadImplementation;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,79 +1,61 @@
|
|||
#include <assert.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/XvMC.h>
|
||||
#include <X11/extensions/XvMClib.h>
|
||||
#include <util/u_memory.h>
|
||||
#include <vl_display.h>
|
||||
#include <vl_screen.h>
|
||||
#include <vl_context.h>
|
||||
#include "xvmc_private.h"
|
||||
|
||||
#define BLOCK_SIZE (64 * 2)
|
||||
|
||||
Status XvMCCreateBlocks(Display *display, XvMCContext *context, unsigned int num_blocks, XvMCBlockArray *blocks)
|
||||
Status XvMCCreateBlocks(Display *dpy, XvMCContext *context, unsigned int num_blocks, XvMCBlockArray *blocks)
|
||||
{
|
||||
struct vlContext *vl_ctx;
|
||||
assert(dpy);
|
||||
|
||||
assert(display);
|
||||
if (!context)
|
||||
return XvMCBadContext;
|
||||
if (num_blocks == 0)
|
||||
return BadValue;
|
||||
|
||||
if (!context)
|
||||
return XvMCBadContext;
|
||||
if (num_blocks == 0)
|
||||
return BadValue;
|
||||
assert(blocks);
|
||||
|
||||
assert(blocks);
|
||||
blocks->context_id = context->context_id;
|
||||
blocks->num_blocks = num_blocks;
|
||||
blocks->blocks = MALLOC(BLOCK_SIZE_BYTES * num_blocks);
|
||||
blocks->privData = NULL;
|
||||
|
||||
vl_ctx = context->privData;
|
||||
assert(display == vlGetNativeDisplay(vlGetDisplay(vlContextGetScreen(vl_ctx))));
|
||||
|
||||
blocks->context_id = context->context_id;
|
||||
blocks->num_blocks = num_blocks;
|
||||
blocks->blocks = MALLOC(BLOCK_SIZE * num_blocks);
|
||||
/* Since we don't have a VL type for blocks, set privData to the display so we can catch mismatches */
|
||||
blocks->privData = display;
|
||||
|
||||
return Success;
|
||||
return Success;
|
||||
}
|
||||
|
||||
Status XvMCDestroyBlocks(Display *display, XvMCBlockArray *blocks)
|
||||
Status XvMCDestroyBlocks(Display *dpy, XvMCBlockArray *blocks)
|
||||
{
|
||||
assert(display);
|
||||
assert(blocks);
|
||||
assert(display == blocks->privData);
|
||||
FREE(blocks->blocks);
|
||||
assert(dpy);
|
||||
assert(blocks);
|
||||
FREE(blocks->blocks);
|
||||
|
||||
return Success;
|
||||
return Success;
|
||||
}
|
||||
|
||||
Status XvMCCreateMacroBlocks(Display *display, XvMCContext *context, unsigned int num_blocks, XvMCMacroBlockArray *blocks)
|
||||
Status XvMCCreateMacroBlocks(Display *dpy, XvMCContext *context, unsigned int num_blocks, XvMCMacroBlockArray *blocks)
|
||||
{
|
||||
struct vlContext *vl_ctx;
|
||||
assert(dpy);
|
||||
|
||||
assert(display);
|
||||
if (!context)
|
||||
return XvMCBadContext;
|
||||
if (num_blocks == 0)
|
||||
return BadValue;
|
||||
|
||||
if (!context)
|
||||
return XvMCBadContext;
|
||||
if (num_blocks == 0)
|
||||
return BadValue;
|
||||
assert(blocks);
|
||||
|
||||
assert(blocks);
|
||||
blocks->context_id = context->context_id;
|
||||
blocks->num_blocks = num_blocks;
|
||||
blocks->macro_blocks = MALLOC(sizeof(XvMCMacroBlock) * num_blocks);
|
||||
blocks->privData = NULL;
|
||||
|
||||
vl_ctx = context->privData;
|
||||
assert(display == vlGetNativeDisplay(vlGetDisplay(vlContextGetScreen(vl_ctx))));
|
||||
|
||||
blocks->context_id = context->context_id;
|
||||
blocks->num_blocks = num_blocks;
|
||||
blocks->macro_blocks = MALLOC(sizeof(XvMCMacroBlock) * num_blocks);
|
||||
/* Since we don't have a VL type for blocks, set privData to the display so we can catch mismatches */
|
||||
blocks->privData = display;
|
||||
|
||||
return Success;
|
||||
return Success;
|
||||
}
|
||||
|
||||
Status XvMCDestroyMacroBlocks(Display *display, XvMCMacroBlockArray *blocks)
|
||||
Status XvMCDestroyMacroBlocks(Display *dpy, XvMCMacroBlockArray *blocks)
|
||||
{
|
||||
assert(display);
|
||||
assert(blocks);
|
||||
assert(display == blocks->privData);
|
||||
FREE(blocks->macro_blocks);
|
||||
assert(dpy);
|
||||
assert(blocks);
|
||||
FREE(blocks->macro_blocks);
|
||||
|
||||
return Success;
|
||||
return Success;
|
||||
}
|
||||
|
|
|
@ -1,210 +1,203 @@
|
|||
#include <assert.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/XvMClib.h>
|
||||
#include <X11/Xlibint.h>
|
||||
#include <pipe/p_context.h>
|
||||
#include <vl_display.h>
|
||||
#include <vl_screen.h>
|
||||
#include <vl_context.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 "xvmc_private.h"
|
||||
|
||||
static Status Validate
|
||||
(
|
||||
Display *display,
|
||||
XvPortID port,
|
||||
int surface_type_id,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
int flags,
|
||||
int *found_port,
|
||||
int *chroma_format,
|
||||
int *mc_type
|
||||
)
|
||||
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)
|
||||
{
|
||||
unsigned int found_surface = 0;
|
||||
XvAdaptorInfo *adaptor_info;
|
||||
unsigned int num_adaptors;
|
||||
int num_types;
|
||||
unsigned int max_width, max_height;
|
||||
Status ret;
|
||||
unsigned int i, j, k;
|
||||
bool found_surface = false;
|
||||
XvAdaptorInfo *adaptor_info;
|
||||
unsigned int num_adaptors;
|
||||
int num_types;
|
||||
unsigned int max_width, max_height;
|
||||
Status ret;
|
||||
|
||||
assert(display && chroma_format);
|
||||
assert(dpy);
|
||||
assert(found_port);
|
||||
assert(screen);
|
||||
assert(chroma_format);
|
||||
assert(mc_type);
|
||||
|
||||
*found_port = 0;
|
||||
*found_port = false;
|
||||
|
||||
ret = XvQueryAdaptors(display, XDefaultRootWindow(display), &num_adaptors, &adaptor_info);
|
||||
if (ret != Success)
|
||||
return ret;
|
||||
for (unsigned int i = 0; i < XScreenCount(dpy); ++i)
|
||||
{
|
||||
ret = XvQueryAdaptors(dpy, XRootWindow(dpy, i), &num_adaptors, &adaptor_info);
|
||||
if (ret != Success)
|
||||
return ret;
|
||||
|
||||
/* Scan through all adaptors looking for this port and surface */
|
||||
for (i = 0; i < num_adaptors && !*found_port; ++i)
|
||||
{
|
||||
/* Scan through all ports of this adaptor looking for our port */
|
||||
for (j = 0; j < adaptor_info[i].num_ports && !*found_port; ++j)
|
||||
{
|
||||
/* If this is our port, scan through all its surfaces looking for our surface */
|
||||
if (adaptor_info[i].base_id + j == port)
|
||||
{
|
||||
XvMCSurfaceInfo *surface_info;
|
||||
for (unsigned int j = 0; j < num_adaptors && !*found_port; ++j)
|
||||
{
|
||||
for (unsigned int k = 0; k < adaptor_info[j].num_ports && !*found_port; ++k)
|
||||
{
|
||||
XvMCSurfaceInfo *surface_info;
|
||||
|
||||
*found_port = 1;
|
||||
surface_info = XvMCListSurfaceTypes(display, adaptor_info[i].base_id, &num_types);
|
||||
if (adaptor_info[j].base_id + k != port)
|
||||
continue;
|
||||
|
||||
if (surface_info)
|
||||
{
|
||||
for (k = 0; k < num_types && !found_surface; ++k)
|
||||
{
|
||||
if (surface_info[k].surface_type_id == surface_type_id)
|
||||
{
|
||||
found_surface = 1;
|
||||
max_width = surface_info[k].max_width;
|
||||
max_height = surface_info[k].max_height;
|
||||
*chroma_format = surface_info[k].chroma_format;
|
||||
*mc_type = surface_info[k].mc_type;
|
||||
}
|
||||
}
|
||||
*found_port = true;
|
||||
|
||||
XFree(surface_info);
|
||||
}
|
||||
else
|
||||
{
|
||||
XvFreeAdaptorInfo(adaptor_info);
|
||||
return BadAlloc;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
surface_info = XvMCListSurfaceTypes(dpy, adaptor_info[j].base_id, &num_types);
|
||||
if (!surface_info)
|
||||
{
|
||||
XvFreeAdaptorInfo(adaptor_info);
|
||||
return BadAlloc;
|
||||
}
|
||||
|
||||
XvFreeAdaptorInfo(adaptor_info);
|
||||
for (unsigned int l = 0; l < num_types && !found_surface; ++l)
|
||||
{
|
||||
if (surface_info[l].surface_type_id != surface_type_id)
|
||||
continue;
|
||||
|
||||
if (!*found_port)
|
||||
return XvBadPort;
|
||||
if (!found_surface)
|
||||
return BadMatch;
|
||||
if (width > max_width || height > max_height)
|
||||
return BadValue;
|
||||
if (flags != XVMC_DIRECT && flags != 0)
|
||||
return BadValue;
|
||||
found_surface = true;
|
||||
max_width = surface_info[l].max_width;
|
||||
max_height = surface_info[l].max_height;
|
||||
*chroma_format = surface_info[l].chroma_format;
|
||||
*mc_type = surface_info[l].mc_type;
|
||||
*screen = i;
|
||||
}
|
||||
|
||||
return Success;
|
||||
XFree(surface_info);
|
||||
}
|
||||
}
|
||||
|
||||
XvFreeAdaptorInfo(adaptor_info);
|
||||
}
|
||||
|
||||
if (!*found_port)
|
||||
return XvBadPort;
|
||||
if (!found_surface)
|
||||
return BadMatch;
|
||||
if (width > max_width || height > max_height)
|
||||
return BadValue;
|
||||
if (flags != XVMC_DIRECT && flags != 0)
|
||||
return BadValue;
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
static enum vlProfile ProfileToVL(int xvmc_profile)
|
||||
static enum pipe_video_profile ProfileToPipe(int xvmc_profile)
|
||||
{
|
||||
if (xvmc_profile & XVMC_MPEG_1)
|
||||
assert(0);
|
||||
else if (xvmc_profile & XVMC_MPEG_2)
|
||||
return vlProfileMpeg2Main;
|
||||
else if (xvmc_profile & XVMC_H263)
|
||||
assert(0);
|
||||
else if (xvmc_profile & XVMC_MPEG_4)
|
||||
assert(0);
|
||||
else
|
||||
assert(0);
|
||||
if (xvmc_profile & XVMC_MPEG_1)
|
||||
assert(0);
|
||||
if (xvmc_profile & XVMC_MPEG_2)
|
||||
return PIPE_VIDEO_PROFILE_MPEG2_MAIN;
|
||||
if (xvmc_profile & XVMC_H263)
|
||||
assert(0);
|
||||
if (xvmc_profile & XVMC_MPEG_4)
|
||||
assert(0);
|
||||
|
||||
assert(0);
|
||||
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static enum vlEntryPoint EntryToVL(int xvmc_entry)
|
||||
static enum pipe_video_chroma_format FormatToPipe(int xvmc_format)
|
||||
{
|
||||
return xvmc_entry & XVMC_IDCT ? vlEntryPointIDCT : vlEntryPointMC;
|
||||
switch (xvmc_format)
|
||||
{
|
||||
case XVMC_CHROMA_FORMAT_420:
|
||||
return PIPE_VIDEO_CHROMA_FORMAT_420;
|
||||
case XVMC_CHROMA_FORMAT_422:
|
||||
return PIPE_VIDEO_CHROMA_FORMAT_422;
|
||||
case XVMC_CHROMA_FORMAT_444:
|
||||
return PIPE_VIDEO_CHROMA_FORMAT_444;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static enum vlFormat FormatToVL(int xvmc_format)
|
||||
Status XvMCCreateContext(Display *dpy, XvPortID port, int surface_type_id,
|
||||
int width, int height, int flags, XvMCContext *context)
|
||||
{
|
||||
switch (xvmc_format)
|
||||
{
|
||||
case XVMC_CHROMA_FORMAT_420:
|
||||
return vlFormatYCbCr420;
|
||||
case XVMC_CHROMA_FORMAT_422:
|
||||
return vlFormatYCbCr422;
|
||||
case XVMC_CHROMA_FORMAT_444:
|
||||
return vlFormatYCbCr444;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
bool found_port;
|
||||
int scrn;
|
||||
int chroma_format;
|
||||
int mc_type;
|
||||
Status ret;
|
||||
struct pipe_screen *screen;
|
||||
struct pipe_video_context *vpipe;
|
||||
XvMCContextPrivate *context_priv;
|
||||
|
||||
return -1;
|
||||
assert(dpy);
|
||||
|
||||
if (!context)
|
||||
return XvMCBadContext;
|
||||
|
||||
ret = Validate(dpy, port, surface_type_id, width, height, flags,
|
||||
&found_port, &scrn, &chroma_format, &mc_type);
|
||||
|
||||
/* Success and XvBadPort have the same value */
|
||||
if (ret != Success || !found_port)
|
||||
return ret;
|
||||
|
||||
context_priv = CALLOC(1, sizeof(XvMCContextPrivate));
|
||||
if (!context_priv)
|
||||
return BadAlloc;
|
||||
|
||||
/* TODO: Reuse screen if process creates another context */
|
||||
screen = vl_screen_create(dpy, scrn);
|
||||
|
||||
if (!screen)
|
||||
{
|
||||
FREE(context_priv);
|
||||
return BadAlloc;
|
||||
}
|
||||
|
||||
vpipe = vl_video_create(screen, ProfileToPipe(mc_type),
|
||||
FormatToPipe(chroma_format), width, height);
|
||||
|
||||
if (!vpipe)
|
||||
{
|
||||
screen->destroy(screen);
|
||||
FREE(context_priv);
|
||||
return BadAlloc;
|
||||
}
|
||||
|
||||
context_priv->vpipe = vpipe;
|
||||
|
||||
context->context_id = XAllocID(dpy);
|
||||
context->surface_type_id = surface_type_id;
|
||||
context->width = width;
|
||||
context->height = height;
|
||||
context->flags = flags;
|
||||
context->port = port;
|
||||
context->privData = context_priv;
|
||||
|
||||
SyncHandle();
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
Status XvMCCreateContext(Display *display, XvPortID port, int surface_type_id, int width, int height, int flags, XvMCContext *context)
|
||||
Status XvMCDestroyContext(Display *dpy, XvMCContext *context)
|
||||
{
|
||||
int found_port;
|
||||
int chroma_format;
|
||||
int mc_type;
|
||||
Status ret;
|
||||
struct vlDisplay *vl_dpy;
|
||||
struct vlScreen *vl_scrn;
|
||||
struct vlContext *vl_ctx;
|
||||
struct pipe_context *pipe;
|
||||
Display *dpy = display;
|
||||
struct pipe_screen *screen;
|
||||
struct pipe_video_context *vpipe;
|
||||
XvMCContextPrivate *context_priv;
|
||||
|
||||
assert(display);
|
||||
assert(dpy);
|
||||
|
||||
if (!context)
|
||||
return XvMCBadContext;
|
||||
if (!context || !context->privData)
|
||||
return XvMCBadContext;
|
||||
|
||||
ret = Validate(display, port, surface_type_id, width, height, flags, &found_port, &chroma_format, &mc_type);
|
||||
context_priv = context->privData;
|
||||
vpipe = context_priv->vpipe;
|
||||
pipe_surface_reference(&context_priv->backbuffer, NULL);
|
||||
screen = vpipe->screen;
|
||||
vpipe->destroy(vpipe);
|
||||
screen->destroy(screen);
|
||||
FREE(context_priv);
|
||||
context->privData = NULL;
|
||||
|
||||
/* XXX: Success and XvBadPort have the same value */
|
||||
if (ret != Success || !found_port)
|
||||
return ret;
|
||||
|
||||
/* XXX: Assumes default screen, should check which screen port is on */
|
||||
pipe = create_pipe_context(display, XDefaultScreen(display));
|
||||
|
||||
assert(pipe);
|
||||
|
||||
vlCreateDisplay(display, &vl_dpy);
|
||||
vlCreateScreen(vl_dpy, XDefaultScreen(display), pipe->screen, &vl_scrn);
|
||||
vlCreateContext
|
||||
(
|
||||
vl_scrn,
|
||||
pipe,
|
||||
width,
|
||||
height,
|
||||
FormatToVL(chroma_format),
|
||||
ProfileToVL(mc_type),
|
||||
EntryToVL(mc_type),
|
||||
&vl_ctx
|
||||
);
|
||||
|
||||
context->context_id = XAllocID(display);
|
||||
context->surface_type_id = surface_type_id;
|
||||
context->width = width;
|
||||
context->height = height;
|
||||
context->flags = flags;
|
||||
context->port = port;
|
||||
context->privData = vl_ctx;
|
||||
|
||||
SyncHandle();
|
||||
return Success;
|
||||
}
|
||||
|
||||
Status XvMCDestroyContext(Display *display, XvMCContext *context)
|
||||
{
|
||||
struct vlContext *vl_ctx;
|
||||
struct vlScreen *vl_screen;
|
||||
struct vlDisplay *vl_dpy;
|
||||
struct pipe_context *pipe;
|
||||
|
||||
assert(display);
|
||||
|
||||
if (!context)
|
||||
return XvMCBadContext;
|
||||
|
||||
vl_ctx = context->privData;
|
||||
|
||||
assert(display == vlGetNativeDisplay(vlGetDisplay(vlContextGetScreen(vl_ctx))));
|
||||
|
||||
pipe = vlGetPipeContext(vl_ctx);
|
||||
vl_screen = vlContextGetScreen(vl_ctx);
|
||||
vl_dpy = vlGetDisplay(vl_screen);
|
||||
vlDestroyContext(vl_ctx);
|
||||
vlDestroyScreen(vl_screen);
|
||||
vlDestroyDisplay(vl_dpy);
|
||||
destroy_pipe_context(pipe);
|
||||
|
||||
return Success;
|
||||
return Success;
|
||||
}
|
||||
|
|
|
@ -1,218 +1,168 @@
|
|||
#include <assert.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/Xvlib.h>
|
||||
#include <X11/extensions/XvMC.h>
|
||||
#include <X11/Xlibint.h>
|
||||
#include <X11/extensions/XvMClib.h>
|
||||
|
||||
Status XvMCCreateSubpicture
|
||||
(
|
||||
Display *display,
|
||||
XvMCContext *context,
|
||||
XvMCSubpicture *subpicture,
|
||||
unsigned short width,
|
||||
unsigned short height,
|
||||
int xvimage_id
|
||||
)
|
||||
Status XvMCCreateSubpicture(Display *dpy, XvMCContext *context, XvMCSubpicture *subpicture,
|
||||
unsigned short width, unsigned short height, int xvimage_id)
|
||||
{
|
||||
Display *dpy = display;
|
||||
assert(display);
|
||||
|
||||
if (!context)
|
||||
return XvMCBadContext;
|
||||
|
||||
assert(subpicture);
|
||||
|
||||
if (width > 2048 || height > 2048)
|
||||
return BadValue;
|
||||
|
||||
if (xvimage_id != 123)
|
||||
return BadMatch;
|
||||
|
||||
subpicture->subpicture_id = XAllocID(display);
|
||||
subpicture->context_id = context->context_id;
|
||||
subpicture->xvimage_id = xvimage_id;
|
||||
subpicture->width = width;
|
||||
subpicture->height = height;
|
||||
subpicture->num_palette_entries = 0;
|
||||
subpicture->entry_bytes = 0;
|
||||
subpicture->component_order[0] = 0;
|
||||
subpicture->component_order[1] = 0;
|
||||
subpicture->component_order[2] = 0;
|
||||
subpicture->component_order[3] = 0;
|
||||
/* TODO: subpicture->privData = ;*/
|
||||
assert(dpy);
|
||||
|
||||
SyncHandle();
|
||||
return Success;
|
||||
if (!context)
|
||||
return XvMCBadContext;
|
||||
|
||||
assert(subpicture);
|
||||
|
||||
/*if (width > || height > )
|
||||
return BadValue;*/
|
||||
|
||||
/*if (xvimage_id != )
|
||||
return BadMatch;*/
|
||||
|
||||
subpicture->subpicture_id = XAllocID(dpy);
|
||||
subpicture->context_id = context->context_id;
|
||||
subpicture->xvimage_id = xvimage_id;
|
||||
subpicture->width = width;
|
||||
subpicture->height = height;
|
||||
subpicture->num_palette_entries = 0;
|
||||
subpicture->entry_bytes = 0;
|
||||
subpicture->component_order[0] = 0;
|
||||
subpicture->component_order[1] = 0;
|
||||
subpicture->component_order[2] = 0;
|
||||
subpicture->component_order[3] = 0;
|
||||
/* TODO: subpicture->privData = ;*/
|
||||
|
||||
SyncHandle();
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
Status XvMCClearSubpicture
|
||||
(
|
||||
Display *display,
|
||||
XvMCSubpicture *subpicture,
|
||||
short x,
|
||||
short y,
|
||||
unsigned short width,
|
||||
unsigned short height,
|
||||
unsigned int color
|
||||
)
|
||||
Status XvMCClearSubpicture(Display *dpy, XvMCSubpicture *subpicture, short x, short y,
|
||||
unsigned short width, unsigned short height, unsigned int color)
|
||||
{
|
||||
assert(display);
|
||||
|
||||
if (!subpicture)
|
||||
return XvMCBadSubpicture;
|
||||
|
||||
/* TODO: Assert clear rect is within bounds? Or clip? */
|
||||
|
||||
return Success;
|
||||
assert(dpy);
|
||||
|
||||
if (!subpicture)
|
||||
return XvMCBadSubpicture;
|
||||
|
||||
/* TODO: Assert clear rect is within bounds? Or clip? */
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
Status XvMCCompositeSubpicture
|
||||
(
|
||||
Display *display,
|
||||
XvMCSubpicture *subpicture,
|
||||
XvImage *image,
|
||||
short srcx,
|
||||
short srcy,
|
||||
unsigned short width,
|
||||
unsigned short height,
|
||||
short dstx,
|
||||
short dsty
|
||||
)
|
||||
Status XvMCCompositeSubpicture(Display *dpy, XvMCSubpicture *subpicture, XvImage *image,
|
||||
short srcx, short srcy, unsigned short width, unsigned short height,
|
||||
short dstx, short dsty)
|
||||
{
|
||||
assert(display);
|
||||
|
||||
if (!subpicture)
|
||||
return XvMCBadSubpicture;
|
||||
|
||||
assert(image);
|
||||
|
||||
if (subpicture->xvimage_id != image->id)
|
||||
return BadMatch;
|
||||
|
||||
/* TODO: Assert rects are within bounds? Or clip? */
|
||||
|
||||
return Success;
|
||||
assert(dpy);
|
||||
|
||||
if (!subpicture)
|
||||
return XvMCBadSubpicture;
|
||||
|
||||
assert(image);
|
||||
|
||||
if (subpicture->xvimage_id != image->id)
|
||||
return BadMatch;
|
||||
|
||||
/* TODO: Assert rects are within bounds? Or clip? */
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
Status XvMCDestroySubpicture(Display *display, XvMCSubpicture *subpicture)
|
||||
Status XvMCDestroySubpicture(Display *dpy, XvMCSubpicture *subpicture)
|
||||
{
|
||||
assert(display);
|
||||
|
||||
if (!subpicture)
|
||||
return XvMCBadSubpicture;
|
||||
|
||||
return BadImplementation;
|
||||
assert(dpy);
|
||||
|
||||
if (!subpicture)
|
||||
return XvMCBadSubpicture;
|
||||
|
||||
return BadImplementation;
|
||||
}
|
||||
|
||||
Status XvMCSetSubpicturePalette(Display *display, XvMCSubpicture *subpicture, unsigned char *palette)
|
||||
Status XvMCSetSubpicturePalette(Display *dpy, XvMCSubpicture *subpicture, unsigned char *palette)
|
||||
{
|
||||
assert(display);
|
||||
|
||||
if (!subpicture)
|
||||
return XvMCBadSubpicture;
|
||||
|
||||
assert(palette);
|
||||
|
||||
/* We don't support paletted subpictures */
|
||||
return BadMatch;
|
||||
assert(dpy);
|
||||
|
||||
if (!subpicture)
|
||||
return XvMCBadSubpicture;
|
||||
|
||||
assert(palette);
|
||||
|
||||
/* We don't support paletted subpictures */
|
||||
return BadMatch;
|
||||
}
|
||||
|
||||
Status XvMCBlendSubpicture
|
||||
(
|
||||
Display *display,
|
||||
XvMCSurface *target_surface,
|
||||
XvMCSubpicture *subpicture,
|
||||
short subx,
|
||||
short suby,
|
||||
unsigned short subw,
|
||||
unsigned short subh,
|
||||
short surfx,
|
||||
short surfy,
|
||||
unsigned short surfw,
|
||||
unsigned short surfh
|
||||
)
|
||||
Status XvMCBlendSubpicture(Display *dpy, XvMCSurface *target_surface, XvMCSubpicture *subpicture,
|
||||
short subx, short suby, unsigned short subw, unsigned short subh,
|
||||
short surfx, short surfy, unsigned short surfw, unsigned short surfh)
|
||||
{
|
||||
assert(display);
|
||||
|
||||
if (!target_surface)
|
||||
return XvMCBadSurface;
|
||||
|
||||
if (!subpicture)
|
||||
return XvMCBadSubpicture;
|
||||
|
||||
if (target_surface->context_id != subpicture->context_id)
|
||||
return BadMatch;
|
||||
|
||||
/* TODO: Assert rects are within bounds? Or clip? */
|
||||
return Success;
|
||||
assert(dpy);
|
||||
|
||||
if (!target_surface)
|
||||
return XvMCBadSurface;
|
||||
|
||||
if (!subpicture)
|
||||
return XvMCBadSubpicture;
|
||||
|
||||
if (target_surface->context_id != subpicture->context_id)
|
||||
return BadMatch;
|
||||
|
||||
/* TODO: Assert rects are within bounds? Or clip? */
|
||||
return Success;
|
||||
}
|
||||
|
||||
Status XvMCBlendSubpicture2
|
||||
(
|
||||
Display *display,
|
||||
XvMCSurface *source_surface,
|
||||
XvMCSurface *target_surface,
|
||||
XvMCSubpicture *subpicture,
|
||||
short subx,
|
||||
short suby,
|
||||
unsigned short subw,
|
||||
unsigned short subh,
|
||||
short surfx,
|
||||
short surfy,
|
||||
unsigned short surfw,
|
||||
unsigned short surfh
|
||||
)
|
||||
Status XvMCBlendSubpicture2(Display *dpy, XvMCSurface *source_surface, XvMCSurface *target_surface,
|
||||
XvMCSubpicture *subpicture, short subx, short suby, unsigned short subw, unsigned short subh,
|
||||
short surfx, short surfy, unsigned short surfw, unsigned short surfh)
|
||||
{
|
||||
assert(display);
|
||||
|
||||
if (!source_surface || !target_surface)
|
||||
return XvMCBadSurface;
|
||||
|
||||
if (!subpicture)
|
||||
return XvMCBadSubpicture;
|
||||
|
||||
if (source_surface->context_id != subpicture->context_id)
|
||||
return BadMatch;
|
||||
|
||||
if (source_surface->context_id != subpicture->context_id)
|
||||
return BadMatch;
|
||||
|
||||
/* TODO: Assert rects are within bounds? Or clip? */
|
||||
return Success;
|
||||
assert(dpy);
|
||||
|
||||
if (!source_surface || !target_surface)
|
||||
return XvMCBadSurface;
|
||||
|
||||
if (!subpicture)
|
||||
return XvMCBadSubpicture;
|
||||
|
||||
if (source_surface->context_id != subpicture->context_id)
|
||||
return BadMatch;
|
||||
|
||||
if (source_surface->context_id != subpicture->context_id)
|
||||
return BadMatch;
|
||||
|
||||
/* TODO: Assert rects are within bounds? Or clip? */
|
||||
return Success;
|
||||
}
|
||||
|
||||
Status XvMCSyncSubpicture(Display *display, XvMCSubpicture *subpicture)
|
||||
Status XvMCSyncSubpicture(Display *dpy, XvMCSubpicture *subpicture)
|
||||
{
|
||||
assert(display);
|
||||
|
||||
if (!subpicture)
|
||||
return XvMCBadSubpicture;
|
||||
|
||||
return Success;
|
||||
assert(dpy);
|
||||
|
||||
if (!subpicture)
|
||||
return XvMCBadSubpicture;
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
Status XvMCFlushSubpicture(Display *display, XvMCSubpicture *subpicture)
|
||||
Status XvMCFlushSubpicture(Display *dpy, XvMCSubpicture *subpicture)
|
||||
{
|
||||
assert(display);
|
||||
|
||||
if (!subpicture)
|
||||
return XvMCBadSubpicture;
|
||||
|
||||
return Success;
|
||||
assert(dpy);
|
||||
|
||||
if (!subpicture)
|
||||
return XvMCBadSubpicture;
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
Status XvMCGetSubpictureStatus(Display *display, XvMCSubpicture *subpicture, int *status)
|
||||
Status XvMCGetSubpictureStatus(Display *dpy, XvMCSubpicture *subpicture, int *status)
|
||||
{
|
||||
assert(display);
|
||||
|
||||
if (!subpicture)
|
||||
return XvMCBadSubpicture;
|
||||
|
||||
assert(status);
|
||||
|
||||
/* TODO */
|
||||
*status = 0;
|
||||
|
||||
return Success;
|
||||
}
|
||||
assert(dpy);
|
||||
|
||||
if (!subpicture)
|
||||
return XvMCBadSubpicture;
|
||||
|
||||
assert(status);
|
||||
|
||||
/* TODO */
|
||||
*status = 0;
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
|
|
@ -1,290 +1,369 @@
|
|||
#include <assert.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/XvMC.h>
|
||||
#include <X11/Xlibint.h>
|
||||
#include <vl_display.h>
|
||||
#include <vl_screen.h>
|
||||
#include <vl_context.h>
|
||||
#include <vl_surface.h>
|
||||
#include <vl_types.h>
|
||||
#include <pipe/p_video_context.h>
|
||||
#include <pipe/p_video_state.h>
|
||||
#include <pipe/p_state.h>
|
||||
#include <util/u_memory.h>
|
||||
#include "xvmc_private.h"
|
||||
|
||||
static enum vlMacroBlockType TypeToVL(int xvmc_mb_type)
|
||||
static enum pipe_mpeg12_macroblock_type TypeToPipe(int xvmc_mb_type)
|
||||
{
|
||||
if (xvmc_mb_type & XVMC_MB_TYPE_INTRA)
|
||||
return vlMacroBlockTypeIntra;
|
||||
if ((xvmc_mb_type & (XVMC_MB_TYPE_MOTION_FORWARD | XVMC_MB_TYPE_MOTION_BACKWARD)) == XVMC_MB_TYPE_MOTION_FORWARD)
|
||||
return vlMacroBlockTypeFwdPredicted;
|
||||
if ((xvmc_mb_type & (XVMC_MB_TYPE_MOTION_FORWARD | XVMC_MB_TYPE_MOTION_BACKWARD)) == XVMC_MB_TYPE_MOTION_BACKWARD)
|
||||
return vlMacroBlockTypeBkwdPredicted;
|
||||
if ((xvmc_mb_type & (XVMC_MB_TYPE_MOTION_FORWARD | XVMC_MB_TYPE_MOTION_BACKWARD)) == (XVMC_MB_TYPE_MOTION_FORWARD | XVMC_MB_TYPE_MOTION_BACKWARD))
|
||||
return vlMacroBlockTypeBiPredicted;
|
||||
if (xvmc_mb_type & XVMC_MB_TYPE_INTRA)
|
||||
return PIPE_MPEG12_MACROBLOCK_TYPE_INTRA;
|
||||
if ((xvmc_mb_type & (XVMC_MB_TYPE_MOTION_FORWARD | XVMC_MB_TYPE_MOTION_BACKWARD)) == XVMC_MB_TYPE_MOTION_FORWARD)
|
||||
return PIPE_MPEG12_MACROBLOCK_TYPE_FWD;
|
||||
if ((xvmc_mb_type & (XVMC_MB_TYPE_MOTION_FORWARD | XVMC_MB_TYPE_MOTION_BACKWARD)) == XVMC_MB_TYPE_MOTION_BACKWARD)
|
||||
return PIPE_MPEG12_MACROBLOCK_TYPE_BKWD;
|
||||
if ((xvmc_mb_type & (XVMC_MB_TYPE_MOTION_FORWARD | XVMC_MB_TYPE_MOTION_BACKWARD)) == (XVMC_MB_TYPE_MOTION_FORWARD | XVMC_MB_TYPE_MOTION_BACKWARD))
|
||||
return PIPE_MPEG12_MACROBLOCK_TYPE_BI;
|
||||
|
||||
assert(0);
|
||||
assert(0);
|
||||
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static enum vlPictureType PictureToVL(int xvmc_pic)
|
||||
static enum pipe_mpeg12_picture_type PictureToPipe(int xvmc_pic)
|
||||
{
|
||||
switch (xvmc_pic)
|
||||
{
|
||||
case XVMC_TOP_FIELD:
|
||||
return vlPictureTypeTopField;
|
||||
case XVMC_BOTTOM_FIELD:
|
||||
return vlPictureTypeBottomField;
|
||||
case XVMC_FRAME_PICTURE:
|
||||
return vlPictureTypeFrame;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
switch (xvmc_pic)
|
||||
{
|
||||
case XVMC_TOP_FIELD:
|
||||
return PIPE_MPEG12_PICTURE_TYPE_FIELD_TOP;
|
||||
case XVMC_BOTTOM_FIELD:
|
||||
return PIPE_MPEG12_PICTURE_TYPE_FIELD_BOTTOM;
|
||||
case XVMC_FRAME_PICTURE:
|
||||
return PIPE_MPEG12_PICTURE_TYPE_FRAME;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static enum vlMotionType MotionToVL(int xvmc_motion_type, int xvmc_dct_type)
|
||||
static enum pipe_mpeg12_motion_type MotionToPipe(int xvmc_motion_type, int xvmc_dct_type)
|
||||
{
|
||||
switch (xvmc_motion_type)
|
||||
{
|
||||
case XVMC_PREDICTION_FRAME:
|
||||
return xvmc_dct_type == XVMC_DCT_TYPE_FIELD ? vlMotionType16x8 : vlMotionTypeFrame;
|
||||
case XVMC_PREDICTION_FIELD:
|
||||
return vlMotionTypeField;
|
||||
case XVMC_PREDICTION_DUAL_PRIME:
|
||||
return vlMotionTypeDualPrime;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
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;
|
||||
case XVMC_PREDICTION_FIELD:
|
||||
return PIPE_MPEG12_MOTION_TYPE_FIELD;
|
||||
case XVMC_PREDICTION_DUAL_PRIME:
|
||||
return PIPE_MPEG12_MOTION_TYPE_DUALPRIME;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
Status XvMCCreateSurface(Display *display, XvMCContext *context, XvMCSurface *surface)
|
||||
static bool
|
||||
CreateOrResizeBackBuffer(struct pipe_video_context *vpipe, unsigned int width, unsigned int height,
|
||||
struct pipe_surface **backbuffer)
|
||||
{
|
||||
struct vlContext *vl_ctx;
|
||||
struct vlSurface *vl_sfc;
|
||||
Display *dpy = display;
|
||||
struct pipe_texture template;
|
||||
struct pipe_texture *tex;
|
||||
|
||||
assert(display);
|
||||
assert(vpipe);
|
||||
|
||||
if (!context)
|
||||
return XvMCBadContext;
|
||||
if (!surface)
|
||||
return XvMCBadSurface;
|
||||
if (*backbuffer)
|
||||
{
|
||||
if ((*backbuffer)->width != width || (*backbuffer)->height != height)
|
||||
pipe_surface_reference(backbuffer, NULL);
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
vl_ctx = context->privData;
|
||||
memset(&template, 0, sizeof(struct pipe_texture));
|
||||
template.target = PIPE_TEXTURE_2D;
|
||||
/* XXX: Needs to match the drawable's format? */
|
||||
template.format = PIPE_FORMAT_X8R8G8B8_UNORM;
|
||||
template.last_level = 0;
|
||||
template.width[0] = width;
|
||||
template.height[0] = height;
|
||||
template.depth[0] = 1;
|
||||
pf_get_block(template.format, &template.block);
|
||||
template.tex_usage = PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
|
||||
|
||||
assert(display == vlGetNativeDisplay(vlGetDisplay(vlContextGetScreen(vl_ctx))));
|
||||
tex = vpipe->screen->texture_create(vpipe->screen, &template);
|
||||
if (!tex)
|
||||
return false;
|
||||
|
||||
if (vlCreateSurface(vlContextGetScreen(vl_ctx),
|
||||
context->width, context->height,
|
||||
vlGetPictureFormat(vl_ctx),
|
||||
&vl_sfc))
|
||||
{
|
||||
return BadAlloc;
|
||||
}
|
||||
*backbuffer = vpipe->screen->get_tex_surface(vpipe->screen, tex, 0, 0, 0,
|
||||
PIPE_BUFFER_USAGE_GPU_READ |
|
||||
PIPE_BUFFER_USAGE_GPU_WRITE);
|
||||
pipe_texture_reference(&tex, NULL);
|
||||
|
||||
vlBindToContext(vl_sfc, vl_ctx);
|
||||
if (!*backbuffer)
|
||||
return false;
|
||||
|
||||
surface->surface_id = XAllocID(display);
|
||||
surface->context_id = context->context_id;
|
||||
surface->surface_type_id = context->surface_type_id;
|
||||
surface->width = context->width;
|
||||
surface->height = context->height;
|
||||
surface->privData = vl_sfc;
|
||||
/* 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);
|
||||
|
||||
SyncHandle();
|
||||
return Success;
|
||||
return true;
|
||||
}
|
||||
|
||||
Status XvMCRenderSurface
|
||||
(
|
||||
Display *display,
|
||||
XvMCContext *context,
|
||||
unsigned int picture_structure,
|
||||
XvMCSurface *target_surface,
|
||||
XvMCSurface *past_surface,
|
||||
XvMCSurface *future_surface,
|
||||
unsigned int flags,
|
||||
unsigned int num_macroblocks,
|
||||
unsigned int first_macroblock,
|
||||
XvMCMacroBlockArray *macroblocks,
|
||||
XvMCBlockArray *blocks
|
||||
static void
|
||||
MacroBlocksToPipe(const XvMCMacroBlockArray *xvmc_macroblocks,
|
||||
const XvMCBlockArray *xvmc_blocks,
|
||||
unsigned int first_macroblock,
|
||||
unsigned int num_macroblocks,
|
||||
struct pipe_mpeg12_macroblock *pipe_macroblocks)
|
||||
{
|
||||
unsigned int i, j, k, l;
|
||||
XvMCMacroBlock *xvmc_mb;
|
||||
|
||||
assert(xvmc_macroblocks);
|
||||
assert(xvmc_blocks);
|
||||
assert(pipe_macroblocks);
|
||||
assert(num_macroblocks);
|
||||
|
||||
xvmc_mb = xvmc_macroblocks->macro_blocks + first_macroblock;
|
||||
|
||||
for (i = 0; i < num_macroblocks; ++i)
|
||||
{
|
||||
pipe_macroblocks->base.codec = PIPE_VIDEO_CODEC_MPEG12;
|
||||
pipe_macroblocks->mbx = xvmc_mb->x;
|
||||
pipe_macroblocks->mby = xvmc_mb->y;
|
||||
pipe_macroblocks->mb_type = TypeToPipe(xvmc_mb->macroblock_type);
|
||||
if (pipe_macroblocks->mb_type != PIPE_MPEG12_MACROBLOCK_TYPE_INTRA)
|
||||
pipe_macroblocks->mo_type = MotionToPipe(xvmc_mb->motion_type, xvmc_mb->dct_type);
|
||||
/* Get rid of Valgrind 'undefined' warnings */
|
||||
else
|
||||
pipe_macroblocks->mo_type = -1;
|
||||
pipe_macroblocks->dct_type = xvmc_mb->dct_type == XVMC_DCT_TYPE_FIELD ?
|
||||
PIPE_MPEG12_DCT_TYPE_FIELD : PIPE_MPEG12_DCT_TYPE_FRAME;
|
||||
|
||||
for (j = 0; j < 2; ++j)
|
||||
for (k = 0; k < 2; ++k)
|
||||
for (l = 0; l < 2; ++l)
|
||||
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;
|
||||
++xvmc_mb;
|
||||
}
|
||||
}
|
||||
|
||||
Status XvMCCreateSurface(Display *dpy, XvMCContext *context, XvMCSurface *surface)
|
||||
{
|
||||
XvMCContextPrivate *context_priv;
|
||||
struct pipe_video_context *vpipe;
|
||||
XvMCSurfacePrivate *surface_priv;
|
||||
struct pipe_video_surface *vsfc;
|
||||
|
||||
assert(dpy);
|
||||
|
||||
if (!context)
|
||||
return XvMCBadContext;
|
||||
if (!surface)
|
||||
return XvMCBadSurface;
|
||||
|
||||
context_priv = context->privData;
|
||||
vpipe = context_priv->vpipe;
|
||||
|
||||
surface_priv = CALLOC(1, sizeof(XvMCSurfacePrivate));
|
||||
if (!surface_priv)
|
||||
return BadAlloc;
|
||||
|
||||
vsfc = vpipe->screen->video_surface_create(vpipe->screen, vpipe->chroma_format,
|
||||
vpipe->width, vpipe->height);
|
||||
if (!vsfc)
|
||||
{
|
||||
FREE(surface_priv);
|
||||
return BadAlloc;
|
||||
}
|
||||
|
||||
surface_priv->pipe_vsfc = vsfc;
|
||||
surface_priv->context = context;
|
||||
|
||||
surface->surface_id = XAllocID(dpy);
|
||||
surface->context_id = context->context_id;
|
||||
surface->surface_type_id = context->surface_type_id;
|
||||
surface->width = context->width;
|
||||
surface->height = context->height;
|
||||
surface->privData = surface_priv;
|
||||
|
||||
SyncHandle();
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
Status XvMCRenderSurface(Display *dpy, XvMCContext *context, unsigned int picture_structure,
|
||||
XvMCSurface *target_surface, XvMCSurface *past_surface, XvMCSurface *future_surface,
|
||||
unsigned int flags, unsigned int num_macroblocks, unsigned int first_macroblock,
|
||||
XvMCMacroBlockArray *macroblocks, XvMCBlockArray *blocks
|
||||
)
|
||||
{
|
||||
struct vlContext *vl_ctx;
|
||||
struct vlSurface *target_vl_surface;
|
||||
struct vlSurface *past_vl_surface;
|
||||
struct vlSurface *future_vl_surface;
|
||||
struct vlMpeg2MacroBlockBatch batch;
|
||||
struct vlMpeg2MacroBlock vl_macroblocks[num_macroblocks];
|
||||
unsigned int i;
|
||||
struct pipe_video_context *vpipe;
|
||||
struct pipe_surface *t_vsfc;
|
||||
struct pipe_surface *p_vsfc;
|
||||
struct pipe_surface *f_vsfc;
|
||||
XvMCContextPrivate *context_priv;
|
||||
XvMCSurfacePrivate *target_surface_priv;
|
||||
XvMCSurfacePrivate *past_surface_priv;
|
||||
XvMCSurfacePrivate *future_surface_priv;
|
||||
struct pipe_mpeg12_macroblock pipe_macroblocks[num_macroblocks];
|
||||
|
||||
assert(display);
|
||||
assert(dpy);
|
||||
|
||||
if (!context)
|
||||
return XvMCBadContext;
|
||||
if (!target_surface)
|
||||
return XvMCBadSurface;
|
||||
if (!context || !context->privData)
|
||||
return XvMCBadContext;
|
||||
if (!target_surface || !target_surface->privData)
|
||||
return XvMCBadSurface;
|
||||
|
||||
if
|
||||
(
|
||||
picture_structure != XVMC_TOP_FIELD &&
|
||||
picture_structure != XVMC_BOTTOM_FIELD &&
|
||||
picture_structure != XVMC_FRAME_PICTURE
|
||||
)
|
||||
return BadValue;
|
||||
if (future_surface && !past_surface)
|
||||
return BadMatch;
|
||||
if (picture_structure != XVMC_TOP_FIELD &&
|
||||
picture_structure != XVMC_BOTTOM_FIELD &&
|
||||
picture_structure != XVMC_FRAME_PICTURE)
|
||||
return BadValue;
|
||||
/* Bkwd pred equivalent to fwd (past && !future) */
|
||||
if (future_surface && !past_surface)
|
||||
return BadMatch;
|
||||
|
||||
vl_ctx = context->privData;
|
||||
assert(context->context_id == target_surface->context_id);
|
||||
assert(!past_surface || context->context_id == past_surface->context_id);
|
||||
assert(!future_surface || context->context_id == future_surface->context_id);
|
||||
|
||||
assert(display == vlGetNativeDisplay(vlGetDisplay(vlContextGetScreen(vl_ctx))));
|
||||
assert(macroblocks);
|
||||
assert(blocks);
|
||||
|
||||
target_vl_surface = target_surface->privData;
|
||||
past_vl_surface = past_surface ? past_surface->privData : NULL;
|
||||
future_vl_surface = future_surface ? future_surface->privData : NULL;
|
||||
assert(macroblocks->context_id == context->context_id);
|
||||
assert(blocks->context_id == context->context_id);
|
||||
|
||||
assert(context->context_id == target_surface->context_id);
|
||||
assert(!past_surface || context->context_id == past_surface->context_id);
|
||||
assert(!future_surface || context->context_id == future_surface->context_id);
|
||||
assert(flags == 0 || flags == XVMC_SECOND_FIELD);
|
||||
|
||||
assert(macroblocks);
|
||||
assert(blocks);
|
||||
target_surface_priv = target_surface->privData;
|
||||
past_surface_priv = past_surface ? past_surface->privData : NULL;
|
||||
future_surface_priv = future_surface ? future_surface->privData : NULL;
|
||||
|
||||
assert(macroblocks->context_id == context->context_id);
|
||||
assert(blocks->context_id == context->context_id);
|
||||
assert(target_surface_priv->context == context);
|
||||
assert(!past_surface || past_surface_priv->context == context);
|
||||
assert(!future_surface || future_surface_priv->context == context);
|
||||
|
||||
assert(flags == 0 || flags == XVMC_SECOND_FIELD);
|
||||
context_priv = context->privData;
|
||||
vpipe = context_priv->vpipe;
|
||||
|
||||
batch.past_surface = past_vl_surface;
|
||||
batch.future_surface = future_vl_surface;
|
||||
batch.picture_type = PictureToVL(picture_structure);
|
||||
batch.field_order = flags & XVMC_SECOND_FIELD ? vlFieldOrderSecond : vlFieldOrderFirst;
|
||||
batch.num_macroblocks = num_macroblocks;
|
||||
batch.macroblocks = vl_macroblocks;
|
||||
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;
|
||||
|
||||
for (i = 0; i < num_macroblocks; ++i)
|
||||
{
|
||||
unsigned int j = first_macroblock + i;
|
||||
MacroBlocksToPipe(macroblocks, blocks, first_macroblock,
|
||||
num_macroblocks, pipe_macroblocks);
|
||||
|
||||
unsigned int k, l, m;
|
||||
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);
|
||||
|
||||
batch.macroblocks[i].mbx = macroblocks->macro_blocks[j].x;
|
||||
batch.macroblocks[i].mby = macroblocks->macro_blocks[j].y;
|
||||
batch.macroblocks[i].mb_type = TypeToVL(macroblocks->macro_blocks[j].macroblock_type);
|
||||
if (batch.macroblocks[i].mb_type != vlMacroBlockTypeIntra)
|
||||
batch.macroblocks[i].mo_type = MotionToVL(macroblocks->macro_blocks[j].motion_type, macroblocks->macro_blocks[j].dct_type);
|
||||
batch.macroblocks[i].dct_type = macroblocks->macro_blocks[j].dct_type == XVMC_DCT_TYPE_FIELD ? vlDCTTypeFieldCoded : vlDCTTypeFrameCoded;
|
||||
|
||||
for (k = 0; k < 2; ++k)
|
||||
for (l = 0; l < 2; ++l)
|
||||
for (m = 0; m < 2; ++m)
|
||||
batch.macroblocks[i].PMV[k][l][m] = macroblocks->macro_blocks[j].PMV[k][l][m];
|
||||
|
||||
batch.macroblocks[i].cbp = macroblocks->macro_blocks[j].coded_block_pattern;
|
||||
batch.macroblocks[i].blocks = blocks->blocks + (macroblocks->macro_blocks[j].index * 64);
|
||||
}
|
||||
|
||||
vlRenderMacroBlocksMpeg2(&batch, target_vl_surface);
|
||||
|
||||
return Success;
|
||||
return Success;
|
||||
}
|
||||
|
||||
Status XvMCFlushSurface(Display *display, XvMCSurface *surface)
|
||||
Status XvMCFlushSurface(Display *dpy, XvMCSurface *surface)
|
||||
{
|
||||
#if 0
|
||||
struct vlSurface *vl_sfc;
|
||||
|
||||
assert(display);
|
||||
assert(dpy);
|
||||
|
||||
if (!surface)
|
||||
return XvMCBadSurface;
|
||||
|
||||
vl_sfc = surface->privData;
|
||||
|
||||
assert(display == vlGetNativeDisplay(vlGetDisplay(vlSurfaceGetScreen(vl_sfc))));
|
||||
|
||||
vlSurfaceFlush(vl_sfc);
|
||||
|
||||
return Success;
|
||||
#endif
|
||||
return Success;
|
||||
}
|
||||
|
||||
Status XvMCSyncSurface(Display *display, XvMCSurface *surface)
|
||||
Status XvMCSyncSurface(Display *dpy, XvMCSurface *surface)
|
||||
{
|
||||
#if 0
|
||||
struct vlSurface *vl_sfc;
|
||||
|
||||
assert(display);
|
||||
assert(dpy);
|
||||
|
||||
if (!surface)
|
||||
return XvMCBadSurface;
|
||||
|
||||
vl_sfc = surface->privData;
|
||||
|
||||
assert(display == vlGetNativeDisplay(vlGetDisplay(vlSurfaceGetScreen(vl_sfc))));
|
||||
|
||||
vlSurfaceSync(vl_sfc);
|
||||
|
||||
return Success;
|
||||
#endif
|
||||
return Success;
|
||||
}
|
||||
|
||||
Status XvMCPutSurface
|
||||
(
|
||||
Display *display,
|
||||
XvMCSurface *surface,
|
||||
Drawable drawable,
|
||||
short srcx,
|
||||
short srcy,
|
||||
unsigned short srcw,
|
||||
unsigned short srch,
|
||||
short destx,
|
||||
short desty,
|
||||
unsigned short destw,
|
||||
unsigned short desth,
|
||||
int flags
|
||||
)
|
||||
Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable,
|
||||
short srcx, short srcy, unsigned short srcw, unsigned short srch,
|
||||
short destx, short desty, unsigned short destw, unsigned short desth,
|
||||
int flags)
|
||||
{
|
||||
Window root;
|
||||
int x, y;
|
||||
unsigned int width, height;
|
||||
unsigned int border_width;
|
||||
unsigned int depth;
|
||||
struct vlSurface *vl_sfc;
|
||||
Window root;
|
||||
int x, y;
|
||||
unsigned int width, height;
|
||||
unsigned int border_width;
|
||||
unsigned int depth;
|
||||
struct pipe_video_context *vpipe;
|
||||
XvMCSurfacePrivate *surface_priv;
|
||||
XvMCContextPrivate *context_priv;
|
||||
XvMCContext *context;
|
||||
struct pipe_video_rect src_rect = {srcx, srcy, srcw, srch};
|
||||
struct pipe_video_rect dst_rect = {destx, desty, destw, desth};
|
||||
|
||||
assert(display);
|
||||
assert(dpy);
|
||||
|
||||
if (!surface)
|
||||
return XvMCBadSurface;
|
||||
if (!surface || !surface->privData)
|
||||
return XvMCBadSurface;
|
||||
|
||||
if (XGetGeometry(display, drawable, &root, &x, &y, &width, &height, &border_width, &depth) == BadDrawable)
|
||||
return BadDrawable;
|
||||
if (XGetGeometry(dpy, drawable, &root, &x, &y, &width, &height, &border_width, &depth) == BadDrawable)
|
||||
return BadDrawable;
|
||||
|
||||
assert(flags == XVMC_TOP_FIELD || flags == XVMC_BOTTOM_FIELD || flags == XVMC_FRAME_PICTURE);
|
||||
assert(flags == XVMC_TOP_FIELD || flags == XVMC_BOTTOM_FIELD || flags == XVMC_FRAME_PICTURE);
|
||||
assert(srcx + srcw - 1 < surface->width);
|
||||
assert(srcy + srch - 1 < surface->height);
|
||||
/*
|
||||
* Some apps (mplayer) hit these asserts because they call
|
||||
* this function after the window has been resized by the WM
|
||||
* but before they've handled the corresponding XEvent and
|
||||
* know about the new dimensions. The output should be clipped
|
||||
* until the app updates destw and desth.
|
||||
*/
|
||||
/*
|
||||
assert(destx + destw - 1 < width);
|
||||
assert(desty + desth - 1 < height);
|
||||
*/
|
||||
|
||||
/* TODO: Correct for negative srcx,srcy & destx,desty by clipping */
|
||||
surface_priv = surface->privData;
|
||||
context = surface_priv->context;
|
||||
context_priv = context->privData;
|
||||
vpipe = context_priv->vpipe;
|
||||
|
||||
assert(srcx + srcw - 1 < surface->width);
|
||||
assert(srcy + srch - 1 < surface->height);
|
||||
/* XXX: Some apps (mplayer) hit these asserts because they call
|
||||
* this function after the window has been resized by the WM
|
||||
* but before they've handled the corresponding XEvent and
|
||||
* know about the new dimensions. The output will be clipped
|
||||
* for a few frames until the app updates destw and desth.
|
||||
*/
|
||||
/*assert(destx + destw - 1 < width);
|
||||
assert(desty + desth - 1 < height);*/
|
||||
if (!CreateOrResizeBackBuffer(vpipe, width, height, &context_priv->backbuffer))
|
||||
return BadAlloc;
|
||||
|
||||
vl_sfc = surface->privData;
|
||||
vpipe->render_picture(vpipe, surface_priv->pipe_vsfc, PictureToPipe(flags), &src_rect,
|
||||
context_priv->backbuffer, &dst_rect, surface_priv->disp_fence);
|
||||
|
||||
vlPutPicture(vl_sfc, drawable, srcx, srcy, srcw, srch, destx, desty, destw, desth, width, height, PictureToVL(flags));
|
||||
vl_video_bind_drawable(vpipe, drawable);
|
||||
|
||||
vpipe->screen->flush_frontbuffer
|
||||
(
|
||||
vpipe->screen,
|
||||
context_priv->backbuffer,
|
||||
vpipe->priv
|
||||
);
|
||||
|
||||
return Success;
|
||||
return Success;
|
||||
}
|
||||
|
||||
Status XvMCGetSurfaceStatus(Display *display, XvMCSurface *surface, int *status)
|
||||
Status XvMCGetSurfaceStatus(Display *dpy, XvMCSurface *surface, int *status)
|
||||
{
|
||||
#if 0
|
||||
struct vlSurface *vl_sfc;
|
||||
enum vlResourceStatus res_status;
|
||||
|
||||
assert(display);
|
||||
assert(dpy);
|
||||
|
||||
if (!surface)
|
||||
return XvMCBadSurface;
|
||||
|
@ -293,8 +372,6 @@ Status XvMCGetSurfaceStatus(Display *display, XvMCSurface *surface, int *status)
|
|||
|
||||
vl_sfc = surface->privData;
|
||||
|
||||
assert(display == vlGetNativeDisplay(vlGetDisplay(vlSurfaceGetScreen(vl_sfc))));
|
||||
|
||||
vlSurfaceGetStatus(vl_sfc, &res_status);
|
||||
|
||||
switch (res_status)
|
||||
|
@ -317,42 +394,36 @@ Status XvMCGetSurfaceStatus(Display *display, XvMCSurface *surface, int *status)
|
|||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
return Success;
|
||||
#endif
|
||||
*status = 0;
|
||||
return Success;
|
||||
}
|
||||
|
||||
Status XvMCDestroySurface(Display *display, XvMCSurface *surface)
|
||||
Status XvMCDestroySurface(Display *dpy, XvMCSurface *surface)
|
||||
{
|
||||
struct vlSurface *vl_sfc;
|
||||
XvMCSurfacePrivate *surface_priv;
|
||||
|
||||
assert(display);
|
||||
assert(dpy);
|
||||
|
||||
if (!surface)
|
||||
return XvMCBadSurface;
|
||||
if (!surface || !surface->privData)
|
||||
return XvMCBadSurface;
|
||||
|
||||
vl_sfc = surface->privData;
|
||||
surface_priv = surface->privData;
|
||||
pipe_video_surface_reference(&surface_priv->pipe_vsfc, NULL);
|
||||
FREE(surface_priv);
|
||||
surface->privData = NULL;
|
||||
|
||||
assert(display == vlGetNativeDisplay(vlGetDisplay(vlSurfaceGetScreen(vl_sfc))));
|
||||
|
||||
vlDestroySurface(vl_sfc);
|
||||
|
||||
return Success;
|
||||
return Success;
|
||||
}
|
||||
|
||||
Status XvMCHideSurface(Display *display, XvMCSurface *surface)
|
||||
Status XvMCHideSurface(Display *dpy, XvMCSurface *surface)
|
||||
{
|
||||
struct vlSurface *vl_sfc;
|
||||
assert(dpy);
|
||||
|
||||
assert(display);
|
||||
if (!surface || !surface->privData)
|
||||
return XvMCBadSurface;
|
||||
|
||||
if (!surface)
|
||||
return XvMCBadSurface;
|
||||
/* No op, only for overlaid rendering */
|
||||
|
||||
vl_sfc = surface->privData;
|
||||
|
||||
assert(display == vlGetNativeDisplay(vlGetDisplay(vlSurfaceGetScreen(vl_sfc))));
|
||||
|
||||
/* No op, only for overlaid rendering */
|
||||
|
||||
return Success;
|
||||
return Success;
|
||||
}
|
||||
|
|
|
@ -1,27 +1,28 @@
|
|||
CFLAGS += -g -Wall
|
||||
LDFLAGS +=
|
||||
LIBS += -lXvMCW -lXvMC -lXv
|
||||
TOP = ../../..
|
||||
include $(TOP)/configs/current
|
||||
|
||||
LIBS = -lXvMCW -lXvMC -lXv -lX11
|
||||
|
||||
#############################################
|
||||
|
||||
.PHONY = all clean
|
||||
.PHONY: default clean
|
||||
|
||||
all: test_context test_surface test_blocks test_rendering xvmc_bench
|
||||
default: test_context test_surface test_blocks test_rendering xvmc_bench
|
||||
|
||||
test_context: test_context.o testlib.o
|
||||
$(CC) ${LDFLAGS} -o $@ $^ ${LIBS}
|
||||
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||
|
||||
test_surface: test_surface.o testlib.o
|
||||
$(CC) ${LDFLAGS} -o $@ $^ ${LIBS}
|
||||
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||
|
||||
test_blocks: test_blocks.o testlib.o
|
||||
$(CC) ${LDFLAGS} -o $@ $^ ${LIBS}
|
||||
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||
|
||||
test_rendering: test_rendering.o testlib.o
|
||||
$(CC) ${LDFLAGS} -o $@ $^ ${LIBS}
|
||||
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||
|
||||
xvmc_bench: xvmc_bench.o testlib.o
|
||||
$(CC) ${LDFLAGS} -o $@ $^ ${LIBS}
|
||||
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||
|
||||
clean:
|
||||
rm -rf *.o test_context test_surface test_blocks test_rendering xvmc_bench
|
||||
$(RM) -rf *.o test_context test_surface test_blocks test_rendering xvmc_bench
|
||||
|
|
|
@ -23,6 +23,9 @@
|
|||
#define DEFAULT_OUTPUT_HEIGHT INPUT_HEIGHT
|
||||
#define DEFAULT_ACCEPTABLE_ERR 0.01
|
||||
|
||||
void ParseArgs(int argc, char **argv, unsigned int *output_width, unsigned int *output_height, double *acceptable_error, int *prompt);
|
||||
void Gradient(short *block, unsigned int start, unsigned int stop, int horizontal);
|
||||
|
||||
void ParseArgs(int argc, char **argv, unsigned int *output_width, unsigned int *output_height, double *acceptable_error, int *prompt)
|
||||
{
|
||||
int fail = 0;
|
||||
|
|
|
@ -6,7 +6,7 @@ int main(int argc, char **argv)
|
|||
{
|
||||
const unsigned int width = 16, height = 16;
|
||||
const unsigned int mc_types[2] = {XVMC_MOCOMP | XVMC_MPEG_2, XVMC_IDCT | XVMC_MPEG_2};
|
||||
|
||||
|
||||
Display *display;
|
||||
XvPortID port_num;
|
||||
int surface_type_id;
|
||||
|
@ -14,9 +14,9 @@ int main(int argc, char **argv)
|
|||
int colorkey;
|
||||
XvMCContext context;
|
||||
XvMCSurface surface = {0};
|
||||
|
||||
|
||||
display = XOpenDisplay(NULL);
|
||||
|
||||
|
||||
if (!GetPort
|
||||
(
|
||||
display,
|
||||
|
@ -34,15 +34,15 @@ int main(int argc, char **argv)
|
|||
XCloseDisplay(display);
|
||||
error(1, 0, "Error, unable to find a good port.\n");
|
||||
}
|
||||
|
||||
|
||||
if (is_overlay)
|
||||
{
|
||||
Atom xv_colorkey = XInternAtom(display, "XV_COLORKEY", 0);
|
||||
XvGetPortAttribute(display, port_num, xv_colorkey, &colorkey);
|
||||
}
|
||||
|
||||
|
||||
assert(XvMCCreateContext(display, port_num, surface_type_id, width, height, XVMC_DIRECT, &context) == Success);
|
||||
|
||||
|
||||
/* Test NULL context */
|
||||
assert(XvMCCreateSurface(display, NULL, &surface) == XvMCBadContext);
|
||||
/* Test NULL surface */
|
||||
|
@ -61,12 +61,11 @@ int main(int argc, char **argv)
|
|||
assert(XvMCDestroySurface(display, &surface) == Success);
|
||||
/* Test NULL surface */
|
||||
assert(XvMCDestroySurface(display, NULL) == XvMCBadSurface);
|
||||
|
||||
|
||||
assert(XvMCDestroyContext(display, &context) == Success);
|
||||
|
||||
|
||||
XvUngrabPort(display, port_num, CurrentTime);
|
||||
XCloseDisplay(display);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,8 @@ struct Config
|
|||
unsigned int reps;
|
||||
};
|
||||
|
||||
void ParseArgs(int argc, char **argv, struct Config *config);
|
||||
|
||||
void ParseArgs(int argc, char **argv, struct Config *config)
|
||||
{
|
||||
int fail = 0;
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
#ifndef xvmc_private_h
|
||||
#define xvmc_private_h
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/XvMClib.h>
|
||||
|
||||
#define BLOCK_SIZE_SAMPLES 64
|
||||
#define BLOCK_SIZE_BYTES (BLOCK_SIZE_SAMPLES * 2)
|
||||
|
||||
struct pipe_video_context;
|
||||
struct pipe_surface;
|
||||
struct pipe_fence_handle;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
struct pipe_video_context *vpipe;
|
||||
struct pipe_surface *backbuffer;
|
||||
} XvMCContextPrivate;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
struct pipe_video_surface *pipe_vsfc;
|
||||
struct pipe_fence_handle *render_fence;
|
||||
struct pipe_fence_handle *disp_fence;
|
||||
|
||||
/* Some XvMC functions take a surface but not a context,
|
||||
so we keep track of which context each surface belongs to. */
|
||||
XvMCContext *context;
|
||||
} XvMCSurfacePrivate;
|
||||
|
||||
#endif /* xvmc_private_h */
|
Loading…
Reference in New Issue