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

📄 dispfmt.c

📁 IT projecotr reference design.
💻 C
📖 第 1 页 / 共 2 页
字号:

    if( dispfmt_ApplyFlip() != PASS )
    {
        rearProjection = temp;
        return FAIL;
    }  
    
    if( dispfmt_ApplyDisplay() != PASS )
    {
        rearProjection = temp;
        dispfmt_ApplyFlip();
        return FAIL;
    }
    
    return PASS;
}

/****************************************************************************/
/* Ceiling projection user controls                                         */
/****************************************************************************/
int08 dispfmt_SetCeilingProjection( uint08 enable )
{
    int16 min, max;
    uint08 temp1;
    int16 temp2;
    
    temp1 = ceilingMount;
    temp2 = anglePitch;
    
    /* Pitch range for Angle Keystone flips when using Ceiling Mount. Ensure that it is within bounds */
    if( enable != ceilingMount ) 
    {
        /* get the range, then negate it -- note that the parameters to DISP_GetKeystonePitchRange are reversed */
        DISP_GetKeystonePitchRange( &min, &max ); 
        min *= -1;
        max *= -1;
        
        /* limit the keystone value to the new range */
        if( anglePitch > max )
            anglePitch = max;
        if( anglePitch < min )
            anglePitch = min;
    }

    ceilingMount = enable;
    if( dispfmt_ApplyFlip() != PASS )
    {
        ceilingMount = temp1;
        anglePitch = temp2;
        return FAIL;
    }
    
    /* reapply keystone because the vertical offset needs to be negated (and pitch might have changed) */
    if( dispfmt_ApplyKeystone() != PASS )
    {
        ceilingMount = temp1;
        anglePitch = temp2;
        dispfmt_ApplyFlip();
        return FAIL;
    }
    
    /* must call applyDisplay to apply new values to hardware */
    if( dispfmt_ApplyDisplay() != PASS )
    {
        ceilingMount = temp1;
        anglePitch = temp2;
        dispfmt_ApplyFlip();
        dispfmt_ApplyKeystone();
        return FAIL;
    }

    return PASS;
}

/****************************************************************************/
/* Keystone user controls                                                   */
/****************************************************************************/
int08 dispfmt_GetKeystoneAnglePitchLimits( int16 *min, int16 *max )
{
    /* note: this requires DISP_SetKeystoneAngles to be called prior to this function */
    return DISP_GetKeystonePitchRange( max, min );
}

int08 dispfmt_GetKeystoneAnglePitch( int16 *pitch )
{
    *pitch = anglePitch;
    
    return TRUE;
}

void dispfmt_SetKeystoneConfigOverride( uint16 throwratio, int16 offset )
{
    throwRatio = throwratio;
    verticalOffset = offset;
}

int08 dispfmt_SetKeystoneAnglePitch( int16 pitch )
{
    int16 min, max, temp;
    
    dispfmt_GetKeystoneAnglePitchLimits( &min, &max );
    if( pitch < min || pitch > max )
        return FAIL;

    temp = anglePitch;
    anglePitch = pitch;
    
    if( dispfmt_ApplyKeystone() != PASS )
    {
        anglePitch = temp;
        return FAIL;
    }
    
    if( dispfmt_ApplyDisplay() != PASS )
    {
        anglePitch = temp;
        dispfmt_ApplyKeystone();
        return FAIL;
    }

    return PASS;
}


/****************************************************************************/
/* Configure the deinterlacer                                               */
/****************************************************************************/
void dispfmt_ApplyDEI( void )
{
    DP_SOURCEDESC *srcDesc;

    datapath_GetSourceDesc( &srcDesc );
    
    if( !srcDesc->sourceActive )
    {
        return;
    }
    
    if( srcDesc->okToDeinterlace )
    {
        DEI_SetMotionAdaptiveMode(DEI_MOTION_ADAPTIVE);
        DEI_SetIntraFieldInterpolationStrength(DEI_OPTIMIZED_3);
        
        DEI_Enable( TRUE );

        /* configure film mode cadence detection */
        if( 57.0f <= srcDesc->inputFrameRate && srcDesc->inputFrameRate <= 63.0f ) /* search for 3:2 cadence on 60Hz sources */
        {
            DEI_SetFilmModeLockThresholds( 1, 1 );
            DEI_SetFilmMode( DEI_MODE_SW_3_2 );
            dbmsg_trace( DBM_DPATH, "DEI Enabled (NTSC)\r\n" );
        }
        else if( 47.0f <= srcDesc->inputFrameRate && srcDesc->inputFrameRate <= 53.0f ) /* search for 2:2 cadence on 50Hz sources */
        {
            DEI_SetFilmModeLockThresholds( 10, 1 );
            DEI_SetFilmMode( DEI_MODE_SW_2_2 );
            dbmsg_trace( DBM_DPATH, "DEI Enabled (PAL)\r\n" );
        }
        else
        {
            DEI_SetFilmMode( DEI_MODE_DISABLE );
            dbmsg_trace( DBM_DPATH, "DEI Enabled (unknown standard)\r\n" );
        }
    }
    else
    {
        DEI_Enable( FALSE );
        dbmsg_trace( DBM_DPATH, "DEI Disabled\r\n" );
    }
}


void dispfmt_CalculateCroppedArea( DP_SOURCEDESC *srcDesc, DISP_DISPLAY_CONFIG *disp_cfg )
{
    disp_cfg->CroppedArea.FirstPixel = 0;
    disp_cfg->CroppedArea.FirstLine = 0;
    disp_cfg->CroppedArea.PixelsPerLine = srcDesc->inputWidth;
    disp_cfg->CroppedArea.LinesPerFrame = srcDesc->inputHeight;

    /* crop splash if the DisplayArea is smaller than the splash */
    /* overscan, magnify, and pan & scan are not supported */
    if( srcDesc->activeDisplay == DP_SPLASH )
    {
        if( disp_cfg->CroppedArea.PixelsPerLine > disp_cfg->DisplayArea.PixelsPerLine )
        {
            disp_cfg->CroppedArea.FirstPixel = (disp_cfg->CroppedArea.PixelsPerLine - disp_cfg->DisplayArea.PixelsPerLine)/2;
            disp_cfg->CroppedArea.PixelsPerLine = disp_cfg->DisplayArea.PixelsPerLine;
        }
        if( disp_cfg->CroppedArea.LinesPerFrame > disp_cfg->DisplayArea.LinesPerFrame )
        {
            disp_cfg->CroppedArea.FirstLine = (disp_cfg->CroppedArea.LinesPerFrame - disp_cfg->DisplayArea.LinesPerFrame)/2;
            disp_cfg->CroppedArea.LinesPerFrame = disp_cfg->DisplayArea.LinesPerFrame;
        } 
        return;
    }

    /* overscan, magnify, and pan & scan are not supported for TPG or SFG */
    if( srcDesc->activeDisplay != DP_EXTERNAL )
        return;
    
    /* calculate CroppedArea for external sources */
    
    /* compute cropping for overscan  */
    if( overscan == TRUE )
    {
        disp_cfg->CroppedArea.PixelsPerLine -= srcDesc->inputWidth/10;
        disp_cfg->CroppedArea.LinesPerFrame -= srcDesc->inputHeight/10;
    }
    
    /* compute magnification -- scale_factor = (magnify_percent + 100%)/100 */
    disp_cfg->CroppedArea.PixelsPerLine = disp_cfg->CroppedArea.PixelsPerLine * 100 / (magnifyPercent + 100);
    disp_cfg->CroppedArea.LinesPerFrame = disp_cfg->CroppedArea.LinesPerFrame * 100 / (magnifyPercent + 100);

    /* compute pan */
    disp_cfg->CroppedArea.FirstPixel += (srcDesc->inputWidth - disp_cfg->CroppedArea.PixelsPerLine)/2; /* center image */
    minPan = -1 * disp_cfg->CroppedArea.FirstPixel;
    maxPan = srcDesc->inputWidth - (disp_cfg->CroppedArea.FirstPixel + disp_cfg->CroppedArea.PixelsPerLine);
    if( pan < minPan )
    {
        disp_cfg->CroppedArea.FirstPixel += minPan;
    }
    else if( pan > maxPan )
    {
        disp_cfg->CroppedArea.FirstPixel += maxPan;
    }
    else
    {
        disp_cfg->CroppedArea.FirstPixel += pan;
    }
    
    /* compute scan */
    disp_cfg->CroppedArea.FirstLine += (srcDesc->inputHeight - disp_cfg->CroppedArea.LinesPerFrame)/2; /* center image */    
    minScan = -1 * disp_cfg->CroppedArea.FirstLine;
    maxScan = srcDesc->inputHeight - (disp_cfg->CroppedArea.FirstLine + disp_cfg->CroppedArea.LinesPerFrame);
    if( scan < minScan )
    {
        disp_cfg->CroppedArea.FirstLine += minScan;
    }
    else if( scan > maxScan )
    {
        disp_cfg->CroppedArea.FirstLine += maxScan;
    }
    else
    {
        disp_cfg->CroppedArea.FirstLine += scan;
    }
}

void dispfmt_CalculateDisplayArea( DP_SOURCEDESC *srcDesc, DISP_DISPLAY_CONFIG *disp_cfg )
{
    uint16 dmdWidth, dmdHeight;
    uint16 ratiox, ratioy;

    DMD_GetResolution( &dmdWidth, &dmdHeight );    
    
    /* set the aspect ratio correction */
    switch( aspectRatio )
    {
        case 1:  //native
            ratiox = srcDesc->nativeWidth;
            ratioy = srcDesc->nativeHeight;
            break;

        case 2: //4:3
            ratiox = 4;
            ratioy = 3;
            break;
            
        case 3:  //16:9
            ratiox = 16;
            ratioy = 9;
            break;
            
        case 0:  //fill (uses DMD aspect ratio)
        default:
            ratiox = dmdWidth;
            ratioy = dmdHeight;
            break;
    }

    /* calculate the output image size (number of lines) */
    switch( imageSize )
    {
        case 2: //Manual
            if( imageSizeSteps > dmdHeight )
            {
                disp_cfg->DisplayArea.LinesPerFrame = dmdHeight;
            }
            else
            {
                disp_cfg->DisplayArea.LinesPerFrame = imageSizeSteps;
            }
            break;
            
        case 1: //Native
            if( srcDesc->nativeHeight <= dmdHeight )
            {
                disp_cfg->DisplayArea.LinesPerFrame = srcDesc->nativeHeight;
            }
            else
            {
                disp_cfg->DisplayArea.LinesPerFrame = dmdHeight;
            }
            break;
            
        case 0:  //Fill
        default:
            disp_cfg->DisplayArea.LinesPerFrame = dmdHeight;
            break;
    }
    
    /* calculate the image width based on the image size and aspect ratio */
    disp_cfg->DisplayArea.PixelsPerLine = disp_cfg->DisplayArea.LinesPerFrame * ratiox / ratioy;

    /* limit to the size of the DMD */
    if( disp_cfg->DisplayArea.PixelsPerLine > dmdWidth )
    {
        disp_cfg->DisplayArea.PixelsPerLine = dmdWidth;
        disp_cfg->DisplayArea.LinesPerFrame = disp_cfg->DisplayArea.PixelsPerLine * ratioy / ratiox;
    }
    
    /* calculate the image position */
    disp_cfg->Centered = FALSE;
    
    /* calculate the horizontal position -- image must be centered to work correctly with keystone */
    disp_cfg->DisplayArea.FirstPixel = (dmdWidth - disp_cfg->DisplayArea.PixelsPerLine)/2;  /* center image */
    
    /* calculate the vertical position */
    disp_cfg->DisplayArea.FirstLine = (dmdHeight - disp_cfg->DisplayArea.LinesPerFrame)/2;  /* center image */
    minImagePosy = -1 * disp_cfg->DisplayArea.FirstLine;
    maxImagePosy = dmdHeight - (disp_cfg->DisplayArea.FirstLine + disp_cfg->DisplayArea.LinesPerFrame);
    if( imagePosy < minImagePosy )
    {
        disp_cfg->DisplayArea.FirstLine += minImagePosy;
    }
    else if( imagePosy > maxImagePosy )
    {
        disp_cfg->DisplayArea.FirstLine += maxImagePosy;
    }
    else
    {
        disp_cfg->DisplayArea.FirstLine += imagePosy;
    }
}

void dispfmt_ApplyScalingFilter( DP_SOURCEDESC *srcDesc, DISP_DISPLAY_CONFIG *disp_cfg )
{  
    if( srcDesc->isVideo || anglePitch != 0.0f )
    {
        if( disp_cfg->CroppedArea.LinesPerFrame >= disp_cfg->DisplayArea.LinesPerFrame )
            DISP_SetScalingFilter( DISP_VIDEO_DOWNSCALING );
        else
            DISP_SetScalingFilter( DISP_VIDEO_UPSCALING );
    }
    else
    {
        if( disp_cfg->CroppedArea.LinesPerFrame >= disp_cfg->DisplayArea.LinesPerFrame )
            DISP_SetScalingFilter( DISP_GRAPHICS_DOWNSCALING );
        else
            DISP_SetScalingFilter( DISP_GRAPHICS_UPSCALING );    
    }
}

int08 dispfmt_ApplyDisplay( void )
{
    DISP_DISPLAY_CONFIG disp_cfg;
    int08 result = PASS;
    DP_SOURCEDESC *srcDesc;
    
    datapath_GetSourceDesc( &srcDesc );

    disp_cfg.Centered = FALSE;
    dispfmt_CalculateDisplayArea( srcDesc, &disp_cfg );
    dispfmt_CalculateCroppedArea( srcDesc, &disp_cfg );
    
    /* apply the settings to hardware */    
    result = DISP_SetDisplay( SRC_PRIMARY, disp_cfg ); 
    if( result < PASS )
    {
        dbmsg_ftrace( DBM_DPATH, "dispfmt: DISP_SetDisplay failed (ret=%d)\r\n", result );
        dbmsg_ftrace( DBM_DPATH, "         CroppedArea = { %d, %d, %d, %d }\r\n", disp_cfg.CroppedArea.FirstPixel, disp_cfg.CroppedArea.FirstLine, disp_cfg.CroppedArea.PixelsPerLine, disp_cfg.CroppedArea.LinesPerFrame );
        dbmsg_ftrace( DBM_DPATH, "         DisplayArea = { %d, %d, %d, %d }\r\n", disp_cfg.DisplayArea.FirstPixel, disp_cfg.DisplayArea.FirstLine, disp_cfg.DisplayArea.PixelsPerLine, disp_cfg.DisplayArea.LinesPerFrame );
        return FAIL;
    }
    
    dispfmt_ApplyScalingFilter( srcDesc, &disp_cfg );

    /* signal the GUI to reposition itself as the active area may have changed */
    guiStyle_Redraw();
    
    return PASS;
}

int08 dispfmt_ApplyFlip( void )
{
    /* these equations assume a horizontal (East/West) flip by the optics */
    DISP_SetHorizontalFlip( (!rearProjection) ^ ceilingMount );
    DISP_SetVerticalFlip( ceilingMount );
    
    return PASS;
}

int08 dispfmt_ApplyKeystone( void )
{
    int16 offset;
    int08 result;
    
    offset = verticalOffset;

    /* if projector is upside-down, we must negate the vertical offset */
    if( ceilingMount )
        offset *= -1;

    result = DISP_SetKeystoneAngles( anglePitch, throwRatio, offset );
    if( result != PASS )
    {
        dbmsg_ftrace( DBM_DPATH, "dispfmt: DISP_SetKeystoneAngles failed (ret=%d)\r\n", result );
        dbmsg_ftrace( DBM_DPATH, "         angle=%4x TR=%x off=%x\r\n", anglePitch, throwRatio, offset );
        return FAIL;
    }
    
    return PASS;
}

void dispfmt_RestoreDefaults()
{
    DP_SOURCEDESC *srcDesc;
    
    datapath_GetSourceDesc( &srcDesc );

    /* set all EEPROM values to defaults from flash */
    EE_PUTVAR( UserMachine.Projector.AspectRatio, gpSettings->UserMachine.Projector.AspectRatio );
    EE_PUTVAR( UserMachine.Projector.ImageSizeEnum, gpSettings->UserMachine.Projector.ImageSizeEnum );     
    EE_PUTVAR( UserMachine.Projector.ImageSizeManualSteps, gpSettings->UserMachine.Projector.ImageSizeManualSteps );
    EE_PUTVAR( UserMachine.Projector.ImageOffset, gpSettings->UserMachine.Projector.ImageOffset );
    if( srcDesc->isVideo == TRUE && srcDesc->activeDisplay == DP_EXTERNAL )
    {
        EE_PUTVAR( UserMachine.ConnectorSettings[srcDesc->connector].Overscan, gpSettings->UserMachine.ConnectorSettings[srcDesc->connector].Overscan );
    }
    EE_PUTVAR( UserMachine.Projector.KeystonePitch, gpSettings->UserMachine.Projector.KeystonePitch );
    EE_PUTVAR( UserMachine.Projector.AutoKeystone, gpSettings->UserMachine.Projector.AutoKeystone );
    
    /* apply settings to projector */
    dispfmt_ConfigureForSource( TRUE );

}

⌨️ 快捷键说明

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