Initial commit for g3dvl.
Initial commit for g3dvl, contains support for basic XvMC features. - Context, surface, block, macroblock creation and deletion - Surface rendering - Frame pictures - Frame based motion compensation - Intra-coded macroblocks - Predicted macroblocks - Bi-directionally predicted macroblocks - Surface display - Color conversion - Scaling
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
TARGET = libg3dvl.a
|
||||
OBJECTS = vl_context.o vl_data.o vl_surface.o
|
||||
GALLIUMDIR = ../..
|
||||
|
||||
CFLAGS += -g -Wall -fPIC -Werror -I${GALLIUMDIR}/include -I${GALLIUMDIR}/auxiliary
|
||||
|
||||
#############################################
|
||||
|
||||
.PHONY = all clean
|
||||
|
||||
all: ${TARGET}
|
||||
|
||||
${TARGET}: ${OBJECTS}
|
||||
ar rcs $@ $^
|
||||
|
||||
clean:
|
||||
rm -rf ${OBJECTS} ${TARGET}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
test_context
|
||||
test_surface
|
||||
test_i_rendering
|
||||
test_p_rendering
|
||||
test_b_rendering
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
GALLIUMDIR = ../../..
|
||||
|
||||
CFLAGS += -g -Wall -Werror \
|
||||
-I${GALLIUMDIR}/state_trackers/g3dvl \
|
||||
-I${GALLIUMDIR}/winsys/g3dvl \
|
||||
-I${GALLIUMDIR}/include \
|
||||
-I${GALLIUMDIR}/auxiliary \
|
||||
-I${GALLIUMDIR}/drivers
|
||||
LDFLAGS += -L${GALLIUMDIR}/state_trackers/g3dvl \
|
||||
-L${GALLIUMDIR}/drivers/softpipe \
|
||||
-L${GALLIUMDIR}/auxiliary/tgsi \
|
||||
-L${GALLIUMDIR}/auxiliary/draw \
|
||||
-L${GALLIUMDIR}/auxiliary/util \
|
||||
-L${GALLIUMDIR}/auxiliary/translate \
|
||||
-L${GALLIUMDIR}/auxiliary/cso_cache \
|
||||
-L${GALLIUMDIR}/auxiliary/rtasm
|
||||
LIBS += -lg3dvl -lsoftpipe -ldraw -ltgsi -ltranslate -lrtasm -lcso_cache -lutil -lX11 -lm
|
||||
|
||||
#############################################
|
||||
|
||||
.PHONY = all clean
|
||||
|
||||
all: test_context test_surface test_i_rendering test_p_rendering test_b_rendering
|
||||
|
||||
test_context: test_context.o ${GALLIUMDIR}/winsys/g3dvl/xsp_winsys.o
|
||||
$(CC) ${LDFLAGS} -o $@ $^ ${LIBS}
|
||||
|
||||
test_surface: test_surface.o ${GALLIUMDIR}/winsys/g3dvl/xsp_winsys.o
|
||||
$(CC) ${LDFLAGS} -o $@ $^ ${LIBS}
|
||||
|
||||
test_i_rendering: test_i_rendering.o ${GALLIUMDIR}/winsys/g3dvl/xsp_winsys.o
|
||||
$(CC) ${LDFLAGS} -o $@ $^ ${LIBS}
|
||||
|
||||
test_p_rendering: test_p_rendering.o ${GALLIUMDIR}/winsys/g3dvl/xsp_winsys.o
|
||||
$(CC) ${LDFLAGS} -o $@ $^ ${LIBS}
|
||||
|
||||
test_b_rendering: test_b_rendering.o ${GALLIUMDIR}/winsys/g3dvl/xsp_winsys.o
|
||||
$(CC) ${LDFLAGS} -o $@ $^ ${LIBS}
|
||||
|
||||
clean:
|
||||
rm -rf *.o test_context test_surface test_i_rendering test_p_rendering test_b_rendering
|
||||
|
||||
@@ -0,0 +1,226 @@
|
||||
#include <stdio.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <vl_context.h>
|
||||
#include <vl_surface.h>
|
||||
#include <xsp_winsys.h>
|
||||
|
||||
static const unsigned short ycbcr16x16_420[8*8*6] =
|
||||
{
|
||||
0x00A5,0x00A5,0x00A5,0x0072,0x00A5,0x0072,0x0072,0x0072,
|
||||
0x0072,0x00A5,0x0072,0x0072,0x00A5,0x0072,0x0072,0x0072,
|
||||
0x0072,0x00A5,0x0072,0x0072,0x00A5,0x00A5,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x00A5,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x00A5,0x00A5,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x00A5,0x00A5,0x00A5,
|
||||
0x0072,0x0072,0x0072,0x0072,0x00A5,0x00A5,0x00A5,0x00A5,
|
||||
|
||||
0x004F,0x004F,0x004F,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,
|
||||
0x00B2,0x00B2,0x004F,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,
|
||||
0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,
|
||||
0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,
|
||||
0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,
|
||||
0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,
|
||||
0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x004F,
|
||||
0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x004F,0x004F,
|
||||
|
||||
0x003E,0x003E,0x003E,0x0060,0x0060,0x0060,0x0060,0x0060,
|
||||
0x0060,0x0060,0x003E,0x0060,0x0060,0x0060,0x0060,0x0060,
|
||||
0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,
|
||||
0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,
|
||||
0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,
|
||||
0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,
|
||||
0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x003E,
|
||||
0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x003E,0x003E
|
||||
};
|
||||
|
||||
static const signed short ycbcr16x16_420_2[8*8*6] =
|
||||
{
|
||||
-0x00A5,-0x00A5,-0x00A5,-0x0072,-0x00A5,-0x0072,-0x0072,-0x0072,
|
||||
-0x0072,-0x00A5,-0x0072,-0x0072,-0x00A5,-0x0072,-0x0072,-0x0072,
|
||||
-0x0072,-0x00A5,-0x0072,-0x0072,-0x00A5,-0x00A5,-0x0072,-0x0072,
|
||||
-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,
|
||||
-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,
|
||||
-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,
|
||||
-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,
|
||||
-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,
|
||||
|
||||
-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,
|
||||
-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,
|
||||
-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,
|
||||
-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,
|
||||
-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,
|
||||
-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,
|
||||
-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,
|
||||
-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,
|
||||
|
||||
-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,
|
||||
-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,
|
||||
-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,
|
||||
-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,
|
||||
-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,
|
||||
-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,
|
||||
-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,
|
||||
-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,
|
||||
|
||||
-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,
|
||||
-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,
|
||||
-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,
|
||||
-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,
|
||||
-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x00A5,
|
||||
-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x00A5,-0x00A5,
|
||||
-0x0072,-0x0072,-0x0072,-0x0072,-0x0072,-0x00A5,-0x00A5,-0x00A5,
|
||||
-0x0072,-0x0072,-0x0072,-0x0072,-0x00A5,-0x00A5,-0x00A5,-0x00A5,
|
||||
|
||||
-0x004F,-0x004F,-0x004F,-0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x00B2,
|
||||
-0x00B2,-0x00B2,-0x004F,-0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x00B2,
|
||||
-0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x00B2,
|
||||
-0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x00B2,
|
||||
-0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x00B2,
|
||||
-0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x00B2,
|
||||
-0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x004F,
|
||||
-0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x00B2,-0x004F,-0x004F,
|
||||
|
||||
-0x003E,-0x003E,-0x003E,-0x0060,-0x0060,-0x0060,-0x0060,-0x0060,
|
||||
-0x0060,-0x0060,-0x003E,-0x0060,-0x0060,-0x0060,-0x0060,-0x0060,
|
||||
-0x0060,-0x0060,-0x0060,-0x0060,-0x0060,-0x0060,-0x0060,-0x0060,
|
||||
-0x0060,-0x0060,-0x0060,-0x0060,-0x0060,-0x0060,-0x0060,-0x0060,
|
||||
-0x0060,-0x0060,-0x0060,-0x0060,-0x0060,-0x0060,-0x0060,-0x0060,
|
||||
-0x0060,-0x0060,-0x0060,-0x0060,-0x0060,-0x0060,-0x0060,-0x0060,
|
||||
-0x0060,-0x0060,-0x0060,-0x0060,-0x0060,-0x0060,-0x0060,-0x003E,
|
||||
-0x0060,-0x0060,-0x0060,-0x0060,-0x0060,-0x0060,-0x003E,-0x003E
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const unsigned int video_width = 32, video_height = 32;
|
||||
const unsigned int window_width = video_width * 2, window_height = video_height * 2;
|
||||
int quit = 0;
|
||||
Display *display;
|
||||
Window root, window;
|
||||
Pixmap framebuffer;
|
||||
XEvent event;
|
||||
struct pipe_context *pipe;
|
||||
struct VL_CONTEXT *ctx;
|
||||
struct VL_SURFACE *sfc, *past_sfc, *future_sfc;
|
||||
struct VL_MOTION_VECTOR motion_vector[2] =
|
||||
{
|
||||
{
|
||||
{0, 0}, {0, 0}
|
||||
},
|
||||
{
|
||||
{0, 0}, {0, 0}
|
||||
}
|
||||
};
|
||||
|
||||
display = XOpenDisplay(NULL);
|
||||
root = XDefaultRootWindow(display);
|
||||
window = XCreateSimpleWindow(display, root, 0, 0, window_width, window_height, 0, 0, 0);
|
||||
framebuffer = XCreatePixmap(display, root, window_width, window_height, 24);
|
||||
|
||||
XSelectInput(display, window, ExposureMask | KeyPressMask);
|
||||
XMapWindow(display, window);
|
||||
XSync(display, 0);
|
||||
|
||||
pipe = create_pipe_context(display);
|
||||
vlCreateContext(display, pipe, video_width, video_height, VL_FORMAT_YCBCR_420, &ctx);
|
||||
vlCreateSurface(ctx, &sfc);
|
||||
vlCreateSurface(ctx, &past_sfc);
|
||||
vlCreateSurface(ctx, &future_sfc);
|
||||
|
||||
vlRenderIMacroBlock(VL_FRAME_PICTURE, VL_FIELD_FIRST, 0, 0, 0x3F, VL_DCT_FRAME_CODED, (short*)ycbcr16x16_420, past_sfc);
|
||||
vlRenderIMacroBlock(VL_FRAME_PICTURE, VL_FIELD_FIRST, 1, 0, 0x3F, VL_DCT_FRAME_CODED, (short*)ycbcr16x16_420, past_sfc);
|
||||
vlRenderIMacroBlock(VL_FRAME_PICTURE, VL_FIELD_FIRST, 0, 1, 0x3F, VL_DCT_FRAME_CODED, (short*)ycbcr16x16_420, past_sfc);
|
||||
vlRenderIMacroBlock(VL_FRAME_PICTURE, VL_FIELD_FIRST, 1, 1, 0x3F, VL_DCT_FRAME_CODED, (short*)ycbcr16x16_420, past_sfc);
|
||||
vlRenderIMacroBlock(VL_FRAME_PICTURE, VL_FIELD_FIRST, 0, 0, 0x3F, VL_DCT_FRAME_CODED, (short*)ycbcr16x16_420, future_sfc);
|
||||
vlRenderIMacroBlock(VL_FRAME_PICTURE, VL_FIELD_FIRST, 1, 0, 0x3F, VL_DCT_FRAME_CODED, (short*)ycbcr16x16_420, future_sfc);
|
||||
vlRenderIMacroBlock(VL_FRAME_PICTURE, VL_FIELD_FIRST, 0, 1, 0x3F, VL_DCT_FRAME_CODED, (short*)ycbcr16x16_420, future_sfc);
|
||||
vlRenderIMacroBlock(VL_FRAME_PICTURE, VL_FIELD_FIRST, 1, 1, 0x3F, VL_DCT_FRAME_CODED, (short*)ycbcr16x16_420, future_sfc);
|
||||
vlRenderBMacroBlock
|
||||
(
|
||||
VL_FRAME_PICTURE,
|
||||
VL_FIELD_FIRST,
|
||||
0,
|
||||
0,
|
||||
VL_FRAME_MC,
|
||||
motion_vector,
|
||||
0x3F,
|
||||
VL_DCT_FRAME_CODED,
|
||||
(short*)ycbcr16x16_420_2,
|
||||
past_sfc,
|
||||
future_sfc,
|
||||
sfc
|
||||
);
|
||||
vlPutSurface(sfc, framebuffer, 0, 0, video_width, video_height, 0, 0, window_width, window_height, VL_FRAME_PICTURE);
|
||||
|
||||
puts("Press any key to continue...");
|
||||
|
||||
while (!quit)
|
||||
{
|
||||
XNextEvent(display, &event);
|
||||
switch (event.type)
|
||||
{
|
||||
case Expose:
|
||||
{
|
||||
XCopyArea
|
||||
(
|
||||
display,
|
||||
framebuffer,
|
||||
window,
|
||||
XDefaultGC(display, XDefaultScreen(display)),
|
||||
0,
|
||||
0,
|
||||
window_width,
|
||||
window_height,
|
||||
0,
|
||||
0
|
||||
);
|
||||
break;
|
||||
}
|
||||
case KeyPress:
|
||||
{
|
||||
quit = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vlDestroySurface(sfc);
|
||||
vlDestroySurface(past_sfc);
|
||||
vlDestroySurface(future_sfc);
|
||||
vlDestroyContext(ctx);
|
||||
|
||||
XFreePixmap(display, framebuffer);
|
||||
XDestroyWindow(display, window);
|
||||
XCloseDisplay(display);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
#include <vl_context.h>
|
||||
#include <xsp_winsys.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const unsigned int video_width = 32, video_height = 32;
|
||||
|
||||
Display *display;
|
||||
struct pipe_context *pipe;
|
||||
struct VL_CONTEXT *ctx;
|
||||
|
||||
display = XOpenDisplay(NULL);
|
||||
pipe = create_pipe_context(display);
|
||||
|
||||
vlCreateContext(display, pipe, video_width, video_height, VL_FORMAT_YCBCR_420, &ctx);
|
||||
vlDestroyContext(ctx);
|
||||
|
||||
XCloseDisplay(display);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
#include <stdio.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <vl_context.h>
|
||||
#include <vl_surface.h>
|
||||
#include <xsp_winsys.h>
|
||||
|
||||
static const unsigned short ycbcr16x16_420[8*8*6] =
|
||||
{
|
||||
0x00A5,0x00A5,0x00A5,0x0072,0x00A5,0x0072,0x0072,0x0072,
|
||||
0x0072,0x00A5,0x0072,0x0072,0x00A5,0x0072,0x0072,0x0072,
|
||||
0x0072,0x00A5,0x0072,0x0072,0x00A5,0x00A5,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x00A5,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x00A5,0x00A5,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x00A5,0x00A5,0x00A5,
|
||||
0x0072,0x0072,0x0072,0x0072,0x00A5,0x00A5,0x00A5,0x00A5,
|
||||
|
||||
0x004F,0x004F,0x004F,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,
|
||||
0x00B2,0x00B2,0x004F,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,
|
||||
0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,
|
||||
0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,
|
||||
0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,
|
||||
0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,
|
||||
0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x004F,
|
||||
0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x004F,0x004F,
|
||||
|
||||
0x003E,0x003E,0x003E,0x0060,0x0060,0x0060,0x0060,0x0060,
|
||||
0x0060,0x0060,0x003E,0x0060,0x0060,0x0060,0x0060,0x0060,
|
||||
0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,
|
||||
0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,
|
||||
0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,
|
||||
0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,
|
||||
0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x003E,
|
||||
0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x003E,0x003E
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const unsigned int video_width = 32, video_height = 32;
|
||||
const unsigned int window_width = video_width * 2, window_height = video_height * 2;
|
||||
int quit = 0;
|
||||
Display *display;
|
||||
Window root, window;
|
||||
Pixmap framebuffer;
|
||||
XEvent event;
|
||||
struct pipe_context *pipe;
|
||||
struct VL_CONTEXT *ctx;
|
||||
struct VL_SURFACE *sfc;
|
||||
|
||||
display = XOpenDisplay(NULL);
|
||||
root = XDefaultRootWindow(display);
|
||||
window = XCreateSimpleWindow(display, root, 0, 0, window_width, window_height, 0, 0, 0);
|
||||
framebuffer = XCreatePixmap(display, root, window_width, window_height, 24);
|
||||
|
||||
XSelectInput(display, window, ExposureMask | KeyPressMask);
|
||||
XMapWindow(display, window);
|
||||
XSync(display, 0);
|
||||
|
||||
pipe = create_pipe_context(display);
|
||||
vlCreateContext(display, pipe, video_width, video_height, VL_FORMAT_YCBCR_420, &ctx);
|
||||
vlCreateSurface(ctx, &sfc);
|
||||
|
||||
vlRenderIMacroBlock(VL_FRAME_PICTURE, VL_FIELD_FIRST, 0, 0, 0x3F, VL_DCT_FRAME_CODED, (short*)ycbcr16x16_420, sfc);
|
||||
vlRenderIMacroBlock(VL_FRAME_PICTURE, VL_FIELD_FIRST, 1, 0, 0x3F, VL_DCT_FRAME_CODED, (short*)ycbcr16x16_420, sfc);
|
||||
vlRenderIMacroBlock(VL_FRAME_PICTURE, VL_FIELD_FIRST, 0, 1, 0x3F, VL_DCT_FRAME_CODED, (short*)ycbcr16x16_420, sfc);
|
||||
vlRenderIMacroBlock(VL_FRAME_PICTURE, VL_FIELD_FIRST, 1, 1, 0x3F, VL_DCT_FRAME_CODED, (short*)ycbcr16x16_420, sfc);
|
||||
vlPutSurface(sfc, framebuffer, 0, 0, video_width, video_height, 0, 0, window_width, window_height, VL_FRAME_PICTURE);
|
||||
|
||||
puts("Press any key to continue...");
|
||||
|
||||
while (!quit)
|
||||
{
|
||||
XNextEvent(display, &event);
|
||||
switch (event.type)
|
||||
{
|
||||
case Expose:
|
||||
{
|
||||
XCopyArea
|
||||
(
|
||||
display,
|
||||
framebuffer,
|
||||
window,
|
||||
XDefaultGC(display, XDefaultScreen(display)),
|
||||
0,
|
||||
0,
|
||||
window_width,
|
||||
window_height,
|
||||
0,
|
||||
0
|
||||
);
|
||||
break;
|
||||
}
|
||||
case KeyPress:
|
||||
{
|
||||
quit = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vlDestroySurface(sfc);
|
||||
vlDestroyContext(ctx);
|
||||
|
||||
XFreePixmap(display, framebuffer);
|
||||
XDestroyWindow(display, window);
|
||||
XCloseDisplay(display);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,214 @@
|
||||
#include <stdio.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <vl_context.h>
|
||||
#include <vl_surface.h>
|
||||
#include <xsp_winsys.h>
|
||||
|
||||
static const unsigned short ycbcr16x16_420[8*8*6] =
|
||||
{
|
||||
0x00A5,0x00A5,0x00A5,0x0072,0x00A5,0x0072,0x0072,0x0072,
|
||||
0x0072,0x00A5,0x0072,0x0072,0x00A5,0x0072,0x0072,0x0072,
|
||||
0x0072,0x00A5,0x0072,0x0072,0x00A5,0x00A5,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x00A5,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x0072,0x00A5,0x00A5,
|
||||
0x0072,0x0072,0x0072,0x0072,0x0072,0x00A5,0x00A5,0x00A5,
|
||||
0x0072,0x0072,0x0072,0x0072,0x00A5,0x00A5,0x00A5,0x00A5,
|
||||
|
||||
0x004F,0x004F,0x004F,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,
|
||||
0x00B2,0x00B2,0x004F,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,
|
||||
0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,
|
||||
0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,
|
||||
0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,
|
||||
0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,
|
||||
0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x004F,
|
||||
0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x00B2,0x004F,0x004F,
|
||||
|
||||
0x003E,0x003E,0x003E,0x0060,0x0060,0x0060,0x0060,0x0060,
|
||||
0x0060,0x0060,0x003E,0x0060,0x0060,0x0060,0x0060,0x0060,
|
||||
0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,
|
||||
0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,
|
||||
0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,
|
||||
0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,
|
||||
0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x003E,
|
||||
0x0060,0x0060,0x0060,0x0060,0x0060,0x0060,0x003E,0x003E
|
||||
};
|
||||
|
||||
static const signed short ycbcr16x16_420_2[8*8*6] =
|
||||
{
|
||||
-51,-51,-51, 0,-51, 0, 0, 0,
|
||||
0,-51, 0, 0,-51, 0, 0, 0,
|
||||
0,-51, 0, 0,-51,-51, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
99, 99, 99, 0, 0, 0, 0, 0,
|
||||
0, 0, 99, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
|
||||
33, 33, 33, 0, 0, 0, 0, 0,
|
||||
0, 0, 33, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const unsigned int video_width = 32, video_height = 32;
|
||||
const unsigned int window_width = video_width * 2, window_height = video_height * 2;
|
||||
int quit = 0;
|
||||
Display *display;
|
||||
Window root, window;
|
||||
Pixmap framebuffer;
|
||||
XEvent event;
|
||||
struct pipe_context *pipe;
|
||||
struct VL_CONTEXT *ctx;
|
||||
struct VL_SURFACE *sfc, *ref_sfc;
|
||||
struct VL_MOTION_VECTOR motion_vector =
|
||||
{
|
||||
{0, 0}, {0, 0}
|
||||
};
|
||||
|
||||
display = XOpenDisplay(NULL);
|
||||
root = XDefaultRootWindow(display);
|
||||
window = XCreateSimpleWindow(display, root, 0, 0, window_width, window_height, 0, 0, 0);
|
||||
framebuffer = XCreatePixmap(display, root, window_width, window_height, 24);
|
||||
|
||||
XSelectInput(display, window, ExposureMask | KeyPressMask);
|
||||
XMapWindow(display, window);
|
||||
XSync(display, 0);
|
||||
|
||||
pipe = create_pipe_context(display);
|
||||
vlCreateContext(display, pipe, video_width, video_height, VL_FORMAT_YCBCR_420, &ctx);
|
||||
vlCreateSurface(ctx, &sfc);
|
||||
vlCreateSurface(ctx, &ref_sfc);
|
||||
|
||||
vlRenderIMacroBlock(VL_FRAME_PICTURE, VL_FIELD_FIRST, 0, 0, 0x3F, VL_DCT_FRAME_CODED, (short*)ycbcr16x16_420, ref_sfc);
|
||||
vlRenderIMacroBlock(VL_FRAME_PICTURE, VL_FIELD_FIRST, 1, 0, 0x3F, VL_DCT_FRAME_CODED, (short*)ycbcr16x16_420, ref_sfc);
|
||||
vlRenderIMacroBlock(VL_FRAME_PICTURE, VL_FIELD_FIRST, 0, 1, 0x3F, VL_DCT_FRAME_CODED, (short*)ycbcr16x16_420, ref_sfc);
|
||||
vlRenderIMacroBlock(VL_FRAME_PICTURE, VL_FIELD_FIRST, 1, 1, 0x3F, VL_DCT_FRAME_CODED, (short*)ycbcr16x16_420, ref_sfc);
|
||||
vlRenderPMacroBlock
|
||||
(
|
||||
VL_FRAME_PICTURE,
|
||||
VL_FIELD_FIRST,
|
||||
0,
|
||||
0,
|
||||
VL_FRAME_MC,
|
||||
&motion_vector,
|
||||
0x3F,
|
||||
VL_DCT_FRAME_CODED,
|
||||
(short*)ycbcr16x16_420_2,
|
||||
ref_sfc,
|
||||
sfc
|
||||
);
|
||||
vlPutSurface(sfc, framebuffer, 0, 0, video_width, video_height, 0, 0, window_width, window_height, VL_FRAME_PICTURE);
|
||||
|
||||
puts("Press any key to continue...");
|
||||
|
||||
while (!quit)
|
||||
{
|
||||
XNextEvent(display, &event);
|
||||
switch (event.type)
|
||||
{
|
||||
case Expose:
|
||||
{
|
||||
XCopyArea
|
||||
(
|
||||
display,
|
||||
framebuffer,
|
||||
window,
|
||||
XDefaultGC(display, XDefaultScreen(display)),
|
||||
0,
|
||||
0,
|
||||
window_width,
|
||||
window_height,
|
||||
0,
|
||||
0
|
||||
);
|
||||
break;
|
||||
}
|
||||
case KeyPress:
|
||||
{
|
||||
quit = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vlDestroySurface(sfc);
|
||||
vlDestroySurface(ref_sfc);
|
||||
vlDestroyContext(ctx);
|
||||
|
||||
XFreePixmap(display, framebuffer);
|
||||
XDestroyWindow(display, window);
|
||||
XCloseDisplay(display);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
#include <vl_context.h>
|
||||
#include <vl_surface.h>
|
||||
#include <xsp_winsys.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const unsigned int video_width = 32, video_height = 32;
|
||||
|
||||
Display *display;
|
||||
struct pipe_context *pipe;
|
||||
struct VL_CONTEXT *ctx;
|
||||
struct VL_SURFACE *sfc;
|
||||
|
||||
display = XOpenDisplay(NULL);
|
||||
pipe = create_pipe_context(display);
|
||||
|
||||
vlCreateContext(display, pipe, video_width, video_height, VL_FORMAT_YCBCR_420, &ctx);
|
||||
vlCreateSurface(ctx, &sfc);
|
||||
vlDestroySurface(sfc);
|
||||
vlDestroyContext(ctx);
|
||||
|
||||
XCloseDisplay(display);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,73 @@
|
||||
#ifndef vl_context_h
|
||||
#define vl_context_h
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <pipe/p_state.h>
|
||||
#include "vl_types.h"
|
||||
|
||||
struct pipe_context;
|
||||
|
||||
struct VL_CONTEXT
|
||||
{
|
||||
Display *display;
|
||||
struct pipe_context *pipe;
|
||||
unsigned int video_width;
|
||||
unsigned int video_height;
|
||||
enum VL_FORMAT video_format;
|
||||
|
||||
struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
struct pipe_rasterizer_state *raster;
|
||||
struct pipe_depth_stencil_alpha_state *dsa;
|
||||
struct pipe_blend_state *blend;
|
||||
} common;
|
||||
|
||||
struct
|
||||
{
|
||||
} idct;
|
||||
|
||||
struct
|
||||
{
|
||||
struct pipe_viewport_state viewport;
|
||||
struct pipe_framebuffer_state render_target;
|
||||
struct pipe_sampler_state *samplers[5];
|
||||
struct pipe_texture *textures[5];
|
||||
struct pipe_shader_state *i_vs, *p_vs, *b_vs;
|
||||
struct pipe_shader_state *i_fs, *p_fs, *b_fs;
|
||||
struct pipe_vertex_buffer vertex_bufs[6];
|
||||
struct pipe_vertex_element vertex_buf_elems[6];
|
||||
struct pipe_constant_buffer vs_const_buf, fs_const_buf;
|
||||
} mc;
|
||||
|
||||
struct
|
||||
{
|
||||
struct pipe_viewport_state viewport;
|
||||
struct pipe_framebuffer_state framebuffer;
|
||||
struct pipe_sampler_state *sampler;
|
||||
struct pipe_shader_state *vertex_shader, *fragment_shader;
|
||||
struct pipe_vertex_buffer vertex_bufs[2];
|
||||
struct pipe_vertex_element vertex_buf_elems[2];
|
||||
struct pipe_constant_buffer fs_const_buf;
|
||||
} csc;
|
||||
} states;
|
||||
};
|
||||
|
||||
int vlCreateContext
|
||||
(
|
||||
Display *display,
|
||||
struct pipe_context *pipe,
|
||||
unsigned int video_width,
|
||||
unsigned int video_height,
|
||||
enum VL_FORMAT video_format,
|
||||
struct VL_CONTEXT **context
|
||||
);
|
||||
|
||||
int vlDestroyContext(struct VL_CONTEXT *context);
|
||||
|
||||
int vlBeginRender(struct VL_CONTEXT *context);
|
||||
int vlEndRender(struct VL_CONTEXT *context);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,188 @@
|
||||
#include "vl_data.h"
|
||||
|
||||
/*
|
||||
* Represents 8 triangles (4 quads, 1 per block) in noormalized coords
|
||||
* that render a macroblock.
|
||||
* Need to be scaled to cover mbW*mbH macroblock pixels and translated into
|
||||
* position on target surface.
|
||||
*/
|
||||
const struct VL_VERTEX2F vl_mb_vertex_positions[24] =
|
||||
{
|
||||
{0.0f, 0.0f}, {0.0f, 0.5f}, {0.5f, 0.0f},
|
||||
{0.5f, 0.0f}, {0.0f, 0.5f}, {0.5f, 0.5f},
|
||||
|
||||
{0.5f, 0.0f}, {0.5f, 0.5f}, {1.0f, 0.0f},
|
||||
{1.0f, 0.0f}, {0.5f, 0.5f}, {1.0f, 0.5f},
|
||||
|
||||
{0.0f, 0.5f}, {0.0f, 1.0f}, {0.5f, 0.5f},
|
||||
{0.5f, 0.5f}, {0.0f, 1.0f}, {0.5f, 1.0f},
|
||||
|
||||
{0.5f, 0.5f}, {0.5f, 1.0f}, {1.0f, 0.5f},
|
||||
{1.0f, 0.5f}, {0.5f, 1.0f}, {1.0f, 1.0f}
|
||||
};
|
||||
|
||||
/*
|
||||
* Represents texcoords for the above for rendering 4 luma blocks arranged
|
||||
* in a bW*(bH*4) texture. First luma block located at 0,0->bW,bH; second at
|
||||
* 0,bH->bW,2bH; third at 0,2bH->bW,3bH; fourth at 0,3bH->bW,4bH.
|
||||
*/
|
||||
const struct VL_TEXCOORD2F vl_luma_texcoords[24] =
|
||||
{
|
||||
{0.0f, 0.0f}, {0.0f, 0.25f}, {1.0f, 0.0f},
|
||||
{1.0f, 0.0f}, {0.0f, 0.25f}, {1.0f, 0.25f},
|
||||
|
||||
{0.0f, 0.25f}, {0.0f, 0.5f}, {1.0f, 0.25f},
|
||||
{1.0f, 0.25f}, {0.0f, 0.5f}, {1.0f, 0.5f},
|
||||
|
||||
{0.0f, 0.5f}, {0.0f, 0.75f}, {1.0f, 0.5f},
|
||||
{1.0f, 0.5f}, {0.0f, 0.75f}, {1.0f, 0.75f},
|
||||
|
||||
{0.0f, 0.75f}, {0.0f, 1.0f}, {1.0f, 0.75f},
|
||||
{1.0f, 0.75f}, {0.0f, 1.0f}, {1.0f, 1.0f}
|
||||
};
|
||||
|
||||
/*
|
||||
* Represents texcoords for the above for rendering 1 chroma block.
|
||||
* Straight forward 0,0->1,1 mapping so we can reuse the MB pos vectors.
|
||||
*/
|
||||
const struct VL_TEXCOORD2F *vl_chroma_420_texcoords = (const struct VL_TEXCOORD2F*)vl_mb_vertex_positions;
|
||||
|
||||
/*
|
||||
* Represents texcoords for the above for rendering 2 chroma blocks arranged
|
||||
* in a bW*(bH*2) texture. First chroma block located at 0,0->bW,bH; second at
|
||||
* 0,bH->bW,2bH. We can render this with 0,0->1,1 mapping.
|
||||
* Straight forward 0,0->1,1 mapping so we can reuse MB pos vectors.
|
||||
*/
|
||||
const struct VL_TEXCOORD2F *vl_chroma_422_texcoords = (const struct VL_TEXCOORD2F*)vl_mb_vertex_positions;
|
||||
|
||||
/*
|
||||
* Represents texcoords for the above for rendering 4 chroma blocks.
|
||||
* Same case as 4 luma blocks.
|
||||
*/
|
||||
const struct VL_TEXCOORD2F *vl_chroma_444_texcoords = vl_luma_texcoords;
|
||||
|
||||
/*
|
||||
* Represents texcoords for the above for rendering a predicted macroblock.
|
||||
* Straight forward 0,0->1,1 mapping so we can reuse MB pos vectors.
|
||||
* Texcoords need to be translated to cover source macroblock on the
|
||||
* past/future surface.
|
||||
*/
|
||||
const struct VL_TEXCOORD2F *vl_ref_surface_texcoords = (const struct VL_TEXCOORD2F*)vl_mb_vertex_positions;
|
||||
|
||||
/*
|
||||
* Represents 2 triangles in a strip in normalized coords.
|
||||
* Used to render the surface onto the frame buffer.
|
||||
*/
|
||||
const struct VL_VERTEX2F vl_surface_vertex_positions[4] =
|
||||
{
|
||||
{0.0f, 0.0f},
|
||||
{0.0f, 1.0f},
|
||||
{1.0f, 0.0f},
|
||||
{1.0f, 1.0f}
|
||||
};
|
||||
|
||||
/*
|
||||
* Represents texcoords for the above. We can use the position values directly.
|
||||
*/
|
||||
const struct VL_TEXCOORD2F *vl_surface_texcoords = (const struct VL_TEXCOORD2F*)vl_surface_vertex_positions;
|
||||
|
||||
/*
|
||||
* Used when rendering P and B macroblocks, multiplier is applied to the A channel,
|
||||
* which is then added to the L channel, then the bias is subtracted from that to
|
||||
* get back the differential. The differential is then added to the samples from the
|
||||
* reference surface(s).
|
||||
*/
|
||||
const struct VL_MC_FS_CONSTS vl_mc_fs_consts =
|
||||
{
|
||||
{256.0f, 256.0f, 256.0f, 0.0f},
|
||||
{256.0f / 255.0f, 256.0f / 255.0f, 256.0f / 255.0f, 0.0f}
|
||||
};
|
||||
|
||||
/*
|
||||
* Identity color conversion constants, for debugging
|
||||
*/
|
||||
const struct VL_CSC_FS_CONSTS vl_csc_fs_consts_identity =
|
||||
{
|
||||
{
|
||||
0.0f, 0.0f, 0.0f, 0.0f
|
||||
},
|
||||
{
|
||||
1.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.0f, 1.0f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Converts ITU-R BT.601 YCbCr pixels to RGB pixels where:
|
||||
* Y is in [16,235], Cb and Cr are in [16,240]
|
||||
* R, G, and B are in [16,235]
|
||||
*/
|
||||
const struct VL_CSC_FS_CONSTS vl_csc_fs_consts_601 =
|
||||
{
|
||||
{
|
||||
0.0f, 0.501960784f, 0.501960784f, 0.0f
|
||||
},
|
||||
{
|
||||
1.0f, 0.0f, 1.371f, 0.0f,
|
||||
1.0f, -0.336f, -0.698f, 0.0f,
|
||||
1.0f, 1.732f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Converts ITU-R BT.601 YCbCr pixels to RGB pixels where:
|
||||
* Y is in [16,235], Cb and Cr are in [16,240]
|
||||
* R, G, and B are in [0,255]
|
||||
*/
|
||||
const struct VL_CSC_FS_CONSTS vl_csc_fs_consts_601_full =
|
||||
{
|
||||
{
|
||||
0.062745098f, 0.501960784f, 0.501960784f, 0.0f
|
||||
},
|
||||
{
|
||||
1.164f, 0.0f, 1.596f, 0.0f,
|
||||
1.164f, -0.391f, -0.813f, 0.0f,
|
||||
1.164f, 2.018f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Converts ITU-R BT.709 YCbCr pixels to RGB pixels where:
|
||||
* Y is in [16,235], Cb and Cr are in [16,240]
|
||||
* R, G, and B are in [16,235]
|
||||
*/
|
||||
const struct VL_CSC_FS_CONSTS vl_csc_fs_consts_709 =
|
||||
{
|
||||
{
|
||||
0.0f, 0.501960784f, 0.501960784f, 0.0f
|
||||
},
|
||||
{
|
||||
1.0f, 0.0f, 1.540f, 0.0f,
|
||||
1.0f, -0.183f, -0.459f, 0.0f,
|
||||
1.0f, 1.816f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Converts ITU-R BT.709 YCbCr pixels to RGB pixels where:
|
||||
* Y is in [16,235], Cb and Cr are in [16,240]
|
||||
* R, G, and B are in [0,255]
|
||||
*/
|
||||
const struct VL_CSC_FS_CONSTS vl_csc_fs_consts_709_full =
|
||||
{
|
||||
{
|
||||
0.062745098f, 0.501960784f, 0.501960784f, 0.0f
|
||||
},
|
||||
{
|
||||
1.164f, 0.0f, 1.793f, 0.0f,
|
||||
1.164f, -0.213f, -0.534f, 0.0f,
|
||||
1.164f, 2.115f, 0.0f, 0.0f,
|
||||
0.0f, 0.0f, 0.0f, 1.0f
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
#ifndef vl_data_h
|
||||
#define vl_data_h
|
||||
|
||||
#include "vl_types.h"
|
||||
|
||||
extern const struct VL_VERTEX2F vl_mb_vertex_positions[24];
|
||||
extern const struct VL_TEXCOORD2F vl_luma_texcoords[24];
|
||||
extern const struct VL_TEXCOORD2F *vl_chroma_420_texcoords;
|
||||
extern const struct VL_TEXCOORD2F *vl_chroma_422_texcoords;
|
||||
extern const struct VL_TEXCOORD2F *vl_chroma_444_texcoords;
|
||||
extern const struct VL_TEXCOORD2F *vl_ref_surface_texcoords;
|
||||
|
||||
extern const struct VL_VERTEX2F vl_surface_vertex_positions[4];
|
||||
extern const struct VL_TEXCOORD2F *vl_surface_texcoords;
|
||||
|
||||
extern const struct VL_MC_FS_CONSTS vl_mc_fs_consts;
|
||||
|
||||
extern const struct VL_CSC_FS_CONSTS vl_csc_fs_consts_identity;
|
||||
extern const struct VL_CSC_FS_CONSTS vl_csc_fs_consts_601;
|
||||
extern const struct VL_CSC_FS_CONSTS vl_csc_fs_consts_601_full;
|
||||
extern const struct VL_CSC_FS_CONSTS vl_csc_fs_consts_709;
|
||||
extern const struct VL_CSC_FS_CONSTS vl_csc_fs_consts_709_full;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
#ifndef vl_defs_h
|
||||
#define vl_defs_h
|
||||
|
||||
#define VL_BLOCK_WIDTH 8
|
||||
#define VL_BLOCK_HEIGHT 8
|
||||
#define VL_BLOCK_SIZE (VL_BLOCK_WIDTH * VL_BLOCK_HEIGHT)
|
||||
#define VL_MACROBLOCK_WIDTH 16
|
||||
#define VL_MACROBLOCK_HEIGHT 16
|
||||
#define VL_MACROBLOCK_SIZE (VL_MACROBLOCK_WIDTH * VL_MACROBLOCK_HEIGHT)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,539 @@
|
||||
#include "vl_surface.h"
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <pipe/p_context.h>
|
||||
#include <pipe/p_state.h>
|
||||
#include <pipe/p_format.h>
|
||||
#include <pipe/p_inlines.h>
|
||||
#include "vl_context.h"
|
||||
#include "vl_defs.h"
|
||||
|
||||
static int vlGrabBlocks
|
||||
(
|
||||
struct VL_CONTEXT *context,
|
||||
unsigned int coded_block_pattern,
|
||||
enum VL_DCT_TYPE dct_type,
|
||||
enum VL_SAMPLE_TYPE sample_type,
|
||||
short *blocks
|
||||
)
|
||||
{
|
||||
struct pipe_surface *tex_surface;
|
||||
short *texels;
|
||||
unsigned int b, x, y, y2;
|
||||
|
||||
assert(context);
|
||||
assert(blocks);
|
||||
|
||||
tex_surface = context->pipe->screen->get_tex_surface
|
||||
(
|
||||
context->pipe->screen,
|
||||
context->states.mc.textures[0],
|
||||
0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE
|
||||
);
|
||||
|
||||
texels = pipe_surface_map(tex_surface, 0);
|
||||
|
||||
for (b = 0; b < 4; ++b)
|
||||
{
|
||||
if ((coded_block_pattern >> b) & 1)
|
||||
{
|
||||
if (dct_type == VL_DCT_FRAME_CODED)
|
||||
{
|
||||
if (sample_type == VL_FULL_SAMPLE)
|
||||
{
|
||||
for (y = VL_BLOCK_HEIGHT * b; y < VL_BLOCK_HEIGHT * (b + 1); ++y)
|
||||
memcpy
|
||||
(
|
||||
texels + y * tex_surface->pitch,
|
||||
blocks + y * VL_BLOCK_WIDTH,
|
||||
VL_BLOCK_WIDTH * 2
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (y = VL_BLOCK_HEIGHT * b; y < VL_BLOCK_HEIGHT * (b + 1); ++y)
|
||||
for (x = 0; x < VL_BLOCK_WIDTH; ++x)
|
||||
texels[y * tex_surface->pitch + x] =
|
||||
blocks[y * VL_BLOCK_WIDTH + x] + 0x100;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sample_type == VL_FULL_SAMPLE)
|
||||
{
|
||||
for
|
||||
(
|
||||
y = VL_BLOCK_HEIGHT * (b % 2), y2 = VL_BLOCK_HEIGHT * b;
|
||||
y < VL_BLOCK_HEIGHT * ((b % 2) + 1);
|
||||
y += 2, ++y2
|
||||
)
|
||||
memcpy
|
||||
(
|
||||
texels + y * tex_surface->pitch,
|
||||
blocks + y2 * VL_BLOCK_WIDTH,
|
||||
VL_BLOCK_WIDTH * 2
|
||||
);
|
||||
for
|
||||
(
|
||||
y = VL_BLOCK_HEIGHT * ((b % 2) + 2);
|
||||
y < VL_BLOCK_HEIGHT * (((b % 2) + 2) + 1);
|
||||
y += 2, ++y2
|
||||
)
|
||||
memcpy
|
||||
(
|
||||
texels + y * tex_surface->pitch,
|
||||
blocks + y2 * VL_BLOCK_WIDTH,
|
||||
VL_BLOCK_WIDTH * 2
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
for
|
||||
(
|
||||
y = VL_BLOCK_HEIGHT * (b % 2), y2 = VL_BLOCK_HEIGHT * b;
|
||||
y < VL_BLOCK_HEIGHT * ((b % 2) + 1);
|
||||
y += 2, ++y2
|
||||
)
|
||||
for (x = 0; x < VL_BLOCK_WIDTH; ++x)
|
||||
texels[y * tex_surface->pitch + x] =
|
||||
blocks[y2 * VL_BLOCK_WIDTH + x] + 0x100;
|
||||
for
|
||||
(
|
||||
y = VL_BLOCK_HEIGHT * ((b % 2) + 2);
|
||||
y < VL_BLOCK_HEIGHT * (((b % 2) + 2) + 1);
|
||||
y += 2, ++y2
|
||||
)
|
||||
for (x = 0; x < VL_BLOCK_WIDTH; ++x)
|
||||
texels[y * tex_surface->pitch + x] =
|
||||
blocks[y2 * VL_BLOCK_WIDTH + x] + 0x100;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (y = VL_BLOCK_HEIGHT * b; y < VL_BLOCK_HEIGHT * (b + 1); ++y)
|
||||
{
|
||||
for (x = 0; x < VL_BLOCK_WIDTH; ++x)
|
||||
texels[y * tex_surface->pitch + x] = 0x100;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pipe_surface_unmap(tex_surface);
|
||||
|
||||
/* TODO: Implement 422, 444 */
|
||||
for (b = 0; b < 2; ++b)
|
||||
{
|
||||
tex_surface = context->pipe->screen->get_tex_surface
|
||||
(
|
||||
context->pipe->screen,
|
||||
context->states.mc.textures[b + 1],
|
||||
0, 0, 0, PIPE_BUFFER_USAGE_CPU_WRITE
|
||||
);
|
||||
|
||||
texels = pipe_surface_map(tex_surface, 0);
|
||||
|
||||
if ((coded_block_pattern >> (b + 4)) & 1)
|
||||
{
|
||||
if (sample_type == VL_FULL_SAMPLE)
|
||||
{
|
||||
for (y = 0; y < tex_surface->height; ++y)
|
||||
memcpy
|
||||
(
|
||||
texels + y * tex_surface->pitch,
|
||||
blocks + VL_BLOCK_SIZE * (b + 4) + y * VL_BLOCK_WIDTH,
|
||||
VL_BLOCK_WIDTH * 2
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (y = 0; y < tex_surface->height; ++y)
|
||||
for (x = 0; x < VL_BLOCK_WIDTH; ++x)
|
||||
texels[y * tex_surface->pitch + x] =
|
||||
blocks[VL_BLOCK_SIZE * (b + 4) + y * VL_BLOCK_WIDTH + x] + 0x100;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (y = 0; y < tex_surface->height; ++y)
|
||||
{
|
||||
for (x = 0; x < VL_BLOCK_WIDTH; ++x)
|
||||
texels[y * tex_surface->pitch + x] = 0x100;
|
||||
}
|
||||
}
|
||||
|
||||
pipe_surface_unmap(tex_surface);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vlCreateSurface(struct VL_CONTEXT *context, struct VL_SURFACE **surface)
|
||||
{
|
||||
struct pipe_context *pipe;
|
||||
struct pipe_texture template;
|
||||
struct VL_SURFACE *sfc;
|
||||
|
||||
assert(context);
|
||||
assert(surface);
|
||||
|
||||
pipe = context->pipe;
|
||||
|
||||
sfc = calloc(1, sizeof(struct VL_SURFACE));
|
||||
|
||||
sfc->context = context;
|
||||
sfc->width = context->video_width;
|
||||
sfc->height = context->video_height;
|
||||
sfc->format = context->video_format;
|
||||
|
||||
memset(&template, 0, sizeof(struct pipe_texture));
|
||||
template.target = PIPE_TEXTURE_2D;
|
||||
template.format = PIPE_FORMAT_A8R8G8B8_UNORM;
|
||||
template.last_level = 0;
|
||||
template.width[0] = sfc->width;
|
||||
template.height[0] = sfc->height;
|
||||
template.depth[0] = 1;
|
||||
template.compressed = 0;
|
||||
template.cpp = 4;
|
||||
|
||||
sfc->texture = pipe->screen->texture_create(pipe->screen, &template);
|
||||
|
||||
*surface = sfc;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vlDestroySurface(struct VL_SURFACE *surface)
|
||||
{
|
||||
assert(surface);
|
||||
pipe_texture_release(&surface->texture);
|
||||
free(surface);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vlRenderIMacroBlock
|
||||
(
|
||||
enum VL_PICTURE picture_type,
|
||||
enum VL_FIELD_ORDER field_order,
|
||||
unsigned int mbx,
|
||||
unsigned int mby,
|
||||
unsigned int coded_block_pattern,
|
||||
enum VL_DCT_TYPE dct_type,
|
||||
short *blocks,
|
||||
struct VL_SURFACE *surface
|
||||
)
|
||||
{
|
||||
struct pipe_context *pipe;
|
||||
struct VL_MC_VS_CONSTS *vscbdata;
|
||||
|
||||
assert(blocks);
|
||||
assert(surface);
|
||||
|
||||
/* TODO: Implement interlaced rendering */
|
||||
/*assert(picture_type == VL_FRAME_PICTURE);*/
|
||||
if (picture_type != VL_FRAME_PICTURE)
|
||||
{
|
||||
/*fprintf(stderr, "field picture (I) unimplemented, ignoring\n");*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
pipe = surface->context->pipe;
|
||||
|
||||
vscbdata = pipe->winsys->buffer_map
|
||||
(
|
||||
pipe->winsys,
|
||||
surface->context->states.mc.vs_const_buf.buffer,
|
||||
PIPE_BUFFER_USAGE_CPU_WRITE
|
||||
);
|
||||
|
||||
vscbdata->scale.x = VL_MACROBLOCK_WIDTH / (float)surface->width;
|
||||
vscbdata->scale.y = VL_MACROBLOCK_HEIGHT / (float)surface->height;
|
||||
vscbdata->scale.z = 1.0f;
|
||||
vscbdata->scale.w = 1.0f;
|
||||
vscbdata->mb_pos_trans.x = (mbx * VL_MACROBLOCK_WIDTH) / (float)surface->width;
|
||||
vscbdata->mb_pos_trans.y = (mby * VL_MACROBLOCK_HEIGHT) / (float)surface->height;
|
||||
vscbdata->mb_pos_trans.z = 0.0f;
|
||||
vscbdata->mb_pos_trans.w = 0.0f;
|
||||
|
||||
pipe->winsys->buffer_unmap(pipe->winsys, surface->context->states.mc.vs_const_buf.buffer);
|
||||
|
||||
vlGrabBlocks(surface->context, coded_block_pattern, dct_type, VL_FULL_SAMPLE, blocks);
|
||||
|
||||
surface->context->states.mc.render_target.cbufs[0] = pipe->screen->get_tex_surface
|
||||
(
|
||||
pipe->screen,
|
||||
surface->texture,
|
||||
0, 0, 0, PIPE_BUFFER_USAGE_CPU_READ | PIPE_BUFFER_USAGE_CPU_WRITE
|
||||
);
|
||||
pipe->set_framebuffer_state(pipe, &surface->context->states.mc.render_target);
|
||||
pipe->set_sampler_textures(pipe, 3, surface->context->states.mc.textures);
|
||||
pipe->bind_sampler_states(pipe, 3, (void**)surface->context->states.mc.samplers);
|
||||
pipe->set_vertex_buffers(pipe, 4, surface->context->states.mc.vertex_bufs);
|
||||
pipe->set_vertex_elements(pipe, 4, surface->context->states.mc.vertex_buf_elems);
|
||||
pipe->bind_vs_state(pipe, surface->context->states.mc.i_vs);
|
||||
pipe->bind_fs_state(pipe, surface->context->states.mc.i_fs);
|
||||
|
||||
pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, 24);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vlRenderPMacroBlock
|
||||
(
|
||||
enum VL_PICTURE picture_type,
|
||||
enum VL_FIELD_ORDER field_order,
|
||||
unsigned int mbx,
|
||||
unsigned int mby,
|
||||
enum VL_MC_TYPE mc_type,
|
||||
struct VL_MOTION_VECTOR *motion_vector,
|
||||
unsigned int coded_block_pattern,
|
||||
enum VL_DCT_TYPE dct_type,
|
||||
short *blocks,
|
||||
struct VL_SURFACE *ref_surface,
|
||||
struct VL_SURFACE *surface
|
||||
)
|
||||
{
|
||||
struct pipe_context *pipe;
|
||||
struct VL_MC_VS_CONSTS *vscbdata;
|
||||
|
||||
assert(motion_vectors);
|
||||
assert(blocks);
|
||||
assert(ref_surface);
|
||||
assert(surface);
|
||||
|
||||
/* TODO: Implement interlaced rendering */
|
||||
/*assert(picture_type == VL_FRAME_PICTURE);*/
|
||||
if (picture_type != VL_FRAME_PICTURE)
|
||||
{
|
||||
/*fprintf(stderr, "field picture (P) unimplemented, ignoring\n");*/
|
||||
return 0;
|
||||
}
|
||||
/* TODO: Implement field based motion compensation */
|
||||
/*assert(mc_type == VL_FRAME_MC);*/
|
||||
if (mc_type != VL_FRAME_MC)
|
||||
{
|
||||
/*fprintf(stderr, "field MC (P) unimplemented, ignoring\n");*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
pipe = surface->context->pipe;
|
||||
|
||||
vscbdata = pipe->winsys->buffer_map
|
||||
(
|
||||
pipe->winsys,
|
||||
surface->context->states.mc.vs_const_buf.buffer,
|
||||
PIPE_BUFFER_USAGE_CPU_WRITE
|
||||
);
|
||||
|
||||
vscbdata->scale.x = VL_MACROBLOCK_WIDTH / (float)surface->width;
|
||||
vscbdata->scale.y = VL_MACROBLOCK_HEIGHT / (float)surface->height;
|
||||
vscbdata->scale.z = 1.0f;
|
||||
vscbdata->scale.w = 1.0f;
|
||||
vscbdata->mb_pos_trans.x = (mbx * VL_MACROBLOCK_WIDTH) / (float)surface->width;
|
||||
vscbdata->mb_pos_trans.y = (mby * VL_MACROBLOCK_HEIGHT) / (float)surface->height;
|
||||
vscbdata->mb_pos_trans.z = 0.0f;
|
||||
vscbdata->mb_pos_trans.w = 0.0f;
|
||||
vscbdata->mb_tc_trans[0].x = (mbx * VL_MACROBLOCK_WIDTH + motion_vector->top_field.x * 0.5f) / (float)surface->width;
|
||||
vscbdata->mb_tc_trans[0].y = (mby * VL_MACROBLOCK_HEIGHT + motion_vector->top_field.y * 0.5f) / (float)surface->height;
|
||||
vscbdata->mb_tc_trans[0].z = 0.0f;
|
||||
vscbdata->mb_tc_trans[0].w = 0.0f;
|
||||
|
||||
pipe->winsys->buffer_unmap(pipe->winsys, surface->context->states.mc.vs_const_buf.buffer);
|
||||
|
||||
vlGrabBlocks(surface->context, coded_block_pattern, dct_type, VL_DIFFERENCE_SAMPLE, blocks);
|
||||
|
||||
surface->context->states.mc.render_target.cbufs[0] = pipe->screen->get_tex_surface
|
||||
(
|
||||
pipe->screen,
|
||||
surface->texture,
|
||||
0, 0, 0, PIPE_BUFFER_USAGE_CPU_READ | PIPE_BUFFER_USAGE_CPU_WRITE
|
||||
);
|
||||
pipe->set_framebuffer_state(pipe, &surface->context->states.mc.render_target);
|
||||
|
||||
surface->context->states.mc.textures[3] = ref_surface->texture;
|
||||
pipe->set_sampler_textures(pipe, 4, surface->context->states.mc.textures);
|
||||
pipe->bind_sampler_states(pipe, 4, (void**)surface->context->states.mc.samplers);
|
||||
pipe->set_vertex_buffers(pipe, 5, surface->context->states.mc.vertex_bufs);
|
||||
pipe->set_vertex_elements(pipe, 5, surface->context->states.mc.vertex_buf_elems);
|
||||
pipe->bind_vs_state(pipe, surface->context->states.mc.p_vs);
|
||||
pipe->bind_fs_state(pipe, surface->context->states.mc.p_fs);
|
||||
|
||||
pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, 24);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vlRenderBMacroBlock
|
||||
(
|
||||
enum VL_PICTURE picture_type,
|
||||
enum VL_FIELD_ORDER field_order,
|
||||
unsigned int mbx,
|
||||
unsigned int mby,
|
||||
enum VL_MC_TYPE mc_type,
|
||||
struct VL_MOTION_VECTOR *motion_vector,
|
||||
unsigned int coded_block_pattern,
|
||||
enum VL_DCT_TYPE dct_type,
|
||||
short *blocks,
|
||||
struct VL_SURFACE *past_surface,
|
||||
struct VL_SURFACE *future_surface,
|
||||
struct VL_SURFACE *surface
|
||||
)
|
||||
{
|
||||
struct pipe_context *pipe;
|
||||
struct VL_MC_VS_CONSTS *vscbdata;
|
||||
|
||||
assert(motion_vectors);
|
||||
assert(blocks);
|
||||
assert(ref_surface);
|
||||
assert(surface);
|
||||
|
||||
/* TODO: Implement interlaced rendering */
|
||||
/*assert(picture_type == VL_FRAME_PICTURE);*/
|
||||
if (picture_type != VL_FRAME_PICTURE)
|
||||
{
|
||||
/*fprintf(stderr, "field picture (B) unimplemented, ignoring\n");*/
|
||||
return 0;
|
||||
}
|
||||
/* TODO: Implement field based motion compensation */
|
||||
/*assert(mc_type == VL_FRAME_MC);*/
|
||||
if (mc_type != VL_FRAME_MC)
|
||||
{
|
||||
/*fprintf(stderr, "field MC (B) unimplemented, ignoring\n");*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
pipe = surface->context->pipe;
|
||||
|
||||
vscbdata = pipe->winsys->buffer_map
|
||||
(
|
||||
pipe->winsys,
|
||||
surface->context->states.mc.vs_const_buf.buffer,
|
||||
PIPE_BUFFER_USAGE_CPU_WRITE
|
||||
);
|
||||
|
||||
vscbdata->scale.x = VL_MACROBLOCK_WIDTH / (float)surface->width;
|
||||
vscbdata->scale.y = VL_MACROBLOCK_HEIGHT / (float)surface->height;
|
||||
vscbdata->scale.z = 1.0f;
|
||||
vscbdata->scale.w = 1.0f;
|
||||
vscbdata->mb_pos_trans.x = (mbx * VL_MACROBLOCK_WIDTH) / (float)surface->width;
|
||||
vscbdata->mb_pos_trans.y = (mby * VL_MACROBLOCK_HEIGHT) / (float)surface->height;
|
||||
vscbdata->mb_pos_trans.z = 0.0f;
|
||||
vscbdata->mb_pos_trans.w = 0.0f;
|
||||
vscbdata->mb_tc_trans[0].x = (mbx * VL_MACROBLOCK_WIDTH + motion_vector[0].top_field.x * 0.5f) / (float)surface->width;
|
||||
vscbdata->mb_tc_trans[0].y = (mby * VL_MACROBLOCK_HEIGHT + motion_vector[0].top_field.y * 0.5f) / (float)surface->height;
|
||||
vscbdata->mb_tc_trans[0].z = 0.0f;
|
||||
vscbdata->mb_tc_trans[0].w = 0.0f;
|
||||
vscbdata->mb_tc_trans[1].x = (mbx * VL_MACROBLOCK_WIDTH + motion_vector[1].top_field.x * 0.5f) / (float)surface->width;
|
||||
vscbdata->mb_tc_trans[1].y = (mby * VL_MACROBLOCK_HEIGHT + motion_vector[1].top_field.y * 0.5f) / (float)surface->height;
|
||||
vscbdata->mb_tc_trans[1].z = 0.0f;
|
||||
vscbdata->mb_tc_trans[1].w = 0.0f;
|
||||
|
||||
pipe->winsys->buffer_unmap(pipe->winsys, surface->context->states.mc.vs_const_buf.buffer);
|
||||
|
||||
vlGrabBlocks(surface->context, coded_block_pattern, dct_type, VL_DIFFERENCE_SAMPLE, blocks);
|
||||
|
||||
surface->context->states.mc.render_target.cbufs[0] = pipe->screen->get_tex_surface
|
||||
(
|
||||
pipe->screen,
|
||||
surface->texture,
|
||||
0, 0, 0, PIPE_BUFFER_USAGE_CPU_READ | PIPE_BUFFER_USAGE_CPU_WRITE
|
||||
);
|
||||
pipe->set_framebuffer_state(pipe, &surface->context->states.mc.render_target);
|
||||
|
||||
surface->context->states.mc.textures[3] = past_surface->texture;
|
||||
surface->context->states.mc.textures[4] = future_surface->texture;
|
||||
pipe->set_sampler_textures(pipe, 5, surface->context->states.mc.textures);
|
||||
pipe->bind_sampler_states(pipe, 5, (void**)surface->context->states.mc.samplers);
|
||||
pipe->set_vertex_buffers(pipe, 6, surface->context->states.mc.vertex_bufs);
|
||||
pipe->set_vertex_elements(pipe, 6, surface->context->states.mc.vertex_buf_elems);
|
||||
pipe->bind_vs_state(pipe, surface->context->states.mc.b_vs);
|
||||
pipe->bind_fs_state(pipe, surface->context->states.mc.b_fs);
|
||||
|
||||
pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLES, 0, 24);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vlPutSurface
|
||||
(
|
||||
struct VL_SURFACE *surface,
|
||||
Drawable drawable,
|
||||
unsigned int srcx,
|
||||
unsigned int srcy,
|
||||
unsigned int srcw,
|
||||
unsigned int srch,
|
||||
unsigned int destx,
|
||||
unsigned int desty,
|
||||
unsigned int destw,
|
||||
unsigned int desth,
|
||||
enum VL_PICTURE picture_type
|
||||
)
|
||||
{
|
||||
unsigned int create_fb = 0;
|
||||
struct pipe_context *pipe;
|
||||
|
||||
assert(surface);
|
||||
|
||||
pipe = surface->context->pipe;
|
||||
|
||||
if (!surface->context->states.csc.framebuffer.cbufs[0])
|
||||
create_fb = 1;
|
||||
else if
|
||||
(
|
||||
surface->context->states.csc.framebuffer.width != destw ||
|
||||
surface->context->states.csc.framebuffer.height != desth
|
||||
)
|
||||
{
|
||||
pipe->winsys->surface_release
|
||||
(
|
||||
pipe->winsys,
|
||||
&surface->context->states.csc.framebuffer.cbufs[0]
|
||||
);
|
||||
|
||||
create_fb = 1;
|
||||
}
|
||||
|
||||
if (create_fb)
|
||||
{
|
||||
surface->context->states.csc.viewport.scale[0] = destw;
|
||||
surface->context->states.csc.viewport.scale[1] = desth;
|
||||
surface->context->states.csc.viewport.scale[2] = 1;
|
||||
surface->context->states.csc.viewport.scale[3] = 1;
|
||||
surface->context->states.csc.viewport.translate[0] = 0;
|
||||
surface->context->states.csc.viewport.translate[1] = 0;
|
||||
surface->context->states.csc.viewport.translate[2] = 0;
|
||||
surface->context->states.csc.viewport.translate[3] = 0;
|
||||
|
||||
surface->context->states.csc.framebuffer.width = destw;
|
||||
surface->context->states.csc.framebuffer.height = desth;
|
||||
surface->context->states.csc.framebuffer.cbufs[0] = pipe->winsys->surface_alloc(pipe->winsys);
|
||||
pipe->winsys->surface_alloc_storage
|
||||
(
|
||||
pipe->winsys,
|
||||
surface->context->states.csc.framebuffer.cbufs[0],
|
||||
destw,
|
||||
desth,
|
||||
PIPE_FORMAT_A8R8G8B8_UNORM,
|
||||
PIPE_BUFFER_USAGE_CPU_READ | PIPE_BUFFER_USAGE_CPU_WRITE,
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
vlEndRender(surface->context);
|
||||
|
||||
pipe->set_sampler_textures(pipe, 1, &surface->texture);
|
||||
pipe->draw_arrays(pipe, PIPE_PRIM_TRIANGLE_STRIP, 0, 4);
|
||||
pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
|
||||
pipe->winsys->flush_frontbuffer
|
||||
(
|
||||
pipe->winsys,
|
||||
surface->context->states.csc.framebuffer.cbufs[0],
|
||||
&drawable
|
||||
);
|
||||
|
||||
vlBeginRender(surface->context);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
#ifndef vl_surface_h
|
||||
#define vl_surface_h
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include "vl_types.h"
|
||||
|
||||
struct pipe_texture;
|
||||
|
||||
struct VL_SURFACE
|
||||
{
|
||||
struct VL_CONTEXT *context;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
enum VL_FORMAT format;
|
||||
struct pipe_texture *texture;
|
||||
};
|
||||
|
||||
int vlCreateSurface(struct VL_CONTEXT *context, struct VL_SURFACE **surface);
|
||||
|
||||
int vlDestroySurface(struct VL_SURFACE *surface);
|
||||
|
||||
int vlRenderIMacroBlock
|
||||
(
|
||||
enum VL_PICTURE picture_type,
|
||||
enum VL_FIELD_ORDER field_order,
|
||||
unsigned int mbx,
|
||||
unsigned int mby,
|
||||
unsigned int coded_block_pattern,
|
||||
enum VL_DCT_TYPE dct_type,
|
||||
short *blocks,
|
||||
struct VL_SURFACE *surface
|
||||
);
|
||||
|
||||
int vlRenderPMacroBlock
|
||||
(
|
||||
enum VL_PICTURE picture_type,
|
||||
enum VL_FIELD_ORDER field_order,
|
||||
unsigned int mbx,
|
||||
unsigned int mby,
|
||||
enum VL_MC_TYPE mc_type,
|
||||
struct VL_MOTION_VECTOR *motion_vector,
|
||||
unsigned int coded_block_pattern,
|
||||
enum VL_DCT_TYPE dct_type,
|
||||
short *blocks,
|
||||
struct VL_SURFACE *ref_surface,
|
||||
struct VL_SURFACE *surface
|
||||
);
|
||||
|
||||
int vlRenderBMacroBlock
|
||||
(
|
||||
enum VL_PICTURE picture_type,
|
||||
enum VL_FIELD_ORDER field_order,
|
||||
unsigned int mbx,
|
||||
unsigned int mby,
|
||||
enum VL_MC_TYPE mc_type,
|
||||
struct VL_MOTION_VECTOR *motion_vector,
|
||||
unsigned int coded_block_pattern,
|
||||
enum VL_DCT_TYPE dct_type,
|
||||
short *blocks,
|
||||
struct VL_SURFACE *past_surface,
|
||||
struct VL_SURFACE *future_surface,
|
||||
struct VL_SURFACE *surface
|
||||
);
|
||||
|
||||
int vlPutSurface
|
||||
(
|
||||
struct VL_SURFACE *surface,
|
||||
Drawable drawable,
|
||||
unsigned int srcx,
|
||||
unsigned int srcy,
|
||||
unsigned int srcw,
|
||||
unsigned int srch,
|
||||
unsigned int destx,
|
||||
unsigned int desty,
|
||||
unsigned int destw,
|
||||
unsigned int desth,
|
||||
enum VL_PICTURE picture_type
|
||||
);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
#ifndef vl_types_h
|
||||
#define vl_types_h
|
||||
|
||||
enum VL_FORMAT
|
||||
{
|
||||
VL_FORMAT_YCBCR_420,
|
||||
VL_FORMAT_YCBCR_422,
|
||||
VL_FORMAT_YCBCR_444
|
||||
};
|
||||
|
||||
enum VL_PICTURE
|
||||
{
|
||||
VL_TOP_FIELD,
|
||||
VL_BOTTOM_FIELD,
|
||||
VL_FRAME_PICTURE
|
||||
};
|
||||
|
||||
enum VL_FIELD_ORDER
|
||||
{
|
||||
VL_FIELD_FIRST,
|
||||
VL_FIELD_SECOND
|
||||
};
|
||||
|
||||
enum VL_DCT_TYPE
|
||||
{
|
||||
VL_DCT_FIELD_CODED,
|
||||
VL_DCT_FRAME_CODED
|
||||
};
|
||||
|
||||
enum VL_SAMPLE_TYPE
|
||||
{
|
||||
VL_FULL_SAMPLE,
|
||||
VL_DIFFERENCE_SAMPLE
|
||||
};
|
||||
|
||||
enum VL_MC_TYPE
|
||||
{
|
||||
VL_FIELD_MC,
|
||||
VL_FRAME_MC
|
||||
};
|
||||
|
||||
struct VL_VERTEX4F
|
||||
{
|
||||
float x, y, z, w;
|
||||
};
|
||||
|
||||
struct VL_VERTEX2F
|
||||
{
|
||||
float x, y;
|
||||
};
|
||||
|
||||
struct VL_TEXCOORD2F
|
||||
{
|
||||
float s, t;
|
||||
};
|
||||
|
||||
struct VL_MC_VS_CONSTS
|
||||
{
|
||||
struct VL_VERTEX4F scale;
|
||||
struct VL_VERTEX4F mb_pos_trans;
|
||||
struct VL_VERTEX4F mb_tc_trans[2];
|
||||
};
|
||||
|
||||
struct VL_MC_FS_CONSTS
|
||||
{
|
||||
struct VL_VERTEX4F multiplier;
|
||||
struct VL_VERTEX4F bias;
|
||||
};
|
||||
|
||||
struct VL_CSC_FS_CONSTS
|
||||
{
|
||||
struct VL_VERTEX4F bias;
|
||||
float matrix[16];
|
||||
};
|
||||
|
||||
struct VL_MOTION_VECTOR
|
||||
{
|
||||
struct
|
||||
{
|
||||
int x, y;
|
||||
} top_field, bottom_field;
|
||||
};
|
||||
|
||||
struct VL_CONTEXT;
|
||||
struct VL_SURFACE;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,256 @@
|
||||
#include "xsp_winsys.h"
|
||||
#include <X11/Xutil.h>
|
||||
#include <pipe/p_winsys.h>
|
||||
#include <pipe/p_state.h>
|
||||
#include <pipe/p_util.h>
|
||||
#include <pipe/p_inlines.h>
|
||||
#include <softpipe/sp_winsys.h>
|
||||
|
||||
/* pipe_winsys implementation */
|
||||
|
||||
struct xsp_pipe_winsys
|
||||
{
|
||||
struct pipe_winsys base;
|
||||
Display *display;
|
||||
XImage fbimage;
|
||||
};
|
||||
|
||||
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));
|
||||
buffer->base.refcount = 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));
|
||||
buffer->base.refcount = 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_winsys *pws, struct pipe_buffer *buffer)
|
||||
{
|
||||
struct xsp_buffer *xsp_buf = (struct xsp_buffer*)buffer;
|
||||
|
||||
assert(pws);
|
||||
assert(buffer);
|
||||
|
||||
if (!xsp_buf->is_user_buffer)
|
||||
align_free(xsp_buf->data);
|
||||
|
||||
free(xsp_buf);
|
||||
}
|
||||
|
||||
static struct pipe_surface* xsp_surface_alloc(struct pipe_winsys *pws)
|
||||
{
|
||||
struct pipe_surface *surface;
|
||||
|
||||
assert(pws);
|
||||
|
||||
surface = calloc(1, sizeof(struct pipe_surface));
|
||||
surface->refcount = 1;
|
||||
surface->winsys = pws;
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
static int xsp_surface_alloc_storage
|
||||
(
|
||||
struct pipe_winsys *pws,
|
||||
struct pipe_surface *surface,
|
||||
unsigned width,
|
||||
unsigned height,
|
||||
enum pipe_format format,
|
||||
unsigned flags,
|
||||
unsigned tex_usage
|
||||
)
|
||||
{
|
||||
const unsigned int ALIGNMENT = 1;
|
||||
|
||||
assert(pws);
|
||||
assert(surface);
|
||||
|
||||
surface->width = width;
|
||||
surface->height = height;
|
||||
surface->format = format;
|
||||
surface->cpp = pf_get_size(format);
|
||||
surface->pitch = width;
|
||||
surface->usage = flags;
|
||||
surface->buffer = pws->buffer_create(pws, ALIGNMENT, PIPE_BUFFER_USAGE_PIXEL, surface->pitch * surface->cpp * height);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void xsp_surface_release(struct pipe_winsys *pws, struct pipe_surface **surface)
|
||||
{
|
||||
struct pipe_surface *s;
|
||||
|
||||
assert(pws);
|
||||
assert(surface);
|
||||
assert(*surface);
|
||||
|
||||
s = *surface;
|
||||
|
||||
s->refcount--;
|
||||
|
||||
if (s->refcount == 0)
|
||||
{
|
||||
pipe_buffer_reference(pws, &s->buffer, NULL);
|
||||
free(s);
|
||||
}
|
||||
|
||||
*surface = NULL;
|
||||
}
|
||||
|
||||
static void xsp_flush_frontbuffer(struct pipe_winsys *pws, struct pipe_surface *surface, void *context_private)
|
||||
{
|
||||
struct xsp_pipe_winsys *xsp_winsys;
|
||||
|
||||
assert(pws);
|
||||
assert(surface);
|
||||
assert(context_private);
|
||||
|
||||
xsp_winsys = (struct xsp_pipe_winsys*)pws;
|
||||
|
||||
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 = pipe_surface_map(surface, 0);
|
||||
|
||||
XPutImage
|
||||
(
|
||||
xsp_winsys->display,
|
||||
*(Drawable*)context_private,
|
||||
XDefaultGC(xsp_winsys->display, XDefaultScreen(xsp_winsys->display)),
|
||||
&xsp_winsys->fbimage,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
surface->width,
|
||||
surface->height
|
||||
);
|
||||
XFlush(xsp_winsys->display);
|
||||
pipe_surface_unmap(surface);
|
||||
}
|
||||
|
||||
static const char* xsp_get_name(struct pipe_winsys *pws)
|
||||
{
|
||||
assert(pws);
|
||||
return "X11 SoftPipe";
|
||||
}
|
||||
|
||||
/* softpipe_winsys implementation */
|
||||
|
||||
static boolean xsp_is_format_supported(struct softpipe_winsys *spws, enum pipe_format format)
|
||||
{
|
||||
assert(spws);
|
||||
|
||||
/* TODO: Test that 'format' is equal to our output window's format */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Show starts here */
|
||||
|
||||
struct pipe_context* create_pipe_context(Display *display)
|
||||
{
|
||||
struct xsp_pipe_winsys *xsp_winsys;
|
||||
struct softpipe_winsys *sp_winsys;
|
||||
struct pipe_screen *p_screen;
|
||||
struct pipe_context *p_context;
|
||||
|
||||
assert(display);
|
||||
|
||||
xsp_winsys = calloc(1, sizeof(struct xsp_pipe_winsys));
|
||||
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_alloc = xsp_surface_alloc;
|
||||
xsp_winsys->base.surface_alloc_storage = xsp_surface_alloc_storage;
|
||||
xsp_winsys->base.surface_release = xsp_surface_release;
|
||||
xsp_winsys->base.flush_frontbuffer = xsp_flush_frontbuffer;
|
||||
xsp_winsys->base.get_name = xsp_get_name;
|
||||
xsp_winsys->display = display;
|
||||
|
||||
{
|
||||
/* XXX: Can't use the returned XImage* directly,
|
||||
since we don't have control over winsys destruction
|
||||
and we wouldn't be able to free it */
|
||||
XImage *template = XCreateImage
|
||||
(
|
||||
display,
|
||||
XDefaultVisual(display, XDefaultScreen(display)),
|
||||
XDefaultDepth(display, XDefaultScreen(display)),
|
||||
ZPixmap,
|
||||
0,
|
||||
NULL,
|
||||
0, /* Don't know the width and height until flush_frontbuffer */
|
||||
0,
|
||||
32,
|
||||
0
|
||||
);
|
||||
|
||||
memcpy(&xsp_winsys->fbimage, template, sizeof(XImage));
|
||||
XInitImage(&xsp_winsys->fbimage);
|
||||
|
||||
XDestroyImage(template);
|
||||
}
|
||||
|
||||
sp_winsys = calloc(1, sizeof(struct softpipe_winsys));
|
||||
sp_winsys->is_format_supported = xsp_is_format_supported;
|
||||
|
||||
p_screen = softpipe_create_screen((struct pipe_winsys*)xsp_winsys);
|
||||
p_context = softpipe_create(p_screen, (struct pipe_winsys*)xsp_winsys, sp_winsys);
|
||||
|
||||
return p_context;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
#ifndef xsp_winsys_h
|
||||
#define xsp_winsys_h
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
struct pipe_context;
|
||||
|
||||
struct pipe_context* create_pipe_context(Display *display);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
TARGET = libXvMCg3dvl.so
|
||||
SONAME = libXvMCg3dvl.so.1
|
||||
GALLIUMDIR = ../gallium
|
||||
OBJECTS = block.o surface.o context.o subpicture.o attributes.o ${GALLIUMDIR}/winsys/g3dvl/xsp_winsys.o
|
||||
|
||||
CFLAGS += -g -fPIC -Wall -Werror \
|
||||
-I${GALLIUMDIR}/state_trackers/g3dvl \
|
||||
-I${GALLIUMDIR}/winsys/g3dvl \
|
||||
-I${GALLIUMDIR}/include \
|
||||
-I${GALLIUMDIR}/auxiliary \
|
||||
-I${GALLIUMDIR}/drivers
|
||||
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
|
||||
LIBS += -lg3dvl -lsoftpipe -ldraw -ltgsi -ltranslate -lrtasm -lcso_cache -lutil
|
||||
|
||||
#############################################
|
||||
|
||||
.PHONY = all clean
|
||||
|
||||
all: ${TARGET}
|
||||
|
||||
${TARGET}: ${OBJECTS}
|
||||
$(CC) ${LDFLAGS} -shared -Wl,-soname,${SONAME} -o $@ $^ ${LIBS}
|
||||
|
||||
clean:
|
||||
rm -rf ${OBJECTS} ${TARGET}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
#include <assert.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/Xvlib.h>
|
||||
#include <X11/extensions/XvMC.h>
|
||||
|
||||
XvAttribute* XvMCQueryAttributes(Display *display, XvMCContext *context, int *number)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Status XvMCSetAttribute(Display *display, XvMCContext *context, Atom attribute, int value)
|
||||
{
|
||||
return BadImplementation;
|
||||
}
|
||||
|
||||
Status XvMCGetAttribute(Display *display, XvMCContext *context, Atom attribute, int *value)
|
||||
{
|
||||
return BadImplementation;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/XvMC.h>
|
||||
#include <vl_context.h>
|
||||
|
||||
/*
|
||||
* XvMC defines 64 element blocks (8x8 elements).
|
||||
* Elements are 8 bits when they represent color values,
|
||||
* 9 bits when they reprecent DCT coefficients, we
|
||||
* store them in 2 bytes in either case. DCT coefficients
|
||||
* can be signed or unsigned, at our option.
|
||||
*/
|
||||
#define BLOCK_SIZE (64 * 2)
|
||||
|
||||
Status XvMCCreateBlocks(Display *display, XvMCContext *context, unsigned int num_blocks, XvMCBlockArray *blocks)
|
||||
{
|
||||
struct vl_context *vl_ctx;
|
||||
|
||||
assert(display);
|
||||
|
||||
if (!context)
|
||||
return XvMCBadContext;
|
||||
if (num_blocks == 0)
|
||||
return BadValue;
|
||||
|
||||
assert(blocks);
|
||||
|
||||
vl_ctx = context->privData;
|
||||
assert(display == vl_ctx->display);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
Status XvMCDestroyBlocks(Display *display, XvMCBlockArray *blocks)
|
||||
{
|
||||
assert(display);
|
||||
assert(blocks);
|
||||
assert(display == blocks->privData);
|
||||
free(blocks->blocks);
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
Status XvMCCreateMacroBlocks(Display *display, XvMCContext *context, unsigned int num_blocks, XvMCMacroBlockArray *blocks)
|
||||
{
|
||||
struct vl_context *vl_ctx;
|
||||
|
||||
assert(display);
|
||||
|
||||
if (!context)
|
||||
return XvMCBadContext;
|
||||
if (num_blocks == 0)
|
||||
return BadValue;
|
||||
|
||||
assert(blocks);
|
||||
|
||||
vl_ctx = context->privData;
|
||||
assert(display == vl_ctx->display);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
Status XvMCDestroyMacroBlocks(Display *display, XvMCMacroBlockArray *blocks)
|
||||
{
|
||||
assert(display);
|
||||
assert(blocks);
|
||||
assert(display == blocks->privData);
|
||||
free(blocks->macro_blocks);
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,154 @@
|
||||
#include <assert.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/XvMClib.h>
|
||||
#include <vl_context.h>
|
||||
#include <xsp_winsys.h>
|
||||
|
||||
static Status Validate(Display *display, XvPortID port, int surface_type_id, unsigned int width, unsigned int height, int flags, int *chroma_format)
|
||||
{
|
||||
unsigned int found_port = 0;
|
||||
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;
|
||||
|
||||
assert(display && chroma_format);
|
||||
|
||||
ret = XvQueryAdaptors(display, XDefaultRootWindow(display), &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;
|
||||
|
||||
found_port = 1;
|
||||
surface_info = XvMCListSurfaceTypes(display, adaptor_info[i].base_id, &num_types);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
XFree(surface_info);
|
||||
}
|
||||
else
|
||||
{
|
||||
XvFreeAdaptorInfo(adaptor_info);
|
||||
return BadAlloc;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 VL_FORMAT FormatToVL(int xvmc_format)
|
||||
{
|
||||
enum VL_FORMAT vl_format;
|
||||
|
||||
switch (xvmc_format)
|
||||
{
|
||||
case XVMC_CHROMA_FORMAT_420:
|
||||
{
|
||||
vl_format = VL_FORMAT_YCBCR_420;
|
||||
break;
|
||||
}
|
||||
case XVMC_CHROMA_FORMAT_422:
|
||||
{
|
||||
vl_format = VL_FORMAT_YCBCR_422;
|
||||
break;
|
||||
}
|
||||
case XVMC_CHROMA_FORMAT_444:
|
||||
{
|
||||
vl_format = VL_FORMAT_YCBCR_444;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
return vl_format;
|
||||
}
|
||||
|
||||
Status XvMCCreateContext(Display *display, XvPortID port, int surface_type_id, int width, int height, int flags, XvMCContext *context)
|
||||
{
|
||||
int chroma_format;
|
||||
Status ret;
|
||||
struct VL_CONTEXT *vl_ctx;
|
||||
struct pipe_context *pipe;
|
||||
|
||||
assert(display);
|
||||
|
||||
if (!context)
|
||||
return XvMCBadContext;
|
||||
|
||||
ret = Validate(display, port, surface_type_id, width, height, flags, &chroma_format);
|
||||
if (ret != Success)
|
||||
return ret;
|
||||
|
||||
pipe = create_pipe_context(display);
|
||||
|
||||
assert(pipe);
|
||||
|
||||
vlCreateContext(display, pipe, width, height, FormatToVL(chroma_format), &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;
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
Status XvMCDestroyContext(Display *display, XvMCContext *context)
|
||||
{
|
||||
struct VL_CONTEXT *vl_ctx;
|
||||
|
||||
assert(display);
|
||||
|
||||
if (!context)
|
||||
return XvMCBadContext;
|
||||
|
||||
vl_ctx = context->privData;
|
||||
|
||||
assert(display == vl_ctx->display);
|
||||
|
||||
vlDestroyContext(vl_ctx);
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
#include <assert.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/Xvlib.h>
|
||||
#include <X11/extensions/XvMC.h>
|
||||
|
||||
Status XvMCCreateSubpicture
|
||||
(
|
||||
Display *display,
|
||||
XvMCContext *context,
|
||||
XvMCSubpicture *subpicture,
|
||||
unsigned short width,
|
||||
unsigned short height,
|
||||
int xvimage_id
|
||||
)
|
||||
{
|
||||
return BadImplementation;
|
||||
}
|
||||
|
||||
Status XvMCClearSubpicture
|
||||
(
|
||||
Display *display,
|
||||
XvMCSubpicture *subpicture,
|
||||
short x,
|
||||
short y,
|
||||
unsigned short width,
|
||||
unsigned short height,
|
||||
unsigned int color
|
||||
)
|
||||
{
|
||||
return BadImplementation;
|
||||
}
|
||||
|
||||
Status XvMCCompositeSubpicture
|
||||
(
|
||||
Display *display,
|
||||
XvMCSubpicture *subpicture,
|
||||
XvImage *image,
|
||||
short srcx,
|
||||
short srcy,
|
||||
unsigned short width,
|
||||
unsigned short height,
|
||||
short dstx,
|
||||
short dsty
|
||||
)
|
||||
{
|
||||
return BadImplementation;
|
||||
}
|
||||
|
||||
Status XvMCDestroySubpicture(Display *display, XvMCSubpicture *subpicture)
|
||||
{
|
||||
return BadImplementation;
|
||||
}
|
||||
|
||||
Status XvMCSetSubpicturePalette(Display *display, XvMCSubpicture *subpicture, unsigned char *palette)
|
||||
{
|
||||
return BadImplementation;
|
||||
}
|
||||
|
||||
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
|
||||
)
|
||||
{
|
||||
return BadImplementation;
|
||||
}
|
||||
|
||||
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
|
||||
)
|
||||
{
|
||||
return BadImplementation;
|
||||
}
|
||||
|
||||
Status XvMCSyncSubpicture(Display *display, XvMCSubpicture *subpicture)
|
||||
{
|
||||
return BadImplementation;
|
||||
}
|
||||
|
||||
Status XvMCFlushSubpicture(Display *display, XvMCSubpicture *subpicture)
|
||||
{
|
||||
return BadImplementation;
|
||||
}
|
||||
|
||||
Status XvMCGetSubpictureStatus(Display *display, XvMCSubpicture *subpicture, int *status)
|
||||
{
|
||||
return BadImplementation;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,373 @@
|
||||
#include <assert.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/XvMC.h>
|
||||
#include <vl_context.h>
|
||||
#include <vl_surface.h>
|
||||
|
||||
static enum VL_PICTURE PictureToVL(int xvmc_pic)
|
||||
{
|
||||
enum VL_PICTURE vl_pic;
|
||||
|
||||
switch (xvmc_pic)
|
||||
{
|
||||
case XVMC_TOP_FIELD:
|
||||
{
|
||||
vl_pic = VL_TOP_FIELD;
|
||||
break;
|
||||
}
|
||||
case XVMC_BOTTOM_FIELD:
|
||||
{
|
||||
vl_pic = VL_BOTTOM_FIELD;
|
||||
break;
|
||||
}
|
||||
case XVMC_FRAME_PICTURE:
|
||||
{
|
||||
vl_pic = VL_FRAME_PICTURE;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
return vl_pic;
|
||||
}
|
||||
|
||||
Status XvMCCreateSurface(Display *display, XvMCContext *context, XvMCSurface *surface)
|
||||
{
|
||||
struct VL_CONTEXT *vl_ctx;
|
||||
struct VL_SURFACE *vl_sfc;
|
||||
|
||||
assert(display);
|
||||
|
||||
if (!context)
|
||||
return XvMCBadContext;
|
||||
if (!surface)
|
||||
return XvMCBadSurface;
|
||||
|
||||
vl_ctx = context->privData;
|
||||
|
||||
assert(display == vl_ctx->display);
|
||||
|
||||
vlCreateSurface(vl_ctx, &vl_sfc);
|
||||
|
||||
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;
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
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
|
||||
)
|
||||
{
|
||||
struct VL_CONTEXT *vl_ctx;
|
||||
struct VL_SURFACE *target_vl_surface;
|
||||
struct VL_SURFACE *past_vl_surface;
|
||||
struct VL_SURFACE *future_vl_surface;
|
||||
unsigned int i;
|
||||
|
||||
assert(display);
|
||||
|
||||
if (!context)
|
||||
return XvMCBadContext;
|
||||
if (!target_surface)
|
||||
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;
|
||||
|
||||
vl_ctx = context->privData;
|
||||
|
||||
assert(display == vl_ctx->display);
|
||||
|
||||
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(vl_ctx == target_vl_surface->context);
|
||||
assert(!past_vl_surface || vl_ctx == past_vl_surface->context);
|
||||
assert(!future_vl_surface || vl_ctx == future_vl_surface->context);
|
||||
|
||||
assert(macroblocks);
|
||||
assert(blocks);
|
||||
|
||||
assert(macroblocks->context_id == context->context_id);
|
||||
assert(blocks->context_id == context->context_id);
|
||||
|
||||
assert(flags == 0 || flags == XVMC_SECOND_FIELD);
|
||||
|
||||
for (i = first_macroblock; i < first_macroblock + num_macroblocks; ++i)
|
||||
if (macroblocks->macro_blocks[i].macroblock_type & XVMC_MB_TYPE_INTRA)
|
||||
vlRenderIMacroBlock
|
||||
(
|
||||
PictureToVL(picture_structure),
|
||||
flags == XVMC_SECOND_FIELD ? VL_FIELD_SECOND : VL_FIELD_FIRST,
|
||||
macroblocks->macro_blocks[i].x,
|
||||
macroblocks->macro_blocks[i].y,
|
||||
macroblocks->macro_blocks[i].coded_block_pattern,
|
||||
macroblocks->macro_blocks[i].dct_type == XVMC_DCT_TYPE_FIELD ? VL_DCT_FIELD_CODED : VL_DCT_FRAME_CODED,
|
||||
blocks->blocks + (macroblocks->macro_blocks[i].index * 64),
|
||||
target_vl_surface
|
||||
);
|
||||
else if
|
||||
(
|
||||
(macroblocks->macro_blocks[i].macroblock_type & (XVMC_MB_TYPE_MOTION_FORWARD | XVMC_MB_TYPE_MOTION_BACKWARD))
|
||||
== XVMC_MB_TYPE_MOTION_FORWARD
|
||||
)
|
||||
{
|
||||
struct VL_MOTION_VECTOR motion_vector =
|
||||
{
|
||||
{
|
||||
macroblocks->macro_blocks[i].PMV[0][0][0],
|
||||
macroblocks->macro_blocks[i].PMV[0][0][1],
|
||||
},
|
||||
{
|
||||
macroblocks->macro_blocks[i].PMV[1][0][0],
|
||||
macroblocks->macro_blocks[i].PMV[1][0][1],
|
||||
}
|
||||
};
|
||||
|
||||
vlRenderPMacroBlock
|
||||
(
|
||||
PictureToVL(picture_structure),
|
||||
flags == XVMC_SECOND_FIELD ? VL_FIELD_SECOND : VL_FIELD_FIRST,
|
||||
macroblocks->macro_blocks[i].x,
|
||||
macroblocks->macro_blocks[i].y,
|
||||
macroblocks->macro_blocks[i].motion_type == XVMC_PREDICTION_FRAME ? VL_FIELD_MC : VL_FRAME_MC,
|
||||
&motion_vector,
|
||||
macroblocks->macro_blocks[i].coded_block_pattern,
|
||||
macroblocks->macro_blocks[i].dct_type == XVMC_DCT_TYPE_FIELD ? VL_DCT_FIELD_CODED : VL_DCT_FRAME_CODED,
|
||||
blocks->blocks + (macroblocks->macro_blocks[i].index * 64),
|
||||
past_vl_surface,
|
||||
target_vl_surface
|
||||
);
|
||||
}
|
||||
else if
|
||||
(
|
||||
(macroblocks->macro_blocks[i].macroblock_type & (XVMC_MB_TYPE_MOTION_FORWARD | XVMC_MB_TYPE_MOTION_BACKWARD))
|
||||
== XVMC_MB_TYPE_MOTION_BACKWARD
|
||||
)
|
||||
{
|
||||
struct VL_MOTION_VECTOR motion_vector =
|
||||
{
|
||||
{
|
||||
macroblocks->macro_blocks[i].PMV[0][1][0],
|
||||
macroblocks->macro_blocks[i].PMV[0][1][1],
|
||||
},
|
||||
{
|
||||
macroblocks->macro_blocks[i].PMV[1][1][0],
|
||||
macroblocks->macro_blocks[i].PMV[1][1][1],
|
||||
}
|
||||
};
|
||||
|
||||
vlRenderPMacroBlock
|
||||
(
|
||||
PictureToVL(picture_structure),
|
||||
flags == XVMC_SECOND_FIELD ? VL_FIELD_SECOND : VL_FIELD_FIRST,
|
||||
macroblocks->macro_blocks[i].x,
|
||||
macroblocks->macro_blocks[i].y,
|
||||
macroblocks->macro_blocks[i].motion_type == XVMC_PREDICTION_FRAME ? VL_FIELD_MC : VL_FRAME_MC,
|
||||
&motion_vector,
|
||||
macroblocks->macro_blocks[i].coded_block_pattern,
|
||||
macroblocks->macro_blocks[i].dct_type == XVMC_DCT_TYPE_FIELD ? VL_DCT_FIELD_CODED : VL_DCT_FRAME_CODED,
|
||||
blocks->blocks + (macroblocks->macro_blocks[i].index * 64),
|
||||
future_vl_surface,
|
||||
target_vl_surface
|
||||
);
|
||||
}
|
||||
else if
|
||||
(
|
||||
(macroblocks->macro_blocks[i].macroblock_type & (XVMC_MB_TYPE_MOTION_FORWARD | XVMC_MB_TYPE_MOTION_BACKWARD))
|
||||
== (XVMC_MB_TYPE_MOTION_FORWARD | XVMC_MB_TYPE_MOTION_BACKWARD)
|
||||
)
|
||||
{
|
||||
struct VL_MOTION_VECTOR motion_vector[2] =
|
||||
{
|
||||
{
|
||||
{
|
||||
macroblocks->macro_blocks[i].PMV[0][0][0],
|
||||
macroblocks->macro_blocks[i].PMV[0][0][1],
|
||||
},
|
||||
{
|
||||
macroblocks->macro_blocks[i].PMV[1][0][0],
|
||||
macroblocks->macro_blocks[i].PMV[1][0][1],
|
||||
}
|
||||
},
|
||||
{
|
||||
{
|
||||
macroblocks->macro_blocks[i].PMV[0][1][0],
|
||||
macroblocks->macro_blocks[i].PMV[0][1][1],
|
||||
},
|
||||
{
|
||||
macroblocks->macro_blocks[i].PMV[1][1][0],
|
||||
macroblocks->macro_blocks[i].PMV[1][1][1],
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
vlRenderBMacroBlock
|
||||
(
|
||||
PictureToVL(picture_structure),
|
||||
flags == XVMC_SECOND_FIELD ? VL_FIELD_SECOND : VL_FIELD_FIRST,
|
||||
macroblocks->macro_blocks[i].x,
|
||||
macroblocks->macro_blocks[i].y,
|
||||
macroblocks->macro_blocks[i].motion_type == XVMC_PREDICTION_FRAME ? VL_FIELD_MC : VL_FRAME_MC,
|
||||
motion_vector,
|
||||
macroblocks->macro_blocks[i].coded_block_pattern,
|
||||
macroblocks->macro_blocks[i].dct_type == XVMC_DCT_TYPE_FIELD ? VL_DCT_FIELD_CODED : VL_DCT_FRAME_CODED,
|
||||
blocks->blocks + (macroblocks->macro_blocks[i].index * 64),
|
||||
past_vl_surface,
|
||||
future_vl_surface,
|
||||
target_vl_surface
|
||||
);
|
||||
}
|
||||
else
|
||||
fprintf(stderr, "Unrecognized macroblock\n");
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
Status XvMCFlushSurface(Display *display, XvMCSurface *surface)
|
||||
{
|
||||
/* TODO: Check display & surface match */
|
||||
return BadImplementation;
|
||||
}
|
||||
|
||||
Status XvMCSyncSurface(Display *display, XvMCSurface *surface)
|
||||
{
|
||||
/* TODO: Check display & surface match */
|
||||
return BadImplementation;
|
||||
}
|
||||
|
||||
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
|
||||
)
|
||||
{
|
||||
Window root;
|
||||
int x, y;
|
||||
unsigned int width, height;
|
||||
unsigned int border_width;
|
||||
unsigned int depth;
|
||||
struct VL_SURFACE *vl_sfc;
|
||||
|
||||
assert(display);
|
||||
|
||||
if (!surface)
|
||||
return XvMCBadSurface;
|
||||
|
||||
if (XGetGeometry(display, 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);
|
||||
|
||||
/* TODO: Correct for negative srcx,srcy & destx,desty by clipping */
|
||||
|
||||
assert(srcx + srcw - 1 < surface->width);
|
||||
assert(srcy + srch - 1 < surface->height);
|
||||
assert(destx + destw - 1 < width);
|
||||
assert(desty + desth - 1 < height);
|
||||
|
||||
vl_sfc = surface->privData;
|
||||
|
||||
vlPutSurface(vl_sfc, drawable, srcx, srcy, srcw, srch, destx, desty, destw, desth, PictureToVL(flags));
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
Status XvMCGetSurfaceStatus(Display *display, XvMCSurface *surface, int *status)
|
||||
{
|
||||
struct VL_CONTEXT *vl_ctx;
|
||||
struct VL_SURFACE *vl_sfc;
|
||||
|
||||
assert(display);
|
||||
|
||||
if (!surface)
|
||||
return XvMCBadSurface;
|
||||
|
||||
assert(status);
|
||||
|
||||
vl_sfc = surface->privData;
|
||||
vl_ctx = vl_sfc->context;
|
||||
|
||||
assert(display == vl_ctx->display);
|
||||
|
||||
/* TODO */
|
||||
*status = 0;
|
||||
|
||||
return BadImplementation;
|
||||
}
|
||||
|
||||
Status XvMCDestroySurface(Display *display, XvMCSurface *surface)
|
||||
{
|
||||
struct VL_CONTEXT *vl_ctx;
|
||||
struct VL_SURFACE *vl_sfc;
|
||||
|
||||
assert(display);
|
||||
|
||||
if (!surface)
|
||||
return XvMCBadSurface;
|
||||
|
||||
vl_sfc = surface->privData;
|
||||
vl_ctx = vl_sfc->context;
|
||||
|
||||
assert(display == vl_ctx->display);
|
||||
|
||||
vlDestroySurface(vl_sfc);
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
Status XvMCHideSurface(Display *display, XvMCSurface *surface)
|
||||
{
|
||||
struct VL_CONTEXT *vl_ctx;
|
||||
struct VL_SURFACE *vl_sfc;
|
||||
|
||||
assert(display);
|
||||
|
||||
if (!surface)
|
||||
return XvMCBadSurface;
|
||||
|
||||
vl_sfc = surface->privData;
|
||||
vl_ctx = vl_sfc->context;
|
||||
|
||||
assert(display == vl_ctx->display);
|
||||
|
||||
/* No op, only for overlaid rendering */
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
test_context
|
||||
test_surface
|
||||
test_blocks
|
||||
test_rendering
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
CFLAGS += -g -Wall -Werror
|
||||
LDFLAGS +=
|
||||
LIBS += -lXvMCW -lXvMC -lXv
|
||||
|
||||
#############################################
|
||||
|
||||
.PHONY = all clean
|
||||
|
||||
all: test_context test_surface test_blocks test_rendering
|
||||
|
||||
test_context: test_context.o testlib.o
|
||||
$(CC) ${LDFLAGS} -o $@ $^ ${LIBS}
|
||||
|
||||
test_surface: test_surface.o testlib.o
|
||||
$(CC) ${LDFLAGS} -o $@ $^ ${LIBS}
|
||||
|
||||
test_blocks: test_blocks.o testlib.o
|
||||
$(CC) ${LDFLAGS} -o $@ $^ ${LIBS}
|
||||
|
||||
test_rendering: test_rendering.o testlib.o
|
||||
$(CC) ${LDFLAGS} -o $@ $^ ${LIBS}
|
||||
|
||||
clean:
|
||||
rm -rf *.o test_context test_surface test_blocks test_rendering
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
#include <assert.h>
|
||||
#include <error.h>
|
||||
#include "testlib.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const unsigned int width = 16, height = 16;
|
||||
const unsigned int min_required_blocks = 1, min_required_macroblocks = 1;
|
||||
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;
|
||||
unsigned int is_overlay, intra_unsigned;
|
||||
int colorkey;
|
||||
XvMCContext context;
|
||||
XvMCSurface surface;
|
||||
XvMCBlockArray blocks = {0};
|
||||
XvMCMacroBlockArray macroblocks = {0};
|
||||
|
||||
display = XOpenDisplay(NULL);
|
||||
|
||||
if (!GetPort
|
||||
(
|
||||
display,
|
||||
width,
|
||||
height,
|
||||
XVMC_CHROMA_FORMAT_420,
|
||||
mc_types,
|
||||
2,
|
||||
&port_num,
|
||||
&surface_type_id,
|
||||
&is_overlay,
|
||||
&intra_unsigned
|
||||
))
|
||||
{
|
||||
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);
|
||||
assert(XvMCCreateSurface(display, &context, &surface) == Success);
|
||||
|
||||
/* Test NULL context */
|
||||
assert(XvMCCreateBlocks(display, NULL, 1, &blocks) == XvMCBadContext);
|
||||
/* Test 0 blocks */
|
||||
assert(XvMCCreateBlocks(display, &context, 0, &blocks) == BadValue);
|
||||
/* Test too many blocks */
|
||||
/*assert(XvMCCreateBlocks(display, &context, 16384, &blocks) == BadAlloc);*/
|
||||
|
||||
/* Note: No XvMCBadBlock(s) error in spec */
|
||||
|
||||
/* Test valid params */
|
||||
assert(XvMCCreateBlocks(display, &context, min_required_blocks, &blocks) == Success);
|
||||
/* Test context id assigned and correct */
|
||||
assert(blocks.context_id == context.context_id);
|
||||
/* Test number of blocks assigned and correct */
|
||||
assert(blocks.num_blocks == min_required_blocks);
|
||||
/* Test block pointer valid */
|
||||
assert(blocks.blocks != NULL);
|
||||
/* Test NULL context */
|
||||
assert(XvMCCreateMacroBlocks(display, NULL, 1, ¯oblocks) == XvMCBadContext);
|
||||
/* Test 0 macroblocks */
|
||||
assert(XvMCCreateMacroBlocks(display, &context, 0, ¯oblocks) == BadValue);
|
||||
/* Test too many macroblocks */
|
||||
/*assert(XvMCCreateMacroBlocks(display, &context, 16384, ¯oblocks) == BadAlloc);*/
|
||||
|
||||
/* Note: No XvMCBadMacroBlock(s) error in spec */
|
||||
|
||||
/* Test valid params */
|
||||
assert(XvMCCreateMacroBlocks(display, &context, min_required_macroblocks, ¯oblocks) == Success);
|
||||
/* Test context id assigned and correct */
|
||||
assert(macroblocks.context_id == context.context_id);
|
||||
/* Test macroblock pointer valid */
|
||||
assert(macroblocks.macro_blocks != NULL);
|
||||
/* Test valid params */
|
||||
assert(XvMCDestroyMacroBlocks(display, ¯oblocks) == Success);
|
||||
/* Test valid params */
|
||||
assert(XvMCDestroyBlocks(display, &blocks) == Success);
|
||||
|
||||
assert(XvMCDestroySurface(display, &surface) == Success);
|
||||
assert(XvMCDestroyContext(display, &context) == Success);
|
||||
|
||||
XvUngrabPort(display, port_num, CurrentTime);
|
||||
XCloseDisplay(display);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
#include <assert.h>
|
||||
#include <error.h>
|
||||
#include "testlib.h"
|
||||
|
||||
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;
|
||||
unsigned int is_overlay, intra_unsigned;
|
||||
int colorkey;
|
||||
XvMCContext context = {0};
|
||||
|
||||
display = XOpenDisplay(NULL);
|
||||
|
||||
if (!GetPort
|
||||
(
|
||||
display,
|
||||
width,
|
||||
height,
|
||||
XVMC_CHROMA_FORMAT_420,
|
||||
mc_types,
|
||||
2,
|
||||
&port_num,
|
||||
&surface_type_id,
|
||||
&is_overlay,
|
||||
&intra_unsigned
|
||||
))
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
/* Note: XvMCBadContext not a valid return for XvMCCreateContext in the XvMC API, but openChrome driver returns it */
|
||||
/* Note: Nvidia binary driver segfaults on NULL context, halts with debug output on bad port */
|
||||
|
||||
/* Test NULL context */
|
||||
assert(XvMCCreateContext(display, port_num, surface_type_id, width, height, XVMC_DIRECT, NULL) == XvMCBadContext);
|
||||
/* Test invalid port */
|
||||
assert(XvMCCreateContext(display, port_num + 1, surface_type_id, width, height, XVMC_DIRECT, &context) == XvBadPort);
|
||||
/* Test invalid surface */
|
||||
assert(XvMCCreateContext(display, port_num, surface_type_id + 1, width, height, XVMC_DIRECT, &context) == BadMatch);
|
||||
/* Test invalid flags */
|
||||
assert(XvMCCreateContext(display, port_num, surface_type_id, width, height, -1, &context) == BadValue);
|
||||
/* Test huge width */
|
||||
assert(XvMCCreateContext(display, port_num, surface_type_id, 16384, height, XVMC_DIRECT, &context) == BadValue);
|
||||
/* Test huge height */
|
||||
assert(XvMCCreateContext(display, port_num, surface_type_id, width, 16384, XVMC_DIRECT, &context) == BadValue);
|
||||
/* Test huge width & height */
|
||||
assert(XvMCCreateContext(display, port_num, surface_type_id, 16384, 16384, XVMC_DIRECT, &context) == BadValue);
|
||||
/* Test valid params */
|
||||
assert(XvMCCreateContext(display, port_num, surface_type_id, width, height, XVMC_DIRECT, &context) == Success);
|
||||
/* Test context id assigned */
|
||||
assert(context.context_id != 0);
|
||||
/* Test surface type id assigned and correct */
|
||||
assert(context.surface_type_id == surface_type_id);
|
||||
/* Test width & height assigned and correct */
|
||||
assert(context.width == width && context.height == height);
|
||||
/* Test port assigned and correct */
|
||||
assert(context.port == port_num);
|
||||
/* Test flags assigned and correct */
|
||||
assert(context.flags == XVMC_DIRECT);
|
||||
/* Test NULL context */
|
||||
assert(XvMCDestroyContext(display, NULL) == XvMCBadContext);
|
||||
/* Test valid params */
|
||||
assert(XvMCDestroyContext(display, &context) == Success);
|
||||
/* Test awkward but valid width */
|
||||
assert(XvMCCreateContext(display, port_num, surface_type_id, width + 1, height, XVMC_DIRECT, &context) == Success);
|
||||
assert(context.width >= width + 1);
|
||||
assert(XvMCDestroyContext(display, &context) == Success);
|
||||
/* Test awkward but valid height */
|
||||
assert(XvMCCreateContext(display, port_num, surface_type_id, width, height + 1, XVMC_DIRECT, &context) == Success);
|
||||
assert(context.height >= height + 1);
|
||||
assert(XvMCDestroyContext(display, &context) == Success);
|
||||
/* Test awkward but valid width & height */
|
||||
assert(XvMCCreateContext(display, port_num, surface_type_id, width + 1, height + 1, XVMC_DIRECT, &context) == Success);
|
||||
assert(context.width >= width + 1 && context.height >= height + 1);
|
||||
assert(XvMCDestroyContext(display, &context) == Success);
|
||||
|
||||
XvUngrabPort(display, port_num, CurrentTime);
|
||||
XCloseDisplay(display);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <error.h>
|
||||
#include "testlib.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const unsigned int width = 32, height = 32;
|
||||
const unsigned int mwidth = width / 16, mheight = height / 16;
|
||||
const unsigned int num_macroblocks = mwidth * mheight;
|
||||
const unsigned int num_blocks = num_macroblocks * 6;
|
||||
const unsigned int mc_types[2] = {XVMC_MOCOMP | XVMC_MPEG_2, XVMC_IDCT | XVMC_MPEG_2};
|
||||
|
||||
int quit = 0;
|
||||
Display *display;
|
||||
Window root, window;
|
||||
Pixmap framebuffer;
|
||||
XEvent event;
|
||||
XvPortID port_num;
|
||||
int surface_type_id;
|
||||
unsigned int is_overlay, intra_unsigned;
|
||||
int colorkey;
|
||||
XvMCContext context;
|
||||
XvMCSurface surface;
|
||||
XvMCBlockArray blocks;
|
||||
XvMCMacroBlockArray macroblocks;
|
||||
unsigned int b, x, y;
|
||||
|
||||
display = XOpenDisplay(NULL);
|
||||
|
||||
if (!GetPort
|
||||
(
|
||||
display,
|
||||
width,
|
||||
height,
|
||||
XVMC_CHROMA_FORMAT_420,
|
||||
mc_types,
|
||||
2,
|
||||
&port_num,
|
||||
&surface_type_id,
|
||||
&is_overlay,
|
||||
&intra_unsigned
|
||||
))
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
root = XDefaultRootWindow(display);
|
||||
window = XCreateSimpleWindow(display, root, 0, 0, width, height, 0, 0, colorkey);
|
||||
framebuffer = XCreatePixmap(display, root, width, height, 24);
|
||||
|
||||
XSelectInput(display, window, ExposureMask | KeyPressMask);
|
||||
XMapWindow(display, window);
|
||||
XSync(display, 0);
|
||||
|
||||
assert(XvMCCreateContext(display, port_num, surface_type_id, width, height, XVMC_DIRECT, &context) == Success);
|
||||
assert(XvMCCreateSurface(display, &context, &surface) == Success);
|
||||
assert(XvMCCreateBlocks(display, &context, num_blocks, &blocks) == Success);
|
||||
assert(XvMCCreateMacroBlocks(display, &context, num_macroblocks, ¯oblocks) == Success);
|
||||
|
||||
for (b = 0; b < 6; ++b)
|
||||
{
|
||||
for (y = 0; y < 8; ++y)
|
||||
{
|
||||
for (x = 0; x < 8; ++x)
|
||||
{
|
||||
blocks.blocks[b * 64 + y * 8 + x] = 0xFFFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (y = 0; y < mheight; ++y)
|
||||
{
|
||||
for (x = 0; x < mwidth; ++x)
|
||||
{
|
||||
macroblocks.macro_blocks[y * mwidth + x].x = x;
|
||||
macroblocks.macro_blocks[y * mwidth + x].y = y;
|
||||
macroblocks.macro_blocks[y * mwidth + x].index = (y * mwidth + x) * 6;
|
||||
macroblocks.macro_blocks[y * mwidth + x].macroblock_type = XVMC_MB_TYPE_INTRA;
|
||||
macroblocks.macro_blocks[y * mwidth + x].coded_block_pattern = 0x3F;
|
||||
macroblocks.macro_blocks[y * mwidth + x].dct_type = XVMC_DCT_TYPE_FRAME;
|
||||
}
|
||||
}
|
||||
|
||||
/* Test NULL context */
|
||||
assert(XvMCRenderSurface(display, NULL, XVMC_FRAME_PICTURE, &surface, NULL, NULL, 0, 1, 0, ¯oblocks, &blocks) == XvMCBadContext);
|
||||
/* Test NULL surface */
|
||||
assert(XvMCRenderSurface(display, &context, XVMC_FRAME_PICTURE, NULL, NULL, NULL, 0, 1, 0, ¯oblocks, &blocks) == XvMCBadSurface);
|
||||
/* Test bad picture structure */
|
||||
assert(XvMCRenderSurface(display, &context, 0, &surface, NULL, NULL, 0, 1, 0, ¯oblocks, &blocks) == BadValue);
|
||||
/* Test valid params */
|
||||
assert(XvMCRenderSurface(display, &context, XVMC_FRAME_PICTURE, &surface, NULL, NULL, 0, num_macroblocks, 0, ¯oblocks, &blocks) == Success);
|
||||
|
||||
/* Test NULL surface */
|
||||
assert(XvMCPutSurface(display, NULL, window, 0, 0, width, height, 0, 0, width, height, XVMC_FRAME_PICTURE) == XvMCBadSurface);
|
||||
/* Test bad window */
|
||||
/* X halts with a bad drawable for some reason, doesn't return BadDrawable as expected */
|
||||
/*assert(XvMCPutSurface(display, &surface, 0, 0, 0, width, height, 0, 0, width, height, XVMC_FRAME_PICTURE) == BadDrawable);*/
|
||||
/* Test valid params */
|
||||
assert(XvMCPutSurface(display, &surface, framebuffer, 0, 0, width, height, 0, 0, width, height, XVMC_FRAME_PICTURE) == Success);
|
||||
|
||||
puts("Press any key to continue...");
|
||||
|
||||
while (!quit)
|
||||
{
|
||||
XNextEvent(display, &event);
|
||||
switch (event.type)
|
||||
{
|
||||
case Expose:
|
||||
{
|
||||
XCopyArea
|
||||
(
|
||||
display,
|
||||
framebuffer,
|
||||
window,
|
||||
XDefaultGC(display, XDefaultScreen(display)),
|
||||
0,
|
||||
0,
|
||||
width,
|
||||
height,
|
||||
0,
|
||||
0
|
||||
);
|
||||
break;
|
||||
}
|
||||
case KeyPress:
|
||||
{
|
||||
quit = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert(XvMCDestroyBlocks(display, &blocks) == Success);
|
||||
assert(XvMCDestroyMacroBlocks(display, ¯oblocks) == Success);
|
||||
assert(XvMCDestroySurface(display, &surface) == Success);
|
||||
assert(XvMCDestroyContext(display, &context) == Success);
|
||||
|
||||
XFreePixmap(display, framebuffer);
|
||||
XvUngrabPort(display, port_num, CurrentTime);
|
||||
XDestroyWindow(display, window);
|
||||
XCloseDisplay(display);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
#include <assert.h>
|
||||
#include <error.h>
|
||||
#include "testlib.h"
|
||||
|
||||
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;
|
||||
unsigned int is_overlay, intra_unsigned;
|
||||
int colorkey;
|
||||
XvMCContext context;
|
||||
XvMCSurface surface = {0};
|
||||
|
||||
display = XOpenDisplay(NULL);
|
||||
|
||||
if (!GetPort
|
||||
(
|
||||
display,
|
||||
width,
|
||||
height,
|
||||
XVMC_CHROMA_FORMAT_420,
|
||||
mc_types,
|
||||
2,
|
||||
&port_num,
|
||||
&surface_type_id,
|
||||
&is_overlay,
|
||||
&intra_unsigned
|
||||
))
|
||||
{
|
||||
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 */
|
||||
assert(XvMCCreateSurface(display, &context, NULL) == XvMCBadSurface);
|
||||
/* Test valid params */
|
||||
assert(XvMCCreateSurface(display, &context, &surface) == Success);
|
||||
/* Test surface id assigned */
|
||||
assert(surface.surface_id != 0);
|
||||
/* Test context id assigned and correct */
|
||||
assert(surface.context_id == context.context_id);
|
||||
/* Test surface type id assigned and correct */
|
||||
assert(surface.surface_type_id == surface_type_id);
|
||||
/* Test width & height assigned and correct */
|
||||
assert(surface.width == width && surface.height == height);
|
||||
/* Test valid params */
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
#include "testlib.h"
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
void test(int pred, const char *pred_string, const char *doc_string, const char *file, unsigned int line)
|
||||
{
|
||||
fputs(doc_string, stderr);
|
||||
if (!pred)
|
||||
fprintf(stderr, " FAIL!\n\t\"%s\" at %s:%u\n", pred_string, file, line);
|
||||
else
|
||||
fputs(" PASS!\n", stderr);
|
||||
}
|
||||
*/
|
||||
|
||||
int GetPort
|
||||
(
|
||||
Display *display,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
unsigned int chroma_format,
|
||||
const unsigned int *mc_types,
|
||||
unsigned int num_mc_types,
|
||||
XvPortID *port_id,
|
||||
int *surface_type_id,
|
||||
unsigned int *is_overlay,
|
||||
unsigned int *intra_unsigned
|
||||
)
|
||||
{
|
||||
unsigned int found_port = 0;
|
||||
XvAdaptorInfo *adaptor_info;
|
||||
unsigned int num_adaptors;
|
||||
int num_types;
|
||||
int ev_base, err_base;
|
||||
unsigned int i, j, k, l;
|
||||
|
||||
if (!XvMCQueryExtension(display, &ev_base, &err_base))
|
||||
return 0;
|
||||
if (XvQueryAdaptors(display, XDefaultRootWindow(display), &num_adaptors, &adaptor_info) != Success)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < num_adaptors && !found_port; ++i)
|
||||
{
|
||||
if (adaptor_info[i].type & XvImageMask)
|
||||
{
|
||||
XvMCSurfaceInfo *surface_info = XvMCListSurfaceTypes(display, adaptor_info[i].base_id, &num_types);
|
||||
|
||||
if (surface_info)
|
||||
{
|
||||
for (j = 0; j < num_types && !found_port; ++j)
|
||||
{
|
||||
if
|
||||
(
|
||||
surface_info[j].chroma_format == chroma_format &&
|
||||
surface_info[j].max_width >= width &&
|
||||
surface_info[j].max_height >= height
|
||||
)
|
||||
{
|
||||
for (k = 0; k < num_mc_types && !found_port; ++k)
|
||||
{
|
||||
if (surface_info[j].mc_type == mc_types[k])
|
||||
{
|
||||
for (l = 0; l < adaptor_info[i].num_ports && !found_port; ++l)
|
||||
{
|
||||
if (XvGrabPort(display, adaptor_info[i].base_id + l, CurrentTime) == Success)
|
||||
{
|
||||
*port_id = adaptor_info[i].base_id + l;
|
||||
*surface_type_id = surface_info[j].surface_type_id;
|
||||
*is_overlay = surface_info[j].flags & XVMC_OVERLAID_SURFACE;
|
||||
*intra_unsigned = surface_info[j].flags & XVMC_INTRA_UNSIGNED;
|
||||
found_port = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
XFree(surface_info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
XvFreeAdaptorInfo(adaptor_info);
|
||||
|
||||
return found_port;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
#ifndef testlib_h
|
||||
#define testlib_h
|
||||
|
||||
/*
|
||||
#define TEST(pred, doc) test(pred, #pred, doc, __FILE__, __LINE__)
|
||||
|
||||
void test(int pred, const char *pred_string, const char *doc_string, const char *file, unsigned int line);
|
||||
*/
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/XvMClib.h>
|
||||
|
||||
/*
|
||||
* display: IN A valid X display
|
||||
* width, height: IN Surface size that the port must display
|
||||
* chroma_format: IN Chroma format that the port must display
|
||||
* mc_types, num_mc_types: IN List of MC types that the port must support, first port that matches the first mc_type will be returned
|
||||
* port_id: OUT Your port's ID
|
||||
* surface_type_id: OUT Your port's surface ID
|
||||
* is_overlay: OUT If 1, port uses overlay surfaces, you need to set a colorkey
|
||||
* intra_unsigned: OUT If 1, port uses unsigned values for intra-coded blocks
|
||||
*/
|
||||
int GetPort
|
||||
(
|
||||
Display *display,
|
||||
unsigned int width,
|
||||
unsigned int height,
|
||||
unsigned int chroma_format,
|
||||
const unsigned int *mc_types,
|
||||
unsigned int num_mc_types,
|
||||
XvPortID *port_id,
|
||||
int *surface_type_id,
|
||||
unsigned int *is_overlay,
|
||||
unsigned int *intra_unsigned
|
||||
);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user