Update of /cvsroot/freevo/kaa/xine/src/drivers
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16410/src/drivers

Modified Files:
        buffer.c 
Added Files:
        yuv2rgb.c yuv2rgb.h yuv2rgb_mmx.c 
Log Message:
Add yuv2rgb code from xine with slight modifications to play better with
evas; add x86(_64) detection to setup.py; lots and lots of updates to
buffer vo -- it's almost done now, sans the vf_osd port.


--- NEW FILE: yuv2rgb_mmx.c ---
/*
 * yuv2rgb_mmx.c
 * Copyright (C) 2000-2001 Silicon Integrated System Corp.
 * All Rights Reserved.
 *
 * Author: Olie Lho <[EMAIL PROTECTED]>
 *
 * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
 *
 * mpeg2dec 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.
 *
 * mpeg2dec 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.
 *
[...1094 lines suppressed...]
  case MODE_15_RGB:
    this->yuv2rgb_fun = mmx_rgb15;
    break;
  case MODE_16_RGB:
    this->yuv2rgb_fun = mmx_rgb16;
    break;
  case MODE_24_RGB:
    this->yuv2rgb_fun = mmx_rgb24;
    break;
  case MODE_32_RGB:
    this->yuv2rgb_fun = mmx_argb32;
    break;
  case MODE_32_BGR:
    this->yuv2rgb_fun = mmx_abgr32;
    break;
  }
}


#endif

--- NEW FILE: yuv2rgb.h ---

#ifndef HAVE_YUV2RGB_H
#define HAVE_YUV2RGB_h

#include "../config.h"

#ifdef HAVE_MLIB
#include <mlib_video.h>
#endif

#include <inttypes.h>

typedef struct yuv2rgb_s yuv2rgb_t;

typedef struct yuv2rgb_factory_s yuv2rgb_factory_t;

/*
 * function types for functions which can be replaced
 * by hardware-accelerated versions
 */

/* internal function use to scale yuv data */
typedef void (*scale_line_func_t) (uint8_t *source, uint8_t *dest, int width, 
int step);

typedef void (*yuv2rgb_fun_t) (yuv2rgb_t *this, uint8_t * image, uint8_t * py, 
uint8_t * pu, uint8_t * pv) ;

typedef void (*yuy22rgb_fun_t) (yuv2rgb_t *this, uint8_t * image, uint8_t * p);

typedef uint32_t (*yuv2rgb_single_pixel_fun_t) (yuv2rgb_t *this, uint8_t y, 
uint8_t u, uint8_t v);

/*
 * modes supported - feel free to implement yours
 */

#define MODE_8_RGB    1
#define MODE_8_BGR    2
#define MODE_15_RGB   3
#define MODE_15_BGR   4
#define MODE_16_RGB   5
#define MODE_16_BGR   6
#define MODE_24_RGB   7
#define MODE_24_BGR   8
#define MODE_32_RGB   9
#define MODE_32_BGR  10
#define MODE_8_GRAY  11
#define MODE_PALETTE 12

struct yuv2rgb_s {
  /*
   * configure converter for scaling factors
   */
  int (*configure) (yuv2rgb_t *this,
                    int source_width, int source_height,
                    int y_stride, int uv_stride,
                    int dest_width, int dest_height,
                    int rgb_stride);

  /*
   * start a new field or frame if dest is NULL
   */
  int (*next_slice) (yuv2rgb_t *this, uint8_t **dest);

  /*
   * free resources
   */
  void (*dispose) (yuv2rgb_t *this);

  /*
   * this is the function to call for the yuv2rgb and scaling process
   */
  yuv2rgb_fun_t     yuv2rgb_fun;

  /*
   * this is the function to call for the yuy2->rgb and scaling process
   */
  yuy22rgb_fun_t    yuy22rgb_fun;

  /*
   * this is the function to call for the yuv2rgb for a single pixel
   * (used for converting clut colors)
   */

  yuv2rgb_single_pixel_fun_t yuv2rgb_single_pixel_fun;

  /* private stuff below */

  int               source_width, source_height;
  int               y_stride, uv_stride;
  int               dest_width, dest_height;
  int               rgb_stride;
  int               slice_height, slice_offset;
  int               step_dx, step_dy;
  int               do_scale, swapped;

  uint8_t          *y_buffer;
  uint8_t          *u_buffer;
  uint8_t          *v_buffer;
  void             *y_chunk;
  void             *u_chunk;
  void             *v_chunk;

#ifdef HAVE_MLIB
  uint8_t          *mlib_buffer;
  uint8_t          *mlib_resize_buffer;
  void             *mlib_chunk;
  void             *mlib_resize_chunk;
  mlib_filter      mlib_filter_type;
#endif

  void            **table_rV;
  void            **table_gU;
  int              *table_gV;
  void            **table_bU;
  void             *table_mmx;

  uint8_t          *cmap;
  scale_line_func_t scale_line;  
} ;

/*
 * convenience class to easily create a lot of converters
 */

struct yuv2rgb_factory_s {
  yuv2rgb_t* (*create_converter) (yuv2rgb_factory_t *this);

  /* 
   * set color space conversion levels
   * for all converters produced by this factory
   */
  void (*set_csc_levels) (yuv2rgb_factory_t *this,
                          int brightness, int contrast, int saturation);

  /*
   * free resources
   */
  void (*dispose) (yuv2rgb_factory_t *this);

  /* private data */

  int      mode;
  int      swapped;
  uint8_t *cmap;

  uint32_t matrix_coefficients;

  void    *table_base;
  void    *table_rV[256];
  void    *table_gU[256];
  int      table_gV[256];
  void    *table_bU[256];
  void    *table_mmx_base;
  void    *table_mmx;

  /* preselected functions for mode/swap/hardware */
  yuv2rgb_fun_t               yuv2rgb_fun;
  yuy22rgb_fun_t              yuy22rgb_fun;
  yuv2rgb_single_pixel_fun_t  yuv2rgb_single_pixel_fun;
};

yuv2rgb_factory_t *yuv2rgb_factory_init (int mode, int swapped, uint8_t 
*colormap);

                   
/*
 * internal stuff below this line
 */

void mmx_yuv2rgb_set_csc_levels(yuv2rgb_factory_t *this,
                                int brightness, int contrast, int saturation);
void yuv2rgb_init_mmxext (yuv2rgb_factory_t *this);
void yuv2rgb_init_mmx (yuv2rgb_factory_t *this);
void yuv2rgb_init_mlib (yuv2rgb_factory_t *this);

#endif

--- NEW FILE: yuv2rgb.c ---
/*
 * yuv2rgb.c
 *
 * Copyright (C) 2003-2004 the xine project
 * This file is part of xine, a free video player.
 *
 * based on work from mpeg2dec:
 * Copyright (C) 1999-2001 Aaron Holtzman <[EMAIL PROTECTED]>
 *
 * This file is part of mpeg2dec, a free MPEG-2 video stream decoder.
 *
 * mpeg2dec 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.
 *
 * mpeg2dec 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
[...3232 lines suppressed...]
    lprintf ("no accelerated colorspace conversion found\n");

    yuv2rgb_c_init (this);
  }

  /*
   * auto-probe for the best yuy22rgb function
   */

  /* FIXME: implement mmx/mlib functions */
  yuy22rgb_c_init (this);

  /*
   * set up single pixel function
   */

  yuv2rgb_single_pixel_init (this);

  return this;
}

Index: buffer.c
===================================================================
RCS file: /cvsroot/freevo/kaa/xine/src/drivers/buffer.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** buffer.c    30 Jul 2005 20:55:15 -0000      1.3
--- buffer.c    1 Aug 2005 04:07:12 -0000       1.4
***************
*** 3,10 ****
  #include "../xine.h"
  #include "../vo_driver.h"
  
! static void _overlay_blend(vo_driver_t *, vo_frame_t *, vo_overlay_t *);
  
  
  typedef struct buffer_frame_s {
      vo_frame_t vo_frame;
--- 3,20 ----
  #include "../xine.h"
  #include "../vo_driver.h"
+ #include "yuv2rgb.h"
  
! //#define STOPWATCH
! 
! #define BUFFER_VO_COMMAND_QUERY_REQUEST 0
! #define BUFFER_VO_COMMAND_QUERY_REDRAW  1
! #define BUFFER_VO_COMMAND_SEND          2
! 
! #define BUFFER_VO_REQUEST_SEND          0x01
! #define BUFFER_VO_REQUEST_PASSTHROUGH   0x02
  
  
+ static void _overlay_blend(vo_driver_t *, vo_frame_t *, vo_overlay_t *);
+ 
  typedef struct buffer_frame_s {
      vo_frame_t vo_frame;
***************
*** 14,18 ****
--- 24,31 ----
  
      unsigned char *yv12_buffer, *yuy2_buffer;
+     unsigned char *bgra_buffer;
+     pthread_mutex_t bgra_lock;
      vo_frame_t *passthrough_frame;
+     yuv2rgb_t *yuv2rgb;
      // more
  } buffer_frame_t;
***************
*** 24,27 ****
--- 37,41 ----
      xine_t *xine;
  
+     yuv2rgb_factory_t *yuv2rgb_factory;
      int aspect;
  
***************
*** 38,41 ****
--- 52,197 ----
  
  
+ #ifdef STOPWATCH
+ static void stopwatch(int n, char *text, ...)
+ {
+     va_list ap;
+     struct timezone tz;
+     static struct {
+         struct timeval tv, last_tv;
+         char text[250];
+     } t[10];
+ 
+     gettimeofday(&t[n].tv, &tz);
+     if (!text) {
+         fprintf(stderr, "@@@ Stopwatch (%d): %s: %ld usec\n", n, t[n].text,
+                (t[n].tv.tv_sec - t[n].last_tv.tv_sec) * 1000000 +
+                (t[n].tv.tv_usec - t[n].last_tv.tv_usec));
+     } else {
+         t[n].last_tv.tv_sec = t[n].tv.tv_sec;
+         t[n].last_tv.tv_usec = t[n].tv.tv_usec;
+ 
+         va_start(ap, text);
+         vsprintf(t[n].text, text, ap);
+         va_end(ap);
+     }
+ }
+ #else
+ #define stopwatch(n, text, ...)
+ #endif
+ 
+ 
+ ////////////
+ 
+ 
+ PyObject *
+ _unlock_frame_cb(PyObject *self, PyObject *args, PyObject *kwargs)
+ {
+     buffer_frame_t *frame = (buffer_frame_t *)PyCObject_AsVoidPtr(self);
+     pthread_mutex_unlock(&frame->bgra_lock);
+     Py_INCREF(Py_None);
+     return Py_None;
+ }
+ 
+ PyMethodDef unlock_frame_def = {
+     "unlock_frame_cb", (PyCFunction)_unlock_frame_cb, 
+     METH_VARARGS, NULL 
+ };
+ 
+ 
+ static int
+ buffer_callback_command_query_redraw(buffer_driver_t *this)
+ {
+     PyObject *args, *result;
+     PyGILState_STATE gstate;
+     int retval = 0;
+ 
+     gstate = PyGILState_Ensure();
+     args = Py_BuildValue("(i())", BUFFER_VO_COMMAND_QUERY_REDRAW);
+     result = PyEval_CallObject(this->callback, args);
+     if (result) {
+         if (PyInt_Check(result))
+             retval = PyLong_AsLong(result);
+         Py_DECREF(result);
+     }
+     if (PyErr_Occurred()) {
+         printf("Exception in buffer callback:\n");
+         PyErr_Print();
+     }
+     Py_DECREF(args);
+     PyGILState_Release(gstate);
+     return retval;
+ }
+ 
+ static int
+ buffer_callback_command_query_request(buffer_driver_t *this, 
+     int *request_return, int *width_return, int *height_return)
+ {
+     PyObject *args, *result;
+     PyGILState_STATE gstate;
+     int retval = 1;
+ 
+     gstate = PyGILState_Ensure();
+     args = Py_BuildValue("(i())", BUFFER_VO_COMMAND_QUERY_REQUEST);
+     result = PyEval_CallObject(this->callback, args);
+     if (result) {
+         PyArg_ParseTuple(result, "iii", request_return, width_return, 
height_return);
+         Py_DECREF(result);
+     }
+     if (PyErr_Occurred()) {
+         printf("Exception in buffer callback:\n");
+         PyErr_Print();
+         retval = 0;
+     }
+     Py_DECREF(args);
+     PyGILState_Release(gstate);
+ 
+     return retval;
+ }
+ 
+ static int
+ buffer_callback_send(buffer_driver_t *this, buffer_frame_t *frame, int w, int 
h)
+ {
+     PyObject *args, *result, *unlock_frame_cb, *frame_pyobject;
+     PyGILState_STATE gstate;
+     int retval = 1;
+ 
+     gstate = PyGILState_Ensure();
+     frame_pyobject = PyCObject_FromVoidPtr((void *)frame, NULL);
+     unlock_frame_cb = PyCFunction_New(&unlock_frame_def, frame_pyobject);
+     args = Py_BuildValue("(i(iidiO))", BUFFER_VO_COMMAND_SEND, w, h, 
+                          frame->ratio, (long)frame->bgra_buffer, 
+                          unlock_frame_cb);
+     Py_DECREF(unlock_frame_cb);
+     Py_DECREF(frame_pyobject);
+     result = PyEval_CallObject(this->callback, args);
+     if (result)
+         Py_DECREF(result);
+     else {
+         printf("Exception in buffer callback:\n");
+         PyErr_Print();
+         retval = 0;
+     }
+     Py_DECREF(args);
+     PyGILState_Release(gstate);
+ 
+     return retval;
+ }
+ 
+ 
+ ////////////
+ 
+ 
+ int
+ pthread_mutex_lock_timeout(pthread_mutex_t *lock, double timeout)
+ {
+     struct timespec abstime;
+     abstime.tv_sec = (int)floor(timeout);
+     abstime.tv_nsec = (timeout-(double)abstime.tv_sec)*1000000000;
+     //printf("Lock timeout: %d sec %d usec\n", abstime.tv_sec, 
abstime.tv_nsec);
+     return pthread_mutex_timedlock(lock, &abstime);
+ }
+ 
+ 
+ 
  static uint32_t 
  buffer_get_capabilities(vo_driver_t *this_gen)
