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

📄 video2vga.c

📁 基于tms320c6416的图像实时采集显示系统
💻 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 + -