⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cim_df.c

📁 LX 800 WindowsCE 6.0 BSP
💻 C
📖 第 1 页 / 共 5 页
字号:
        }
        
        /* PROGRAM A NEW LINE SIZE */
        /* The line size must be updated when using the Double Horizontal  */
        /* Downscale (DHD) bit.  This is because the amount of VFIFO space */
        /* consumed is effectively half in this mode.                      */

        size  = ((src_width >> 1) + 7) & 0xFFF8;
	    vcfg |= (size & 0x00FF) << 8;
	    if (size & 0x0100) vcfg |= DF_VCFG_LINE_SIZE_BIT8;
	    if (size & 0x0200) vcfg |= DF_VCFG_LINE_SIZE_BIT9;
        WRITE_VID32 (DF_VIDEO_CONFIG, vcfg);
        WRITE_VID32 (DF_VIDEO_XSCALE, ((0x10000 * src_width) / dst_width));
    }
    if (flags & DF_SCALEFLAG_CHANGEY)
    {
        unlock = READ_REG32 (DC3_UNLOCK);
        gcfg   = READ_REG32 (DC3_GENERAL_CFG) & ~DC3_GCFG_VDSE;
        WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
        if (dst_height < (src_height >> 1))
        {
            gcfg |= DC3_GCFG_VDSE;
            downscale = READ_REG32 (DC3_VID_DS_DELTA) & ~DC3_DS_DELTA_MASK;
            if (dst_height == (src_height >> 2))
                downscale |= (0x3FFF << 18);
            else
                downscale |= (((src_height >> 1) << 14) / dst_height) << 18;
            
            WRITE_REG32 (DC3_VID_DS_DELTA, downscale);
            WRITE_VID32 (DF_VIDEO_YSCALE, 0x20000);
        }
        else
        {
            WRITE_VID32 (DF_VIDEO_YSCALE, ((0x10000 * src_height) / dst_height));
        }
        WRITE_REG32 (DC3_GENERAL_CFG, gcfg);
        WRITE_REG32 (DC3_UNLOCK, unlock);
    }

	/* CHECK IF SCALING IS DISABLED */
	/* If no scaling occurs, we disable the hardware filter. */

	temp = READ_VID32 (DF_VIDEO_CONFIG);
	if ((READ_VID32 (DF_VIDEO_XSCALE) == 0x10000) &&
		(READ_VID32 (DF_VIDEO_YSCALE) == 0x10000))
	{
		WRITE_VID32 (DF_VIDEO_CONFIG, (temp | DF_VCFG_SC_BYP));
	}
	else
		WRITE_VID32 (DF_VIDEO_CONFIG, (temp & ~DF_VCFG_SC_BYP));

	return CIM_STATUS_OK;
}

/*---------------------------------------------------------------------------
 * df_set_video_position
 *
 * This routine programs the position of the video window on the display.
 * An indent parameter is also passed to this program to prevent artifacts
 * when the video window is moved beyond the left edge of the screen.
 *---------------------------------------------------------------------------*/

