? DXR3.patch Index: configure =================================================================== RCS file: /cvsroot/mplayer/main/configure,v retrieving revision 1.360 diff -u -r1.360 configure --- configure 7 Jan 2002 12:17:21 -0000 1.360 +++ configure 10 Jan 2002 12:59:30 -0000 @@ -1904,9 +1904,7 @@ if test "$_dxr3" = yes ; then _def_dxr3='#define HAVE_DXR3 1' _vosrc="$_vosrc vo_dxr3.c" - _aosrc="$_aosrc ao_dxr3.c" _vomodules="dxr3 $_vomodules" - _aomodules="dxr3 $_aomodules" else _def_dxr3='#undef HAVE_DXR3' if test "$_mp1e" = auto ; then Index: DOCS/DXR3 =================================================================== RCS file: /cvsroot/mplayer/main/DOCS/DXR3,v retrieving revision 1.8 diff -u -r1.8 DXR3 --- DOCS/DXR3 6 Jan 2002 15:24:56 -0000 1.8 +++ DOCS/DXR3 10 Jan 2002 12:59:30 -0000 @@ -1,118 +1,58 @@ -DXR3/H+ video/audio output plugins manual by David Holm -======================================================= +How to use a Sigma Designs Hollywood Plus and/or a Creative DXR3 by David Holm +============================================================================== -2002-01-06: I've started working on config support. - You can try -vo dxr3:swsync to disable hardware - syncing and use mplayers software syncer instead. - I'd like some feedback on which one works best - on your particular machine =). (I recommend - using em8300 0.10 or later) - -2001-12-28: There is a whole bunch of updates since the - last time. For one thing, digital audio now - works thanks to Steven Brookes. - This is the first version to exclusively - use the dxr3's hardware sync. It seems as if - there are some bugs in the driver, so bugreports - will be appreciated. - Also, you will need to get the em8300 drivers - from cvs unless a version newer than 0.9.0 has - been released. - Note1: Seeking won't work with -vc mpegpes! - Note2: You now MUST use -ao dxr3 for proper - a/v sync! - -2001-12-04: Thanks to Inaki Garci'a Etxebarria of - zapping.sourceforge.net we have now - abandoned rte since it caused problems for - users who didn't rtfm and compiled it with - ffmpeg support. Instead we are now using - libmp1e which is a modified version of mp1e. - -1. Introduction - -The DXR3 and Hollywood+ are two not too different mpeg-(1/2) and ac3 -hardware playback cards that came at about the same time as the first -dvd-rom drives hit the market. At that time most computers weren't -powerful enough for synced software dvd playback. And even the faster -(intel-based) computers had troubles with artifacts. -Sigma Designs came up with the great idea to create a hardware -mpeg-(1/2), ac3 decoder. Sigma Designs are known for their realmagic -hardware (or they bought the company who came up with the first -realmagic boards, I don't know which). -Later Creative Labs thought, hey, we also wan't this product, and to -distribute it with our dvd-drives (the DVD Encore packages if I recall -correctly). So they bought the designs for the Hollywood plus and -replaced the circuit used to produce a proper video feed for tv's -called adv7170 or adv7175a depending on which h+ board you own with -a bt865. The reason for this is beyond my understanding as this seems -complete illogical to me, but I have had great experiences with -bt(brooktree) circuits in the past, so I don't mind. -Well, nowadays most people have no use for a mpeg-(1/2) or ac3 -hardware decoder since most computers these days have no problem doing -this in software and have cycles left for posprocessing (removing of -artefacts and other garbage produced by compression). -These days, you have two uses for this card: -1. You have a slow computer which you use for vcd/dvd playback -2. You discover what I have done with the implementation of this as - an audio/video output device for mplayer (read on and you'll find - out). - - - -2. Requirements +1. Requirements * First of all you will need the DXR3/H+ drivers properly installed. - Version 0.9.0 or later + Version 0.10.0 or later. You can find it at + http://dxr3.sourceforge.net/ * Run /configure and make sure that DXR3/H+ support = yes + if you want to play files other than mpeg libmp1e should be = yes as well From here on compilation (of at least my code ;) should go without any problems. -3. Usage +2. Usage -After installation you will have two new outdevices in mplayer: - -vo dxr3 For video output - -ao dxr3 For audio output + -vo dxr3: For video output + -ao oss: For audio output + -ac hwac3 For digital audio output instead of analog + -vc mpegpes For mpeg playback + Number of device to use for playback (if you + have more than one card.). This can usually + be left out (-vo dxr3). + Mandrake 8.1 uses devfs by default. If you are + running mandrake 8.1 please use -vo dxr3:0 + Normally /dev/em8300_ma or + /dev/em8300_ma- + (-ao dxr3:/dev/em8300_ma). If left out the + default oss device will be used (normally + soundcard). MPEG-1, MPEG-2, VCD and DVD Notes -There are some notes to take into account here for optimum playback. -When playing any mpeg-(1/2) file, this including usage of the "-dvd" -and "-vcd" options you must either add the "-vc mpegpes" or edit -codecs.conf and make sure videocodec mpegpes is listed above mpeg12. -If you fail to do this you will only get software playback which kinda -spoils most of the useful features of this card except for tv-out ;). -Remember that if you edit the codecs.conf file and move the mpegpes -section will have to specify "-vc mpeg12" if you want to playback -any of these video types _without_ "-vo dxr3"! -Use -ac hwac3 if you want AC3 audio to be handled by hardware (please -send some feedback on this). - -DIVX Notes -When playing divx's add "-vc odivx" for maximum performance. -I've switched to mp1e from ffmpeg so it should be lightning fast now. -libmp1e currently does not work on nonx86 processor and nonmmx processors. -I'm in the process of fixing this. - -Other codecs: -No "-vc " switches should be required as mplayer will autodetect. -If you find an unsupported codec please contact me! - -* Avoid running mplayer as root or setuid root as rtc timing seems to - slow down playback on the dxr3 for some users. I will look into this - at a later point as this hardly qualifies as a severe bug * +There are some important notes to take into account here for optimum playback. +MPlayer currently does not autodetect that the dxr3 can playback mpegs. So for +mpeg files, dvd's and vcd's you have to add -vc mpegpes to tell mplayer that +you are using a hardware accelerator. Otherwise mplayer will decode the movie +in software, which is much slower. +Note that you cannot use -vc mpegpes with movies that aren't mpeg 1 or 2 or +you will get an error message saying "Can't find codec for video format...". + +* If you run mplayer as root, or set userid root it will use your pc's internal + realtime clockgenerator for syncing. (If your kernel supports it (It's + located in character devices and called "Enhanced realtime clock support")). + Some people report that this has improved playback (which it should), but + others have had problems with it. You will have to experiment yourself with + this to find your optimum setup. - -4. Contacting me + +3. Contacting me You can contact me either by e-mailing me, or by using icq: 798427 Feedback, bugreports and general suggestions are appreciated (preferably -by e-mail). My name is David Holm for those of you who are incapable of -reading a heading. ;) - - +by e-mail). Index: libao2/audio_out.c =================================================================== RCS file: /cvsroot/mplayer/main/libao2/audio_out.c,v retrieving revision 1.20 diff -u -r1.20 audio_out.c --- libao2/audio_out.c 3 Dec 2001 01:13:14 -0000 1.20 +++ libao2/audio_out.c 10 Jan 2002 12:59:30 -0000 @@ -34,9 +34,6 @@ #ifdef USE_SGI_AUDIO extern ao_functions_t audio_out_sgi; #endif -#ifdef HAVE_DXR3 -extern ao_functions_t audio_out_dxr3; -#endif extern ao_functions_t audio_out_pcm; extern ao_functions_t audio_out_mpegpes; extern ao_functions_t audio_out_pss; @@ -68,9 +65,6 @@ #endif #ifdef HAVE_SDL &audio_out_sdl, -#endif -#ifdef HAVE_DXR3 - &audio_out_dxr3, #endif &audio_out_pcm, &audio_out_mpegpes, Index: libvo/vo_dxr3.c =================================================================== RCS file: /cvsroot/mplayer/main/libvo/vo_dxr3.c,v retrieving revision 1.28 diff -u -r1.28 vo_dxr3.c --- libvo/vo_dxr3.c 9 Jan 2002 16:20:41 -0000 1.28 +++ libvo/vo_dxr3.c 10 Jan 2002 12:59:30 -0000 @@ -1,59 +1,72 @@ /* * vo_dxr3.c - DXR3/H+ video out * - * Copyright (C) 2001 David Holm + * Copyright (C) 2002 David Holm * */ -#include "fastmemcpy.h" -#include -#include -#include -#include +/* ChangeLog added 2002-01-10 + * 2002-01-10: + * I rehauled the entire codebase. I have now changed to + * Kernighan & Ritchie codingstyle, please mail me if you + * find any inconcistencies. + */ + #include #include #include #include +#include +#include +#include +#include #include #include #include #include "config.h" +#include "fastmemcpy.h" + #include "video_out.h" #include "video_out_internal.h" +#include "../postproc/rgb2rgb.h" + #ifdef USE_MP1E #include "../libmp1e/libmp1e.h" #endif -#include "../postproc/rgb2rgb.h" #ifdef HAVE_MMX #include "mmx.h" #endif -#include "aspect.h" - LIBVO_EXTERN (dxr3) #ifdef USE_MP1E +/* libmp1e specific stuff */ rte_context *mp1e_context = NULL; rte_codec *mp1e_codec = NULL; rte_buffer mp1e_buffer; -#endif +/* Color buffer data used with libmp1e */ static unsigned char *picture_data[3]; static unsigned int picture_linesize[3]; +#endif -static int v_width,v_height; -static int s_width,s_height; -static int s_pos_x,s_pos_y; -static int d_pos_x,d_pos_y; -static int osd_w,osd_h; +/* Resolutions and positions */ +static int v_width, v_height; +static int s_width, s_height; +static int s_pos_x, s_pos_y; +static int d_pos_x, d_pos_y; +static int osd_w, osd_h; static int img_format = 0; +/* File descriptors */ static int fd_control = -1; static int fd_video = -1; static int fd_spu = -1; + +/* Static variable used in ioctl's */ static int ioval = 0; static vo_info_t vo_info = @@ -65,363 +78,397 @@ }; #ifdef USE_MP1E -void write_dxr3( rte_context* context, void* data, size_t size, void* user_data ) +void write_dxr3(rte_context* context, void* data, size_t size, void* user_data) { - size_t data_left = size; - if(ioctl(fd_video,EM8300_IOCTL_VIDEO_SETPTS,&vo_pts) < 0) - printf( "VO: [dxr3] Unable to set pts\n" ); - while( data_left ) - data_left -= write( fd_video, (void*) data+(size-data_left), data_left ); + size_t data_left = size; + /* Set the timestamp of the next video packet */ + if (ioctl(fd_video, EM8300_IOCTL_VIDEO_SETPTS, &vo_pts) < 0) + printf("VO: [dxr3] Unable to set pts\n"); + + /* Write the entire video packet */ + while (data_left) + data_left -= write(fd_video, (void*) data + (size - data_left), data_left); } #endif static uint32_t init(uint32_t scr_width, uint32_t scr_height, uint32_t width, uint32_t height, uint32_t fullscreen, char *title, uint32_t format) { - int tmp1,tmp2; - - fd_control = open( "/dev/em8300", O_WRONLY ); - if( fd_control < 1 ) - { - printf( "VO: [dxr3] Error opening /dev/em8300 for writing!\n" ); - return -1; - } - fd_video = open( "/dev/em8300_mv", O_WRONLY ); - if( fd_video < 0 ) - { - printf( "VO: [dxr3] Error opening /dev/em8300_mv for writing!\n" ); - return -1; - } - else printf( "VO: [dxr3] Opened /dev/em8300_mv\n" ); - fd_spu = open( "/dev/em8300_sp", O_WRONLY ); - if( fd_spu < 0 ) - { - printf( "VO: [dxr3] Error opening /dev/em8300_sp for writing!\n" ); - return -1; - } - - /* Subpic code isn't working yet, don't set to ON - unless you are really sure what you are doing */ - ioval = EM8300_SPUMODE_OFF; - if( ioctl( fd_control, EM8300_IOCTL_SET_SPUMODE, &ioval ) < 0 ) - { - printf( "VO: [dxr3] Unable to set subpicture mode!\n" ); - return -1; - } - - ioval = EM8300_PLAYMODE_PLAY; - if( ioctl( fd_control, EM8300_IOCTL_SET_PLAYMODE, &ioval ) < 0 ) - printf( "VO: [dxr3] Unable to set playmode!\n" ); - - img_format = format; - v_width = scr_width; - v_height = scr_height; - - s_width = (v_width+15)/16; s_width*=16; - s_height = (v_height+15)/16; s_height*=16; - - /* Try to figure out whether to use ws output or not */ - tmp1 = abs(height - ((width/4)*3)); - tmp2 = abs(height - (int)(width/2.35)); - if(tmp1 < tmp2) - { - tmp1 = EM8300_ASPECTRATIO_4_3; - printf( "VO: [dxr3] Setting aspect ratio to 4:3\n" ); - } - else - { - tmp1 = EM8300_ASPECTRATIO_16_9; - printf( "VO: [dxr3] Setting aspect ratio to 16:9\n" ); - } - ioctl(fd_control,EM8300_IOCTL_SET_ASPECTRATIO,&tmp1); - close(fd_control); - - if( format == IMGFMT_YV12 || format == IMGFMT_YUY2 || format == IMGFMT_BGR24 ) - { -#ifdef USE_MP1E - int size; - enum rte_frame_rate frame_rate; - enum rte_pixformat pixel_format; - - if( !rte_init() ) - { - printf( "VO: [dxr3] Unable to initialize MP1E!\n" ); - return -1; - } - - mp1e_context = rte_context_new( s_width, s_height, NULL ); - rte_set_verbosity( mp1e_context, 0 ); + int tmp1,tmp2; + char devname[80]; - printf( "VO: [dxr3] %dx%d => %dx%d\n", v_width, v_height, s_width, s_height ); - - if( !mp1e_context ) - { - printf( "VO: [dxr3] Unable to create context!\n" ); - return -1; - } - - if( !rte_set_format( mp1e_context, "mpeg1" ) ) - { - printf( "VO: [dxr3] Unable to set format\n" ); - return -1; + /* Open the control interface */ + if (vo_subdevice) + sprintf(devname, "/dev/em8300-%s", vo_subdevice); + else + sprintf(devname, "/dev/em8300"); + fd_control = open(devname, O_WRONLY); + if (fd_control < 1) { + printf("VO: [dxr3] Error opening %s for writing!\n", devname); + return -1; } - rte_set_mode( mp1e_context, RTE_VIDEO ); - mp1e_codec = rte_codec_set( mp1e_context, RTE_STREAM_VIDEO, 0, "mpeg1-video" ); - - if( vo_fps < 24.0 ) frame_rate = RTE_RATE_1; - else if( vo_fps < 25.0 ) frame_rate = RTE_RATE_2; - else if( vo_fps < 29.97 ) frame_rate = RTE_RATE_3; - else if( vo_fps < 30.0 ) frame_rate = RTE_RATE_4; - else if( vo_fps < 50.0 ) frame_rate = RTE_RATE_5; - else if( vo_fps < 59.97 ) frame_rate = RTE_RATE_6; - else if( vo_fps < 60.0 ) frame_rate = RTE_RATE_7; - else if( vo_fps > 60.0 ) frame_rate = RTE_RATE_8; - else frame_rate = RTE_RATE_NORATE; - - if( format == IMGFMT_YUY2 ) - pixel_format = RTE_YUYV; + /* Open the video packet interface */ + if (vo_subdevice) + sprintf(devname, "/dev/em8300_mv-%s", vo_subdevice); else - pixel_format = RTE_YUV420; - if( !rte_set_video_parameters( mp1e_context, pixel_format, mp1e_context->width, - mp1e_context->height, frame_rate, - 3e6, "I" ) ) - { - printf( "VO: [dxr3] Unable to set mp1e context!\n" ); - rte_context_destroy( mp1e_context ); - return -1; + sprintf(devname, "/dev/em8300_mv"); + fd_video = open(devname, O_WRONLY); + if (fd_video < 0) { + printf("VO: [dxr3] Error opening %s for writing!\n", devname); + uninit(); + return -1; + } else + printf("VO: [dxr3] Opened %s\n", devname); + + /* Open the subpicture packet interface */ + if (vo_subdevice) + sprintf(devname, "/dev/em8300_sp-%s", vo_subdevice); + else + sprintf(devname, "/dev/em8300_sp"); + fd_spu = open(devname, O_WRONLY); + if (fd_spu < 0) { + printf("VO: [dxr3] Error opening %s for writing!\n", devname); + uninit(); + return -1; } - - rte_set_input( mp1e_context, RTE_VIDEO, RTE_PUSH, TRUE, NULL, NULL, NULL ); - rte_set_output( mp1e_context, (void*)write_dxr3, NULL, NULL ); - - if( !rte_init_context( mp1e_context ) ) - { - printf( "VO: [dxr3] Unable to init mp1e context!\n" ); - rte_context_delete( mp1e_context ); - return -1; + + /* Subpic code isn't working yet, don't set to ON + * unless you are really sure what you are doing + */ + ioval = EM8300_SPUMODE_OFF; + if (ioctl(fd_control, EM8300_IOCTL_SET_SPUMODE, &ioval) < 0) { + printf("VO: [dxr3] Unable to set subpicture mode!\n"); + uninit(); + return -1; } - osd_w=s_width; - d_pos_x=(s_width-v_width)/2; - if(d_pos_x<0) - { - s_pos_x=-d_pos_x;d_pos_x=0; - osd_w=s_width; - } else s_pos_x=0; + /* Set the playmode to play (just in case another app has set it to something else) */ + ioval = EM8300_PLAYMODE_PLAY; + if (ioctl(fd_control, EM8300_IOCTL_SET_PLAYMODE, &ioval) < 0) + printf("VO: [dxr3] Unable to set playmode!\n"); - osd_h=s_height; - d_pos_y=(s_height-v_height)/2; - if(d_pos_y<0) - { - s_pos_y=-d_pos_y;d_pos_y=0; - osd_h=s_height; - } else s_pos_y=0; + img_format = format; + v_width = scr_width; + v_height = scr_height; + + /* libmp1e requires a width and height that is x|16 */ + s_width = (v_width + 15) / 16; + s_width *= 16; + s_height = (v_height + 15) / 16; + s_height *= 16; - printf("VO: [dxr3] Position mapping: %d;%d => %d;%d\n",s_pos_x,s_pos_y,d_pos_x,d_pos_y); - - size = s_width*s_height; - - if( format == IMGFMT_YUY2 ) - { - picture_data[0] = NULL; - picture_linesize[0] = s_width * 2; - } - else - { - picture_data[0] = malloc((size * 3)/2); - picture_data[1] = picture_data[0] + size; - picture_data[2] = picture_data[1] + size / 4; - picture_linesize[0] = s_width; - picture_linesize[1] = s_width / 2; - picture_linesize[2] = s_width / 2; + /* Try to figure out whether to use widescreen output or not */ + tmp1 = abs(height - ((width / 4) * 3)); + tmp2 = abs(height - (int) (width / 2.35)); + if (tmp1 < tmp2) { + ioval = EM8300_ASPECTRATIO_4_3; + printf("VO: [dxr3] Setting aspect ratio to 4:3\n"); + } else { + ioval = EM8300_ASPECTRATIO_16_9; + printf("VO: [dxr3] Setting aspect ratio to 16:9\n"); } + ioctl(fd_control, EM8300_IOCTL_SET_ASPECTRATIO, &ioval); + close(fd_control); + + if (format == IMGFMT_YV12 || format == IMGFMT_YUY2 || format == IMGFMT_BGR24) { +#ifdef USE_MP1E + int size; + enum rte_frame_rate frame_rate; + enum rte_pixformat pixel_format; + + /* Here follows initialization of libmp1e specific stuff */ + if (!rte_init()) { + printf("VO: [dxr3] Unable to initialize MP1E!\n"); + uninit(); + return -1; + } + + mp1e_context = rte_context_new(s_width, s_height, NULL); + rte_set_verbosity(mp1e_context, 0); + + printf("VO: [dxr3] %dx%d => %dx%d\n", v_width, v_height, s_width, s_height); + + if (!mp1e_context) { + printf( "VO: [dxr3] Unable to create context!\n" ); + uninit(); + return -1; + } + + if (!rte_set_format(mp1e_context, "mpeg1")) { + printf("VO: [dxr3] Unable to set format\n"); + uninit(); + return -1; + } + + rte_set_mode(mp1e_context, RTE_VIDEO); + mp1e_codec = rte_codec_set(mp1e_context, RTE_STREAM_VIDEO, 0, "mpeg1-video"); + + if (vo_fps < 24.0) + frame_rate = RTE_RATE_1; + else if (vo_fps < 25.0) + frame_rate = RTE_RATE_2; + else if (vo_fps < 29.97) + frame_rate = RTE_RATE_3; + else if (vo_fps < 30.0) + frame_rate = RTE_RATE_4; + else if (vo_fps < 50.0) + frame_rate = RTE_RATE_5; + else if (vo_fps < 59.97) + frame_rate = RTE_RATE_6; + else if (vo_fps < 60.0) + frame_rate = RTE_RATE_7; + else if (vo_fps > 60.0) + frame_rate = RTE_RATE_8; + else + frame_rate = RTE_RATE_NORATE; + + if (format == IMGFMT_YUY2) + pixel_format = RTE_YUYV; + else + pixel_format = RTE_YUV420; + if (!rte_set_video_parameters(mp1e_context, pixel_format, mp1e_context->width, mp1e_context->height, frame_rate, 3e6, "I")) { + printf("VO: [dxr3] Unable to set mp1e context!\n"); + rte_context_destroy(mp1e_context); + mp1e_context = 0; + uninit(); + return -1; + } + + rte_set_input(mp1e_context, RTE_VIDEO, RTE_PUSH, TRUE, NULL, NULL, NULL); + rte_set_output(mp1e_context, (void*) write_dxr3, NULL, NULL); + + if (!rte_init_context(mp1e_context)) { + printf("VO: [dxr3] Unable to init mp1e context!\n"); + uninit(); + return -1; + } + + /* This stuff calculations the relative position of video and osd on screen */ + osd_w=s_width; + d_pos_x=(s_width-v_width)/2; + if (d_pos_x < 0) { + s_pos_x = -d_pos_x; + d_pos_x = 0; + osd_w = s_width; + } else + s_pos_x = 0; + + osd_h = s_height; + d_pos_y = (s_height-v_height)/2; + if (d_pos_y < 0) { + s_pos_y =- d_pos_y; + d_pos_y = 0; + osd_h = s_height; + } else + s_pos_y = 0; + + printf("VO: [dxr3] Position mapping: %d;%d => %d;%d\n", s_pos_x, s_pos_y, d_pos_x, d_pos_y); + + size = s_width * s_height; - - if( !rte_start_encoding( mp1e_context ) ) - { - printf( "VO: [dxr3] Unable to start mp1e encoding!\n" ); - uninit(); - return -1; + if (format == IMGFMT_YUY2) { + picture_data[0] = NULL; + picture_linesize[0] = s_width * 2; + } else { + picture_data[0] = malloc((size * 3)/2); + picture_data[1] = picture_data[0] + size; + picture_data[2] = picture_data[1] + size / 4; + picture_linesize[0] = s_width; + picture_linesize[1] = s_width / 2; + picture_linesize[2] = s_width / 2; + } + + + if(!rte_start_encoding(mp1e_context)) { + printf("VO: [dxr3] Unable to start mp1e encoding!\n"); + uninit(); + return -1; + } + + if(format == IMGFMT_BGR24) + yuv2rgb_init(24, MODE_BGR); + return 0; +#endif + return -1; + } else if (format == IMGFMT_MPEGPES) { + printf("VO: [dxr3] Format: MPEG-PES (no conversion needed)\n"); + return 0; } - if(format == IMGFMT_BGR24) yuv2rgb_init(24, MODE_BGR); - return 0; -#endif + printf("VO: [dxr3] Format: Unsupported\n"); + uninit(); return -1; - } - else if(format==IMGFMT_MPEGPES) - { - printf( "VO: [dxr3] Format: MPEG-PES (no conversion needed)\n" ); - return 0; - } - - printf( "VO: [dxr3] Format: Unsupported\n" ); - return -1; } static const vo_info_t* get_info(void) { - return &vo_info; + return &vo_info; } static void draw_alpha(int x0, int y0, int w, int h, unsigned char* src, unsigned char *srca, int srcstride) { - switch(img_format) - { - case IMGFMT_BGR24: - case IMGFMT_YV12: - vo_draw_alpha_yv12(w,h,src,srca,srcstride,picture_data[0]+(x0+d_pos_x)+(y0+d_pos_y)*picture_linesize[0],picture_linesize[0]); - break; - case IMGFMT_YUY2: - vo_draw_alpha_yuy2(w,h,src,srca,srcstride,picture_data[0]+(x0+d_pos_x)*2+(y0+d_pos_y)*picture_linesize[0],picture_linesize[0]); - break; - } + /* This function draws the osd and subtitles etc. It will change to use spuenc soon */ + switch (img_format) { + case IMGFMT_BGR24: + case IMGFMT_YV12: + vo_draw_alpha_yv12(w, h, src, srca, srcstride, + picture_data[0] + (x0 + d_pos_x) + (y0 + d_pos_y) * picture_linesize[0], picture_linesize[0]); + break; + case IMGFMT_YUY2: + vo_draw_alpha_yuy2(w, h, src, srca, srcstride, + picture_data[0] + (x0 + d_pos_x) * 2 + (y0 + d_pos_y) * picture_linesize[0], picture_linesize[0]); + break; + } } static void draw_osd(void) { - vo_draw_text(osd_w,osd_h,draw_alpha); + vo_draw_text(osd_w, osd_h, draw_alpha); } static uint32_t draw_frame(uint8_t * src[]) { - if( img_format == IMGFMT_MPEGPES ) - { - vo_mpegpes_t *p=(vo_mpegpes_t *)src[0]; - size_t data_left = p->size; - - if(ioctl(fd_video,EM8300_IOCTL_VIDEO_SETPTS,&p->timestamp) < 0) - printf( "VO: [dxr3] Unable to set pts\n" ); - - while( data_left ) - data_left -= write( fd_video, (void*) p->data+(p->size-data_left), data_left ); - - return 0; - } + if (img_format == IMGFMT_MPEGPES) { + vo_mpegpes_t *p = (vo_mpegpes_t *) src[0]; + size_t data_left = p->size; + + if (ioctl(fd_video, EM8300_IOCTL_VIDEO_SETPTS, &vo_pts) < 0) + printf("VO: [dxr3] Unable to set pts\n"); + + while (data_left) + data_left -= write(fd_video, (void*) (p->data + p->size-data_left), data_left); + return 0; + } #ifdef USE_MP1E - else if( img_format == IMGFMT_YUY2 ) - { - picture_data[0] = src[0]; - return 0; - } - else if( img_format == IMGFMT_BGR24 ) - { - int x,y,w=v_width,h=v_height; - unsigned char *s,*dY,*dU,*dV; - - if(d_pos_x+w>picture_linesize[0]) w=picture_linesize[0]-d_pos_x; - if(d_pos_y+h>s_height) h=s_height-d_pos_y; - - s = src[0]+s_pos_y*(w*3); - - dY = picture_data[0]+d_pos_y*picture_linesize[0]; - dU = picture_data[1]+(d_pos_y/2)*picture_linesize[1]; - dV = picture_data[2]+(d_pos_y/2)*picture_linesize[2]; - - rgb24toyv12(s,dY,dU,dV,w,h,picture_linesize[0],picture_linesize[1],v_width*3); - - mp1e_buffer.data = picture_data[0]; - mp1e_buffer.time = vo_pts/90000.0; - mp1e_buffer.user_data = NULL; - vo_draw_text(osd_w,osd_h,draw_alpha); - rte_push_video_buffer( mp1e_context, &mp1e_buffer ); - - return 0; - } + else if (img_format == IMGFMT_YUY2) { + picture_data[0] = src[0]; + return 0; + } else if (img_format == IMGFMT_BGR24) { + /* BGR24 needs to be converted to YUV420 before libmp1e will touch it */ + int x, y, w = v_width, h = v_height; + unsigned char *s,*dY,*dU,*dV; + + if (d_pos_x+w>picture_linesize[0]) + w = picture_linesize[0] - d_pos_x; + if (d_pos_y+h>s_height) + h = s_height - d_pos_y; + + s = src[0] + s_pos_y * (w * 3); + + dY = picture_data[0] + d_pos_y * picture_linesize[0]; + dU = picture_data[1] + (d_pos_y / 2) * picture_linesize[1]; + dV = picture_data[2] + (d_pos_y / 2) * picture_linesize[2]; + + rgb24toyv12(s, dY, dU, dV, w, h, picture_linesize[0], picture_linesize[1], v_width * 3); + + mp1e_buffer.data = picture_data[0]; + mp1e_buffer.time = vo_pts / 90000.0; + mp1e_buffer.user_data = NULL; + vo_draw_text(osd_w, osd_h, draw_alpha); + rte_push_video_buffer(mp1e_context, &mp1e_buffer); + return 0; + } #endif - return -1; + return -1; } -static void flip_page (void) +static void flip_page(void) { #ifdef USE_MP1E - if( img_format == IMGFMT_YV12 ) - { - mp1e_buffer.data = picture_data[0]; - mp1e_buffer.time = vo_pts/90000.0; - mp1e_buffer.user_data = NULL; - rte_push_video_buffer( mp1e_context, &mp1e_buffer ); - } - else if( img_format == IMGFMT_YUY2 ) - { - mp1e_buffer.data = picture_data[0]; - mp1e_buffer.time = vo_pts/90000.0; - mp1e_buffer.user_data = NULL; - rte_push_video_buffer( mp1e_context, &mp1e_buffer ); - } + if (img_format == IMGFMT_YV12) { + mp1e_buffer.data = picture_data[0]; + mp1e_buffer.time = vo_pts / 90000.0; + mp1e_buffer.user_data = NULL; + rte_push_video_buffer(mp1e_context, &mp1e_buffer); + } else if (img_format == IMGFMT_YUY2) { + mp1e_buffer.data = picture_data[0]; + mp1e_buffer.time = vo_pts / 90000.0; + mp1e_buffer.user_data = NULL; + rte_push_video_buffer(mp1e_context, &mp1e_buffer); + } #endif } -static uint32_t draw_slice( uint8_t *srcimg[], int stride[], int w, int h, int x0, int y0 ) +static uint32_t draw_slice(uint8_t *srcimg[], int stride[], int w, int h, int x0, int y0) { - if( img_format == IMGFMT_YV12 ) - { - int y; - unsigned char *s,*s1; - unsigned char *d,*d1; - - x0+=d_pos_x; - y0+=d_pos_y; - - if(x0+w>picture_linesize[0]) w=picture_linesize[0]-x0; - if(y0+h>s_height) h=s_height-y0; - - s=srcimg[0]+s_pos_x+s_pos_y*stride[0]; - d=picture_data[0]+x0+y0*picture_linesize[0]; - for(y=0;y picture_linesize[0]) + w = picture_linesize[0]-x0; + if ((y0 + h) > s_height) + h = s_height-y0; + + s = srcimg[0] + s_pos_x + s_pos_y * stride[0]; + d = picture_data[0] + x0 + y0 * picture_linesize[0]; + for(y = 0; y < h; y++) { + memcpy(d, s, w); + s += stride[0]; + d += picture_linesize[0]; + } + + w /= 2; + h /= 2; + x0 /= 2; + y0 /= 2; + + s = srcimg[1] + s_pos_x + (s_pos_y * stride[1]); + d = picture_data[1] + x0 + (y0 * picture_linesize[1]); + s1 = srcimg[2] + s_pos_x + (s_pos_y * stride[2]); + d1 = picture_data[2] + x0 + (y0 * picture_linesize[2]); + for(y = 0; y < h; y++) { + memcpy(d, s, w); + memcpy(d1, s1, w); + s += stride[1]; + s1 += stride[2]; + d += picture_linesize[1]; + d1 += picture_linesize[2]; + } + return 0; } - - return 0; - } - - return -1; + return -1; } - -static uint32_t -query_format(uint32_t format) +static uint32_t query_format(uint32_t format) { - uint32_t flag = 0; - if(format==IMGFMT_MPEGPES) flag = 0x2|0x4; + uint32_t flag = 0; + + if (format == IMGFMT_MPEGPES) + flag = 0x2 | 0x4; #ifdef USE_MP1E - if(format==IMGFMT_YV12) flag = 0x1|0x4; - if(format==IMGFMT_YUY2) flag = 0x1|0x4; - if(format==IMGFMT_BGR24) flag = 0x1|0x4; - else printf( "VO: [dxr3] Format unsupported, mail dholm@iname.com\n" ); + if (format == IMGFMT_YV12) + flag = 0x1 | 0x4; + if (format == IMGFMT_YUY2) + flag = 0x1 | 0x4; + if (format == IMGFMT_BGR24) + flag = 0x1 | 0x4; + else + printf("VO: [dxr3] Format unsupported, mail dholm@iname.com\n"); #else - else printf( "VO: [dxr3] You have disabled libmp1e support, you won't be able to play this format!\n" ); + else + printf("VO: [dxr3] You have disabled libmp1e support, you won't be able to play this format!\n"); #endif - return flag; + return flag; } static void uninit(void) { - printf( "VO: [dxr3] Uninitializing\n" ); - if( picture_data[0] ) free(picture_data[0]); - if( fd_video ) close(fd_video); - if( fd_spu ) close(fd_spu); + printf("VO: [dxr3] Uninitializing\n"); + if (mp1e_context) + rte_context_delete(mp1e_context); + if (picture_data[0]) + free(picture_data[0]); + if (fd_video) + close(fd_video); + if(fd_spu) + close(fd_spu); } - static void check_events(void) { } -