[DSP编程]

DSP处理视频问题求助

[复制链接]
1396|4
手机看帖
扫描二维码
随时随地手机跟帖
LIYUANJUN|  楼主 | 2017-3-16 11:02 | 显示全部楼层 |阅读模式
main.c

#include "stdio.h"
#include "evmdm6437.h"
#include "video_test.h"
#include "evmdm6437_uart.h"

extern far cregister volatile unsigned int IER;
extern far cregister volatile unsigned int CSR;
extern far cregister volatile unsigned int ICR;
extern far cregister volatile unsigned int ISTP;
extern far cregister volatile unsigned int ISR;
extern far cregister volatile unsigned int IFR;


void InterruptInit();


Uint8 store,store1;
Int16 errors = 0;

Int32 test_timeout = 0x100000;


/* ------------------------------------------------------------------------ *
*                                                                          *
*  main( )                                                                 *
*                                                                          *
* ------------------------------------------------------------------------ */
void main( void )
{
        ntsc_pal_mode = PAL;
        output_mode   = COMPOSITE_OUT;

        enable_input         = 0;
        enable_output        = 0;
        inputframe_end        = 0;
        outputframe_end        = 0;

        inputframe_selectzone        = IMAGEZONE_IN_PUT_ONE;

    /* Initialize BSL */
    EVMDM6437_init( );
   
    // 初始化中断
          InterruptInit();

        // 初始化串口
    uart1 = EVMDM6437_UART_open( 1, 115200 );
        
        // 初始化视频解码芯片
        tvp5151_init( ntsc_pal_mode, output_mode );

          // 初始化视频输入
    vpfe_init( ntsc_pal_mode, inputframe_selectzone );
       
          // 初始化视频输出
    vpbe_init( LOOPBACK, ntsc_pal_mode, output_mode, inputframe_selectzone+IMAGEZONE_OFFSET );
       
        inputframe_end        = 1;
        outputframe_end        = 1;
    //_waitusec( 1000 );        // wait 1 msec
//////////////////////////////////////////////////////////////
        for(;;)
        {       
                // 输入与输出模块传输好一帧图像后再处理图像
                if( (inputframe_end == 1) && (outputframe_end == 1) )
                //if( outputframe_end == 1 )
                {
                        // 处理图像时禁止切换图像存放的位置
                        enable_input  = 0;
                        enable_output = 0;
                       
                        // 对图像进行处理,数据总量请根据实际情况计算
                        image_transform( ((inputframe_selectzone==IMAGEZONE_IN_PUT_ONE)?IMAGEZONE_IN_PUT_TWO:IMAGEZONE_IN_PUT_ONE), 720 * 288 );
                                          
                        // 表示下次要处理的图像块还未传输
                        inputframe_end = 0;
                        outputframe_end= 0;

                        // 指示输入与输出模块可以切换下一帧图像
                        enable_input  = 1;
                        enable_output = 1;
                }
        }
///////////////////////////////////////////////////////////////
}


// 初始化中断
void InterruptInit()
{
        CSR=0x100;                /* disable all interrupts            */
          IER=1;                        /* disable all interrupts except NMI */
          ICR=0xffff;                /* clear all pending interrupts      */   
         
        ISTP = 0x10800000;
          
           INTC_EVTCLR0  = 0xFFFFFFFF;
           INTC_EVTCLR1  = 0xFFFFFFFF;
           INTC_EVTCLR2  = 0xFFFFFFFF;
           INTC_EVTCLR3  = 0xFFFFFFFF;   
           INTC_EVTMASK3 = 0xFFFFFFFF;
           INTC_EVTMASK2 = 0xFFFFFFFF;
           INTC_EVTMASK1 = 0xFFFFFFFF;
           INTC_EVTMASK0 = 0xFFFFFFEF;

        INTC_INTMUX1  = 0x00000000;
        // 使能VDINT(中断号24)VENCINT(中断号32)
        INTC_INTMUX2  = 0x00002018;
        // 使能UART1(中断号85)
           INTC_INTMUX3  = 0x00550000;

        // 使能中断8 9 14
           IER |= 0x00004302;
           CSR  = 0x01;                /* enable all interrupts */
}

video.test.c

#include "stdio.h"
#include "evmdm6437.h"
#include "video_test.h"
#include "evmdm6437_uart.h"

Uint32 enable_input;
Uint32 enable_output;
Uint32 inputframe_end;
Uint32 outputframe_end;
Uint32 inputframe_selectzone;
Uint32 outputframe_selectzone;

Uint32 ntsc_pal_mode;
Uint32 output_mode;

UART_Handle uart1;

/////////////////////////////////////////////////////////////////////
// 用于image_transform中的变量
Uint32 i, temp;
Uint8 yh, yl, temp8;

// 自行添加的图像处理部分代码   video_buffer为处理的起始像素地址
Uint32 image_transform( Uint32 video_buffer, Uint32 total_data )
{
        Uint32 video_vpfe_buffer = video_buffer;
        total_data = 720 * 288;

        //_waitusec( 50000 );        // wait 50 msec
        // 彩色图变灰度图
        for( i = 0; i < total_data; i++ )
        {
    //注意Cb/Cr顺序 由VPBE_OSD_MODE的15bit决定,0=cb/cr(set),1=cr/cb
    // 刚好32位排列为Y-Cr-Y-Cb
                temp = *(int *) video_vpfe_buffer;
                yh = ((temp >> 24) & 0xFF);  //高Y
                yl = ((temp >> 8) & 0xFF);

                temp = (yh << 24) | (0x80 << 16) | (yl << 8) | 0x80;
                *(int *) (video_vpfe_buffer + IMAGEZONE_OFFSET) = temp;
                video_vpfe_buffer = video_vpfe_buffer + 4;
        }

        return video_buffer;
}
//////////////////////////////////////////////////////////////////////

/* ------------------------------------------------------------------------ *
*                                                                          *
*  tvp5151_rset                                                            *
*                                                                          *
*      Set codec register regnum to value regval                           *
*                                                                          *
* ------------------------------------------------------------------------ */
void tvp5151_rset( Uint8 regnum, Uint8 regval )
{
    Uint8 cmd[2];
    cmd[0] = regnum;    // 8-bit Register Address
    cmd[1] = regval;    // 8-bit Register Data

    EVMDM6437_I2C_write( TVP5151_I2C_ADDR, cmd, 2 );
}

/* ------------------------------------------------------------------------ *
*                                                                          *
*  tvp5151_rget                                                            *
*                                                                          *
*      Return value of codec register regnum                               *
*                                                                          *
* ------------------------------------------------------------------------ */
Uint8 tvp5151_rget( Uint8 regnum )
{
    Uint8 cmd[2];

    cmd[0] = regnum;    // 8-bit Register Address
    cmd[1] = 0;         // 8-bit Register Data

    EVMDM6437_I2C_write( TVP5151_I2C_ADDR, cmd, 1 );
    EVMDM6437_I2C_read ( TVP5151_I2C_ADDR, cmd, 1 );

    return cmd[0];
}

/* ------------------------------------------------------------------------ *
*                                                                          *
*  tvp5146_init( )                                                         *
*                                                                          *
*      Initialize the TVP5146                                              *
*                                                                          *
* ------------------------------------------------------------------------ */
void tvp5151_init( Uint32 ntsc_pal_mode, Uint32 input_mode )
{
        tvp5151_rset( 0x00, 0x00 );         // Input Video: CVBS : VI_1_A
       
        tvp5151_rset( 0x03, 0x09 );         // Enabling clock & Y/CB/CR input format
   
    tvp5151_rset( 0x0D, 0x47 );         

    _waitusec( 1000 );                  // wait 1 msec
}



/* ------------------------------------------------------------------------ *
*                                                                          *
*  vpfe_init( ntsc/pal )                                                   *
*                                                                          *
* ------------------------------------------------------------------------ */
void vpfe_init( Uint32 ntsc_pal_mode, Uint32 video_buffer )
{
    Uint32 width;
    Uint32 height;

    width   = 720;
    height  = 576;


    VPFE_CCDC_SYN_MODE  = 0x00032F84;   // interlaced, with VD pority as negative
    VPFE_CCDC_HD_VD_WID = 0;
    VPFE_CCDC_PIX_LINES = 0x02CF020D;

    /*
     *  sph = 1, nph = 1440, according to page 32-33 of the CCDC spec
     *  for BT.656 mode, this setting captures only the 720x480 of the
     *  active NTSV video window
     */
    VPFE_CCDC_HORZ_INFO  = width << 1;   // Horizontal lines
    VPFE_CCDC_HSIZE_OFF  = width << 1;   // Horizontal line offset
    VPFE_CCDC_VERT_START = 0;            // Vertical start line
    VPFE_CCDC_VERT_LINES = height >> 1;  // Vertical lines
    VPFE_CCDC_CULLING    = 0xFFFF00FF;   // Disable cullng

    /*
     *  Interleave the two fields
     */
    VPFE_CCDC_SDOFST    = 0x00000249;
    VPFE_CCDC_SDR_ADDR  = video_buffer; // 输入图像起始存放地址
    VPFE_CCDC_CLAMP     = 0;
    VPFE_CCDC_DCSUB     = 0;
    VPFE_CCDC_COLPTN    = 0xEE44EE44;
    VPFE_CCDC_BLKCMP    = 0;
    VPFE_CCDC_FPC_ADDR  = 0x86800000;
    VPFE_CCDC_FPC       = 0;
    VPFE_CCDC_VDINT     = 0x01380000;  // 控制输入中断
    VPFE_CCDC_ALAW      = 0;
    VPFE_CCDC_REC656IF  = 0x00000003;

    /*
     *  Input format is Cb:Y:Cr:Y, w/ Y in odd-pixel position
     */
    VPFE_CCDC_CCDCFG    = 0x00000800;
    VPFE_CCDC_FMTCFG    = 0;
    VPFE_CCDC_FMT_HORZ  = 0x000002D0;
    VPFE_CCDC_FMT_VERT  = 0x0000020E;
    VPFE_CCDC_FMT_ADDR0 = 0;
    VPFE_CCDC_FMT_ADDR1 = 0;
    VPFE_CCDC_FMT_ADDR2 = 0;
    VPFE_CCDC_FMT_ADDR3 = 0;
    VPFE_CCDC_FMT_ADDR4 = 0;
    VPFE_CCDC_FMT_ADDR5 = 0;
    VPFE_CCDC_FMT_ADDR6 = 0;
    VPFE_CCDC_FMT_ADDR7 = 0;
    VPFE_CCDC_PRGEVEN_0 = 0;
    VPFE_CCDC_PRGEVEN_1 = 0;
    VPFE_CCDC_PRGODD_0  = 0;
    VPFE_CCDC_PRGODD_1  = 0;
    VPFE_CCDC_VP_OUT    = 0x041A2D00;
    VPFE_CCDC_PCR       = 0x00000001;   // Enable CCDC
}

/* ------------------------------------------------------------------------ *
*                                                                          *
*  vpbe_init( colorbars/loopback, ntsc/pal, svideo/composite )             *
*                                                                          *
* ------------------------------------------------------------------------ */
void vpbe_init( Uint32 colorbar_loopback_mode, Uint32 ntsc_pal_mode, Uint32 output_mode, Uint32 video_buffer )
{
    Uint32 basep_x;
    Uint32 basep_y;
    Uint32 width;
    Uint32 height;

    basep_x = 132;
    basep_y = 22;
    width   = 720;
    height  = 576;

    /*
     * Setup VPBE
     */
    VPSS_CLK_CTRL       = 0x0000018;    // Enable DAC and VENC clock, both at 27 MHz
    VPBE_PCR            = 0;            // No clock div, clock enable

    /*
     * Setup OSD
     */
    VPBE_OSD_MODE       = 0x000000fc;   // Blackground color blue using clut in ROM0
    VPBE_OSD_OSDWIN0MD  = 0;            // Disable both osd windows and cursor window
    VPBE_OSD_OSDWIN1MD  = 0;
    VPBE_OSD_RECTCUR    = 0;

    VPBE_OSD_VIDWIN0OFST= width >> 4;
    VPBE_OSD_VIDWIN0ADR = video_buffer;// 输出图像起始存放地址
    VPBE_OSD_BASEPX     = basep_x;
    VPBE_OSD_BASEPY     = basep_y;
    VPBE_OSD_VIDWIN0XP  = 0;
    VPBE_OSD_VIDWIN0YP  = 0;
    VPBE_OSD_VIDWIN0XL  = width;
    VPBE_OSD_VIDWIN0YL  = height >> 1;
    VPBE_OSD_MISCCTL    = 0;

    VPBE_OSD_VIDWINMD   = 0x00000003;   // Disable vwindow 1 and enable vwindow 0
                                        // Frame mode with no up-scaling

    /*
     *  Setup VENC
     */
    VPBE_VENC_VMOD          = 0x00000043;   // Standard PAL interlaced output
    VPBE_VENC_VDPRO     = colorbar_loopback_mode << 8;
    VPBE_VENC_DACTST    = 0;
    VPBE_VENC_DACSEL    = 0x00004210;

    /*
     *  Choose Output mode
     */
    if ( output_mode == COMPOSITE_OUT )
        VPBE_VENC_DACSEL = 0x00000000;
    else if ( output_mode == SVIDEO_OUT )
        VPBE_VENC_DACSEL = 0x00004210;
}

// VDINT0中断(输入一帧完整图像)
interrupt void extint8_InputFrame(void)
{
        if( (enable_input == 1) && (inputframe_end==0) )
        {
                if( inputframe_selectzone == IMAGEZONE_IN_PUT_ONE)
                {
                    VPFE_CCDC_SDR_ADDR                 = IMAGEZONE_IN_PUT_TWO;
                        inputframe_selectzone         = IMAGEZONE_IN_PUT_TWO;
                }
                else
                {
                        VPFE_CCDC_SDR_ADDR                 = IMAGEZONE_IN_PUT_ONE;
                        inputframe_selectzone         = IMAGEZONE_IN_PUT_ONE;
                }
               
                inputframe_end = 1;
                //enable_input = 0;
        }

        else
        {
                //inputframe_end = 0;
        }

//        return;
}

// VENCINT中断(输出一帧完整图像)
interrupt void extint9_OutputFrame( void )
{
        if( enable_output == 1 && outputframe_end==0)
        {
                if( inputframe_selectzone == IMAGEZONE_IN_PUT_ONE )
                {
                    VPBE_OSD_VIDWIN0ADR = IMAGEZONE_OUTPUT_TWO;       
                }
                else
                {
                        VPBE_OSD_VIDWIN0ADR = IMAGEZONE_OUTPUT_ONE;
                }
                               
                outputframe_end = 1;
                //enable_output = 0;
        }

        else
        {
                //outputframe_end = 0;
        }

//        return;
}

// UART1中断
interrupt void extint14_Uart( void )
{
        Uint8 store = 1;
        EVMDM6437_UART_getChar( uart1, &store );    // Read 1 byte
        printf( "UART1 received  %d\n", store );
}
用DSP处理实时视频,采用乒乓缓存方式对视频进行灰度化处理,编译没错误,但是就是一直无法显示处理后的视频,请问大神这个该怎么改,谢谢了,如果可以解决的话也可以付钱给大神,谢谢了

相关帖子

zhangmangui| | 2017-3-16 22:11 | 显示全部楼层
好多代码    看不到 啊

使用特权

评论回复
LIYUANJUN|  楼主 | 2017-3-17 10:11 | 显示全部楼层
zhangmangui 发表于 2017-3-16 22:11
好多代码    看不到 啊

我好想找到错误了,应该是我采用通过两片SDRAM的乒乓操作来完成图像数据的缓存,我设置的两块缓存输入图像起始地址与输出图像起始地址分别是
IMAGEZONE_IN_PUT_ONE=DDR_BASE     IMAGEZONE_OUTPUT_ONE=DDR_BASE+0X01000000
IMAGEZONE_IN_PUT_TWO=DDR_BASE+0X02000000     IMAGEZONE_OUTPUT_TWO=DDR_BASE+0X03000000,但是不知道为什么当图像输入到第二个缓存时就无法显示出来,请问大神知道是为什么吗??能否告知一下

使用特权

评论回复
zhangmangui| | 2017-3-17 23:26 | 显示全部楼层
LIYUANJUN 发表于 2017-3-17 10:11
我好想找到错误了,应该是我采用通过两片SDRAM的乒乓操作来完成图像数据的缓存,我设置的两块缓存输入图像 ...

这个真不懂      你再找找问题    抱歉

使用特权

评论回复
从薪| | 2017-3-19 08:32 | 显示全部楼层
应该跟算法有关吧!重新理一下,看看有没有更好的算法来解决这个问题!也可以在网上收收关于DSP视频的算法!希望能帮到你的,谢谢!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

5

主题

10

帖子

0

粉丝