📄 video2vga.c
字号:
/*!
==============================================================================
Video2VGA
目的:验证DAM6416P的视频I/O功能。帮助用户了解如何创建一个视频应用程序。
内容:采集PAL制式的标准模拟视频信号,并送往VGA进行输出。
运行方式:PCI方式和脱机运行方式。
运行环境:CCS2.2 or later(if any)
Copyright 2003 Wintech Digital. All Rights Reserved.
=============================================================================*/
#include <stdio.h>
#include <csl.h>
#include <csl_edma.h>
#include <csl_dat.h>
#include <std.h>
#include <sys.h>
#include <tsk.h>
#include <log.h>
#include "iekc64.h"
#include "img_ycbcr422p_rgb565.h" //header file for C64x IMGLIB
// color-space-conversion matrix coefficients for YUV->RGB
static Int16 coeff[] = { 0x2543, 0x3313, -0x0C8A, -0x1A04, 0x408D };
//
// Depending on the demo configuration (PAL/NTSC, FULL/CIF)
// prepare some constants
//
// DEMO_PAL is already defined in the compiler options
// for Debug_PAL build configuration
#ifdef PAL_DEMO_CIF
#define DEMO_STANDARD (PAL)
#define DEMO_RES (RES_PAL_CIF)
#define DEMO_RES_VGA (RES_VGA_PAL_352X576)
#define WIDTH (352)
#define HEIGHT (288)
#endif
#ifdef NTSC_DEMO_CIF
#define DEMO_STANDARD (NTSC)
#define DEMO_RES (RES_NTSC_CIF)
#define DEMO_RES_VGA (RES_VGA_NTSC_352X480)
#define WIDTH (352)
#define HEIGHT (240)
#endif
#define FRAME_SIZE_IN_PIXELS (WIDTH*HEIGHT) //frame size
// DSP/BIOS object
extern Uint32 seg_sdrama;
extern Uint32 seg_isram;
extern far LOG_Obj myLOG;
// Define image buffers
#define Frames_Count 4 // frames in the buffer
#define Frames_ToKeep 1 // frames to be kept in the buffer
// YUV422 and RGB565 pixels are 16 bits word, so Uint16
Uint16 CaptureBuffer[FRAME_SIZE_IN_PIXELS*Frames_Count]; //the capture buffer
Uint16 OutputBuffer[2][WIDTH*HEIGHT*4];//ping-pong structure for output
Uint16 RGBBuffer[2][WIDTH*HEIGHT]; //ping-pong structure for RGB
Uint8 BufferY[WIDTH*HEIGHT]; // seperated Y
Uint8 BufferU[WIDTH*HEIGHT/2]; // seperated U
Uint8 BufferV[WIDTH*HEIGHT/2]; // seperated V
Uint8 outVGAIndex=0; //output frame index
// Video moudle definition
Handle hVin; // video input handle
Handle hVout; // video output handle
// Function definition
void tsk_main(void); //main task
void simpledelay(Uint16 delay_count); //a simple delay funciton
//a simple delay funciton
void simpledelay(Uint16 delay_count)
{
int i;
for (i=0;i<delay_count; i++)
{
asm(" nop ");
}
}
void main(void)
{
IEKC64_STATUS status;
TSK_Attrs attrs;
//
// Remember you should call CSL_init() first when using CSL of DSP/BIOS
//
CSL_init();
//
// This is the first API call you need.
// It is mandatory to initialize the board!
//
status = IEKC64_init();
if (!IEKC64_SUCCESS(status))
{
printf( "IEKC64_Init() failed with 0x%08X\n", status );
abort();
}
// Toggle the on board LEDs
// First turn off all LEDs
LED_set( BRACKET_RED, OFF );
LED_set( BRACKET_GREEN, OFF );
LED_set( ONBOARD_GREEN, OFF );
LED_set( ONBOARD_YELLOW, OFF );
LED_set( ONBOARD_RED, OFF );
// Now toggle
LED_set( ONBOARD_GREEN, ON );
simpledelay(1000);
LED_set( ONBOARD_YELLOW, ON );
simpledelay(1000);
LED_set( ONBOARD_RED, ON );
simpledelay(1000);
LED_set( BRACKET_RED, ON );
simpledelay(1000);
LED_set( BRACKET_GREEN, ON );
simpledelay(5000);
// Turn off again
LED_set( BRACKET_RED, OFF );
LED_set( BRACKET_GREEN, OFF );
LED_set( ONBOARD_GREEN, OFF );
LED_set( ONBOARD_YELLOW, OFF );
LED_set( ONBOARD_RED, OFF );
// Notice for the users!!!
// Put your application specific initialization function here!
//
// Now create the main task
attrs = TSK_ATTRS;
attrs.priority = 4;
attrs.stacksize = 9024;
attrs.stackseg = seg_sdrama;
TSK_create((Fxn)tsk_main, &attrs);
// After the main() exit, DSP/BIOS will be entered.
}
// This is the main task which will be entered after the DSP/BIOS was run
void tsk_main(void)
{
IEKC64_STATUS status;
Uint32 boardCpuClock;
Uint32 dspBiosCpuClock;
Uint32 i=0;
Uint16* temp_address1=NULL;
Uint8* temp_address3=NULL;
static Uint32 index=1;
IEKC64_VIDEOOUT videoOut = IEKC64_VIDEOOUT_DEFAULT;
IEKC64_VIDEOIN videoIn = IEKC64_VIDEOIN_DEFAULT;
// Check CPU frequency configuration
// 函数的返回值为 IEKC64_cpuClock,
// 而同时*pDspBiosClock被赋予由DSP/BIOS反算得到的DSP Speed。
boardCpuClock=IEKC64_getCpuClock(&dspBiosCpuClock);
LOG_printf(&myLOG, "DSP clock frequency: %u Mhz\n", boardCpuClock);
LOG_printf(&myLOG, "DSP/BIOS clock frequency: %u Mhz\n", dspBiosCpuClock);
if(boardCpuClock != dspBiosCpuClock)
{
LOG_printf(&myLOG, "WARNING: Board clock is different from DSP/BIOS configuration file clock.\n");
// turn on the red LED to indicate the difference
LED_set( ONBOARD_RED, ON );
}
// Now init various buffers
memset(RGBBuffer[0],0x00,WIDTH*HEIGHT*sizeof(Uint16));
memset(RGBBuffer[1],0x00,WIDTH*HEIGHT*sizeof(Uint16));
memset(OutputBuffer[0],0x00,WIDTH*HEIGHT*4*sizeof(Uint16));
memset(OutputBuffer[1],0x00,WIDTH*HEIGHT*4*sizeof(Uint16));
//
// Now we prepare the VIN & VOUT moudle configurations
//
videoIn.Standard=DEMO_STANDARD;
videoIn.Resolution=DEMO_RES;
videoIn.FrameFormat=YUV422PIXEL;
videoIn.VideoInSelect=COMPOSITE;
videoIn.nTemporalDecimationFactor=1;
videoIn.isOneShot=FALSE;
videoIn.nFramesInBuffer=Frames_Count;
videoIn.nFramesToKeep=Frames_ToKeep;
videoIn.pCaptureBuffer=(Uint32*)CaptureBuffer;
videoOut.Standard=DEMO_STANDARD;
videoOut.Resolution=DEMO_RES_VGA;
videoOut.FrameFormat=RGB565PIXEL;
videoOut.VideoOutSelect=VGA;
//
// Let's open VIN & VOUT
//
status = VIN_open(&videoIn,&hVin);
if (!IEKC64_SUCCESS(status))
{
LOG_printf(&myLOG, "VIN_open() failed with 0x%08X\n", status );
abort();
}
status = VOUT_open(&videoOut,&hVout);
if (!IEKC64_SUCCESS(status))
{
LOG_printf(&myLOG, "VOUT_open() failed with 0x%08X\n", status );
abort();
}
//
// Let's start video acquire & generation
//
status = VOUT_start(hVout);
if (!IEKC64_SUCCESS(status))
{
LOG_printf(&myLOG, "VOUT_start() failed with 0x%08X\n", status );
abort();
}
status = VIN_start(hVin);
if (!IEKC64_SUCCESS(status))
{
LOG_printf(&myLOG, "VIN_start() failed with 0x%08X\n", status );
abort();
}
// Init the output frame pointer
outVGAIndex=0;
//
// Open DAT copy module in 2D
//
DAT_open(DAT_CHAANY,DAT_PRI_LOW,DAT_OPEN_2D);
LOG_printf(&myLOG, "Video2VGA Example Starts!\n\n");
while(1)
{
// ouput LOG information
LOG_printf(&myLOG, "Video2VGA Example. Getting Video Frame index:%d !\n", index++);
// toggle the green LED
if (index%20)
LED_set( ONBOARD_GREEN, OFF );
else
LED_set( ONBOARD_GREEN, ON );
//
// Try to get a new frame
//
status = VIN_getFrame(hVin, (void**)&temp_address1,IEKC64_VIDEO_WAIT_INFINITE);
if (IEKC64_SUCCESS(status))
{
//
// If we have the new frame, we can process it
// For simplicity reasons, we just move the input frame data to
// the ouput frame with necessary format transform(YUV->RGB)
// Porcessing begins!
// We just transform the YUV->RGB and then output
// For details on YUV->RGB conversion, pls refer to TI Doc SPRU023
// First extract seperate Y/U/V from YUV 4:2:2 pixels
temp_address3 =(Uint8*)temp_address1; //point to Y0
for (i=0;i<FRAME_SIZE_IN_PIXELS;i++)
*(BufferY+i) = *(temp_address3+(i*2));
temp_address3++; //point to U0
for (i=0;i<FRAME_SIZE_IN_PIXELS/2;i++)
*(BufferU+i) = *(temp_address3+(i*4));
temp_address3++; //point to Y1
temp_address3++; //point to V0
for (i=0;i<FRAME_SIZE_IN_PIXELS/2;i++)
*(BufferV+i) = *(temp_address3+(i*4));
//
// Convert YUV 4:2:2 to RGB 16 bits format for VGA
// Refer to IMGLIB of TI for reference
IMG_ycbcr422p_rgb565( (short*) coeff, BufferY, BufferU, BufferV, RGBBuffer[outVGAIndex], FRAME_SIZE_IN_PIXELS);
//
// As we play CIF format in 352x576 or 352x480 we need to double the lines from CIF format
// to display on VGA.
// The FPGA on the board center the video output and double the columns.
//
DAT_copy2d (DAT_1D2D, RGBBuffer[outVGAIndex], OutputBuffer[outVGAIndex], WIDTH*2 , HEIGHT , WIDTH*4);
DAT_copy2d (DAT_1D2D, RGBBuffer[outVGAIndex], &OutputBuffer[outVGAIndex][WIDTH], WIDTH*2 , HEIGHT , WIDTH*4);
//
// Display the new frame
//
// Notice for the users!!!
// Put your specific processing codes here!
//
// Porcessing ends!
// Now output the frame
VOUT_putFrame(hVout,OutputBuffer[outVGAIndex],IEKC64_VIDEO_NO_WAIT);
// update the index and output frame pointer
outVGAIndex=(outVGAIndex+1)%2;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -