[MPlayer-dev-eng] Video output for RV280+Mesa3D

malc av1474 at comtv.ru
Fri Dec 5 11:44:51 CET 2008


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.

Index: Makefile
===================================================================
--- Makefile	(revision 28089)
+++ 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 28089)
+++ 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,732 @@
+#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_key(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 ();
+
+    glMatrixMode(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;
+}
+
+/*
+ * AltiVec-enhanced yuv2yuvX
+ *
+ * Copyright (C) 2004 Romain Dolbeau <romain at dolbeau.org>
+ * based on the equivalent C code in "postproc/swscale.c"
+ * ...
+ */
+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); */
+}
+
+/*
+ * AltiVec-enhanced yuv2yuvX
+ *
+ * Copyright (C) 2004 Romain Dolbeau <romain at dolbeau.org>
+ * based on the equivalent C code in "postproc/swscale.c"
+ * ...
+ */
+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_lvsl(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 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"
@@ -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