***************
*** 57,65 ****
      //printf("buffer_frame_dispose\n");
      pthread_mutex_destroy(&frame->vo_frame.mutex);
      if (frame->yv12_buffer)
          free(frame->yv12_buffer);
      if (frame->yuy2_buffer)
          free(frame->yuy2_buffer);
! 
      free(frame);
  }
--- 213,224 ----
      //printf("buffer_frame_dispose\n");
      pthread_mutex_destroy(&frame->vo_frame.mutex);
+     pthread_mutex_destroy(&frame->bgra_lock);
      if (frame->yv12_buffer)
          free(frame->yv12_buffer);
      if (frame->yuy2_buffer)
          free(frame->yuy2_buffer);
!     if (frame->bgra_buffer)
!         free(frame->bgra_buffer);
!     frame->yuv2rgb->dispose (frame->yuv2rgb);
      free(frame);
  }
***************
*** 86,91 ****
  
      pthread_mutex_init(&frame->vo_frame.mutex, NULL);
  
!     frame->yv12_buffer = frame->yuy2_buffer = NULL;
  
      frame->vo_frame.base[0] = NULL;
--- 245,251 ----
  
      pthread_mutex_init(&frame->vo_frame.mutex, NULL);
+     pthread_mutex_init(&frame->bgra_lock, NULL);
  
!     frame->yv12_buffer = frame->yuy2_buffer = frame->bgra_buffer = NULL;
  
      frame->vo_frame.base[0] = NULL;
***************
*** 103,106 ****
--- 263,267 ----
      frame->passthrough_frame->lock = vo_frame_inc_lock;
  
+     frame->yuv2rgb = 
this->yuv2rgb_factory->create_converter(this->yuv2rgb_factory);
  
      return (vo_frame_t *)frame;
***************
*** 117,122 ****
      int y_size, uv_size;
  
! //    printf("buffer_update_frame_format: %x format=%d  %dx%d\n", frame, 
format, width, height);
  
  
      this->passthrough->update_frame_format(this->passthrough,
--- 278,284 ----
      int y_size, uv_size;
  
!     //printf("buffer_update_frame_format: %x format=%d  %dx%d\n", frame, 
format, width, height);
  
+     // XXX: locking in this function risks deadlock.
  
      this->passthrough->update_frame_format(this->passthrough,
***************
*** 126,130 ****
      memcpy(&frame->vo_frame.base, frame->passthrough_frame->base, sizeof(char 
*)*3);
  
- 
  #if 0
      if (frame->width != width || frame->height != height || format != 
frame->format) {
--- 288,291 ----
***************
*** 180,186 ****
  {
      buffer_driver_t *this = (buffer_driver_t *)vo;
!     //printf("buffer_redraw_needed: %x\n", vo);
!     return this->passthrough->redraw_needed(this->passthrough);
!     return 1;
  }
  
--- 341,349 ----
  {
      buffer_driver_t *this = (buffer_driver_t *)vo;
!     int redraw;
! 
!     redraw = buffer_callback_command_query_redraw(this);
!     //printf("buffer_redraw_needed: %d\n", redraw);
!     return redraw || this->passthrough->redraw_needed(this->passthrough);
  }
  
***************
*** 191,196 ****
      buffer_frame_t *frame = (buffer_frame_t *)frame_gen;
      vo_frame_t *passthrough_frame;
!     int do_passthrough = 1;
!     PyObject *args, *result;
      PyGILState_STATE gstate;
  
--- 354,358 ----
      buffer_frame_t *frame = (buffer_frame_t *)frame_gen;
      vo_frame_t *passthrough_frame;
!     int request = 0, dst_width = -1, dst_height = -1;
      PyGILState_STATE gstate;
  
***************
*** 198,222 ****
      pthread_mutex_lock(&this->lock);
  
!     gstate = PyGILState_Ensure();
!     args = Py_BuildValue("(iidi)", frame->width, frame->height, frame->ratio,
!                          (long)frame->vo_frame.base[0]);
!     result = PyEval_CallObject(this->callback, args);
!     if (result) {
!         if (PyInt_Check(result))
!             do_passthrough = PyLong_AsLong(result);
!             
!         Py_DECREF(result);
!     } else {
!         printf("Exception in buffer callback:\n");
!         PyErr_Print();
      }
-     Py_DECREF(args);
-     PyGILState_Release(gstate);
  
!     if (this->passthrough && do_passthrough) {
          this->passthrough->display_frame(this->passthrough, 
frame->passthrough_frame);
      }
      frame->vo_frame.free(&frame->vo_frame);
      pthread_mutex_unlock(&this->lock);
  }
  
--- 360,413 ----
      pthread_mutex_lock(&this->lock);
  
!     buffer_callback_command_query_request(this, &request, &dst_width, 
&dst_height);
!     if (dst_width == -1 || dst_height == -1) {
!         dst_width = frame->width;
!         dst_height = frame->height;
      }
  
!     if (request & BUFFER_VO_REQUEST_SEND) {
!         if (pthread_mutex_lock_timeout(&frame->bgra_lock, 0.2) != 0) {
!             printf("FAILED to acquire lock\n");
!             goto bail;
!         }
!         if (!frame->bgra_buffer || 
!              frame->width != frame->yuv2rgb->source_width || 
!              frame->height != frame->yuv2rgb->source_height ||
!              frame->vo_frame.pitches[0] != frame->yuv2rgb->y_stride ||
!              frame->vo_frame.pitches[1] != frame->yuv2rgb->uv_stride ||
!              frame->yuv2rgb->dest_width != dst_width ||
!              frame->yuv2rgb->dest_height != dst_height) {
!             if (frame->bgra_buffer)
!                 free(frame->bgra_buffer);
!             frame->bgra_buffer = malloc(frame->width*frame->height*4);
!             frame->yuv2rgb->configure(frame->yuv2rgb, frame->width, 
frame->height,
!                                       frame->vo_frame.pitches[0],
!                                       frame->vo_frame.pitches[1],
!                                       dst_width, dst_height, 4*(dst_width));
!         }
!         if (frame->format == XINE_IMGFMT_YV12) {
!             stopwatch(0, "yv12 to bgra32");
!             frame->yuv2rgb->yuv2rgb_fun (frame->yuv2rgb, frame->bgra_buffer,
!                                          frame->vo_frame.base[0],  
!                                          frame->vo_frame.base[1],  
!                                          frame->vo_frame.base[2]);
!             stopwatch(0, NULL);
!         } else {
!             stopwatch(0, "yuy2 to bgra32");
!             frame->yuv2rgb->yuy22rgb_fun (frame->yuv2rgb, frame->bgra_buffer,
!                                           frame->vo_frame.base[0]);
!             stopwatch(0, NULL);
!         }
!         buffer_callback_send(this, frame, dst_width, dst_height);
!     }
! 
! bail:
!     if (this->passthrough && request & BUFFER_VO_REQUEST_PASSTHROUGH) {
          this->passthrough->display_frame(this->passthrough, 
frame->passthrough_frame);
      }
+ 
      frame->vo_frame.free(&frame->vo_frame);
      pthread_mutex_unlock(&this->lock);
+ 
  }
  
***************
*** 281,284 ****
--- 472,476 ----
      PyGILState_Release(gstate);
  
+     this->yuv2rgb_factory->dispose(this->yuv2rgb_factory);
      free(this);
      printf("Returning from buffer_dispose\n");
***************
*** 334,337 ****
--- 526,531 ----
      this->passthrough_pyobject = passthrough;
  
+     this->yuv2rgb_factory = yuv2rgb_factory_init(MODE_32_RGB, 0, NULL);
+ 
  //    memcpy(&this->vo_driver, this->passthrough->driver, 
sizeof(vo_driver_t));
      return &this->vo_driver;
***************
*** 797,801 ****
      buffer_frame_t *frame = (buffer_frame_t *)frame_gen;
  
!     printf("buffer_overlay_blend: format=%d overlay=%x\n", frame->format, 
vo_overlay);
      if (frame->format == XINE_IMGFMT_YV12)
         _overlay_blend_yuv(frame->vo_frame.base, vo_overlay,
--- 991,995 ----
      buffer_frame_t *frame = (buffer_frame_t *)frame_gen;
  
!     //printf("buffer_overlay_blend: format=%d overlay=%x\n", frame->format, 
vo_overlay);
      if (frame->format == XINE_IMGFMT_YV12)
         _overlay_blend_yuv(frame->vo_frame.base, vo_overlay,
***************
*** 808,812 ****
  }
  
- 
  static vo_info_t buffer_vo_info = {
      1,
--- 1002,1005 ----



-------------------------------------------------------
SF.Net email is sponsored by: Discover Easy Linux Migration Strategies
from IBM. Find simple to follow Roadmaps, straightforward articles,
informative Webcasts and more! Get everything you need to get up to
speed, fast. http://ads.osdn.com/?ad_id=7477&alloc_id=16492&op=click
_______________________________________________
Freevo-cvslog mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/freevo-cvslog

Reply via email to