Hi,

after same experiments with an ivtvfb plugin for xine using the osd (fb) of the PVR 350, I found out, that it is nearly impossible to get an well working plugin. The main problem is to get writing into the framebuffer in sync with the drawing on tv.

My goal is to get the video out of the PVR 350 working (the tv out quality is really great) without X and also to use xine(fb), because of the dvd menus.

So last weekend I had the idea to implement vidixfb support for the PVR 350 based on the YUV cappability of the MPEG decoder. Now it is ready .

Attached you will find two patches for:
1) xine-ui-0.99.5 to improve usability of xinefb and
2) xine-lib-1.1.6. to get vidixfb ivtv support for xine.

I have tested the stuff with ivtv-0.10.1 driver and PAL.
Currently I don't now, if the plugin is also working with NTSC. Please test and let me know.

Here some technical details:
How to patch:
cd xine-ui-0.99.5
patch -p1 < "PATHTO"/xine-ui-0.99.5-vidix-ivtv.patch
cd xine-lib-1.1.6
patch -p 1 < "PATHTO"/xine-lib-1.1.6-vidix-ivtv.patch

How to set up your environment:
export FRAMEBUFFER=/dev/fb? (? stands for the framebuffer device you want to use) fbset -fb /dev/fb? -g 720 576 720 576 32 -t 42158 1 55 1 14 24 2 -rgba 8/16,8/8,8/0,8/24 (set console to max resolution (PAL))
ivtvfbctl -d /dev/fb? -v 0 ("disable" alpha blending)

Now start xinefb and have fun:
fbxine --stdctl -A alsa -V vidixfb dvd://

It would be great if someone can test the stuff and let me know if it is working correctly. If so I will commit the patches to the xine and vidix project directly.

Best regards
Lutz
diff -Nuri xine-lib-1.1.6/src/video_out/video_out_vidix.c 
xine-lib-1.1.6.ivtv.patch/src/video_out/video_out_vidix.c
--- xine-lib-1.1.6/src/video_out/video_out_vidix.c      2007-04-15 
19:42:17.000000000 +0200
+++ xine-lib-1.1.6.ivtv.patch/src/video_out/video_out_vidix.c   2007-05-09 
00:09:19.314774506 +0200
@@ -1091,7 +1091,7 @@
     free(this);
     return NULL;
   }
