[Mplayer-cvslog] CVS: main/libvo gtf.c,NONE,1.1 gtf.h,NONE,1.1 Makefile,1.35,1.36 video_out.c,1.54,1.55 video_out.h,1.39,1.40 vo_fbdev.c,1.66,1.67 vo_vesa.c,1.75,1.76

Arpi of Ize arpi at mplayerhq.hu
Fri Aug 23 01:03:53 CEST 2002


Update of /cvsroot/mplayer/main/libvo
In directory mail:/var/tmp.root/cvs-serv7643/libvo

Modified Files:
	Makefile video_out.c video_out.h vo_fbdev.c vo_vesa.c 
Added Files:
	gtf.c gtf.h 
Log Message:
General Timing Formula algorithm from a scratch.
vo_vesa.c so now adjust the timing to highest possible refresh rate using
the monitor capabilities from a config file.
patch by Rudolf Marek <MAREKR2 at cs.felk.cvut.cz>


--- NEW FILE ---
/*
 *      Copyright (C) Rudolf Marek <r.marek at sh.cvut.cz> - Aug 2002
 *
 *  You can redistribute this file under terms and conditions
 *  of GNU General Public licence v2.
 * 
 *  GTF calculations formulas are taken from GTF_V1R1.xls
 *  created by ANDY.MORRISH at NSC.COM
 */
       
//Version 0.4
#include <stdio.h> 
#include <stdlib.h> 
#include <math.h> 
#include "gtf.h"

#undef GTF_DEBUG

#ifdef GTF_DEBUG
#define DEBUG_PRINTF(a,b) printf(a,b);
#else
#define DEBUG_PRINTF(a,b)
#endif

static GTF_constants GTF_given_constants = { 3.0,550.0,1,8,1.8,8,40,20,128,600 };

static double round(double v) 
{ 
        return floor(v + 0.5); 
} 
	
static void GetRoundedConstants(GTF_constants *c)
    {
    c->Vsync_need = round(GTF_given_constants.Vsync_need);
    c->min_Vsync_BP = GTF_given_constants.min_Vsync_BP;
    c->min_front_porch = round(GTF_given_constants.min_front_porch);
    c->char_cell_granularity = GTF_given_constants.char_cell_granularity;
    c->margin_width = GTF_given_constants.margin_width;
    c->sync_width = GTF_given_constants.sync_width;
    c->c = ((GTF_given_constants.c - GTF_given_constants.j)*(GTF_given_constants.k / 256)) + GTF_given_constants.j;
    c->j = GTF_given_constants.j;
    c->k = GTF_given_constants.k;
    c->m = (GTF_given_constants.k / 256) * GTF_given_constants.m;
    }

