[MPlayer-dev-eng] Mplayer -vo ps3
Kristian Jerpetjøn
kristian.jerpetjoen at gmail.com
Tue Apr 7 01:50:01 CEST 2009
2009/4/5 Reimar Döffinger <Reimar.Doeffinger at gmx.de>:
> On Sat, Apr 04, 2009 at 10:26:33PM +0200, Kristian Jerpetjøn wrote:
>> >> +/* preinit - pre-initialization section
>> >> +*
>> >> +* Called before initializing video output driver for evaluating subopts.
>> >> +* Currently, we don't utilize any subopts (e.g. -vo ps3:subopt
>> >> +*/
>> >
>> > Comment is outdated, it should be doxygen compatible, but documenting functions
>> > that are part of the standard VO API is a bit pointless.
>>
>> Working on it throughout file
>> This style is correct / ok ?
>>
>> /**
>> * Pointless test function
>> *
>> * @param testval test value for testfunct
>> * @return returns the test val
>> */
>> static int testfuct(int testval){
>> return testval;
>> }
>
> Yes, looks right to me.
>
>> >> + return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_SWSCALE | VFCAP_ACCEPT_STRIDE;
>> >
>> > not sure VFCAP_SWSCALE is right, at least you are not using libswscale...
>>
>> removed seems to work fine without
>
> I am just not sure if it should actually set the HWSCALE flag or what it is
> called. Sure, it is in software, but with recent GPUs OpenGL etc. is just
> software too, the point is that it does not use the "main CPU".
> But as said, I am not completely sure myself.
Unsure seems to work without from what i managed to read out of
vf_vo.c its fine
>
>> >> + vo_doublebuffering = VO_TRUE;
>> >> + vo_directrendering = VO_TRUE;
>> >
>> > These really should be left to the user and not overridden.
>>
>> removed now generates uglyness if -dr is disabled from user
>
> Yes, I think I started understanding what the code does, hopefully
> I can explain to you what goes wrong and why.
Solved Uglyness
>
>> I need a serious amount of help here..
>> changing MP_IMGFLAG_ALLOCATED to MP_IMGFLAG_DIRECT gives me green/tearing output
>
> Yeah, it looks like "a load of bugs which all together almost cancel each other out"
Think i solved this one as well
>> >> + case VOCTRL_UPDATE_SCREENINFO: /* 32 */
>> >> + mp_msg ( MSGT_VO, MSGL_WARN, "[vo_ps3] control: todo: handle UPDATE_SCREENINFO (%u)\n", request );
>> >> + return VO_NOTIMPL;
>> >
>> > can't you just set xinerama_x, xinerama_y, vo_screenwidth and vo_screenheight?
>> > xinerama_? to 0, the others to the framebuffer dimension (not this is called
>> > before config but after preinit).
>>
>> need to understand implications of this with respect to current code
>> before attempting
>
> Basically it just preinitializes vo_dx/vo_dy/vo_dwidth etc. and sets up
> aspect stuff. Should just allow you to remove a lot of code but not change much.
Think i solved this one as well
>> >> + vo_dx = vo_dy = 0;
>> >> + vo_screenwidth=fbW - ( fbX*2 );
>> >> + vo_screenheight=fbH - ( fbY*2 );
>> > [...]
>> >> + //set aspect stuff
>> >> + aspect_save_orig ( srcW, srcH );
>> >> + aspect_save_screenres ( vo_screenwidth, vo_screenheight );
>> >> + aspect_save_prescale ( dstW, dstH );
>> >> +
>> >> + geometry ( &vo_dx, &vo_dy, &dstW, &dstH, vo_screenwidth, vo_screenheight );
>> >> + aspect ( &dstW, &dstH, A_NOZOOM );
>> >> + //center image -- this is wrong from mplayer's perspective - it should be
>> >> + // before the geometry & aspect call, but i don't want
>> >> + // mplayer to center the image because i can do it in
>> >> + // spu-medialib and we don't have to draw the extra black bars
>> >> + vo_dx = ( fbW - ( 2 * fbX ) - dstW ) /2;
>> >> + vo_dx = ( vo_dx+3 ) &~3;
>> >> + vo_dy = ( fbH - ( 2 * fbY ) - dstH ) /2;
>> >
>> > Implement VOCTRL_UPDATE_SCREENINFO and you (hopefully) shouldn't need any of that.
>> > I have no idea WTF that comment is talking about.
>> > I guess the code was never tested with -geometry though...
>>
>> need some help implementing geometry correctly
>> however i did some cleanup here
>
> Well, the idea is: just implement VOCTRL_UPDATE_SCREENINFO and then display
> the video at vo_dx, vo_dy with size vo_dwidth, vo_dheight.
> To go fullscreen remember these and set the size from aspect(..., A_ZOOM) and
> vo_dx, vo_dy to create proper black borders.
> To return from fullscreen, restore the previous values.
New implementation
>
>> >> + yuvscsc_set_srcW ( yuvcsc, srcW );
>> >> + yuvscsc_set_srcH ( yuvcsc, srcH );
>> >> + yuvscsc_set_dstW ( yuvcsc, dstW );
>> >> + yuvscsc_set_dstH ( yuvcsc, dstH );
>> >> + yuvscsc_set_offset ( yuvcsc, offset );
>> >> + yuvscsc_set_maxwidth ( yuvcsc, maxW );
>> >
>> > Somebody has not yet found out about the thing called "struct" yet?!?
>>
>> Yes we have but unfortunately i have not bothered to make a new API
>> for this part of spu-medialib yet i should put it on the todo for 0.2
>
> It's not that bad, I just considered it a bit funny and coould not resist a comment.
Well now its gone..
>
>> It is one step closer now and i need help on a few parts regarding the
>> get_image and draw_image and general buffer handling
>>
>> Currently spu-medialib is configured with two planar images as input
>> divided amongst 6 buffers for yv12 etc...
>
> Two buffers is not going to great with -dr.
> For it to work well with MPEG-2 you need one to store the I-frame in,
> one to store the P-frame in, and then you need to draw the B-frame
> without break the I- or P-frame.
Solved buffers = 4 when doing DR..
>
>> +static uint32_t get_image ( mp_image_t * mpi )
>> +{
>> + //TODO fix this whole mess somehow
>> + get_image_count++;
>> +
>> + if ( ( mpi->flags & MP_IMGFLAG_READABLE ) && ( mpi->type == MP_IMGTYPE_IPB\
>> + || mpi->type == MP_IMGTYPE_IP ) )
>
removed
>
>> + {
>> + buf_plane_ptr[0] = parking_lot_y[parking_lot_page];
>> + buf_plane_ptr[1] = parking_lot_u[parking_lot_page];
>> + buf_plane_ptr[2] = parking_lot_v[parking_lot_page];
>> + //mpi->flags |=MP_IMGFLAG_DIRECT;
>> + //FIXME crash without understand what Bill was thinking here
>> + mpi->flags |= MP_IMGFLAG_ALLOCATED;
>> + parking_lot_page^=1;
>> + }
>> + else
>> + {
>> + buf_plane_ptr[0] = inbuf_y[page];
>> + buf_plane_ptr[1] = inbuf_u[page];
>> + buf_plane_ptr[2] = inbuf_v[page];
>> + mpi->flags |= MP_IMGFLAG_DIRECT;
>> + }
>
> If you do not set MP_IMGFLAG_DIRECT that means in draw_image you will
> still call memcpy, thus get_image is completely pointless then, so just
> returning VO_FALSE in that case should work the same.
> Next, you have only two buffers available. You need one in case you
> somehow get and mpi without MP_IMGFLAG_DIRECT in draw_image.
> Since you do not know when that will happen, you can not give that one
> out in get_image when MP_IMGFLAG_PRESERVE is set (i.e. the application
> expects to get the same content back somewhen).
> Now I am not sure if the second buffer is available or if that one might
> still be processed by the SPEs.
> Either way, that one buffer is not enought for MP_IMGTYPE_IP.
> So you end up with two possibilities:
> 1)
> if (mpi->flags & MP_IMGFLAG_PRESERVE) return VO_FALSE;
> if (mpi->type != MP_IMGTYPE_STATIC && mpi->type != MP_IMGTYPE_TEMP &&
> (mpi->type != MP_IMGTYPE_NUMBERED || mpi->number))
> return VO_FALSE;
> fill planes etc. with the same buffer you would use in draw_image and
> set MP_IMGFLAG_DIRECT, skip the memcpy in draw_image if that flag is set
>
> 2)
> if (mpi->type != MP_IMGTYPE_STATIC && mpi->type != MP_IMGTYPE_TEMP &&
> (mpi->type != MP_IMGTYPE_NUMBERED || mpi->number))
> return VO_FALSE;
> fill planes etc. with the second buffer and set MP_IMGFLAG_DIRECT, skip
> the memcpy in draw_image if that flag is set.
> If that flag is not set in memcpy, memcpy _always_ to the first buffer
> in draw_image.
>
> Either way unless you provide at least 3 buffers (and ignore correctness a bit,
> which is okay since vo_xv does so already) or better 4 buffers, you will
> probably gain little from direct-rendering...
> btw. you should just call draw_slice to make the memcpy in draw_image,
> if they do not use the same code they are almost certainly wrong :-)
4 buffers seemed fine :)
>
>> +static void draw_osd ( void )
>> +{
>> +
>> + vo_draw_text ( srcW, srcH, draw_alpha );
>> +}
>
> Hm, I somehow missed it, what does draw_alpha draw onto?
> Hopefully not onto something you gave out as PRESERVE/READABLE in get_image
> because then you'd just have broken a promise :-)
I will not solve OSD in this patch
However i have now solved a lot of issues and the overall quality is
greatly improved
optional and working -fs -double -dr -geometry i think
I have to make a new release of spu-medialib but it was a neccesary
step to make it work with 4 buffers that release is ready the day the
patch is approved
Cheers
--
Kristian Jerpetjøn
Tlf: +4721694436
Mob +4792822774
Email: kristian.jerpetjoen at gmail.com
-------------- next part --------------
Index: Makefile
===================================================================
--- Makefile (revision 29136)
+++ Makefile (working copy)
@@ -618,6 +618,7 @@
SRCS_MPLAYER-$(OSS) += libao2/ao_oss.c
SRCS_MPLAYER-$(PNG) += libvo/vo_png.c
SRCS_MPLAYER-$(PNM) += libvo/vo_pnm.c
+SRCS_MPLAYER-$(PS3) += libvo/vo_ps3.c
SRCS_MPLAYER-$(PULSE) += libao2/ao_pulse.c
SRCS_MPLAYER-$(QUARTZ) += libvo/vo_quartz.c
SRCS_MPLAYER-$(S3FB) += libvo/vo_s3fb.c
Index: libvo/video_out.c
===================================================================
--- libvo/video_out.c (revision 29136)
+++ libvo/video_out.c (working copy)
@@ -114,6 +114,7 @@
extern vo_functions_t video_out_directx;
extern vo_functions_t video_out_kva;
extern vo_functions_t video_out_dxr2;
+extern vo_functions_t video_out_ps3;
extern vo_functions_t video_out_dxr3;
extern vo_functions_t video_out_ivtv;
extern vo_functions_t video_out_v4l2;
@@ -201,6 +202,9 @@
&video_out_fbdev,
&video_out_fbdev2,
#endif
+#ifdef CONFIG_PS3
+ &video_out_ps3,
+#endif
#ifdef CONFIG_SVGALIB
&video_out_svga,
#endif
Index: libvo/vo_ps3.c
===================================================================
--- libvo/vo_ps3.c (revision 0)
+++ libvo/vo_ps3.c (revision 0)
@@ -0,0 +1,593 @@
+/*
+ * video driver for cell / BE Playstation3 framebuffer
+ * Copyright 2007 by Bill Garrett <wgarrett at sc.rr.com>
+ * Copyright 2009 by Kristian Jerpetjoen <kristian.jerpetjoen at gmail.com>
+ *
+ * This video out device uses the Cell Broadband Engine spe's to accelerate
+ * scaling and colorspace conversion to a Framebuffer
+ *
+ * This vo depends on spu-medialib which is a BSDv2 library
+ * https://sourceforge.net/projects/spu-medialib
+ *
+ * This file is part of MPlayer.
+ *
+ * MPlayer 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.
+ *
+ * MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <libspe2.h>
+
+#include "config.h"
+#include "mplayer.h"
+#include "aspect.h"
+#include "mp_msg.h"
+#include "help_mp.h"
+#include "video_out.h"
+#include "video_out_internal.h"
+#include "subopt-helper.h"
+#include "fastmemcpy.h"
+#include "osd.h"
+#include "sub.h"
+
+#if HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+
+#include <spu-medialib/spu_control.h>
+#include <spu-medialib/yuv2argb_scaler.h>
+
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <linux/kd.h>
+#include <linux/fb.h>
+#include <asm/ps3fb.h>
+
+#define NUM_BUFFERS 4
+#define MAXW 1920
+#define MAXH 1200
+
+#define FB_DEV "/dev/fb0"
+#define CONSOLE "/dev/tty"
+#define FALLBACK "/dev/console"
+
+static vo_info_t info =
+{
+ "PS3 framebuffer w/ spe offload courtesy of spu_medialib (https://sourceforge.net/projects/spu-medialib)",
+ "ps3",
+ "Bill Garrett <wgarrett at sc.rr.com>",
+ "Kristian Jerpetjoen <kristian.jerpetjoen at gmail.com"
+};
+
+LIBVO_EXTERN(ps3)
+
+static uint8_t *inbuf_y[NUM_BUFFERS], *inbuf_u[NUM_BUFFERS], *inbuf_v[NUM_BUFFERS];
+
+static uint32_t src_stride[3], src_p_siz[3], src_fmt, src_bpp;
+static uint32_t offsetW, offsetH;
+static uint32_t suggestedW, suggestedH;
+static uint8_t *buf_plane_ptr[3];
+static int fb, console, fb_length;
+
+static int current_buf = 0;
+static int current_ip_buf = 0;
+static int num_buffers = 1; // default
+static int visible_buf = -1; // no visible buffer
+
+static unsigned int yuvcsc_msg;
+static int wait_yuvcsc, yuvcsc_not_ready;
+
+static struct ps3fb_ioctl_res ps3_fb;
+
+static struct spu_medialib_conv_ctx_s conv_ctx;
+
+static yuvscaler2argb_t *yuvcsc;
+
+
+/**
+ * Initiates the ps3 framebuffer and disables the console
+ * @return -1 if unsuccessful
+ */
+static int init_framebuffer(void)
+{
+ int arg;
+ int res = 0;
+
+ console = open(CONSOLE, O_NONBLOCK);
+
+ if (console >= 0)
+ res = ioctl(console, KDGETMODE, &arg);
+
+ //This will only work if you are root
+ if (console < 0 || res < 0) {
+
+ if (console >= 0)
+ close(console);
+
+ console = open(FALLBACK, O_NONBLOCK);
+ res = ioctl(console, KDGETMODE, &arg);
+ }
+
+ if (console >= 0){
+ if (arg !=KD_GRAPHICS && ioctl(console, KDSETMODE, KD_GRAPHICS) < 0)
+ mp_msg(MSGT_VO,MSGL_INFO,"[vo_ps3] failed to disable console\n");
+ }
+ //we got this far now even if the console failed we continue
+ res = 0;
+
+ fb = open(FB_DEV, O_RDWR);
+
+ if (fb < 0) {
+
+ mp_msg(MSGT_VO, MSGL_INFO,
+ "[vo_ps3] init_framebuffer: failed to open fb\n" );
+ goto fail;
+ }
+
+ if (ioctl(fb, PS3FB_IOCTL_SCREENINFO, (unsigned long)&ps3_fb) < 0) {
+
+ mp_msg(MSGT_VO, MSGL_INFO,
+ "[vo_ps3] init_framebuffer: failed to get fb info\n" );
+ goto fail;
+ }
+
+ if (ioctl(fb, PS3FB_IOCTL_ON ) < 0) {
+
+ mp_msg(MSGT_VO, MSGL_INFO,
+ "[vo_ps3] init_framebuffer: failed to set manual swap control\n"
+ );
+ goto fail;
+ }
+
+ fb_length = ps3_fb.xres * ps3_fb.yres * 4;
+
+ //get the FB mmap
+ conv_ctx.Out = mmap(NULL, fb_length, PROT_WRITE, MAP_SHARED, fb, 0);
+ //actual widt of FB including offscreen
+ conv_ctx.maxwidth = ps3_fb.xres;
+
+ return 0;
+
+fail:
+ if (fb >= 0) {
+ ioctl(fb,PS3FB_IOCTL_OFF);
+ close(fb);
+ }
+
+ if (console >= 0) {
+ ioctl (console, KDSETMODE, KD_TEXT);
+ close(console);
+ }
+
+ return -1;
+}
+
+/**
+ * yuvcsc_check - check spu_yuv2argb_scaler process
+ * make sure it's not running
+ */
+static void yuvcsc_check(void)
+{
+
+ if (!wait_yuvcsc)
+ return;
+
+ yuvcsc_msg = yuvscsc_receive_message(yuvcsc);
+
+ while (yuvcsc_msg != RDY) {
+
+ yuvcsc_not_ready++;
+ mp_msg(MSGT_VO, MSGL_WARN,
+ "VO: [ps3] yuvcsc_check: ***yuvcsc not ready to run! :(\n" );
+
+ yuvcsc_msg = yuvscsc_receive_message(yuvcsc);
+ }
+
+ wait_yuvcsc = 0;
+}
+
+/**
+ * Puts the destination image onto the framebuffer
+ */
+static void yuvcsc_blit(void)
+{
+ wait_yuvcsc = 1;
+
+ conv_ctx.planes[0] = inbuf_y[current_buf];
+ conv_ctx.planes[1] = inbuf_u[current_buf];
+ conv_ctx.planes[2] = inbuf_v[current_buf];
+
+ yuvscsc_blit_yuvscaler2argb(yuvcsc, &conv_ctx);
+}
+
+/**
+ * Initiates the spu medialib spe vo accellerator
+ */
+static void init_spu_medialib(void)
+{
+ yuvcsc = yuvscsc_init_yuvscaler2argb();
+ //set wait flag
+ wait_yuvcsc = 1;
+ //wait for init to complete
+ yuvcsc_check();
+ mp_msg(MSGT_VO, MSGL_INFO,
+ "VO: [ps3] Initiated\n" );
+}
+
+/**
+ * Clears the target-framebuffer
+ */
+static void clear_framebuffer(void)
+{
+ //make sure spu medialib is not currently drawing on target framebuffer
+ yuvcsc_check();
+ //clear target framebuffer
+ memset(conv_ctx.Out, 0, fb_length);
+}
+
+/**
+ * Updates the screen settings
+ */
+static void update_screen(void)
+{
+ if (vo_fs){
+ aspect(&conv_ctx.dstW, &conv_ctx.dstH, A_ZOOM);
+ vo_dx = (vo_screenwidth - conv_ctx.dstW) / 2;
+ vo_dy = (vo_screenheight - conv_ctx.dstH) / 2;
+ } else {
+ conv_ctx.dstW = suggestedW;
+ conv_ctx.dstH = suggestedH;
+ vo_dx = offsetW;
+ vo_dy = offsetH;
+ }
+
+ //round down to nearest 4x4 users should consider restrictions
+ aspect_fit(&conv_ctx.dstW, &conv_ctx.dstH, conv_ctx.dstW & (~0x3),
+ conv_ctx.dstH & (~0x3));
+
+ //round offset up to nearest 4x4 users should consider restrictions
+ vo_dx=(vo_dx + 3) & (~0x3);
+ vo_dy=(vo_dy + 3) & (~0x3);
+ conv_ctx.offset=vo_dx + (vo_dy*ps3_fb.xres);
+}
+
+
+/**
+ * Toggles fullscreen off and on
+ */
+static void toggle_fullscreen(void)
+{
+ //toggle fullscreen flag
+ vo_fs = !vo_fs;
+ //check that nothings currently working on the framebufer
+ yuvcsc_check();
+ //clear the framebuffer in case vo_dy/vo_dx was in the outer rims
+ clear_framebuffer();
+ //update_screen
+ update_screen();
+}
+
+//buildtin documented elsewhere
+static int query_format(uint32_t format)
+{
+
+ switch(format)
+ {
+ case IMGFMT_I420: //Planar I420 0x30323449
+ case IMGFMT_YV12: //Planar YV12 0x32315659
+ case IMGFMT_IYUV: //Planar IYUV 0x56555949
+ return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW |
+ VFCAP_ACCEPT_STRIDE ;
+ default:
+ return VO_FALSE; //not supporting anything else yet
+ }
+}
+
+//buildtin documented elsewhere
+static void draw_osd(void){
+//TODO make me draw osd
+}
+
+//buildtin documented elsewhere
+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)
+{
+ int i;
+
+ conv_ctx.srcW = width;
+ conv_ctx.srcH = height;
+
+ offsetW=vo_dx;
+ offsetH=vo_dy;
+
+ suggestedW = d_width;
+ suggestedH = d_height;
+
+ switch(format)
+ {
+ case IMGFMT_I420: //Planar I420 0x30323449
+ case IMGFMT_YV12: //Planar YV12 0x32315659
+ case IMGFMT_IYUV: //Planar IYUV 0x56555949
+ //TODO add more sanity to strides inside spu-medialib
+ src_stride[0] = conv_ctx.srcW;
+ src_stride[1] = src_stride[2] = src_stride[0]/2;
+ src_p_siz[0] = conv_ctx.srcW * conv_ctx.srcH;
+ src_p_siz[1] = src_p_siz[2] = (conv_ctx.srcW/2) * (conv_ctx.srcH/2);
+ src_bpp = 12;
+ break;
+ default:
+ mp_msg(MSGT_VO, MSGL_FATAL,
+ "[vo_ps3] config: Unsupported format: %i\n", format );
+ return 1;
+ }
+
+ src_fmt=format;
+
+ if (vo_doublebuffering)
+ num_buffers=2;
+
+ if (vo_directrendering)
+ num_buffers=NUM_BUFFERS;
+
+ for (i = 0; i < num_buffers; i++) {
+ inbuf_y[i] = memalign(128, src_p_siz[0] * 2);
+ inbuf_u[i] = memalign(128, src_p_siz[1] * 2);
+ inbuf_v[i] = memalign(128, src_p_siz[2] * 2);
+ }
+ //make sure we have black borders
+ clear_framebuffer();
+ //get the right screen
+ update_screen();
+ //initiate accelerator
+ init_spu_medialib();
+
+ return 0;
+}
+
+//buildtin documented elsewhere
+static int draw_slice(uint8_t *src[], int stride[], int w, int h, int x, int y)
+{
+ int i;
+ int slice_siz[3], slice_p_w[3], slice_p_h[3], offset[3];
+
+ buf_plane_ptr[0] = inbuf_y[current_buf];
+ buf_plane_ptr[1] = inbuf_u[current_buf];
+ buf_plane_ptr[2] = inbuf_v[current_buf];
+
+ slice_siz[0] = stride[0] * h;
+ slice_siz[1] = stride[1] * h/2;
+ slice_siz[2] = stride[2] * h/2;
+
+ slice_p_w[0] = w;
+ slice_p_w[1] = slice_p_w[2] = w/2;
+
+ slice_p_h[0] = h;
+ slice_p_h[1] = slice_p_h[2] = h/2;
+
+ offset[0] = y * src_stride[0] + x;
+ offset[1] = y/2 * src_stride[1] + x/2;
+ offset[2] = y/2 * src_stride[2] + x/2;
+
+ for ( i=0; i<3; i++ ) {
+ memcpy_pic(buf_plane_ptr[i] + offset[i], src[i], slice_p_w[i],
+ slice_p_h[i], src_stride[i], stride[i]);
+ }
+ return 0;
+}
+
+//buildtin documented elsewhere
+static uint32_t draw_image(mp_image_t *mpi)
+{
+ if (mpi->flags & MP_IMGFLAG_DIRECT) {
+ //direct rendering
+ current_buf = (int) (mpi->priv);// hack! seems to work on spu-medialib?
+ return VO_TRUE;
+ }
+
+ if (mpi->flags & MP_IMGFLAG_DRAW_CALLBACK)
+ return VO_TRUE; // done
+
+ if (mpi->flags & MP_IMGFLAG_PLANAR) {
+ draw_slice(mpi->planes, mpi->stride, mpi->w, mpi->h, 0, 0);
+ return VO_TRUE;
+ }
+
+ return VO_FALSE; // not (yet) supported
+
+}
+
+//buildtin documented elsewhere
+static uint32_t get_image(mp_image_t * mpi)
+{
+ int buf = current_buf;
+
+ if (mpi->type == MP_IMGTYPE_STATIC && num_buffers > 1)
+ return VO_FALSE; // it is not static
+
+ if (mpi->imgfmt != src_fmt)
+ return VO_FALSE; // needs conversion :(
+
+ if (mpi->flags & MP_IMGFLAG_READABLE &&
+ (mpi->type == MP_IMGTYPE_IPB || mpi->type == MP_IMGTYPE_IP))
+ {
+ // reference (I/P) frame of IP or IPB:
+ if (num_buffers < 2)
+ return VO_FALSE; // not enough
+
+ current_ip_buf ^= 1;
+ // for IPB with 2 buffers we can DR only one of the 2 P frames:
+ if (mpi->type == MP_IMGTYPE_IPB && num_buffers < 3
+ && current_ip_buf)
+ return VO_FALSE;
+
+ buf = current_ip_buf;
+
+ if (mpi->type == MP_IMGTYPE_IPB)
+ ++buf; // preserve space for B
+ }
+
+ if (mpi->flags & (MP_IMGFLAG_ACCEPT_STRIDE | MP_IMGFLAG_ACCEPT_WIDTH))
+ {
+ current_buf = buf;
+ mpi->planes[0] = inbuf_y[current_buf];
+ mpi->stride[0] = src_stride[0];
+ mpi->width = mpi->stride[0] / (mpi->bpp / 8);
+
+ if (mpi->flags & MP_IMGFLAG_PLANAR) {
+ if (mpi->flags & MP_IMGFLAG_SWAPPED) {
+ // I420
+ mpi->planes[1] = inbuf_v[current_buf];
+ mpi->planes[2] = inbuf_u[current_buf];
+ mpi->stride[1] = src_stride[1];
+ mpi->stride[2] = src_stride[1];
+ } else
+ {
+ // YV12
+ mpi->planes[1] = inbuf_u[current_buf];
+ mpi->planes[2] = inbuf_v[current_buf];
+ mpi->stride[1] = src_stride[1];
+ mpi->stride[2] = src_stride[1];
+ }
+ }
+
+ if (current_buf == visible_buf)
+ yuvcsc_check();
+
+ mpi->flags |= MP_IMGFLAG_DIRECT;
+ mpi->priv = (void *) current_buf;
+ return VO_TRUE;
+ }
+ return VO_FALSE;
+ return 0;
+}
+
+//buildtin documented elsewhere
+static int draw_frame(uint8_t *src[])
+{
+ //do nothing
+ return 0;
+}
+
+//buildtin documented elsewhere
+static void flip_page(void)
+{
+ int frame = 0;
+ int crt = 0;
+
+ //make sure last frame is done
+ yuvcsc_check();
+ //flip output to monitor
+ ioctl(fb, PS3FB_IOCTL_FSEL, (unsigned long)&frame);
+ //make sure flip is complete
+ ioctl(fb, FBIO_WAITFORVSYNC, (unsigned long)&crt);
+ //run process next frame
+ yuvcsc_blit();
+ //set buffer as visible
+ visible_buf = current_buf;
+
+ if (num_buffers > 1) {
+ current_buf = vo_directrendering ? 0 : ((current_buf + 1) %num_buffers);
+ } else {
+ //make sure spu-medialib is done with buffer
+ yuvcsc_check();
+ }
+}
+
+//buildtin documented elsewhere
+static void check_events(void)
+{
+ //no events to check
+}
+
+//buildtin documented elsewhere
+static void uninit(void)
+{
+
+ int i;
+ // Cleanup spu-medialib
+ yuvcsc_check();
+
+ yuvscsc_destroy(yuvcsc);
+
+ //Cleanup FrameBuffer and re-enable console */
+ ioctl(fb, PS3FB_IOCTL_OFF);
+
+ ioctl(console, KDSETMODE, KD_TEXT);
+
+ if (console >= 0)
+ close(console);
+
+ if (console >= 0)
+ close(fb);
+
+ for (i = 0; i < num_buffers; i++) {
+ free(inbuf_y[i]);
+ free(inbuf_u[i]);
+ free(inbuf_v[i]);
+ }
+
+ mp_msg(MSGT_VO, MSGL_INFO,
+ "VO: [ps3] Closed and re-enabled console.\n" );
+}
+
+//buildtin documented elsewhere
+static int preinit(const char *arg)
+{
+ /* init PS3 FrameBuffer */
+ if (init_framebuffer() < 0)
+ return -1;
+ return 0;
+}
+
+//buildtin documented elsewhere
+static int control(uint32_t request, void *data, ...)
+{
+ switch(request)
+ {
+ case VOCTRL_QUERY_FORMAT:
+ return query_format (*(uint32_t*)data);
+
+ case VOCTRL_FULLSCREEN:
+ toggle_fullscreen();
+ return 0;
+
+ case VOCTRL_PAUSE:
+ return 0;
+
+ case VOCTRL_RESUME:
+ return 0;
+
+ case VOCTRL_GET_IMAGE:
+ return get_image(data);
+
+ case VOCTRL_DRAW_IMAGE:
+ return draw_image(data);
+
+ case VOCTRL_UPDATE_SCREENINFO:
+ vo_screenwidth = (int)(ps3_fb.xres - (ps3_fb.xoff * 2));
+ vo_screenheight = (int)(ps3_fb.yres - (ps3_fb.yoff * 2));
+ xinerama_x=xinerama_y=0;
+ aspect_save_screenres(vo_screenwidth, vo_screenheight);
+ return VO_TRUE;
+
+ default:
+ return VO_NOTIMPL;
+ }
+}
Index: configure
===================================================================
--- configure (revision 29136)
+++ configure (working copy)
@@ -391,6 +391,7 @@
--enable-xshape enable XShape support [autodetect]
--disable-xss disable screensaver support via xss [autodetect]
--enable-fbdev enable FBDev video output [autodetect]
+ --enable-ps3 enable FBDev video output SPU optimized for PS3 [autodetect]
--enable-mlib enable mediaLib video output (Solaris) [disable]
--enable-3dfx enable obsolete /dev/3dfx video output [disable]
--enable-tdfxfb enable tdfxfb video output [disable]
@@ -577,6 +578,7 @@
_svga=auto
_vesa=auto
_fbdev=auto
+_ps3=auto
_dvb=auto
_dvbhead=auto
_dxr2=auto
@@ -931,6 +933,8 @@
--disable-vesa) _vesa=no ;;
--enable-fbdev) _fbdev=yes ;;
--disable-fbdev) _fbdev=no ;;
+ --enable-ps3) _ps3=yes ;;
+ --disable-ps3) _ps3=no ;;
--enable-dvb) _dvb=yes ;;
--disable-dvb) _dvb=no ;;
--enable-dvbhead) _dvbhead=yes ;;
@@ -4758,6 +4762,26 @@
echores "$_fbdev"
+echocheck "PS3"
+if test "$_ps3" = auto ; then
+ cat > $TMPC << EOF
+#include <libspe2.h>
+#include <spu-medialib/spu_control.h>
+#include <spu-medialib/yuv2argb_scaler.h>
+int main(void) { return 0; }
+EOF
+ _ps3=no
+ cc_check -lspu-medialib -lspe2 && _ps3=yes
+fi
+if test "$_ps3" = yes; then
+ def_ps3='#define CONFIG_PS3 1'
+ libs_mplayer="$libs_mplayer -lspu-medialib -lspe2"
+ _vomodules="ps3 $_vomodules"
+else
+ def_ps3='#undef CONFIG_PS3'
+ _novomodules="ps3 $_novomodules"
+fi
+echores "$_ps3"
echocheck "DVB"
if test "$_dvb" = auto ; then
@@ -8257,6 +8281,7 @@
PNG = $_png
PNM = $_pnm
PRIORITY = $_priority
+PS3 = $_ps3
PULSE = $_pulse
PVR = $_pvr
QTX_CODECS = $_qtx
@@ -8730,6 +8755,7 @@
$def_mng
$def_png
$def_pnm
+$def_ps3
$def_quartz
$def_s3fb
$def_sdl
More information about the MPlayer-dev-eng
mailing list