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