void GTF_calcTimings(double X,double Y,double freq, int type,  
		     int want_margins, int want_interlace,struct VesaCRTCInfoBlock *result )
{
    GTF_constants   c;
    double RR, margin_top, margin_bottom, margin_left, margin_right;
    double estimated_H_period,sync_plus_BP,BP,interlace,V_total_lines_field;
    double estimated_V_field_rate,actual_H_period,actual_V_field_freq;
    double total_active_pixels, ideal_duty_cycle, blanking_time, H_total_pixels;
    double H_freq, pixel_freq,actual_V_frame_freq;
    double H_sync_start, H_sync_end, H_back_porch, H_front_porch, H_sync_width;
    double V_back_porch, V_front_porch, V_sync_start, V_sync_end,V_sync_width;    
    double ideal_H_period;
    GetRoundedConstants(&c);

    
    pixel_freq = RR = freq;

    /* DETERMINE IF 1/2 LINE INTERLACE IS PRESENT */
    
    interlace = 0;    
    
    if (want_interlace) {
    RR = RR * 2;    
    Y=Y/2;
    interlace = 0.5;
    }
    
    result->Flags = 0;
    
    if ((Y==300)||(Y==200)||(Y==240))
    {
    Y*=2;
    result->Flags = VESA_CRTC_DOUBLESCAN; /* TODO: check if mode support   */
    }			
    
    /* DETERMINE NUMBER OF LINES IN V MARGIN */
    /* DETERMINE NUMBER OF PIXELS IN H MARGIN [pixels] */
    
    margin_left = margin_right = 0;
    margin_top = margin_bottom = 0;
    
    if (want_margins) {
	margin_top = margin_bottom = (c.margin_width / 100) * Y;
        margin_left = round(( X* c.margin_width/100)/c.char_cell_granularity) \
		    * c.char_cell_granularity;
    margin_right = margin_left;
    DEBUG_PRINTF("margin_left_right : %f\n",margin_right)
    DEBUG_PRINTF("margin_top_bottom : %f\n",margin_top)
    } 
    
    /* FIND TOTAL NUMBER OF ACTIVE PIXELS (IMAGE + MARGIN) [pixels] */        
    
    total_active_pixels = margin_left + margin_right + X;
    DEBUG_PRINTF("total_active_pixels: %f\n",total_active_pixels)

    if (type == GTF_PF)
    {
    ideal_H_period = ((c.c-100)+(sqrt(((100-c.c)*(100-c.c) )+(0.4*c.m*(total_active_pixels + margin_left + margin_right) / freq))))/2/c.m*1000; 
    
    DEBUG_PRINTF("ideal_H_period: %f\n",ideal_H_period)
    
    /* FIND IDEAL BLANKING DUTY CYCLE FROM FORMULA [%] */
    ideal_duty_cycle = c.c - (c.m * ideal_H_period /1000);
    DEBUG_PRINTF("ideal_duty_cycle: %f\n",ideal_duty_cycle)

    /* FIND BLANKING TIME (TO NEAREST CHAR CELL) [pixels] */
    
    blanking_time = round(total_active_pixels * ideal_duty_cycle \
		    / (100-ideal_duty_cycle) / (2*c.char_cell_granularity))  \
		    * (2*c.char_cell_granularity);
    DEBUG_PRINTF("blanking_time : %f\n",blanking_time )

    /* FIND TOTAL NUMBER OF PIXELS IN A LINE [pixels] */		    
    H_total_pixels = total_active_pixels + blanking_time ;
    DEBUG_PRINTF("H_total_pixels: %f\n",H_total_pixels)
    H_freq = freq / H_total_pixels * 1000;
    DEBUG_PRINTF("H_freq: %f\n",H_freq)
    actual_H_period = 1000 / H_freq;
    DEBUG_PRINTF("actual_H_period: %f\n",actual_H_period)
    sync_plus_BP = round(H_freq * c.min_Vsync_BP/1000);
//   sync_plus_BP = round( freq / H_total_pixels * c.min_Vsync_BP);
   
    DEBUG_PRINTF("sync_plus_BP: %f\n",sync_plus_BP)

    } else if (type == GTF_VF) 
    {
    
    /* ESTIMATE HORIZ. PERIOD [us] */

    estimated_H_period = (( 1/RR ) - c.min_Vsync_BP/1000000 ) /  (Y + (2 * margin_top) + c.min_front_porch + interlace) * 1000000;
    
    DEBUG_PRINTF("estimated_H_period: %f\n",estimated_H_period)

    /* FIND NUMBER OF LINES IN (SYNC + BACK PORCH) [lines] */
    
    sync_plus_BP = round( c.min_Vsync_BP / estimated_H_period );
    DEBUG_PRINTF("sync_plus_BP: %f\n",sync_plus_BP)

    } else if (type == GTF_HF)
    {
    sync_plus_BP = round(freq * c.min_Vsync_BP/1000);
    DEBUG_PRINTF("sync_plus_BP: %f\n",sync_plus_BP)
    }
    
    
    
    /* FIND TOTAL NUMBER OF LINES IN VERTICAL FIELD */

    V_total_lines_field = sync_plus_BP+interlace+margin_bottom+margin_top+Y+c.min_front_porch;
    DEBUG_PRINTF("V_total_lines_field : %f\n",V_total_lines_field )

    if (type == GTF_VF)
    {
    /* ESTIMATE VERTICAL FIELD RATE [hz] */
    
    estimated_V_field_rate = 1 / estimated_H_period / V_total_lines_field * 1000000;
    DEBUG_PRINTF(" estimated_V_field_rate: %f\n", estimated_V_field_rate)
    /* FIND ACTUAL HORIZONTAL PERIOD [us] */
    
    actual_H_period = estimated_H_period / (RR / estimated_V_field_rate);
    DEBUG_PRINTF("actual_H_period: %f\n",actual_H_period)
    /* FIND ACTUAL VERTICAL FIELD FREQUENCY [Hz] */

    actual_V_field_freq = 1 / actual_H_period / V_total_lines_field * 1000000;
    DEBUG_PRINTF("actual_V_field_freq: %f\n",actual_V_field_freq)

    /* FIND IDEAL BLANKING DUTY CYCLE FROM FORMULA [%] */
    ideal_duty_cycle = c.c - (c.m * actual_H_period /1000);
    DEBUG_PRINTF("ideal_duty_cycle: %f\n",ideal_duty_cycle)
    //if (type == GTF_VF)
    //{
    //moved
    //}
    } else if (type == GTF_HF)
    {
    /* FIND IDEAL BLANKING DUTY CYCLE FROM FORMULA [%] */
    ideal_duty_cycle = c.c - (c.m  / freq);
    DEBUG_PRINTF("ideal_duty_cycle: %f\n",ideal_duty_cycle)
    }

    /* FIND BLANKING TIME (TO NEAREST CHAR CELL) [pixels] */

    if (!(type == GTF_PF))
    {
    blanking_time = round(total_active_pixels * ideal_duty_cycle \
		    / (100-ideal_duty_cycle) / (2*c.char_cell_granularity))  \
		    * (2*c.char_cell_granularity);
    DEBUG_PRINTF("blanking_time : %f\n",blanking_time )
    }
    else
//    if (type == GTF_PF)
    {
    actual_V_field_freq = H_freq / V_total_lines_field * 1000;
    }

    if (type == GTF_HF)
    {
    /* Hz */
    actual_V_field_freq = freq / V_total_lines_field * 1000;
    DEBUG_PRINTF("actual_V_field_freq: %f\n",actual_V_field_freq)    
    }
    
        
    actual_V_frame_freq = actual_V_field_freq;

    /* FIND ACTUAL VERTICAL  FRAME FREQUENCY [Hz]*/
    
    if (want_interlace) actual_V_frame_freq = actual_V_field_freq / 2;
    DEBUG_PRINTF("actual_V_frame_freq: %f\n",actual_V_frame_freq)
    
//    V_freq = actual_V_frame_freq;
//    DEBUG_PRINTF("V_freq %f\n",V_freq)    

    
    if (!(type == GTF_PF))
    {    
    /* FIND TOTAL NUMBER OF PIXELS IN A LINE [pixels] */		    
    H_total_pixels = total_active_pixels + blanking_time ;
    DEBUG_PRINTF("H_total_pixels: %f\n",H_total_pixels)
        if (type == GTF_VF)
	{
	/* FIND PIXEL FREQUENCY [Mhz] */
	pixel_freq = H_total_pixels / actual_H_period ;
	DEBUG_PRINTF("pixel_freq: %f\n",pixel_freq)
	} else if (type == GTF_HF)
	{
	/* FIND PIXEL FREQUENCY [Mhz] */
	pixel_freq = H_total_pixels * freq / 1000 ;
	DEBUG_PRINTF("pixel_freq: %f\n",pixel_freq)
	actual_H_period = 1000/freq;
	}

        /* FIND ACTUAL HORIZONTAL FREQUENCY [KHz] */
    
        H_freq = 1000 / actual_H_period;
	DEBUG_PRINTF("H_freq %f\n",H_freq)

    
    }

    /* FIND NUMBER OF LINES IN BACK PORCH [lines] */
    
    BP = sync_plus_BP - c.Vsync_need;
    DEBUG_PRINTF("BP: %f\n",BP)

/*------------------------------------------------------------------------------------------------*/
    /* FIND H SYNC WIDTH (TO NEAREST CHAR CELL) */
    H_sync_width = round(c.sync_width/100*H_total_pixels/c.char_cell_granularity)*c.char_cell_granularity;
    DEBUG_PRINTF("H_sync_width %f\n",H_sync_width)

    /* FIND FRONT H PORCH(TO NEAREST CHAR CELL) */
    H_front_porch = (blanking_time/2) - H_sync_width;
    DEBUG_PRINTF("H_front_porch %f\n",H_front_porch)    
    /* FIND BACK H PORCH(TO NEAREST CHAR CELL) */
    H_back_porch = H_sync_width + H_front_porch;
    DEBUG_PRINTF("H_back_porch%f\n",H_back_porch)  

    H_sync_start = H_total_pixels  - (H_sync_width + H_back_porch);
    DEBUG_PRINTF("H_sync_start %f\n",H_sync_start)
    H_sync_end = H_total_pixels  - H_back_porch;
    DEBUG_PRINTF("H_sync_end %f\n",H_sync_end) 
    
    V_back_porch = interlace + BP;
    DEBUG_PRINTF("V_back_porch%f\n",V_back_porch)
    V_front_porch = interlace + c.min_front_porch;
    DEBUG_PRINTF("V_front_porch%f\n",V_front_porch)   
    
    V_sync_width = c.Vsync_need;
    V_sync_start = V_total_lines_field  - (V_sync_width + V_back_porch);
    DEBUG_PRINTF("V_sync_start %f\n",V_sync_start)    
    V_sync_end = V_total_lines_field  - V_back_porch;
    DEBUG_PRINTF("V_sync_end %f\n",V_sync_end) 
    
    result->hTotal = H_total_pixels;
    result-> hSyncStart  = H_sync_start;  /* Horizontal sync start in pixels */
    result-> hSyncEnd = H_sync_end;   /* Horizontal sync end in pixels */
    result-> vTotal= V_total_lines_field;     /* Vertical total in lines */
    result-> vSyncStart = V_sync_start; /* Vertical sync start in lines */
    result-> vSyncEnd = V_sync_end;   /* Vertical sync end in lines */
    result->  Flags = (result->Flags)|VESA_CRTC_HSYNC_NEG;      /* Flags (Interlaced, Double Scan etc) */
    
    if (want_interlace) 
    {
    result->Flags = (result->Flags) | VESA_CRTC_INTERLACED;
    }
   
    result->  PixelClock = pixel_freq*1000000; /* Pixel clock in units of Hz */
    result-> RefreshRate = actual_V_frame_freq*100;/* Refresh rate in units of 0.01 Hz*/
					
    }



