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

📄 cim_vip.c

📁 LX 800 WindowsCE 6.0 BSP
💻 C
📖 第 1 页 / 共 4 页
字号:
 /*
  * <LIC_AMD_STD>
  * Copyright (C) 2005 Advanced Micro Devices, Inc.  All Rights Reserved.
  * </LIC_AMD_STD>
  *
  * <CTL_AMD_STD>
  * </CTL_AMD_STD>
  *
  * <DOC_AMD_STD>
  * Cimarron VIP configuration routines.
  * </DOC_AMD_STD>
  *
  */

/*---------------------------------------------------------------------------
 * vip_initialize
 *
 * This routine initializes the internal module state and prepares the
 * module for subsequent VIP orientated activities.
 *---------------------------------------------------------------------------*/

int vip_initialize(VIPSETMODEBUFFER *buffer)
{
    unsigned long vip_control1, vip_control2, vip_control3;

    if (!buffer)
        return CIM_STATUS_INVALIDPARAMS;

	vip_control1  = 0;
	vip_control2  = 0;
    vip_control3  = 0;

	/* CONFIGURE CONTROL WORDS BASED ON MODE STRUCTURE                  */
    /* Note that some of the input parameters match the register fields */
    /* they represent.                                                  */

    /* STREAM ENABLES */

	vip_control1 |= buffer->stream_enables;
	
    /* VIP CAPTURE MODE */

    vip_control1 |= buffer->operating_mode;
		
    /* HANDLE PLANAR CAPTURE */

    if (buffer->flags & VIP_MODEFLAG_PLANARCAPTURE)
    {
        vip_control1 |= VIP_CONTROL1_PLANAR;

        if (buffer->planar_capture == VIP_420CAPTURE_EVERYLINE)
        {
            vip_control1 |= VIP_CONTROL1_DISABLE_DECIMATION;
        }
        else if (buffer->planar_capture == VIP_420CAPTURE_ALTERNATINGFIELDS)
        {
            if (buffer->flags & VIP_MODEFLAG_PROGRESSIVE)
                return CIM_STATUS_INVALIDPARAMS;

            vip_control1 |= VIP_CONTROL1_DISABLE_DECIMATION;
            vip_control3 |= VIP_CONTROL3_DECIMATE_EVEN;
        }
        else if (buffer->planar_capture != VIP_420CAPTURE_ALTERNATINGLINES)
            return CIM_STATUS_INVALIDPARAMS;

        /* CONFIGURE THE VIDEO FIFO THRESHOLD BASED ON THE FIFO DEPTH */

        vip_control2 |= VIP_CONTROL2_DEFAULT_VIDTH_420 << VIP_CONTROL2_VIDTH_SHIFT;

    }
    else
    {
        vip_control2 |= VIP_CONTROL2_DEFAULT_VIDTH_422 << VIP_CONTROL2_VIDTH_SHIFT;
    }

    /* CONFIGURE DEFAULT ANCILARRY THRESHOLD AND VIDEO FLUSH VALUES */

    vip_control2 |= VIP_CONTROL2_DEFAULT_ANCTH  << VIP_CONTROL2_ANCTH_SHIFT;
    vip_control1 |= VIP_CONTROL1_DEFAULT_ANC_FF << VIP_CONTROL1_ANC_FF_SHIFT;
    vip_control1 |= VIP_CONTROL1_DEFAULT_VID_FF << VIP_CONTROL1_VID_FF_SHIFT;

    /* PROGRAM VIP OPTIONS */
    /* The options are sanitized based on the current configuration. */

    if (buffer->flags & VIP_MODEFLAG_PROGRESSIVE)
        vip_control1 |= VIP_CONTROL1_NON_INTERLACED;
    else
    {
        if (buffer->flags & VIP_MODEFLAG_TOGGLEEACHFIELD)
            vip_control3 |= VIP_CONTROL3_BASE_UPDATE;
        if (buffer->flags & VIP_MODEFLAG_INVERTPOLARITY)
            vip_control2 |= VIP_CONTROL2_INVERT_POLARITY;
    }

    if ((buffer->operating_mode == VIP_MODE_MSG ||
         buffer->operating_mode == VIP_MODE_DATA) &&
        (buffer->flags & VIP_MODEFLAG_FLIPMESSAGEWHENFULL))
    {
        vip_control1 |= VIP_CONTROL1_MSG_STRM_CTRL;
    }

    else if (buffer->operating_mode == VIP_MODE_VIP2_8BIT ||
             buffer->operating_mode == VIP_MODE_VIP2_16BIT)
    {
        if (buffer->flags & VIP_MODEFLAG_ENABLEREPEATFLAG)
            vip_control2 |= VIP_CONTROL2_REPEAT_ENABLE;
        if (buffer->flags & VIP_MODEFLAG_INVERTTASKPOLARITY)
            vip_control3 |= VIP_CONTROL3_TASK_POLARITY;
    }

	if (buffer->flags & VIP_MODEFLAG_DISABLEZERODETECT)
        vip_control1 |= VIP_CONTROL1_DISABLE_ZERO_DETECT;	
    if (buffer->flags & VIP_MODEFLAG_10BITANCILLARY)
        vip_control2 |= VIP_CONTROL2_ANC10;
        	
    /* WRITE THE CONTROL REGISTERS */
    /* The control registers are kept 'live' to allow separate instances of */
    /* Cimarron to control the VIP hardware.                                */

    WRITE_VIP32 (VIP_CONTROL1, vip_control1);
    WRITE_VIP32 (VIP_CONTROL2, vip_control2);
    WRITE_VIP32 (VIP_CONTROL3, vip_control3);

    /* CONFIGURE 601 PARAMETERS */

    if (buffer->operating_mode == VIP_MODE_8BIT601 ||
        buffer->operating_mode == VIP_MODE_16BIT601)
    {
        vip_update_601_params (&buffer->vip601_settings);
    }

    return CIM_STATUS_OK;	
}

/*---------------------------------------------------------------------------
 * vip_update_601_params
 *
 * This routine configures all aspects of 601 VIP data capture, including
 * start and stop timings and input polarities.
 *---------------------------------------------------------------------------*/

int vip_update_601_params (VIP_601PARAMS *buffer)
{
    unsigned long vip_control3, vip_control1;

    if (!buffer)
        return CIM_STATUS_INVALIDPARAMS;

    vip_control1 = READ_VIP32 (VIP_CONTROL3);
    vip_control3 = READ_VIP32 (VIP_CONTROL3);

    if (buffer->flags & VIP_MODEFLAG_VSYNCACTIVEHIGH) vip_control3 |=  VIP_CONTROL3_VSYNC_POLARITY;
    else                                              vip_control3 &= ~VIP_CONTROL3_VSYNC_POLARITY;
    if (buffer->flags & VIP_MODEFLAG_HSYNCACTIVEHIGH) vip_control3 |=  VIP_CONTROL3_HSYNC_POLARITY;
    else                                              vip_control3 &= ~VIP_CONTROL3_HSYNC_POLARITY;

    WRITE_VIP32 (VIP_CONTROL3,       vip_control3);
    WRITE_VIP32 (VIP_601_HORZ_START, buffer->horz_start);
    WRITE_VIP32 (VIP_601_VBI_START,  buffer->vbi_start);
    WRITE_VIP32 (VIP_601_VBI_END,    buffer->vbi_start + buffer->vbi_height - 1);
    WRITE_VIP32 (VIP_601_EVEN_START_STOP,
        buffer->vert_start_even | ((buffer->vert_start_even + buffer->even_height - 1) << 16));
    WRITE_VIP32 (VIP_601_ODD_START_STOP,
        buffer->vert_start_odd | ((buffer->vert_start_odd + buffer->odd_height - 1) << 16));
    WRITE_VIP32 (VIP_ODD_FIELD_DETECT,
        buffer->odd_detect_start | (buffer->odd_detect_end << 16));

    /* SPECIAL CASE FOR HORIZONTAL DATA */
    /* 601 horizontal parameters are based on the number of clocks and not the */
    /* number of pixels.                                                       */

    if ((vip_control1 & VIP_CONTROL1_MODE_MASK) == VIP_MODE_16BIT601)
        WRITE_VIP32 (VIP_601_HORZ_END,   buffer->horz_start + (buffer->width << 1) + 3);
    else
        WRITE_VIP32 (VIP_601_HORZ_END,   buffer->horz_start + buffer->width + 3);

    return CIM_STATUS_OK;
}

/*---------------------------------------------------------------------------
 * vip_configure_capture_buffers
 *
 * This routine configures the base offsets for video, ancillary or message
 * mode capture.  The input structure can also contain multiple offsets, such
 * that the calling application can avoid updating the structure for each flip.
 *
 * The new buffer addresses are written to the hardware registers although
 * they may not be latched immediately. Calling vip_is_buffer_update_latched
 * allows the determination of whether the update has occured.
 *
 * Review the Cimarron VIP API documentation to determine which buffer addresses are
 * latched immediately.
 *---------------------------------------------------------------------------*/

int vip_configure_capture_buffers (int buffer_type, VIPINPUTBUFFER *buffer)
{
    VIPINPUTBUFFER_ADDR *offsets;
    unsigned long cur_buffer = buffer->current_buffer;

    if (!buffer)
        return CIM_STATUS_INVALIDPARAMS;

	if (buffer_type == VIP_BUFFER_A || buffer_type == VIP_BUFFER_601)
    {
        offsets = &buffer->offsets[VIP_BUFFER_TASK_A];

        /* SET VIDEO PITCH */

        WRITE_VIP32 (VIP_TASKA_VID_PITCH, offsets->y_pitch | (offsets->uv_pitch << 16));

        /* SET BASE OFFSETS */

        if (buffer->flags & VIP_INPUTFLAG_INVERTPOLARITY)
        {
            WRITE_VIP32 (VIP_TASKA_VID_ODD_BASE,  offsets->even_base[cur_buffer]);
            WRITE_VIP32 (VIP_TASKA_VID_EVEN_BASE, offsets->odd_base[cur_buffer]);
            if (buffer->flags & VIP_INPUTFLAG_VBI)
            {
                WRITE_VIP32 (VIP_TASKA_VBI_ODD_BASE,  offsets->vbi_even_base);
                WRITE_VIP32 (VIP_TASKA_VBI_EVEN_BASE, offsets->vbi_odd_base);
            }
        }
        else
        {
            WRITE_VIP32 (VIP_TASKA_VID_ODD_BASE,  offsets->odd_base[cur_buffer]);
            WRITE_VIP32 (VIP_TASKA_VID_EVEN_BASE, offsets->even_base[cur_buffer]);
            if (buffer->flags & VIP_INPUTFLAG_VBI)
            {
                WRITE_VIP32 (VIP_TASKA_VBI_ODD_BASE,  offsets->vbi_odd_base);
                WRITE_VIP32 (VIP_TASKA_VBI_EVEN_BASE, offsets->vbi_even_base);
            }
        }

        /* SET 4:2:0 OFFSETS */

        if (buffer->flags & VIP_INPUTFLAG_PLANAR)
        {
            WRITE_VIP32 (VIP_TASKA_U_OFFSET, offsets->odd_uoffset);
            WRITE_VIP32 (VIP_TASKA_V_OFFSET, offsets->odd_voffset);
            WRITE_VIP32 (VIP_TASKA_U_EVEN_OFFSET, offsets->even_uoffset);
            WRITE_VIP32 (VIP_TASKA_V_EVEN_OFFSET, offsets->even_voffset);
        }
    }
    else if (buffer_type == VIP_BUFFER_B)
    {
        offsets = &buffer->offsets[VIP_BUFFER_TASK_B];

        /* SET VIDEO PITCH */

        WRITE_VIP32 (VIP_TASKB_VID_PITCH, offsets->y_pitch | (offsets->uv_pitch << 16));

        /* SET BASE OFFSETS */

        if (buffer->flags & VIP_INPUTFLAG_INVERTPOLARITY)
        {
            WRITE_VIP32 (VIP_TASKB_VID_ODD_BASE,  offsets->even_base[cur_buffer]);
            WRITE_VIP32 (VIP_TASKB_VID_EVEN_BASE, offsets->odd_base[cur_buffer]);
            if (buffer->flags & VIP_INPUTFLAG_VBI)
            {
                WRITE_VIP32 (VIP_TASKB_VBI_ODD_BASE,  offsets->vbi_even_base);
                WRITE_VIP32 (VIP_TASKB_VBI_EVEN_BASE, offsets->vbi_odd_base);
            }
        }
        else
        {
            WRITE_VIP32 (VIP_TASKB_VID_ODD_BASE,  offsets->odd_base[cur_buffer]);
            WRITE_VIP32 (VIP_TASKB_VID_EVEN_BASE, offsets->even_base[cur_buffer]);
            if (buffer->flags & VIP_INPUTFLAG_VBI)
            {
                WRITE_VIP32 (VIP_TASKB_VBI_ODD_BASE,  offsets->vbi_odd_base);
                WRITE_VIP32 (VIP_TASKB_VBI_EVEN_BASE, offsets->vbi_even_base);
            }
        }

        /* SET 4:2:0 OFFSETS */

        if (buffer->flags & VIP_INPUTFLAG_PLANAR)
        {
            WRITE_VIP32 (VIP_TASKB_U_OFFSET, offsets->odd_uoffset);
            WRITE_VIP32 (VIP_TASKB_V_OFFSET, offsets->odd_voffset);
        }
    }
    else if (buffer_type == VIP_BUFFER_ANC || buffer_type == VIP_BUFFER_MSG)
    {
        WRITE_VIP32(VIP_ANC_MSG1_BASE, buffer->ancillaryData.msg1_base);
		WRITE_VIP32(VIP_ANC_MSG2_BASE, buffer->ancillaryData.msg2_base);
		WRITE_VIP32(VIP_ANC_MSG_SIZE,  buffer->ancillaryData.msg_size);
    }
    else
    {
        return CIM_STATUS_INVALIDPARAMS;
    }

    return CIM_STATUS_OK;
}

/*---------------------------------------------------------------------------
 * vip_toggle_vip_video_offsets
 *
 * This routine updates the offsets for video capture.  It is a simplified
 * version of vip_configure_capture_buffers that is designed to be called from
 * interrupt service routines or other buffer flipping applications that
 * require low latency.
 *---------------------------------------------------------------------------*/

int vip_toggle_video_offsets (int buffer_type, VIPINPUTBUFFER *buffer)
{
    unsigned long cur_buffer = buffer->current_buffer;
    VIPINPUTBUFFER_ADDR *offsets;

	if (buffer_type == VIP_BUFFER_A)
    {
        offsets = &buffer->offsets[VIP_BUFFER_TASK_A];

        /* SET BASE OFFSETS */

        if (buffer->flags & VIP_INPUTFLAG_INVERTPOLARITY)
        {
            WRITE_VIP32 (VIP_TASKA_VID_ODD_BASE,  offsets->even_base[cur_buffer]);
            WRITE_VIP32 (VIP_TASKA_VID_EVEN_BASE, offsets->odd_base[cur_buffer]);
        }
        else
        {
            WRITE_VIP32 (VIP_TASKA_VID_ODD_BASE,  offsets->odd_base[cur_buffer]);
            WRITE_VIP32 (VIP_TASKA_VID_EVEN_BASE, offsets->even_base[cur_buffer]);
        }
    }
    else if (buffer_type == VIP_BUFFER_B)
    {
        offsets = &buffer->offsets[VIP_BUFFER_TASK_B];

        /* SET BASE OFFSETS */

        if (buffer->flags & VIP_INPUTFLAG_INVERTPOLARITY)
        {
            WRITE_VIP32 (VIP_TASKB_VID_ODD_BASE,  offsets->even_base[cur_buffer]);
            WRITE_VIP32 (VIP_TASKB_VID_EVEN_BASE, offsets->odd_base[cur_buffer]);
        }
        else
        {
            WRITE_VIP32 (VIP_TASKB_VID_ODD_BASE,  offsets->odd_base[cur_buffer]);
            WRITE_VIP32 (VIP_TASKB_VID_EVEN_BASE, offsets->even_base[cur_buffer]);
        }
    }
    else if (buffer_type == VIP_BUFFER_A_ODD)
    {
        offsets = &buffer->offsets[VIP_BUFFER_TASK_A];

        /* SET BASE OFFSETS */

        if (buffer->flags & VIP_INPUTFLAG_INVERTPOLARITY)
            WRITE_VIP32 (VIP_TASKA_VID_ODD_BASE,  offsets->even_base[cur_buffer]);
        else
            WRITE_VIP32 (VIP_TASKA_VID_ODD_BASE,  offsets->odd_base[cur_buffer]);
    }
    else if (buffer_type == VIP_BUFFER_A_EVEN)
    {
        offsets = &buffer->offsets[VIP_BUFFER_TASK_A];

        /* SET BASE OFFSETS */

        if (buffer->flags & VIP_INPUTFLAG_INVERTPOLARITY)
            WRITE_VIP32 (VIP_TASKA_VID_EVEN_BASE, offsets->odd_base[cur_buffer]);
        else
            WRITE_VIP32 (VIP_TASKA_VID_EVEN_BASE,  offsets->even_base[cur_buffer]);
    }
    else if (buffer_type == VIP_BUFFER_B_ODD)
    {
        offsets = &buffer->offsets[VIP_BUFFER_TASK_B];

        /* SET BASE OFFSETS */

        if (buffer->flags & VIP_INPUTFLAG_INVERTPOLARITY)
            WRITE_VIP32 (VIP_TASKB_VID_ODD_BASE,  offsets->even_base[cur_buffer]);
        else
            WRITE_VIP32 (VIP_TASKB_VID_ODD_BASE,  offsets->odd_base[cur_buffer]);
    }
    else if (buffer_type == VIP_BUFFER_B_EVEN)
    {
        offsets = &buffer->offsets[VIP_BUFFER_TASK_B];

        /* SET BASE OFFSETS */

        if (buffer->flags & VIP_INPUTFLAG_INVERTPOLARITY)
            WRITE_VIP32 (VIP_TASKB_VID_EVEN_BASE, offsets->odd_base[cur_buffer]);
        else
            WRITE_VIP32 (VIP_TASKB_VID_EVEN_BASE, offsets->even_base[cur_buffer]);
    }
    else
        return CIM_STATUS_INVALIDPARAMS;

    return CIM_STATUS_OK;

⌨️ 快捷键说明

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