[MPlayer-dev-eng] Video output for RV280+Mesa3D
malc
av1474 at comtv.ru
Sat Dec 6 14:32:06 CET 2008
On Sat, 6 Dec 2008, Diego Biurrun wrote:
> On Fri, Dec 05, 2008 at 01:44:51PM +0300, malc wrote:
>>
>> The patch implements the most performant(at least on this mac mini) way to
>> put YV12/I420/YUY2/UYVY data on screen. Constraints include:
>> a) PPC
>> b) Altivec presence
>> c) Mesa3D + GLX_MESA_allocate_memory
>> d) Horizontal resolution being multiple of 16
>>
>> The code also relies on SDL for operation.
>>
>> --- libvo/vo_rv280.c (revision 0)
>> +++ libvo/vo_rv280.c (revision 0)
>> @@ -0,0 +1,732 @@
>> +#define GL_GLEXT_PROTOTYPES
>> +#define GLX_GLXEXT_PROTOTYPES
>
> This is missing a license header
>
>> +void mplayer_put_key(int code);
>
> Please #include mp_fifo.h instead.
>
>> +/*
>> + * AltiVec-enhanced yuv2yuvX
>> + *
>> + * Copyright (C) 2004 Romain Dolbeau <romain at dolbeau.org>
>> + * based on the equivalent C code in "postproc/swscale.c"
>
> You mean libswscale/swscale.c?
No, i took it from postproc/swscale, it has been moved since then.
>> +/*
>> + * AltiVec-enhanced yuv2yuvX
>> + *
>> + * Copyright (C) 2004 Romain Dolbeau <romain at dolbeau.org>
>> + * based on the equivalent C code in "postproc/swscale.c"
>
> ditto
Ditto what?
> I think this code should be added to libswscale if it is really faster.
As i explained elsewhere it uses transient stores and as such is not really
a candidate for general purpose scaling mechanism.
>> +static void flip_page (void)
>
> Sometimes you put a space before the opening parenthesis, sometimes you
> don't. Leave it out.
Save for one instance i always add space before parenthesis, in all other
instance the code without spaces was just copy&pasted from swscale/vo_sdl
>> --- configure (revision 28089)
>> +++ configure (working copy)
>> @@ -4891,6 +4891,10 @@
>> _vomodules="sdl $_vomodules"
>> _aomodules="sdl $_aomodules"
>> _res_comment="using $_sdlconfig"
>> + if test "$_gl" = yes && linux && ppc ; then
>> + _def_rv280="#define HAVE_RV280 1"
>> + _rv280="yes"
>> + fi
>> else
>> _def_sdl='#undef CONFIG_SDL'
>> _novomodules="sdl $_novomodules"
>
> I think it should be possible to enable this separately.
Most definitely, i have no idea of the most idiomatic way to do that and
hence it was left out.
Index: Makefile
===================================================================
--- Makefile (revision 28107)
+++ Makefile (working copy)
@@ -544,6 +544,7 @@
SRCS_MPLAYER-$(GGI) += libvo/vo_ggi.c
SRCS_MPLAYER-$(GIF) += libvo/vo_gif89a.c
SRCS_MPLAYER-$(GL) += libvo/gl_common.c libvo/vo_gl.c libvo/vo_gl2.c
+SRCS_MPLAYER-$(RV280) += libvo/vo_rv280.c
SRCS_MPLAYER-$(GL_WIN32) += libvo/w32_common.c
SRCS_MPLAYER-$(GUI) += gui/bitmap.c
SRCS_MPLAYER-$(GUI_GTK) += gui/app.c \
Index: libvo/video_out.c
===================================================================
--- libvo/video_out.c (revision 28107)
+++ libvo/video_out.c (working copy)
@@ -114,6 +114,7 @@
extern vo_functions_t video_out_quartz;
extern vo_functions_t video_out_pnm;
extern vo_functions_t video_out_md5sum;
+extern vo_functions_t video_out_rv280;
const vo_functions_t* const video_out_drivers[] =
{
@@ -250,6 +251,9 @@
#ifdef CONFIG_MD5SUM
&video_out_md5sum,
#endif
+#ifdef HAVE_RV280
+ &video_out_rv280,
+#endif
NULL
};
Index: libvo/vo_rv280.c
===================================================================
--- libvo/vo_rv280.c (revision 0)
+++ libvo/vo_rv280.c (revision 0)
@@ -0,0 +1,743 @@
+/* This code unless otherwise noted is in public domain */
+#define GL_GLEXT_PROTOTYPES
+#define GLX_GLXEXT_PROTOTYPES
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "config.h"
+#include "aspect.h"
+#include "video_out.h"
+#include "video_out_internal.h"
+#include "sub.h"
+#include "subopt-helper.h"
+#include "mp_msg.h"
+#include "osdep/keycodes.h"
+#include "x11_common.h"
+
+#include <SDL.h>
+#include <SDL_syswm.h>
+
+#include <GL/gl.h>
+#include <GL/glx.h>
+#include <GL/glu.h>
+
+#include <altivec.h>
+
+#define fail(...) mp_msg(MSGT_VO, MSGL_FATAL, "[rv280]: " __VA_ARGS__)
+#define sdl_fail(fmt, ...) fail(fmt ": %s\n", SDL_GetError())
+
+void mplayer_put_ke(int code);
+
+extern int vd_use_slices;
+
+static vo_info_t info = {
+ "rv280",
+ "rv280",
+ "",
+ ""
+};
+
+LIBVO_EXTERN(rv280);
+
+typedef struct {
+ uint32_t format;
+ int w, h, dw, dh, vx, vy, vw, vh;
+ SDL_Surface *screen;
+ Uint32 sdl_flags;
+ Display *dpy;
+ Window win;
+ void *memory;
+ GLuint texid[2];
+ GLint coords[4][2];
+ int gl_initialized;
+ int cursor_visible;
+ int bytes_per_line;
+ void *memory_osd;
+ int bytes_per_line_osd;
+ uint32_t hint_chroma;
+ uint32_t hint_luma;
+ uint32_t hint_dst;
+} State;
+
+static State glob_state;
+
+static void rv280_clear_osd(State *s)
+{
+ size_t i;
+ vector float *dst = s->memory_osd;
+ vector float zero = {0};
+
+ for (i = 0; i < s->bytes_per_line_osd * s->h;) {
+ vec_st(zero, i, dst); i += 16;
+ vec_st(zero, i, dst); i += 16;
+ }
+}
+
+static void *rv280_gart_alloc(State *s)
+{
+ void *memory;
+
+ s->bytes_per_line =((s->w * 2 + 63) & ~63);
+ memory = glXAllocateMemoryMESA(s->dpy, DefaultScreen(s->dpy),
+ s->bytes_per_line * s->h,
+ 0.0, 0.0, 0.0);
+ if (!memory)
+ fail("glXAllocateMemoryMESA failed\n");
+
+ if (1) {
+ s->bytes_per_line_osd =((s->w * 4 + 63) & ~63);
+ s->memory_osd = glXAllocateMemoryMESA(s->dpy, DefaultScreen(s->dpy),
+ s->bytes_per_line_osd * s->h,
+ 0.0, 0.0, 0.0);
+ }
+ return memory;
+}
+
+static void rv280_gart_free(State *s)
+{
+ if (s->memory)
+ glXFreeMemoryMESA(s->dpy, DefaultScreen(s->dpy), s->memory);
+ s->memory = NULL;
+ if (s->memory_osd)
+ glXFreeMemoryMESA(s->dpy, DefaultScreen(s->dpy), s->memory_osd);
+ s->memory_osd = NULL;
+}
+
+static int rv280_sdl_set_mode(State *s, int w, int h, int dw, int dh)
+{
+ int retcode;
+ SDL_SysWMinfo info;
+
+ retcode = SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+ if (retcode) {
+ sdl_fail("SDL_GL_SetAttribute failed");
+ goto err0;
+ }
+
+ s->screen = SDL_SetVideoMode(dw, dh, 0, s->sdl_flags);
+ if (!s->screen) {
+ sdl_fail("SDL_SetVideoMode failed");
+ goto err0;
+ }
+
+ SDL_VERSION(&info.version);
+ retcode = SDL_GetWMInfo(&info);
+ if (!retcode) {
+ sdl_fail("SDL_GetWMInfo failed");
+ goto err0;
+ }
+
+ s->dpy = info.info.x11.display;
+ s->win = info.info.x11.wmwindow;
+
+ s->w = w;
+ s->h = h;
+ s->memory = rv280_gart_alloc(s);
+ if (!s->memory) goto err0;
+ s->cursor_visible = 0;
+ SDL_ShowCursor(0);
+ return 0;
+
+ err0:
+ return -1;
+}
+
+static void rv280_sdl_fini(State *s)
+{
+ rv280_gart_free(s);
+ s->screen = NULL;
+}
+
+static int rv280_gl_init(State *s)
+{
+ glGenTextures(s->memory_osd ? 2 : 1, s->texid);
+
+ memset(s->coords, 0, sizeof(s->coords));
+ s->coords[1][0] = s->w;
+ s->coords[2][0] = s->w;
+ s->coords[2][1] = s->h;
+ s->coords[3][1] = s->h;
+ s->gl_initialized = 1;
+ return 0;
+}
+
+static void rv280_gl_fini(State *s)
+{
+ if (s->gl_initialized) {
+ s->gl_initialized = 0;
+ glDeleteTextures(s->memory_osd ? 2 : 1, s->texid);
+ }
+}
+
+static void rv280_draw(State *s)
+{
+ int i;
+ const GLint quad[] = {-1, 1, 1, 1, 1, -1, -1, -1};
+
+ glBegin(GL_QUADS);
+ {
+ for (i = 0; i < 4; ++i) {
+ if (!s->memory_osd) {
+ glTexCoord2iv(&s->coords[i][0]);
+ }
+ else {
+ glMultiTexCoord2iv(GL_TEXTURE0_ARB, &s->coords[i][0]);
+ glMultiTexCoord2iv(GL_TEXTURE1_ARB, &s->coords[i][0]);
+ }
+ glVertex2iv(quad + i * 2);
+ }
+ }
+ glEnd();
+}
+
+
+static void rv280_resize_gl(State *s, int w, int h)
+{
+ glViewport(0, 0, w, h);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+
+ glMatrixMod(GL_MODELVIEW);
+ glLoadIdentity();
+
+ glClear(GL_COLOR_BUFFER_BIT);
+ vo_osd_changed(1);
+}
+
+static int rv280_sdl_resize(State *s, int x, int y)
+{
+ int retcode;
+ SDL_SysWMinfo info;
+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+
+ s->screen = SDL_SetVideoMode(x, y, 0, s->sdl_flags);
+ if (!s->screen) {
+ sdl_fail("SDL_SetVideoMode failed");
+ return -1;
+ }
+
+ rv280_resize_gl(s, x, y);
+
+ SDL_VERSION(&info.version);
+ retcode = SDL_GetWMInfo(&info);
+ if (!retcode) {
+ sdl_fail("SDL_GetWMInfo failed");
+ return -1;
+ }
+
+ s->dpy = info.info.x11.display;
+ s->win = info.info.x11.wmwindow;
+
+ s->dw = x;
+ s->dh = y;
+
+ s->vw = x;
+ s->vh = y;
+ s->vx = 0;
+ s->vy = 0;
+
+ if (vo_fs) {
+ aspect(&s->vw, &s->vh, A_ZOOM);
+ s->vx =(x - s->vw) / 2;
+ s->vy =(y - s->vh) / 2;
+ }
+
+ glViewport(s->vx, s->vy, s->vw, s->vh);
+
+ if (s->memory_osd) {
+ glActiveTexture(GL_TEXTURE1_ARB);
+ glEnable(GL_TEXTURE_RECTANGLE_ARB);
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, s->texid[1]);
+
+ glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE_ARB);
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_TEXTURE);
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_ALPHA);
+
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+ glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, s->bytes_per_line_osd >> 2);
+ }
+
+ glActiveTexture(GL_TEXTURE0_ARB);
+ glEnable(GL_TEXTURE_RECTANGLE_ARB);
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, s->texid[0]);
+
+ glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+ glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, s->bytes_per_line >> 1);
+ return 0;
+}
+
+static uint32_t rv280_compute_hint(int w)
+{
+ union {
+ struct {
+ int stride : 16;
+ int count : 8;
+ int size : 5;
+ int pad : 3;
+ } hint;
+ uint32_t val;
+ } u;
+
+ u.hint.stride = 16;
+ u.hint.count = 1;
+ u.hint.size = w >> 4;
+ u.hint.pad = 0;
+ return u.val;
+ /* return(u.hint.stride << 16) |(u.hint.count << 8) |(u.hint.size << 3); */
+}
+
+/*
+ * Following function is based on:
+ *
+ * AltiVec-enhanced yuv2yuvX
+ *
+ * Copyright (C) 2004 Romain Dolbeau <romain at dolbeau.org>
+ * based on the equivalent C code in libswscale/swscale.c
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+static void rv280_yv12toyuy2_unscaled_altivec(
+ State *s,
+ uint8_t* src[],
+ int srcStride[],
+ uint8_t* dst,
+ int dstStride
+ )
+{
+ uint8_t *ysrc = src[0];
+ uint8_t *usrc = src[1];
+ uint8_t *vsrc = src[2];
+ const int width = s->w;
+ const int height = s->h;
+ const int lumStride = srcStride[0];
+ const int chromStride = srcStride[1];
+ const vector unsigned char yperm = vec_lvs(0, ysrc);
+ register int y;
+
+ /* this code assume:
+
+ 1) dst is 16 bytes-aligned
+ 2) dstStride is a multiple of 16
+ 3) width is a multiple of 16
+ 4) lum&chrom stride are multiple of 8
+ */
+
+ for (y=0; y<height; y++) {
+ int i;
+
+ vec_dstt(ysrc, s->hint_luma, 0);
+ /* vec_dststt(dst, s->hint_dst, 3); */
+ if (!(y & 1)) {
+ vec_dstt(usrc, s->hint_chroma, 1);
+ vec_dstt(vsrc, s->hint_chroma, 2);
+ }
+
+ for (i = 0; i < width - 31; i+= 32) {
+ const unsigned int j = i >> 1;
+ vector unsigned char v_yA = vec_ld(i, ysrc);
+ vector unsigned char v_yB = vec_ld(i + 16, ysrc);
+ vector unsigned char v_yC = vec_ld(i + 32, ysrc);
+ vector unsigned char v_y1 = vec_perm(v_yA, v_yB, yperm);
+ vector unsigned char v_y2 = vec_perm(v_yB, v_yC, yperm);
+ vector unsigned char v_uA = vec_ld(j, usrc);
+ vector unsigned char v_uB = vec_ld(j + 16, usrc);
+ vector unsigned char v_u = vec_perm(v_uA, v_uB, vec_lvsl(j, usrc));
+ vector unsigned char v_vA = vec_ld(j, vsrc);
+ vector unsigned char v_vB = vec_ld(j + 16, vsrc);
+ vector unsigned char v_v = vec_perm(v_vA, v_vB, vec_lvsl(j, vsrc));
+ vector unsigned char v_uv_a = vec_mergeh(v_u, v_v);
+ vector unsigned char v_uv_b = vec_mergel(v_u, v_v);
+ vector unsigned char v_yuy2_0 = vec_mergeh(v_y1, v_uv_a);
+ vector unsigned char v_yuy2_1 = vec_mergel(v_y1, v_uv_a);
+ vector unsigned char v_yuy2_2 = vec_mergeh(v_y2, v_uv_b);
+ vector unsigned char v_yuy2_3 = vec_mergel(v_y2, v_uv_b);
+ vec_st(v_yuy2_0,(i << 1), dst);
+ vec_st(v_yuy2_1,(i << 1) + 16, dst);
+ vec_st(v_yuy2_2,(i << 1) + 32, dst);
+ vec_st(v_yuy2_3,(i << 1) + 48, dst);
+ }
+ if (i < width) {
+ const unsigned int j = i >> 1;
+ vector unsigned char v_y1 = vec_ld(i, ysrc);
+ vector unsigned char v_u = vec_ld(j, usrc);
+ vector unsigned char v_v = vec_ld(j, vsrc);
+ vector unsigned char v_uv_a = vec_mergeh(v_u, v_v);
+ vector unsigned char v_yuy2_0 = vec_mergeh(v_y1, v_uv_a);
+ vector unsigned char v_yuy2_1 = vec_mergel(v_y1, v_uv_a);
+ vec_st(v_yuy2_0,(i << 1), dst);
+ vec_st(v_yuy2_1,(i << 1) + 16, dst);
+ }
+ if (y & 1) {
+ usrc += chromStride;
+ vsrc += chromStride;
+ }
+ ysrc += lumStride;
+ dst += dstStride;
+ }
+}
+
+static int preinit(const char *arg)
+{
+ int retcode;
+ State *s = &glob_state;
+
+ if (!vo_init()) {
+ fail("vo_init failed\n");
+ return -1;
+ }
+
+ retcode = SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE);
+ if (retcode) {
+ sdl_fail("SDL_Init failed");
+ return -1;
+ }
+
+ s->sdl_flags = SDL_OPENGL | SDL_RESIZABLE;
+ vd_use_slices = 0;
+
+ return 0;
+}
+
+static int query_format(uint32_t format)
+{
+ int flags = 0;
+
+ if (format == IMGFMT_I420 || format == IMGFMT_YV12 || format == IMGFMT_IYUV
+ || format == IMGFMT_YUY2 || format == IMGFMT_YVYU || format == IMGFMT_UYVY) {
+ flags = VFCAP_CSP_SUPPORTED
+ | VFCAP_CSP_SUPPORTED_BY_HW
+ | VFCAP_HWSCALE_UP
+ | VFCAP_HWSCALE_DOWN
+ ;
+ }
+ return flags;
+}
+
+static int control(uint32_t request, void *data, ...)
+{
+ switch(request) {
+ case VOCTRL_QUERY_FORMAT:
+ return query_format(*(uint32_t *)data);
+
+ case VOCTRL_FULLSCREEN:
+ return VO_TRUE;
+
+ case VOCTRL_UPDATE_SCREENINFO:
+ update_xinerama_info();
+ return VO_TRUE;
+
+ default:
+ return VO_NOTIMPL;
+ }
+}
+
+static int draw_slice(uint8_t *src[], int stride[], int w, int h, int x, int y)
+{
+ State *s = &glob_state;
+ GLenum type = GL_UNSIGNED_SHORT_8_8_REV_MESA;
+
+ switch(s->format) {
+ case IMGFMT_YV12:
+ case IMGFMT_I420:
+ rv280_yv12toyuy2_unscaled_altivec(s, src, stride, s->memory, s->bytes_per_line);
+ break;
+
+ case IMGFMT_UYVY:
+ type = GL_UNSIGNED_SHORT_8_8_MESA;
+ case IMGFMT_YUY2:
+ {
+ char *sp = src[0];
+ char *dp = s->memory;
+ int count = s->w * 2;
+
+ for (y = 0; y < s->h; ++y) {
+ memcpy(dp, sp, count);
+ sp += stride[0];
+ dp += s->bytes_per_line;
+ }
+ }
+ break;
+
+ default:
+ fail("draw_slice unknown format %x %*s\n", s->format, 4,(char *) &s->format);
+ return -1;
+ }
+ glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_YCBCR_MESA,
+ s->w, s->h, 0, GL_YCBCR_MESA, type, s->memory);
+ return 0;
+}
+
+static int draw_frame(uint8_t *src[])
+{
+ State *s = &glob_state;
+
+ switch(s->format) {
+ case IMGFMT_UYVY:
+ case IMGFMT_YUY2:
+ {
+ int stride = s->w * 2;
+ return draw_slice(src, &stride, 0, 0, s->w, s->h);
+ }
+
+ default:
+ fail("draw_frame unknown format %x %*s\n", s->format, 4,(char *) &s->format);
+ return -1;
+ }
+}
+
+static void draw_alpha_yuy2(int x0, int y0, int w, int h,
+ unsigned char *src, unsigned char *srca,
+ int stride)
+{
+ State *s = &glob_state;
+ x0 += s->w *(vo_panscan_x >> 1) /(s->dw + vo_panscan_x);
+ vo_draw_alpha_yuy2(w, h, src, srca, stride,
+ (char *) s->memory + s->bytes_per_line * y0 + 2 * x0,
+ s->bytes_per_line);
+}
+
+static void rv280_load_osd(State *s)
+{
+ glActiveTexture(GL_TEXTURE1_ARB);
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, s->texid[1]);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, s->bytes_per_line_osd >> 2);
+ glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA,
+ s->w, s->h, 0, GL_BGRA,
+ GL_UNSIGNED_INT_8_8_8_8_REV, s->memory_osd);
+ glActiveTexture(GL_TEXTURE0_ARB);
+ glBindTexture(GL_TEXTURE_RECTANGLE_ARB, s->texid[0]);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, s->bytes_per_line >> 1);
+}
+
+static void draw_alpha_rgba(int x0, int y0, int w, int h,
+ unsigned char *src, unsigned char *srca,
+ int stride)
+{
+ State *s = &glob_state;
+ char *p;
+ int y, x;
+
+ p = s->memory_osd;
+ p += s->bytes_per_line_osd * y0 + 4 * x0;
+
+ for (y = 0; y < h; ++y) {
+ for (x = 0; x < w; ++x) {
+ p[x*4 + 0] = src[x];
+ p[x*4 + 1] = src[x];
+ p[x*4 + 2] = src[x];
+ p[x*4 + 3] = -srca[x];
+ }
+ p += s->bytes_per_line_osd;
+ src += stride;
+ srca += stride;
+ }
+}
+
+static void draw_osd(void)
+{
+ State *s = &glob_state;
+
+ if (!s->memory_osd) {
+ vo_draw_text(s->w, s->h, draw_alpha_yuy2);
+ }
+ else {
+ if (vo_osd_changed(0)) {
+ rv280_clear_osd(s);
+ vo_draw_text(s->w, s->h, draw_alpha_rgba);
+ rv280_load_osd(s);
+ }
+ }
+}
+
+static void flip_page(void)
+{
+ State *s = &glob_state;
+ rv280_draw(s);
+ SDL_GL_SwapBuffers();
+}
+
+#define shift_key(event->key.keysym.mod==(KMOD_LSHIFT||KMOD_RSHIFT))
+static void rv280_process_keydown(State *s, SDL_Event *event)
+{
+ int key = event->key.keysym.sym;
+
+ switch(key) {
+ case SDLK_RETURN: mplayer_put_key(KEY_ENTER);break;
+ case SDLK_ESCAPE: mplayer_put_key(KEY_ESC);break;
+ case SDLK_q: mplayer_put_key('q');break;
+
+ case SDLK_F1: mplayer_put_key(KEY_F+1);break;
+ case SDLK_F2: mplayer_put_key(KEY_F+2);break;
+ case SDLK_F3: mplayer_put_key(KEY_F+3);break;
+ case SDLK_F4: mplayer_put_key(KEY_F+4);break;
+ case SDLK_F5: mplayer_put_key(KEY_F+5);break;
+ case SDLK_F6: mplayer_put_key(KEY_F+6);break;
+ case SDLK_F7: mplayer_put_key(KEY_F+7);break;
+ case SDLK_F8: mplayer_put_key(KEY_F+8);break;
+ case SDLK_F9: mplayer_put_key(KEY_F+9);break;
+ case SDLK_F10: mplayer_put_key(KEY_F+10);break;
+ case SDLK_F11: mplayer_put_key(KEY_F+11);break;
+ case SDLK_F12: mplayer_put_key(KEY_F+12);break;
+
+ case SDLK_h: mplayer_put_key('h');break;
+ case SDLK_k: mplayer_put_key('k');break;
+ case SDLK_j: mplayer_put_key('j');break;
+ case SDLK_v: mplayer_put_key('v');break;
+ case SDLK_o: mplayer_put_key('o');break;
+ case SDLK_l: mplayer_put_key('l');break;
+ case SDLK_f:
+ vo_fs ^= 1;
+ vo_fs_type = vo_wm_FULLSCREEN;
+ vo_window = s->win;
+ mDisplay = s->dpy;
+ vo_x11_ewmh_fullscreen(_NET_WM_STATE_TOGGLE);
+ break;
+ case SDLK_SPACE: mplayer_put_key(' ');break;
+ case SDLK_p: mplayer_put_key('p');break;
+ case SDLK_7: mplayer_put_key(shift_key?'/':'7'); break;
+ case SDLK_PLUS: mplayer_put_key(shift_key?'*':'+'); break;
+ case SDLK_KP_PLUS: mplayer_put_key('+');break;
+ case SDLK_MINUS:
+ case SDLK_KP_MINUS: mplayer_put_key('-');break;
+ case SDLK_TAB: mplayer_put_key('\t');break;
+ case SDLK_PAGEUP: mplayer_put_key(KEY_PAGE_UP);break;
+ case SDLK_PAGEDOWN: mplayer_put_key(KEY_PAGE_DOWN);break;
+ case SDLK_UP: mplayer_put_key(KEY_UP);break;
+ case SDLK_DOWN: mplayer_put_key(KEY_DOWN);break;
+ case SDLK_LEFT: mplayer_put_key(KEY_LEFT);break;
+ case SDLK_RIGHT: mplayer_put_key(KEY_RIGHT);break;
+ case SDLK_LESS: mplayer_put_key(shift_key?'>':'<'); break;
+ case SDLK_GREATER: mplayer_put_key('>'); break;
+ case SDLK_ASTERISK:
+ case SDLK_KP_MULTIPLY: mplayer_put_key('*'); break;
+ case SDLK_SLASH:
+ case SDLK_KP_DIVIDE: mplayer_put_key('/'); break;
+ case SDLK_KP0: mplayer_put_key(KEY_KP0); break;
+ case SDLK_KP1: mplayer_put_key(KEY_KP1); break;
+ case SDLK_KP2: mplayer_put_key(KEY_KP2); break;
+ case SDLK_KP3: mplayer_put_key(KEY_KP3); break;
+ case SDLK_KP4: mplayer_put_key(KEY_KP4); break;
+ case SDLK_KP5: mplayer_put_key(KEY_KP5); break;
+ case SDLK_KP6: mplayer_put_key(KEY_KP6); break;
+ case SDLK_KP7: mplayer_put_key(KEY_KP7); break;
+ case SDLK_KP8: mplayer_put_key(KEY_KP8); break;
+ case SDLK_KP9: mplayer_put_key(KEY_KP9); break;
+ case SDLK_KP_PERIOD: mplayer_put_key(KEY_KPDEC); break;
+ case SDLK_KP_ENTER: mplayer_put_key(KEY_KPENTER); break;
+ case SDLK_c: SDL_ShowCursor(s->cursor_visible = !s->cursor_visible); break;
+
+ default: break;
+ }
+}
+
+static void check_events(void)
+{
+ State *s = &glob_state;
+
+ for (;;) {
+ int retcode;
+ SDL_Event ev;
+
+ retcode = SDL_PollEvent(&ev);
+ if (!retcode) return;
+
+ switch(ev.type) {
+ case SDL_QUIT:
+ mplayer_put_key('q');
+ break;
+
+ case SDL_VIDEORESIZE:
+ rv280_sdl_resize(s, ev.resize.w, ev.resize.h);
+ break;
+
+ case SDL_KEYDOWN:
+ rv280_process_keydown(s, &ev);
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+static int config(uint32_t width, uint32_t height, uint32_t d_width,
+ uint32_t d_height, uint32_t flags, char *title,
+ uint32_t format)
+{
+ State *s = &glob_state;
+
+ rv280_gl_fini(s);
+ rv280_sdl_fini(s);
+
+ if (width & 15) {
+ fail("can't handle width that is not multiple of sixteen\n");
+ return -1;
+ }
+
+ if (rv280_sdl_set_mode(s, width, height, d_width, d_height))
+ return -1;
+
+ if (rv280_gl_init(s)) {
+ rv280_sdl_fini(s);
+ return -1;
+ }
+
+ rv280_sdl_resize(s, d_width, d_height);
+
+ s->w = width;
+ s->h = height;
+ s->dw = d_width;
+ s->dh = d_height;
+ s->vw = d_width;
+ s->vh = d_height;
+ s->format = format;
+
+ s->hint_luma = rv280_compute_hint(s->w);
+ s->hint_chroma = rv280_compute_hint(s->w >> 1);
+ s->hint_dst = rv280_compute_hint(s->w << 1);
+
+ aspect_save_orig(width, height);
+ aspect_save_prescale(d_width, d_height);
+ SDL_WM_SetCaption(title, NULL);
+ return 0;
+}
+
+static void uninit(void)
+{
+ State *s = &glob_state;
+ rv280_gl_fini(s);
+ rv280_sdl_fini(s);
+}
Index: configure
===================================================================
--- configure (revision 28107)
+++ configure (working copy)
@@ -4891,6 +4891,10 @@
_vomodules="sdl $_vomodules"
_aomodules="sdl $_aomodules"
_res_comment="using $_sdlconfig"
+ if test "$_gl" = yes && linux && ppc ; then
+ _def_rv280="#define HAVE_RV280 1"
+ _rv280="yes"
+ fi
else
_def_sdl='#undef CONFIG_SDL'
_novomodules="sdl $_novomodules"
@@ -8072,6 +8076,7 @@
XVMC = $_xvmc
YUV4MPEG = $_yuv4mpeg
ZR = $_zr
+RV280 = $_rv280
# FFmpeg
LIBAVUTIL = $_libavutil
@@ -8501,6 +8506,7 @@
$_def_xvr100
$_def_yuv4mpeg
$_def_zr
+$_def_rv280
/* FFmpeg */
--
mailto:av1474 at comtv.ru
More information about the MPlayer-dev-eng
mailing list