-  this->vidix_handler = vdlOpen((XINE_PLUGINDIR"/vidix/"), NULL, TYPE_OUTPUT, 
0);
+  this->vidix_handler = vdlOpen((XINE_PLUGINDIR"/vidix/"), NULL, TYPE_OUTPUT, 
xine->verbosity);
   if(this->vidix_handler == NULL)
   {
     xprintf(xine, XINE_VERBOSITY_LOG,
@@ -1231,11 +1231,18 @@
   char                     *device;
   int                       fd;
   struct fb_var_screeninfo  fb_var;
+  char                      fb_dev_name[] = "/dev/fb0\0";
+  char                      *device_name = NULL;
+ 
+  device_name = getenv("FRAMEBUFFER");
+  if(NULL == device_name) {
+    device_name = fb_dev_name;
+  }
     
   this->visual_type = XINE_VISUAL_TYPE_FB;
   
   /* Register config option for fb device */
-  device = config->register_filename(config, "video.device.vidixfb_device", 
"/dev/fb0", XINE_CONFIG_STRING_IS_DEVICE_NAME,
+  device = config->register_filename(config, "video.device.vidixfb_device", 
device_name, XINE_CONFIG_STRING_IS_DEVICE_NAME,
     _("framebuffer device name"),
     _("Specifies the file name for the framebuffer device to be used.\n"
       "This setting is security critical, because when changed to a different 
file, xine "
@@ -1244,7 +1251,7 @@
     XINE_CONFIG_SECURITY, NULL, NULL);
   
   /* Open fb device for reading */
-  if((fd = open("/dev/fb0", O_RDONLY)) < 0) {
+  if((fd = open(device_name, O_RDONLY)) < 0) {
     xprintf(this->xine, XINE_VERBOSITY_DEBUG, 
            "video_out_vidix: unable to open frame buffer device \"%s\": %s\n", 
device, strerror(errno));
     return NULL;
diff -Nuri xine-lib-1.1.6/src/video_out/vidix/drivers/Makefile.am 
xine-lib-1.1.6.ivtv.patch/src/video_out/vidix/drivers/Makefile.am
--- xine-lib-1.1.6/src/video_out/vidix/drivers/Makefile.am      2007-04-17 
03:00:50.000000000 +0200
+++ xine-lib-1.1.6.ivtv.patch/src/video_out/vidix/drivers/Makefile.am   
2007-05-09 00:03:26.859457799 +0200
@@ -15,7 +15,8 @@
        unichrome_vid.la \
        nvidia_vid.la \
        sis_vid.la \
-       savage_vid.la 
+       savage_vid.la \
+       ivtvfb_vid.la
 endif
 
 vidix_LTLIBRARIES = $(vidix_drivers)
@@ -58,6 +59,9 @@
 savage_vid_la_SOURCES = savage_vid.c
 savage_vid_la_LDFLAGS = -avoid-version -module -lm
 
+ivtvfb_vid_la_SOURCES = ivtvfb_vid.c
+ivtvfb_vid_la_LDFLAGS = -avoid-version -module
+
 noinst_HEADERS = mach64.h glint_regs.h pm3_regs.h radeon.h savage_regs.h \
        cyberblade_regs.h unichrome_regs.h sis_defs.h sis_regs.h
 
diff -Nuri xine-lib-1.1.6/src/video_out/vidix/drivers/ivtvfb_vid.c 
xine-lib-1.1.6.ivtv.patch/src/video_out/vidix/drivers/ivtvfb_vid.c
--- xine-lib-1.1.6/src/video_out/vidix/drivers/ivtvfb_vid.c     1970-01-01 
01:00:00.000000000 +0100
+++ xine-lib-1.1.6.ivtv.patch/src/video_out/vidix/drivers/ivtvfb_vid.c  
2007-05-09 01:02:18.852737113 +0200
@@ -0,0 +1,448 @@
+/**
+    VIDIX driver for Hauppauge PVR 350.
+
+    Copyright 2007 Lutz Koschorreck.
+
+    Based on genfb_vid.c and ivtv_xv.c
+
+    This program 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.
+
+    This program 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 this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+    09.05.2007 Lutz Koschorreck
+    First version: Tested with ivtv-0.10.1, xine-ui-0.99.5, xine-lib-1.1.6
+
+**/
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <math.h>
+#include <inttypes.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <linux/fb.h>
+#include <linux/ivtv.h>
+
+#include "../vidix.h"
+#include "../fourcc.h"
+#include "../../libdha/libdha.h"
+#include "../../libdha/pci_ids.h"
+#include "../../libdha/pci_names.h"
+
+#define VIDIX_STATIC ivtv_
+
+#define IVTV_MSG "[ivtv-vid] "
+#define MAXLINE 128
+#define IVTVMAXWIDTH 720
+#define IVTVMAXHEIGHT 576
+
+static int fbdev = 0;
+static int yuvdev = 0;
+static void *memBase = 0;
+static int frameSize = 0;
+static int probed = 0;
+static int ivtv_verbose;
+static vidix_rect_t destVideo;
+static vidix_rect_t srcVideo;
+static unsigned char *outbuf = NULL;
+
+/* VIDIX exports */
+
+static vidix_capability_t genfb_cap =
+{
+       "Hauppauge PVR 350 YUV Video",
+       "Lutz Koschorreck",
+       TYPE_OUTPUT,
+       { 0, 0, 0, 0 },
+       IVTVMAXHEIGHT,
+       IVTVMAXWIDTH,
+       4,
+       4,
+       -1,
+       FLAG_UPSCALER|FLAG_DOWNSCALER,
+       -1,
+       -1,
+       { 0, 0, 0, 0 }
+};
+
+static void de_macro_y(unsigned char *src, unsigned char *dst,
+                      int w, int h, int src_x, int src_y, int height, int 
width)
+{
+       unsigned int x, y, i;
+       unsigned char *dst_2;
+       unsigned int h_tail, w_tail;
+       unsigned int h_size, w_size;
+
+       // Always round the origin, but compensate by increasing the size
+       if (src_x & 15) {
+               w += src_x & 15;
+               src_x &= ~15;
+       }
+
+       if (src_y & 15) {
+               h += src_y & 15;
+               src_y &= ~15;
+       }
+
+       // The right / bottom edge might not be a multiple of 16
+       h_tail = h & 15;
+       w_tail = w & 15;
+
+       // One block is 16 pixels high
+       h_size = 16;
+
+       // descramble Y plane
+       for (y = 0; y < h; y += 16) {
+
+               // Clip if we've reached the bottom & the size isn't a multiple 
of 16
+               if (y + 16 > h) h_size = h_tail;
+
+               for (x = 0; x < w; x += 16) {
+                       if (x + 16 > w)
+                               w_size = w_tail;
+                       else
+                               w_size = 16;
+
+                       dst_2 = dst + (720 * y) + (720 * src_y) + (256 * 
(src_x>>4)) + (x * 16);
+
+                       for (i = 0; i < h_size; i++) {
+                               memcpy(dst_2, src + src_x + x + (y + i) * width 
+ (src_y * width), w_size);
+                               dst_2 += 16;
+                       }
+               }
+       }
+}
+
+static void de_macro_uv(unsigned char *srcu, unsigned char *srcv,
+                       unsigned char *dst, int w, int h, int src_x, int src_y,
+                      int height, int width)
+{
+       unsigned int x, y, i, f;
+       unsigned char *dst_2;
+       unsigned int h_tail, w_tail;
+       unsigned int h_size;
+
+       // The uv plane is half the size of the y plane, so 'correct' all 
dimensions.
+       w /= 2;
+       h /= 2;
+       src_x /= 2;
+       src_y /= 2;
+       height /= 2;
+       width /= 2;
+
+       // Always round the origin, but compensate by increasing the size
+       if (src_x & 7) {
+               w += src_x & 7;
+               src_x &= ~7;
+       }
+
+       if (src_y & 15) {
+               h += src_y & 15;
+               src_y &= ~15;
+       }
+
+       // The right / bottom edge may not be a multiple of 16
+       h_tail = h & 15;
+       w_tail = w & 7;
+
+       h_size = 16;
+
+       // descramble U/V plane
+       for (y = 0; y < h; y += 16) {
+               if ( y + 16 > h ) h_size = h_tail;
+               for (x = 0; x < w; x += 8) {
+                       dst_2 = dst + (720 * y) + (720 * src_y) + (256 * 
(src_x>>3)) + (x * 32);
+                       if (x + 8 <= w) {
+                               for (i = 0; i < h_size; i++) {
+                                       int idx = src_x + x + ((y + i) * width) 
+ (src_y * width);
+                                       dst_2[0] = srcu[idx + 0];
+                                       dst_2[1] = srcv[idx + 0];
+                                       dst_2[2] = srcu[idx + 1];
+                                       dst_2[3] = srcv[idx + 1];
+                                       dst_2[4] = srcu[idx + 2];
+                                       dst_2[5] = srcv[idx + 2];
+                                       dst_2[6] = srcu[idx + 3];
+                                       dst_2[7] = srcv[idx + 3];
+                                       dst_2[8] = srcu[idx + 4];
+                                       dst_2[9] = srcv[idx + 4];
+                                       dst_2[10] = srcu[idx + 5];
+                                       dst_2[11] = srcv[idx + 5];
+                                       dst_2[12] = srcu[idx + 6];
+                                       dst_2[13] = srcv[idx + 6];
+                                       dst_2[14] = srcu[idx + 7];
+                                       dst_2[15] = srcv[idx + 7];
+                                       dst_2 += 16;
+                               }
+                       }
+                       else {
+                               for (i = 0; i < h_size; i ++) {
+                                       int idx = src_x + x + ((y + i) * width) 
+ (src_y * width);
+                                       for (f = 0; f < w_tail; f++) {
+                                               dst_2[0] = srcu[idx + f];
+                                               dst_2[1] = srcv[idx + f];
+                                               dst_2 += 2;
+                                       }
+/*
+                                       // Used for testing edge cutoff. Sets 
colour to Green
+                                       for (f = w_tail;f < 8;f ++) {
+                                               dst_2[0] = 0;
+                                               dst_2[1] = 0;
+                                               dst_2 += 2;
+                                       }
+*/
+                                       dst_2 += 16 - (w_tail << 1);
+                               }
+                       }
+               }
+       }
+}
+unsigned int VIDIX_NAME(vixGetVersion)(void)
+{
+       return(VIDIX_VERSION);
+}
+
+int VIDIX_NAME(vixProbe)(int verbose,int force)
+{
+       pciinfo_t lst[MAX_PCI_DEVICES];
+       unsigned int i, num_pci;
+       int err;
+       FILE *procFb;
+       unsigned char fb_number = 0;
+
+       if(verbose)
+               printf(IVTV_MSG"probe\n");
+
+       ivtv_verbose = verbose;
+
+       err = pci_scan(lst, &num_pci);
+       if(err) {
+               printf(IVTV_MSG"Error occured during pci scan: %s\n", 
strerror(err));
+               return err;
+       }
+
+       if(ivtv_verbose)
+               printf(IVTV_MSG"Found %d pci devices\n", num_pci);
+
+       for(i = 0; i < num_pci; i++) {
+               if(2 == ivtv_verbose)
+                       printf(IVTV_MSG"Found chip [%04X:%04X] '%s' '%s'\n"
+                               ,lst[i].vendor
+                               ,lst[i].device
+                               ,pci_vendor_name(lst[i].vendor)
+                               ,pci_device_name(lst[i].vendor,lst[i].device));
+               if(VENDOR_INTERNEXT == lst[i].vendor) {
+                       switch(lst[i].device)
+                       {
+                       case DEVICE_INTERNEXT_ITVC15_MPEG_2_ENCODER:
+                               if(ivtv_verbose)
+                                       printf(IVTV_MSG"Found PVR 350\n");
+                               goto card_found;
+                       }
+               }
+       }
+       
+       if(ivtv_verbose)
+               printf(IVTV_MSG"Can't find chip\n");
+       return(ENXIO);
+
+card_found:
+       
+       /* Try to find framebuffer device */
+       procFb = fopen("/proc/fb", "r");
+       if(procFb) {
+               char procEntry[MAXLINE] = {0};
+               while( NULL != fgets(procEntry, MAXLINE, procFb)) {
+                       if(ivtv_verbose)
+                               printf(IVTV_MSG" %s", procEntry);
+                       char *pos = NULL;
+                       if(NULL != (pos = strstr(procEntry, " cx23415 TV 
out"))) {
+                               *pos = '\0';
+                               fb_number = atoi(procEntry);
+                               if(ivtv_verbose)
+                                       printf(IVTV_MSG"Framebuffer found 
#%u\n", fb_number);
+                               goto fb_found;
+                       }
+               }
+       } else {
+               if(ivtv_verbose)
+                       printf(IVTV_MSG"Framebuffer device not found\n");
+               return(ENXIO);
+       }
+
+fb_found:
+       fclose(procFb);
+       
+       /* Try to find YUV device */
+       unsigned char yuv_device_number = 48, yuv_device = 48 + fb_number;
+       char yuv_device_name[] = "/dev/videoXXX\0";
+       
+       do {
+               sprintf(yuv_device_name, "/dev/video%u", yuv_device);
+               yuvdev = open(yuv_device_name, O_RDWR);
+               if(-1 != yuvdev) {
+                       if(ivtv_verbose)
+                               printf(IVTV_MSG"YUV device found 
/dev/video%u\n", yuv_device);
+                       goto yuv_found;
+               } else {
+                       if(ivtv_verbose)
+                               printf(IVTV_MSG"YUV device not found: 
/dev/video%u\n", yuv_device);
+               }
+       } while(yuv_device-- > yuv_device_number);
+       
+       return(ENXIO);
+
+yuv_found:
+       probed = 1;
+       return(0);
+}
+
+int VIDIX_NAME(vixInit)(const char *args)
+{
+       if(ivtv_verbose)
+               printf(IVTV_MSG"init\n");
+    
+       if (!probed) {
+               if(ivtv_verbose)
+                       printf(IVTV_MSG"Driver was not probed but is being 
initialized\n");
+               return(EINTR);
+       }
+       outbuf = malloc((IVTVMAXHEIGHT * IVTVMAXWIDTH) + (IVTVMAXHEIGHT * 
IVTVMAXWIDTH / 2));
+       if(NULL == outbuf) {
+               if(ivtv_verbose)
+                       printf(IVTV_MSG"Not enough memory availabe!\n");
+               return(EINTR);
+       }
+       
+       return(0);
+}
+
+void VIDIX_NAME(vixDestroy)(void)
+{
+       if(ivtv_verbose)
+               printf(IVTV_MSG"destory\n");
+       close(yuvdev);  
+       free(outbuf);
+}
+
+int VIDIX_NAME(vixGetCapability)(vidix_capability_t *to)
+{
+       if(ivtv_verbose)
+               printf(IVTV_MSG"GetCap\n");
+       memcpy(to, &genfb_cap, sizeof(vidix_capability_t));
+       return(0);
+}
+
+int VIDIX_NAME(vixQueryFourcc)(vidix_fourcc_t *to)
+{
+       if(ivtv_verbose)
+               printf(IVTV_MSG"query fourcc (%x)\n", to->fourcc);
+       
+       int supports = 0;
+       switch(to->fourcc)
+       {
+       case IMGFMT_YV12:
+               supports = 1;
+               break;
+       default:
+               supports = 0;
+       }
+       
+       if(!supports) {
+               to->depth = to->flags = 0;
+               return(ENOTSUP);
+       }
+       to->depth = VID_DEPTH_12BPP |
+               VID_DEPTH_15BPP | VID_DEPTH_16BPP |
+               VID_DEPTH_24BPP | VID_DEPTH_32BPP;
+       to->flags = 0;
+
+       return(0);
+}
+
+int VIDIX_NAME(vixConfigPlayback)(vidix_playback_t *info)
+{
+       if(ivtv_verbose)
+               printf(IVTV_MSG"config playback\n");
+
+       if(2 == ivtv_verbose){
+               printf(IVTV_MSG"src : x:%d y:%d w:%d h:%d\n", 
+                       info->src.x, info->src.y, info->src.w, info->src.h);
+               printf(IVTV_MSG"dest: x:%d y:%d w:%d h:%d\n", 
+                       info->dest.x, info->dest.y, info->dest.w, info->dest.h);
+       }
+       
+       memcpy(&destVideo, &info->dest, sizeof(vidix_rect_t));
+       memcpy(&srcVideo, &info->src, sizeof(vidix_rect_t));
+
+       info->num_frames = 2;
+       info->frame_size = frameSize = 
info->src.w*info->src.h+(info->src.w*info->src.h)/2;
+       info->dest.pitch.y = 16;
+       info->dest.pitch.u = info->dest.pitch.v = 16;
+       info->offsets[0] = 0;
+       info->offsets[1] = info->frame_size;
+       info->offset.y = 0;
+       info->offset.u = IVTVMAXWIDTH*IVTVMAXHEIGHT;
+       info->offset.v = IVTVMAXWIDTH*IVTVMAXHEIGHT + 
(IVTVMAXWIDTH/2)*(IVTVMAXHEIGHT/2);    
+       info->dga_addr = memBase = malloc(info->num_frames*info->frame_size);   
+       if(ivtv_verbose)
+           printf(IVTV_MSG"frame_size: %d, dga_addr: %p\n",
+       info->frame_size, info->dga_addr);
+       return(0);
+}
+
+int VIDIX_NAME(vixPlaybackOn)(void)
+{
+       if(ivtv_verbose)
+               printf(IVTV_MSG"playback on\n");
+       return(0);
+}
+
+int VIDIX_NAME(vixPlaybackOff)(void)
+{
+       if(ivtv_verbose)
+               printf(IVTV_MSG"playback off\n");
+       return(0);
+}
+
+int VIDIX_NAME(vixPlaybackFrameSelect)(unsigned int frame)
+{
+       struct ivtvyuv_ioctl_dma_host_to_ivtv_args args;
+
+       de_macro_y((memBase + (frame * frameSize)), outbuf, srcVideo.w, 
srcVideo.h, srcVideo.x, srcVideo.y, destVideo.h, destVideo.w);
+       de_macro_uv((memBase + (frame * frameSize)) + (srcVideo.w * srcVideo.h) 
+ srcVideo.w * srcVideo.h / 4,
+               (memBase + (frame * frameSize)) + (srcVideo.w * srcVideo.h), 
outbuf + IVTVMAXWIDTH * IVTVMAXHEIGHT,
+               srcVideo.w,  srcVideo.h, srcVideo.x, srcVideo.y, destVideo.h, 
destVideo.w);
+
+       args.y_source = outbuf;
+       args.uv_source = outbuf + (IVTVMAXWIDTH * IVTVMAXHEIGHT);
+       args.src_x = srcVideo.x;
+       args.src_y = srcVideo.y;
+        args.dst_x = destVideo.x;
+        args.dst_y = destVideo.y;
+       args.src_w = srcVideo.w;
+        args.dst_w = destVideo.w;
+        args.srcBuf_width = srcVideo.w;
+       args.src_h = srcVideo.h;
+        args.dst_h = destVideo.h;
+        args.srcBuf_height = srcVideo.h;
+       args.yuv_type = 0;
+       
+       if(ioctl(yuvdev, IVTV_IOC_PREP_FRAME_YUV, &args) == -1) {
+               printf("Ioctl IVTV_IOC_PREP_FRAME_YUV returned failed Error\n");
+       }
+       return(0);
+}
+
diff -Nuri xine-ui-0.99.5/src/fb/main.c xine-ui-0.99.5.ivtv.patch/src/fb/main.c
--- xine-ui-0.99.5/src/fb/main.c        2006-06-19 15:56:50.000000000 +0200
+++ xine-ui-0.99.5.ivtv.patch/src/fb/main.c     2007-05-09 01:00:08.550771535 
+0200
@@ -41,6 +41,7 @@
 
 struct fbxine fbxine =
 {
+       xine: NULL,
        tty_fd:        -1,
        video_port_id: "fb",
 
@@ -76,7 +77,7 @@
                        XINE_CONFIG_FILE);
        }
        xine_config_load(fbxine.xine, fbxine.configfile);
-        xine_engine_set_param(fbxine.xine, XINE_ENGINE_PARAM_VERBOSITY, 
fbxine.verbosity);
+       xine_engine_set_param(fbxine.xine, XINE_ENGINE_PARAM_VERBOSITY, 
fbxine.verbosity);
 }
 
 static int check_version(void)
@@ -141,6 +142,7 @@
            fbxine.video_port =
                xine_open_video_driver(fbxine.xine, fbxine.video_port_id,
                                       XINE_VISUAL_TYPE_X11, NULL);
+
        else if (!strcmp(fbxine.video_port_id, "none"))
            fbxine.video_port =
                xine_open_video_driver(fbxine.xine, fbxine.video_port_id,
@@ -209,6 +211,9 @@
        xine_event_create_listener_thread(fbxine.event_queue, 
                                          event_listener, NULL);
 
+       xine_set_param(fbxine.stream, XINE_PARAM_VO_ASPECT_RATIO, aspect_ratio);
+        fprintf(stderr,"ratio: %d\n",aspect_ratio);
+
        return 1;
 }
 
@@ -252,14 +257,14 @@
 {
        if(!check_version())
                return 0;
-       if(!init_xine())
-               return 0;
        switch(parse_options(argc, argv))
        {
                case 0:
                case -1:
                        return 0;
        }
+       if(!init_xine())
+               return 0;
 
        if (stdctl)
                fbxine_init_stdctl();
diff -Nuri xine-ui-0.99.5/src/fb/options.c 
xine-ui-0.99.5.ivtv.patch/src/fb/options.c
--- xine-ui-0.99.5/src/fb/options.c     2005-09-17 02:19:49.000000000 +0200
+++ xine-ui-0.99.5.ivtv.patch/src/fb/options.c  2007-05-09 00:59:57.530605302 
+0200
@@ -40,6 +40,7 @@
 
 int stdctl;
 int no_lirc;
+int                     aspect_ratio    = XINE_VO_ASPECT_AUTO ;
 char                  **pplugins        = NULL;
 int                     pplugins_num    = 0;
 
@@ -75,31 +76,36 @@
 static void print_usage(void)
 {
        const char *const *driver_id;
-       
+       xine_t *xine = NULL;
+
+       xine = xine_new();
+       xine_init(xine);
+
        printf("Usage: fbxine [options] <MRL> ...\n"
               "\n"
               "  -v, --version                  Display version.\n"
                "      --verbose [=level]         Set verbosity level. Default 
is 1.\n"
               "  -V, --video-driver <drv>       Select video driver:\n");
        
-       driver_id = xine_list_video_output_plugins(fbxine.xine);
+       driver_id = xine_list_video_output_plugins(xine);
        while(*driver_id)
-               printf("                                   '%s'\n",
-                      *driver_id++);
-       
+               printf("                                   '%s'\n", 
+                       *driver_id++);
+
        printf("\n"
               "  -A, --audio-driver <drv>       Select audio driver:\n");
-       
-       driver_id = xine_list_audio_output_plugins(fbxine.xine);
+
+       driver_id = xine_list_audio_output_plugins(xine);
        while(*driver_id)
                printf("                                    '%s'\n",
                       *driver_id++);
-       
        printf("\n"
               "  -a, --audio-channel <number>   Select audio channel.\n");
 #ifdef HAVE_LIRC
        printf("  -L, --no-lirc                  Turn off LIRC support.\n");
 #endif
+       printf("  -r, --aspect-ratio <mode>      Set aspect ratio of video 
output. Modes are:\n"
+               "                                 'auto', 'square', '4:3', 
'anamorphic', 'dvb'.\n");
        printf("  -D, --deinterlace              Deinterlace video output. One 
or more post plugin\n"
               "                                 can be specified, with 
optional parameters.\n"
               "                                 Syntax is the same as --post 
option.\n"
@@ -121,6 +127,7 @@
               "\n");
 
        print_banner();
+       xine_exit(xine);
 }
 
 int parse_options(int argc, char **argv)
@@ -138,6 +145,7 @@
 #endif
                        { "stdctl",        optional_argument, 0, OPTION_STDCTL 
},
                        { "post",          required_argument, 0, OPTION_POST },
+                       { "aspect-ratio",  required_argument, 0, 'r' },
                        { "deinterlace",   no_argument,       0, 'D' },
                        { "verbose",       optional_argument, 0, OPTION_VERBOSE 
},
                        { 0,               no_argument,       0,  0  }
@@ -188,6 +196,27 @@
                                fbxine.video_port_id = strdup(optarg);
                                break;
                                
+                       case 'r':
+                               if(optarg != NULL) {
+                                       char *p = xine_chomp(optarg);
+
+                                       if(!strcasecmp(p, "auto"))
+                                               aspect_ratio = 
XINE_VO_ASPECT_AUTO;
+                                       else if(!strcasecmp(p, "square"))
+                                               aspect_ratio = 
XINE_VO_ASPECT_SQUARE;
+                                       else if(!strcasecmp(p, "4:3"))
+                                               aspect_ratio = 
XINE_VO_ASPECT_4_3;
+                                       else if(!strcasecmp(p, "anamorphic"))
+                                               aspect_ratio = 
XINE_VO_ASPECT_ANAMORPHIC;
+                                       else if(!strcasecmp(p, "dvb"))
+                                               aspect_ratio = 
XINE_VO_ASPECT_DVB;
+                                       else {
+                                               printf("Bad aspect ratio mode 
'%s', see xine --help\n", optarg);
+                                               return -1;
+                                       }
+                               }
+                               break;
+
                        case 'v':
                                print_version();
                                return 0;
@@ -214,7 +243,7 @@
 
                         case OPTION_VERBOSE:
                                 if(!optarg)
-                                    fbxine.verbosity = 1;
+                                   fbxine.verbosity = 1;
                                 else
                                     fbxine.verbosity = strtol(optarg, &optarg, 
10);
                                 break;
diff -Nuri xine-ui-0.99.5/src/fb/options.h 
xine-ui-0.99.5.ivtv.patch/src/fb/options.h
--- xine-ui-0.99.5/src/fb/options.h     2003-07-27 19:40:36.000000000 +0200
+++ xine-ui-0.99.5.ivtv.patch/src/fb/options.h  2007-05-09 01:00:01.490665035 
+0200
@@ -28,6 +28,7 @@
 int parse_options(int argc, char **argv);
 extern int no_lirc;
 extern int stdctl;
+extern int aspect_ratio;
 
 extern char **pplugins;
 extern int pplugins_num;
diff -Nuri xine-ui-0.99.5/src/fb/stdctl.c 
xine-ui-0.99.5.ivtv.patch/src/fb/stdctl.c
--- xine-ui-0.99.5/src/fb/stdctl.c      2007-04-10 00:39:35.000000000 +0200
+++ xine-ui-0.99.5.ivtv.patch/src/fb/stdctl.c   2007-05-09 01:00:17.330903984 
+0200
@@ -148,8 +148,10 @@
       secs /= 1000;
 
       if (secs != last_secs) {
+#if 0
        fprintf(stdout, "time: %d\n", secs);
        fflush(stdout);
+#endif
        last_secs = secs;
       }
     }
_______________________________________________
ivtv-devel mailing list
[email protected]
http://ivtvdriver.org/mailman/listinfo/ivtv-devel

Reply via email to