--- NEW FILE ---
#ifndef __GTF_H
#define __GTF_H

#include "linux/vbelib.h"

#define GTF_VF 0 
#define GTF_HF 1 
#define GTF_PF 2

		     
typedef struct {
    double	Vsync_need;	   /* Number of lines for vert sync (default 3) */
    double	min_Vsync_BP;	   /* Minimum vertical sync + back porch (us) (default 550)*/
    double	min_front_porch;   /* Minimum front porch in lines (default 1)	*/
    double	char_cell_granularity;  /* Character cell granularity in pixels (default 8) */
    double	margin_width;	   /* Top/ bottom MARGIN size as % of height (%) (default 1.8) */
    double	sync_width;	  /* Sync width percent of line period ( default 8) */
    double  c;		/* Blanking formula offset (default 40)*/
    double  j;		/* Blanking formula scaling factor weight (default 20)*/
    double  k;		/* Blanking formula scaling factor (default 128)*/
    double  m;		/* Blanking formula gradient (default 600)*/
    } GTF_constants;

//#ifndef __VESA_VBELIB_INCLUDED__ 
//    struct VesaCRTCInfoBlock {
//    unsigned short hTotal;     /* Horizontal total in pixels */
//    unsigned short hSyncStart; /* Horizontal sync start in pixels */
//    unsigned short hSyncEnd;   /* Horizontal sync end in pixels */
//    unsigned short vTotal;     /* Vertical total in lines */
//    unsigned short vSyncStart; /* Vertical sync start in lines */
//    unsigned short vSyncEnd;   /* Vertical sync end in lines */
//    unsigned char  Flags;      /* Flags (Interlaced, Double Scan etc) */
//    unsigned long  PixelClock; /* Pixel clock in units of Hz */
//    unsigned short RefreshRate;/* Refresh rate in units of 0.01 Hz*/
//    unsigned char  Reserved[40];/* remainder of CRTCInfoBlock*/
//}__attribute__ ((packed));		    

//#define VESA_CRTC_DOUBLESCAN 0x01
//#define VESA_CRTC_INTERLACED 0x02
//#define VESA_CRTC_HSYNC_NEG  0x04
//#define VESA_CRTC_VSYNC_NEG  0x08

//#endif

void GTF_calcTimings(double X,double Y,double freq, int type,
                     int want_margins, int want_interlace,struct VesaCRTCInfoBlock *result);

#endif

Index: Makefile
===================================================================
RCS file: /cvsroot/mplayer/main/libvo/Makefile,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -r1.35 -r1.36
--- Makefile	16 Jun 2002 14:03:54 -0000	1.35
+++ Makefile	22 Aug 2002 23:03:50 -0000	1.36
@@ -3,7 +3,7 @@
 
 LIBNAME = libvo.a
 
-SRCS=aspect.c aclib.c osd.c font_load.c spuenc.c video_out.c vo_null.c vo_pgm.c vo_md5.c vo_mpegpes.c vo_yuv4mpeg.c $(OPTIONAL_SRCS) sub.c
+SRCS=aspect.c aclib.c osd.c font_load.c gtf.c spuenc.c video_out.c vo_null.c vo_pgm.c vo_md5.c vo_mpegpes.c vo_yuv4mpeg.c $(OPTIONAL_SRCS) sub.c
 OBJS=$(SRCS:.c=.o)
 
 ifeq ($(VIDIX),yes)

Index: video_out.c
===================================================================
RCS file: /cvsroot/mplayer/main/libvo/video_out.c,v
retrieving revision 1.54
retrieving revision 1.55
diff -u -r1.54 -r1.55
--- video_out.c	24 Jul 2002 18:16:59 -0000	1.54
+++ video_out.c	22 Aug 2002 23:03:50 -0000	1.55
@@ -201,3 +201,85 @@
   vo_dxr2_register_options(cfg);
 #endif
 }
+#if defined(HAVE_FBDEV)||defined(HAVE_VESA)  
+/* Borrowed from vo_fbdev.c 
+Monitor ranges related functions*/
+
+char *monitor_hfreq_str = NULL;
+char *monitor_vfreq_str = NULL;
+char *monitor_dotclock_str = NULL;
+
+float range_max(range_t *r)
+{
+float max = 0;
+
+	for (/* NOTHING */; (r->min != -1 && r->max != -1); r++)
+		if (max < r->max) max = r->max;
+	return max;
+}
+
+
+int in_range(range_t *r, float f)
+{
+	for (/* NOTHING */; (r->min != -1 && r->max != -1); r++)
+		if (f >= r->min && f <= r->max)
+			return 1;
+	return 0;
+}
+
+range_t *str2range(char *s)
+{
+	float tmp_min, tmp_max;
+	char *endptr = s;	// to start the loop
+	range_t *r = NULL;
+	int i;
+
+	if (!s)
+		return NULL;
+	for (i = 0; *endptr; i++) {
+		if (*s == ',')
+			goto out_err;
+		if (!(r = (range_t *) realloc(r, sizeof(*r) * (i + 2)))) {
+			printf("can't realloc 'r'\n");
+			return NULL;
+		}
+		tmp_min = strtod(s, &endptr);
+		if (*endptr == 'k' || *endptr == 'K') {
+			tmp_min *= 1000.0;
+			endptr++;
+		} else if (*endptr == 'm' || *endptr == 'M') {
+			tmp_min *= 1000000.0;
+			endptr++;
+		}
+		if (*endptr == '-') {
+			tmp_max = strtod(endptr + 1, &endptr);
+			if (*endptr == 'k' || *endptr == 'K') {
+				tmp_max *= 1000.0;
+				endptr++;
+			} else if (*endptr == 'm' || *endptr == 'M') {
+				tmp_max *= 1000000.0;
+				endptr++;
+			}
+			if (*endptr != ',' && *endptr)
+				goto out_err;
+		} else if (*endptr == ',' || !*endptr) {
+			tmp_max = tmp_min;
+		} else
+			goto out_err;
+		r[i].min = tmp_min;
+		r[i].max = tmp_max;
+		if (r[i].min < 0 || r[i].max < 0)
+			goto out_err;
+		s = endptr + 1;
+	}
+	r[i].min = r[i].max = -1;
+	return r;
+out_err:
+	if (r)
+		free(r);
+	return NULL;
+}
+
+/* Borrowed from vo_fbdev.c END */
+#endif
+

Index: video_out.h
===================================================================
RCS file: /cvsroot/mplayer/main/libvo/video_out.h,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -r1.39 -r1.40
--- video_out.h	14 Aug 2002 23:02:45 -0000	1.39
+++ video_out.h	22 Aug 2002 23:03:50 -0000	1.40
@@ -241,4 +241,20 @@
 
 extern char *vo_subdevice;
 
+#if defined(HAVE_FBDEV)||defined(HAVE_VESA) 
+
+typedef struct {
+        float min;
+	float max;
+	} range_t;
+
+extern float range_max(range_t *r);
+extern int in_range(range_t *r, float f);
+extern range_t *str2range(char *s);
+extern char *monitor_hfreq_str;
+extern char *monitor_vfreq_str;
+extern char *monitor_dotclock_str;
+
+#endif 
+		
 #endif

Index: vo_fbdev.c
===================================================================
RCS file: /cvsroot/mplayer/main/libvo/vo_fbdev.c,v
retrieving revision 1.66
retrieving revision 1.67
diff -u -r1.66 -r1.67
--- vo_fbdev.c	30 Jul 2002 18:52:57 -0000	1.66
+++ vo_fbdev.c	22 Aug 2002 23:03:50 -0000	1.67
@@ -57,6 +57,14 @@
 *	fb.modes support      *
 ******************************/
 
+extern char *monitor_hfreq_str;
+extern char *monitor_vfreq_str;
+extern char *monitor_dotclock_str;
+
+static range_t *monitor_hfreq = NULL;
+static range_t *monitor_vfreq = NULL;
+static range_t *monitor_dotclock = NULL;
+
 typedef struct {
 	char *name;
 	uint32_t xres, yres, vxres, vyres, depth;
@@ -396,18 +404,6 @@
 	return hsf(m) / vtotal;
 }
 
-typedef struct {
-	float min;
-	float max;
-} range_t;
-
-static int in_range(range_t *r, float f)
-{
-	for (/* NOTHING */; (r->min != -1 && r->max != -1); r++)
-		if (f >= r->min && f <= r->max)
-			return 1;
-	return 0;
-}
 
 static int mode_works(fb_mode_t *m, range_t *hfreq, range_t *vfreq,
 		range_t *dotclock)
@@ -558,58 +554,6 @@
 	v->vmode = m->vmode;
 }
 
-static range_t *str2range(char *s)
-{
-	float tmp_min, tmp_max;
-	char *endptr = s;	// to start the loop
-	range_t *r = NULL;
-	int i;
-
-	if (!s)
-		return NULL;
-	for (i = 0; *endptr; i++) {
-		if (*s == ',')
-			goto out_err;
-		if (!(r = (range_t *) realloc(r, sizeof(*r) * (i + 2)))) {
-			printf("can't realloc 'r'\n");
-			return NULL;
-		}
-		tmp_min = strtod(s, &endptr);
-		if (*endptr == 'k' || *endptr == 'K') {
-			tmp_min *= 1000.0;
-			endptr++;
-		} else if (*endptr == 'm' || *endptr == 'M') {
-			tmp_min *= 1000000.0;
-			endptr++;
-		}
-		if (*endptr == '-') {
-			tmp_max = strtod(endptr + 1, &endptr);
-			if (*endptr == 'k' || *endptr == 'K') {
-				tmp_max *= 1000.0;
-				endptr++;
-			} else if (*endptr == 'm' || *endptr == 'M') {
-				tmp_max *= 1000000.0;
-				endptr++;
-			}
-			if (*endptr != ',' && *endptr)
-				goto out_err;
-		} else if (*endptr == ',' || !*endptr) {
-			tmp_max = tmp_min;
-		} else
-			goto out_err;
-		r[i].min = tmp_min;
-		r[i].max = tmp_max;
-		if (r[i].min < 0 || r[i].max < 0)
-			goto out_err;
-		s = endptr + 1;
-	}
-	r[i].min = r[i].max = -1;
-	return r;
-out_err:
-	if (r)
-		free(r);
-	return NULL;
-}
 
 /******************************
 *	    vo_fbdev	      *
@@ -619,14 +563,7 @@
 char *fb_dev_name = NULL;
 char *fb_mode_cfgfile = "/etc/fb.modes";
 char *fb_mode_name = NULL;
-char *monitor_hfreq_str = NULL;
-char *monitor_vfreq_str = NULL;
-char *monitor_dotclock_str = NULL;
 
-/* fb.modes related variables */
-static range_t *monitor_hfreq = NULL;
-static range_t *monitor_vfreq = NULL;
-static range_t *monitor_dotclock = NULL;
 static fb_mode_t *fb_mode = NULL;
 
 /* vt related variables */

Index: vo_vesa.c
===================================================================
RCS file: /cvsroot/mplayer/main/libvo/vo_vesa.c,v
retrieving revision 1.75
retrieving revision 1.76
diff -u -r1.75 -r1.76
--- vo_vesa.c	16 Aug 2002 22:23:50 -0000	1.75
+++ vo_vesa.c	22 Aug 2002 23:03:50 -0000	1.76
@@ -16,7 +16,7 @@
   - refresh rate support (need additional info from mplayer)
 */
 #include "config.h"
-
+#include "gtf.h"
 #include <stdio.h>
 #ifdef HAVE_MALLOC_H
 #include <malloc.h>
@@ -54,6 +54,10 @@
 
 extern int verbose;
 
+extern char *monitor_hfreq_str;
+extern char *monitor_vfreq_str;
+extern char *monitor_dotclock_str;
+
 #define MAX_BUFFERS 3
 
 #ifndef max
@@ -523,18 +527,69 @@
   return i;
 }
 
-
+static int set_refresh(unsigned x, unsigned y, unsigned mode,struct VesaCRTCInfoBlock *crtc_pass)
+{
+    unsigned pixclk;
+    float H_freq;
+    
+    range_t *monitor_hfreq = NULL;
+    range_t *monitor_vfreq = NULL;
+    range_t *monitor_dotclock = NULL;
+
+    monitor_hfreq = str2range(monitor_hfreq_str);
+    monitor_vfreq = str2range(monitor_vfreq_str);
+    monitor_dotclock = str2range(monitor_dotclock_str);
+    
+		if (!monitor_hfreq || !monitor_vfreq || !monitor_dotclock) {
+			printf("vo_vesa: you have to specify the capabilities of"
+					" the monitor. Not changing refresh rate.\n");
+			return 0;
+		}
+
+    H_freq = range_max(monitor_hfreq)/1000;
+    
+//    printf("H_freq MAX %f\n",H_freq);
+    
+    do
+    {
+    H_freq -= 0.1;
+    GTF_calcTimings(x,y,H_freq,GTF_HF,0, 0,crtc_pass);		      
+//    printf("PixelCLK %d\n",(unsigned)crtc_pass->PixelClock);    
+    }
+    while (!in_range(monitor_vfreq,crtc_pass->RefreshRate/100));
+    
+    pixclk = crtc_pass->PixelClock;
+//    printf("PIXclk before %d\n",pixclk);
+    vbeGetPixelClock(&mode,&pixclk); 
+//    printf("PIXclk after %d\n",pixclk);
+    GTF_calcTimings(x,y,pixclk/1000000,GTF_PF,0,0,crtc_pass);
+//    printf("Flags: %x\n",(unsigned) crtc_pass->Flags);
+/*    
+    printf("hTotal %d\n",crtc_pass->hTotal);
+    printf("hSyncStart %d\n",crtc_pass->hSyncStart);
+    printf("hSyncEnd %d\n",crtc_pass->hSyncEnd);
+    
+    printf("vTotal %d\n",crtc_pass->vTotal);
+    printf("vSyncStart %d\n",crtc_pass->vSyncStart);
+    printf("vSyncEnd %d\n",crtc_pass->vSyncEnd);
+    
+    printf("RR %d\n",crtc_pass->RefreshRate);
+    printf("PixelCLK %d\n",(unsigned)crtc_pass->PixelClock);*/
+    return 1;
+}
 /* fullscreen:
  * bit 0 (0x01) means fullscreen (-fs)
  * bit 1 (0x02) means mode switching (-vm)
  * bit 2 (0x04) enables software scaling (-zoom)
  * bit 3 (0x08) enables flipping (-flip) (NK: and for what?)
  */
+
 static uint32_t
 config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t flags, char *title, uint32_t format,const vo_tune_info_t *info)
 {
-  struct VbeInfoBlock vib;
+  struct VbeInfoBlock vib;  
   struct VesaModeInfoBlock vmib;
+  struct VesaCRTCInfoBlock crtc_pass;
   size_t i,num_modes;
   uint32_t w,h;
   unsigned short *mode_ptr,win_seg;
@@ -831,11 +886,26 @@
 			PRINT_VBE_ERR("vbeSaveState",err);
 			return -1;
 		}
-		if((err=vbeSetMode(video_mode,NULL)) != VBE_OK)
+		/* TODO: check for VBE 3, monitor limitation
+		         user might pass refresh value
+			 GTF constants might be read from monitor
+			 for best results
+		*/
+		if (((int)(vib.VESAVersion >> 8) & 0xff) > 2) {
+		
+		if (set_refresh(dstW,dstH,video_mode,&crtc_pass))
+		video_mode = video_mode | 0x800;
+		
+		}
+		
+		;
+		
+		if ((err=vbeSetMode(video_mode,&crtc_pass)) != VBE_OK)
 		{
 			PRINT_VBE_ERR("vbeSetMode",err);
 			return -1;
 		}
+		
 		/* Now we are in video mode!!!*/
 		/* Below 'return -1' is impossible */
 		if(verbose)




More information about the MPlayer-cvslog mailing list