xf86-video-ati: Branch 'master'

Roland Scheidegger sroland at kemper.freedesktop.org
Wed Nov 29 17:48:40 EET 2006


 man/radeon.man      |   11 +++++++++++
 src/radeon.h        |    2 ++
 src/radeon_driver.c |   29 +++++++++++++++++++++++++++--
 src/radeon_video.c  |   40 +++++++++++++++++++++-------------------
 src/radeon_video.h  |    3 +--
 5 files changed, 62 insertions(+), 23 deletions(-)

New commits:
diff-tree 9f5ea3981449f29ff204eb154166e8fc813205fa (from 35a5eaf5adf103ef57f8d4590dae25b0c50bd780)
Author: Roland Scheidegger <rscheidegger_lists at hispeed.ch>
Date:   Wed Nov 29 16:46:57 2006 +0100

    radeon: bug #1462, predownscale to make HD video work.
    
    Use the overlay scaler's predownscale capability to make videos with large
    horizontal resolution work if it exceeds the scaler buffer width. Make the
    scaler buffer width user-configurable since we don't know it for all chips,
    and using predownscaling may otherwise reduce quality even if it wouldn't
    be needed. This should fix bug #1462.

diff --git a/man/radeon.man b/man/radeon.man
index 9dc75fc..ddfd0ff 100644
--- a/man/radeon.man
+++ b/man/radeon.man
@@ -140,6 +140,17 @@ This overrides the default pixel value f
 The default value is
 .B 0x1E.
 .TP
+.BI "Option \*qScalerWidth\*q \*q" integer \*q
+This sets the overlay scaler buffer width. Accepted values range from 1024 to
+2048, divisible by 64, values other than 1536 and 1920 may not make sense
+though. Should be set automatically, but noone has a clue what the limit is
+for which chip. If you think quality is not optimal when playing back HD video
+(with horizontal resolution larger than this setting), increase this value, if
+you get an empty area at the right (usually pink), decrease it. Note this only
+affects the "true" overlay via xv, it won't affect things like textured video.
+.br
+The default value is either 1536 (for most chips) or 1920.
+.TP
 .BI "Option \*qUseFBDev\*q \*q" boolean \*q
 Enable or disable use of an OS\-specific framebuffer device interface
 (which is not supported on all OSs).  MergedFB does not work when this
diff --git a/src/radeon.h b/src/radeon.h
index 7789a9a..646b742 100644
--- a/src/radeon.h
+++ b/src/radeon.h
@@ -142,6 +142,7 @@ typedef enum {
     OPTION_TUNER_TYPE,
     OPTION_RAGE_THEATRE_MICROC_PATH,
     OPTION_RAGE_THEATRE_MICROC_TYPE,
+    OPTION_SCALER_WIDTH,
 #endif
 #ifdef RENDER
     OPTION_RENDER_ACCEL,
@@ -739,6 +740,7 @@ typedef struct {
         CARD8 input[5];
     	} MM_TABLE;
     CARD16 video_decoder_type;
+    int overlay_scaler_buffer_width;
 
     /* Render */
     Bool              RenderAccel;
diff --git a/src/radeon_driver.c b/src/radeon_driver.c
index 1950f75..251c439 100644
--- a/src/radeon_driver.c
+++ b/src/radeon_driver.c
@@ -182,8 +182,9 @@ static const OptionInfoRec RADEONOptions
     { OPTION_RAGE_THEATRE_COMPOSITE_PORT, "RageTheatreCompositePort", OPTV_INTEGER, {0}, FALSE },
     { OPTION_RAGE_THEATRE_SVIDEO_PORT,    "RageTheatreSVideoPort",    OPTV_INTEGER, {0}, FALSE },
     { OPTION_TUNER_TYPE,                  "TunerType",                OPTV_INTEGER, {0}, FALSE },
-	{ OPTION_RAGE_THEATRE_MICROC_PATH,	"RageTheatreMicrocPath",	 OPTV_STRING, {0}, FALSE },
-	{ OPTION_RAGE_THEATRE_MICROC_TYPE, 	"RageTheatreMicrocType",	 OPTV_STRING, {0}, FALSE },
+    { OPTION_RAGE_THEATRE_MICROC_PATH,    "RageTheatreMicrocPath",    OPTV_STRING, {0}, FALSE },
+    { OPTION_RAGE_THEATRE_MICROC_TYPE,    "RageTheatreMicrocType",    OPTV_STRING, {0}, FALSE },
+    { OPTION_SCALER_WIDTH,                "ScalerWidth",              OPTV_INTEGER, {0}, FALSE }, 
 #endif
 #ifdef RENDER
     { OPTION_RENDER_ACCEL,   "RenderAccel",      OPTV_BOOLEAN, {0}, FALSE },
@@ -3049,6 +3050,30 @@ _X_EXPORT Bool RADEONPreInit(ScrnInfoPtr
     	info->tunerType=-1;
     }
 
+    if(xf86GetOptValInteger(info->Options, OPTION_SCALER_WIDTH, &(info->overlay_scaler_buffer_width))) {
+	if ((info->overlay_scaler_buffer_width < 1024) ||
+	  (info->overlay_scaler_buffer_width > 2048) ||
+	  ((info->overlay_scaler_buffer_width % 64) != 0)) {
+	    xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Attempt to set illegal scaler width. Using default\n");
+	    info->overlay_scaler_buffer_width = 0;
+	}
+    }
+    else info->overlay_scaler_buffer_width = 0;
+    if (!info->overlay_scaler_buffer_width) {
+       /* overlay scaler line length differs for different revisions 
+       this needs to be maintained by hand  */
+	switch(info->ChipFamily){
+	case CHIP_FAMILY_R200:
+	case CHIP_FAMILY_R300:
+		info->overlay_scaler_buffer_width = 1920;
+		break;
+	default:
+		info->overlay_scaler_buffer_width = 1536;
+	}
+    }
+    xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Assuming overlay scaler buffer width is %d\n",
+	info->overlay_scaler_buffer_width);
+
     if(info->tunerType>31){
          xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Attempt to set tuner type to invalid value. Disabling setting\n");
 	 info->tunerType=-1;
diff --git a/src/radeon_video.c b/src/radeon_video.c
index b9b479f..6a910a1 100644
--- a/src/radeon_video.c
+++ b/src/radeon_video.c
@@ -1364,17 +1364,6 @@ RADEONAllocAdaptor(ScrnInfoPtr pScrn)
         OUTPLL(pScrn, RADEON_VCLK_ECP_CNTL,
 	       (INPLL(pScrn, RADEON_VCLK_ECP_CNTL) | (1<<18)));
     }
-    
-    /* overlay scaler line length differs for different revisions 
-       this needs to be maintained by hand  */
-    switch(info->ChipFamily){
-    	case CHIP_FAMILY_R200:
-	case CHIP_FAMILY_R300:
-		pPriv->overlay_scaler_buffer_width=1920;
-		break;
-	default:
-		pPriv->overlay_scaler_buffer_width=1536;
-    	}
 
     /* Decide on tuner type */
     if((info->tunerType<0) && (info->MM_TABLE_valid)) {
@@ -2439,6 +2428,8 @@ RADEONDisplayVideo(
     CARD32 scale_cntl;
     double dsr;
     int tap_set;
+    int predownscale=0;
+    int src_w_d;
 
     is_rgb=0;
     switch(id){
@@ -2513,17 +2504,27 @@ RADEONDisplayVideo(
     step_by_y = 1;
     step_by_uv = step_by_y;
 
+    src_w_d = src_w;
+#if 0
+    /* XXX this does not appear to work */
     /* if the source width was larger than what would fit in overlay scaler increase step_by values */
     i=src_w;
-    while(i>pPriv->overlay_scaler_buffer_width){
-    	step_by_y++;
+    while(i>info->overlay_scaler_buffer_width){
+	step_by_y++;
 	step_by_uv++;
 	h_inc >>=1;
 	i=i/2;
-    	}
-
+	}
+#else
+    /* predownscale instead (yes this hurts quality) - will only work for widths up
+       to 2 times the overlay_scaler_buffer_width, should be enough */
+    if (src_w_d > info->overlay_scaler_buffer_width) {
+	src_w_d /= 2; /* odd widths? */
+	predownscale = 1;
+    }
+#endif
 
-    h_inc_d = src_w;
+    h_inc_d = src_w_d;
     h_inc_d = h_inc_d/drw_w;
     /* we could do a tad better  - but why
        bother when this concerns downscaling and the code is so much more
@@ -2540,7 +2541,7 @@ RADEONDisplayVideo(
     h_inc_uv = h_inc>>(step_by_uv-step_by_y);
     h_inc = h_inc * h_inc_d;
     h_inc_uv = h_inc_uv * h_inc_d;
-    /* pPriv->overlay_scaler_buffer_width is magic number - maximum line length the overlay scaler can fit 
+    /* info->overlay_scaler_buffer_width is magic number - maximum line length the overlay scaler can fit 
        in the buffer for 2 tap filtering */
     /* the only place it is documented in is in ATI source code */
     /* we need twice as much space for 4 tap filtering.. */
@@ -2550,7 +2551,7 @@ RADEONDisplayVideo(
 #if 0
     if(!is_rgb && (step_by_y==1) && (step_by_uv==1) && (h_inc < (1<<12))
        && (deinterlacing_method!=METHOD_WEAVE)
-       && (drw_w*2 <= pPriv->overlay_scaler_buffer_width)){
+       && (drw_w*2 <= info->overlay_scaler_buffer_width)){
         step_by_y=0;
         step_by_uv=1;
         h_inc_uv = h_inc;
@@ -2592,7 +2593,8 @@ RADEONDisplayVideo(
 
     RADEONWaitForFifo(pScrn, 10);
     OUTREG(RADEON_OV0_H_INC, h_inc | ((h_inc_uv >> 1) << 16));
-    OUTREG(RADEON_OV0_STEP_BY, step_by_y | (step_by_uv << 8));
+    OUTREG(RADEON_OV0_STEP_BY, step_by_y | (step_by_uv << 8) |
+	predownscale << 4 | predownscale << 12);
 
     x_off = 8;
     y_off = 0;
diff --git a/src/radeon_video.h b/src/radeon_video.h
index 33e78df..4b97d51 100644
--- a/src/radeon_video.h
+++ b/src/radeon_video.h
@@ -62,8 +62,7 @@ typedef struct {
 #define METHOD_ADAPTIVE 3
 
    int           overlay_deinterlacing_method;
-   int		 overlay_scaler_buffer_width;
-   
+
    int           capture_vbi_data;
 
    int           dec_brightness;



More information about the xorg-commit mailing list