int df_set_video_position (DF_VIDEO_POSITION *video_window)
{
	unsigned long vblankstart_even, vblankend_even, vsyncend_even, vtotal_even, vactive_even;
    unsigned long hblankstart, hblankend, hsyncend, htotal, hactive;
	unsigned long vblankstart, vblankend, vsyncend, vtotal, vactive;
    unsigned long width, height, height_even;
    unsigned long adjust, border_x, border_y, border_y_even;
	unsigned long xstart, xend;
	unsigned long ystart, yend;
	unsigned long ckey_x, ckey_y;
    unsigned long x_copy, y_copy;
    unsigned long width_copy, height_copy;
	unsigned long vcfg, initread;
    unsigned long xscale, dst_clip;
    unsigned long ypos, ypos_even;
    unsigned long y, gfxscale;
    unsigned long misc, fbactive;
    unsigned long scale, src;
    unsigned long irq_ctl;
    unsigned long unlock;

	hsyncend    = ((READ_REG32 (DC3_H_SYNC_TIMING)   >> 16) & 0xFFF) + 1;
	vsyncend    = ((READ_REG32 (DC3_V_SYNC_TIMING)   >> 16) & 0xFFF) + 1;
    vblankend   = ((READ_REG32 (DC3_V_BLANK_TIMING)   >> 16) & 0xFFF) + 1;
    hblankend   = ((READ_REG32 (DC3_H_BLANK_TIMING)   >> 16) & 0xFFF) + 1;
	htotal      = ((READ_REG32 (DC3_H_ACTIVE_TIMING) >> 16) & 0xFFF) + 1;
	vtotal      = ((READ_REG32 (DC3_V_ACTIVE_TIMING) >> 16) & 0xFFF) + 1;
	vblankstart =  (READ_REG32 (DC3_V_BLANK_TIMING)  & 0xFFF) + 1;
    hblankstart =  (READ_REG32 (DC3_H_BLANK_TIMING)  & 0xFFF) + 1;
    hactive     =  (READ_REG32 (DC3_H_ACTIVE_TIMING) & 0xFFF) + 1;
	vactive     =  (READ_REG32 (DC3_V_ACTIVE_TIMING) & 0xFFF) + 1;
    unlock      =   READ_REG32 (DC3_UNLOCK);

    /* INCLUDE BORDER IF REQUESTED */

    if (video_window->flags & DF_POSFLAG_INCLUDEBORDER)
    {
        border_x = htotal - hblankend;
        border_y = vtotal - vblankend;
        hactive = hblankstart + htotal - hblankend;
        vactive = vblankstart + vtotal - vblankend;
    }
    else
    {
        border_x = border_y = 0;
    }

    /* APPLY THE GRAPHICS SCALE     */
    /* Do not alter the input data. */

    width_copy  = video_window->width;
    height_copy = video_window->height;
    x_copy = video_window->x;
    y_copy = video_window->y;

    misc = READ_VID32 (DF_VID_MISC);
    if (misc & DF_USER_IMPLICIT_SCALING)
    {
        gfxscale = READ_REG32 (DC3_GFX_SCALE);
        fbactive = READ_REG32 (DC3_FB_ACTIVE);

        /* REVERSE ENGINEER THE SCALE FACTOR */

        scale =  gfxscale & 0xFFFF;
        src   = (fbactive >> 16) + 1;
        if (scale != 0x4000)
        {
            width_copy = width_copy * (((0x4000 * src) / scale) + 1);
            width_copy /= src;
            x_copy = x_copy * (((0x4000 * src) / scale) + 1);
            x_copy /= src;
        }

        scale =  gfxscale >> 16;
        src   = (fbactive & 0xFFFF) + 1;
        if (scale != 0x4000)
        {
            height_copy = height_copy * (((0x4000 * src) / scale) + 1);
            height_copy /= src;
            y_copy = y_copy * (((0x4000 * src) / scale) + 1);
            y_copy /= src;
        }
    }

    /* HANDLE INTERLACING */
    /* When the output is interlaced, we must set the position and height */
    /* on the fields and not on the composite image.                      */

    if ((irq_ctl = READ_REG32 (DC3_IRQ_FILT_CTL)) & DC3_IRQFILT_INTL_EN)
    {
        vsyncend_even    = ((READ_REG32 (DC3_V_SYNC_EVEN)   >> 16) & 0xFFF) + 1;
        vtotal_even      = ((READ_REG32 (DC3_V_ACTIVE_EVEN) >> 16) & 0xFFF) + 1;
        vblankend_even   = ((READ_REG32 (DC3_V_BLANK_EVEN)  >> 16) & 0xFFF) + 1;
        vactive_even     =  (READ_REG32 (DC3_V_ACTIVE_EVEN) & 0xFFF) + 1;
        vblankstart_even =  (READ_REG32 (DC3_V_BLANK_EVEN)  & 0xFFF) + 1;

        if (video_window->flags & DF_POSFLAG_INCLUDEBORDER)
        {
            border_y_even = vtotal_even- vblankend_even;
            vactive_even = vblankstart_even + vtotal_even - vblankend_even;
        }
        else
            border_y_even = 0;

        /* THE ODD FIELD MUST ALWAYS PRECEDE THE EVEN FIELD */
        /* This implies that we can never start video on an odd y position   */
        /* in the composite image.  This is required because the only way to */
        /* accomplish an odd y start would be to switch the buffer offsets,  */
        /* which could have serious repercussions for genlocked VIP.         */

        y = y_copy >> 1;

        /* CALCULATE Y POSITION FOR ODD FIELD */
        /* Clip the video window to the odd field timings. Note that the */
        /* height in the odd field may be greater if the video height is */
        /* odd.                                                          */

        height = (height_copy + 1) >> 1;
        if ((y + height) > vactive)
		    height = vactive - y;

        ystart = y + vtotal_even - vsyncend_even + 1;
        if (video_window->flags & DF_POSFLAG_INCLUDEBORDER)
            ystart -= border_y_even;

        yend   = ystart + height;
        ypos   = (yend << 16) | ystart;

        /* CALCULATE Y POSITION FOR EVEN FIELD */

        height_even = height_copy >> 1;
        if ((y + height_even) > vactive_even)
		    height_even = vactive_even - y;

        ystart = y + vtotal - vsyncend + 1;
        if (video_window->flags & DF_POSFLAG_INCLUDEBORDER)
            ystart -= border_y;

        yend = ystart + height_even;
        ypos_even = (yend << 16) | ystart;

        /* CALCULATE ACTUAL FRAME BUFFER HEIGHT */
        /* The y position and height are used to determine the actual    */
        /* placement of the color key region.  The region will either be */
        /* the sum of the even and odd fields (for interlaced addressing */
        /* or flicker filtering) or it will be the union of the two (for */
        /* line doubling).  We must also adjust the region such that the */
        /* origin (0, 0) is centered on the beginning of graphics data.  */
        /* This is only a problem if video is being displayed over the   */
        /* overscan area.                                                */

        if ((READ_REG32 (DC3_GENLK_CTL) & DC3_GC_FLICKER_FILTER_ENABLE) ||
            (irq_ctl & DC3_IRQFILT_INTL_ADDR))
        {
            y <<= 1;
            height += height_even;
            adjust = border_y + border_y_even;
        }
        else
        {
            adjust = border_y;
            if (height_even > height)
                height = height_even;
        }
        if (video_window->flags & DF_POSFLAG_INCLUDEBORDER)
        {
            if (y > adjust)
            {
                y -= adjust;
                adjust = 0;
            }
            else
            {
                adjust -= y;
                if (height > adjust)
                    height -= adjust;
                else
                    height = 0;
            }
        }

    }
    else
    {
        y = y_copy;

        height = height_copy;
        if ((y + height) > vactive)
		    height = vactive - y;

        ystart = y + vtotal - vsyncend + 1;
        if (video_window->flags & DF_POSFLAG_INCLUDEBORDER)
            ystart -= border_y;

        yend = ystart + height;
        ypos = (yend << 16) | ystart;
        ypos_even = 0;
    }
	
    /* HORIZONTAL POSITION */
    /* The horizontal values are identical for the even and odd field. */

    width   = width_copy;
	xstart  = x_copy + htotal - hsyncend - 14;
    if (video_window->flags & DF_POSFLAG_INCLUDEBORDER)
        xstart -= border_x;

	/* RIGHT CLIPPING */

	if ((x_copy + width) > hactive)
		width = hactive - x_copy;
	
	xend = xstart + width;
	
	/* CALCULATE LEFT CLIPPING PARAMETER */
	/* The value passed in can be interpreted as destination pixels, in which   */
	/* case the video scale is factored in, or as source pixels, in which case  */
	/* the value is written directly.  Also, the display filter's initial read  */
	/* address value is only programmable on 4-pixel increments.  However, we   */
	/* can achieve an arbitrary left clip by adjusting the xstart value, as     */
	/* there is a 14-clock delay in which to play.  Also, according to the      */
	/* designers, 4:2:0 and 4:2:2 behave identically when setting the initial   */
	/* read address.  The addition of scaling further complicates the           */
    /* algorithm.  When setting the initial read address, it is in terms of     */
    /* source pixels, while adjusting the xstart value is in destination pixels */
    /* We may thus not be able to achieve a perfect clipping fit for scaled     */
    /* video.   We compensate by including two clipping parameters in our       */
    /* structure.  This allows us the user additional control and it allows us  */
    /* to accurately convey to the user the state of clipping on the machine.   */

	initread = video_window->left_clip;
    dst_clip = 0;
	if (!(video_window->flags & DF_POSFLAG_DIRECTCLIP))
    {
        xscale = READ_VID32 (DF_VIDEO_XSCALE) & 0xFFFFF;
		initread =  (initread * xscale) / 0x10000;
        if (xscale)
            dst_clip = ((initread & 3) * 0x10000) / xscale;
    }
    else
        dst_clip = video_window->dst_clip;
		
    /* LIMIT THE CLIP */
    /* We technically have a 14 pixel window in which to play.  However, taking */
    /* the entire 14 pixels makes the video timing a little hairy...  Also note */
    /* that we cannot do this when performing panel centering, as the video     */
    /* would then exceed the mode size.                                         */

    if (dst_clip > 4)
        dst_clip = 4;
    if (READ_REG32 (DC3_DISPLAY_CFG) & DC3_DCFG_DCEN)
        dst_clip = 0;

	xstart -= dst_clip;
    	
	vcfg = READ_VID32 (DF_VIDEO_CONFIG);
	vcfg &= ~DF_VCFG_INIT_READ_MASK;
	vcfg |= (initread >> 2) << 16;

	/* SET COLOR KEY REGION */
	/* We are assuming that color keying will never be desired outside   */
	/* of the video region.  We adjust the color key region for graphics */
    /* scaling.                                                          */

    gfxscale = READ_REG32 (DC3_GFX_SCALE);

    ckey_x =   ((x_copy * (gfxscale & 0xFFFF)) / 0x4000) |
             ((((x_copy + width) * (gfxscale & 0xFFFF)) / 0x4000) << 16);
	ckey_y =   ((y * (gfxscale >> 16)) / 0x4000) |
             ((((y + height) * (gfxscale >> 16)) / 0x4000) << 16);

	/* WRITE ALL PARAMETERS AT ONCE */

    WRITE_REG32 (DC3_UNLOCK, DC3_UNLOCK_VALUE);
	WRITE_REG32 (DC3_CLR_KEY_X, ckey_x);
	WRITE_REG32 (DC3_CLR_KEY_Y, ckey_y);
	WRITE_VID32 (DF_VIDEO_X_POS, (xend << 16) | xstart);
	WRITE_VID32 (DF_VIDEO_Y_POS, ypos);
    WRITE_VID32 (DF_VID_YPOS_EVEN, ypos_even);
	WRITE_VID32 (DF_VIDEO_CONFIG, vcfg);
    WRITE_REG32 (DC3_UNLOCK, unlock);

	return CIM_STATUS_OK;
}

/*---------------------------------------------------------------------------
 * df_set_video_filter_coefficients
 *
 * This routine sets the horizontal and vertical filter coefficients for video
 * scaling.  These coefficients are used for upscaling and downscaling video.
 * If the phase256 parameter is 1, the coefficient arrays are used as single
 * arrays of 256 phases for both vertical and horizontal scaling.  If the
 * phase256 parameter is clear, the coefficient arrays are used as two 128-phase
 * arrays.  The first 128 entries represent the phases for vertical scaling.
 * The last 128 entries represent the phases for horizontal scaling.
 *---------------------------------------------------------------------------*/

int df_set_video_filter_coefficients (long taps[][4], int phase256)
{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -