usr_routines.c

来自「快速开发基于Blackfin处理器的视频应用」· C语言 代码 · 共 544 行 · 第 1/2 页

C
544
字号
/*****************************************************************************
Copyright(c) 2005 Analog Devices, Inc.  All Rights Reserved. This software is 
proprietary and confidential to Analog Devices, Inc. and its licensors.
******************************************************************************

$RCSfile: usr_routines.c,v $
$Revision: 1.2 $
$Date: 2005/10/28 02:49:13 $

Project:	Developer Kit
Title:		User defined routines to be called by service/utility modules
Author(s):	dwu
Revised by: 

Description:
			User defined ISRs for the PPI and MDMA.

References:
			None

******************************************************************************
Tab Setting:			4

Target Processor:		ADSP-BF533
Target Tools Revision:	ADSP VisualDSP++ v4.0.1.0 (Mar 18 2005 Update)
******************************************************************************

Modification History:
====================
$Log: usr_routines.c,v $
Revision 1.2  2005/10/28 02:49:13  dwu
Added error checking code for JPEG/MJPEG routines, and added ADI
legal headers.

Revision 1.1.1.1  2005/10/13 02:50:16  dwu
no message

Revision 1.3  2005/09/28 01:36:33  dwu
the playback now plays frame from previous YUV buffer if the MJPEG decoder
is running behind.

Revision 1.2  2005/09/16 02:30:39  dwu
Added multiple input and output buffers to absorb encodinig/decoding MIPS
spikes. Need to update to the newer JPEG_MCUBuffer.c to have these
files link.

Revision 1.1  2005/07/29 06:28:03  dwu
Newly added files to contain project specific routines/data


*****************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include "usr_routines.h"
#include "video_656.h"
#include "YUV.h"
#include "system.h"
#include "codec.h"
#include "system_services_install.h"
#include <cycle_count.h> 			// for basic cycle counting


/*********************************************************************
	User defined variables
 *********************************************************************/
unsigned int                display_Width   = 0;
unsigned int		        display_Height  = 0;
unsigned int		        Frame_Offset    = 0;
unsigned int				width 			= 0;
unsigned int				height			= 0;
unsigned int				Input_Width		= 0;
unsigned int				Input_Height	= 0;

// define the YUV buffer used by the encoder/decoder in SDRAM 
// (separate bank from 656 frames and USB buffer)
// buffer size is max image size * 1.5 for 4:2:0 subsampling
// max image size is defined in system.h 
#pragma section("sdram0_bank1_bsz_cache", NO_INIT)
char YUV420Buffer[MAX_DECODED_WIDTH * MAX_DECODED_HEIGTH *3/2];

section("L1_data_a") volatile char*	YUV_Buffer_Address[NUM_OF_YUV_BUFS];
section("L1_data_a") volatile int   BufferLevel         = 0;
section("L1_data_a") volatile int   YUVBufferReadIndex  = 0;
section("L1_data_a") volatile int   YUVBufferWriteIndex = 0;


/*****************************************************************************
 *			Macros															 *
 *****************************************************************************/
#define max(a, b)  (((int)(a) > (int)(b)) ? (a) : (b))
#define min(a, b)  (((int)(a) < (int)(b)) ? (a) : (b))


/*
**
** Function:            InitBufferQueue
**
** Description:         Initialize all the buffer control variables
**
**
*/
void InitBufferQueue(void)
{
	int i;
	
	for(i=0;i<NUM_OF_YUV_BUFS;i++)
		YUV_Buffer_Address[i] = &YUV420Buffer[CCIR656_ACTIVEWIDTH*CCIR656_ACTIVEHEIGHT*3/2 * i];
	
    BufferLevel         = 0;
    YUVBufferReadIndex  = 0;
    YUVBufferWriteIndex = 0;
    
	Frame_Dropped_Counter = 0;
	Frame_Dropped = false;
}


/*
**
** Function:            UpdateYUVIndex
**
** Description:         Increments the read and write index variables
**
**
*/
void UpdateYUVIndex(int UpdateType)
{
    switch(UpdateType)
    {
        case UPDATETYPE_READ:
        {
            YUVBufferReadIndex++;
            if(YUVBufferReadIndex >= NUM_OF_YUV_BUFS)
                YUVBufferReadIndex = 0;
            break;
        }
        case UPDATETYPE_WRITE:
        {
            YUVBufferWriteIndex++;
            if(YUVBufferWriteIndex >= NUM_OF_YUV_BUFS)
            	YUVBufferWriteIndex = 0;
            break;
        }
        default:
        {
            return;
        }
    }
}


/*
**
** Function:            InitDescriptorChains_Output
**
** Description:         Initialize the MDMA descriptor chains
**
**
*/
void InitDescriptorChains_Output()
{
	display_Width = min(width, CCIR656_ACTIVEWIDTH);		// display max CCIR656_ACTIVEWIDTH horizontal pixels
	display_Height = min(height, CCIR656_ACTIVEHEIGHT);		// display max CCIR656_ACTIVEHEIGHT vertical pixels
	
	// source Y 1st half
	memdma1_descriptor_data[0].Large.XCount = display_Width;
	memdma1_descriptor_data[0].Large.YCount = display_Height/2;
	memdma1_descriptor_data[0].Large.YModify = width + (width - display_Width) + 1;
	
	// destination Y 1st half
	memdma1_descriptor_data[6].Large.XCount = display_Width;
	memdma1_descriptor_data[6].Large.YCount = display_Height/2;
	memdma1_descriptor_data[6].Large.YModify = (CCIR656_WIDTH-(display_Width-1)*2);

	// source U 1st half
	memdma1_descriptor_data[1].Large.XCount = display_Width/2;
	memdma1_descriptor_data[1].Large.YCount = display_Height/2;
	memdma1_descriptor_data[1].Large.YModify = (width - display_Width)/2 + 1;
	
	// destination U 1st half
	memdma1_descriptor_data[7].Large.XCount = display_Width/2;
	memdma1_descriptor_data[7].Large.YCount = display_Height/2;
	memdma1_descriptor_data[7].Large.YModify = (CCIR656_WIDTH-(display_Width-1)*2+2);
	
	// source V 1st half
	memdma1_descriptor_data[2].Large.XCount = display_Width/2;
	memdma1_descriptor_data[2].Large.YCount = display_Height/2;
	memdma1_descriptor_data[2].Large.YModify = (width - display_Width)/2 + 1;
	
	// destination V 1st half
	memdma1_descriptor_data[8].Large.XCount = display_Width/2;
	memdma1_descriptor_data[8].Large.YCount = display_Height/2;
	memdma1_descriptor_data[8].Large.YModify = (CCIR656_WIDTH-(display_Width-1)*2+2);

	// setup 2nd half of YUV source descriptor chain (MEMDMA channel 1)

	// source Y 2nd half
	memdma1_descriptor_data[3].Large.XCount = display_Width;
	memdma1_descriptor_data[3].Large.YCount = display_Height/2;
	memdma1_descriptor_data[3].Large.YModify = width + (width - display_Width) + 1;
	
	// destination Y 2nd half
	memdma1_descriptor_data[9].Large.XCount = display_Width;
	memdma1_descriptor_data[9].Large.YCount = display_Height/2;
	memdma1_descriptor_data[9].Large.YModify = (CCIR656_WIDTH-(display_Width-1)*2);

	// source U 2nd half
	memdma1_descriptor_data[4].Large.XCount = display_Width/2;
	memdma1_descriptor_data[4].Large.YCount = display_Height/2;
	memdma1_descriptor_data[4].Large.YModify = (width - display_Width)/2 + 1;
	
	// destination U 2nd half
	memdma1_descriptor_data[10].Large.XCount = display_Width/2;
	memdma1_descriptor_data[10].Large.YCount = display_Height/2;
	memdma1_descriptor_data[10].Large.YModify = (CCIR656_WIDTH-(display_Width-1)*2+2);
	
	// source V 2nd half
	memdma1_descriptor_data[5].Large.XCount = display_Width/2;
	memdma1_descriptor_data[5].Large.YCount = display_Height/2;
	memdma1_descriptor_data[5].Large.YModify = (width - display_Width)/2 + 1;
	
	// destination V 2nd half
	memdma1_descriptor_data[11].Large.XCount = display_Width/2;
	memdma1_descriptor_data[11].Large.YCount = display_Height/2;
	memdma1_descriptor_data[11].Large.YModify = (CCIR656_WIDTH-(display_Width-1)*2+2);	    

	// center in output display
	Frame_Offset = max(0, (CCIR656_ACTIVEWIDTH - display_Width)/2)*2 + max(0, (CCIR656_ACTIVEHEIGHT - display_Height)/2) * CCIR656_WIDTH/2;
 
    Start_of_active_Video_Frame[0] = (CCIR656_WIDTH*CCIR656_FIELD1_OFFSET) + (CCIR656_WIDTH-2*CCIR656_ACTIVEWIDTH) + CCIR656_YOFFSET + Frame_Offset;
	Start_of_active_Video_Frame[1] = (CCIR656_WIDTH*CCIR656_FIELD1_OFFSET) + (CCIR656_WIDTH-2*CCIR656_ACTIVEWIDTH) + CCIR656_UOFFSET + Frame_Offset;
	Start_of_active_Video_Frame[2] = (CCIR656_WIDTH*CCIR656_FIELD1_OFFSET) + (CCIR656_WIDTH-2*CCIR656_ACTIVEWIDTH) + CCIR656_VOFFSET + Frame_Offset;			
	Start_of_active_Video_Frame[3] = (CCIR656_WIDTH*CCIR656_FIELD2_OFFSET) + (CCIR656_WIDTH-2*CCIR656_ACTIVEWIDTH) + CCIR656_YOFFSET + Frame_Offset;			
	Start_of_active_Video_Frame[4] = (CCIR656_WIDTH*CCIR656_FIELD2_OFFSET) + (CCIR656_WIDTH-2*CCIR656_ACTIVEWIDTH) + CCIR656_UOFFSET + Frame_Offset;			
	Start_of_active_Video_Frame[5] = (CCIR656_WIDTH*CCIR656_FIELD2_OFFSET) + (CCIR656_WIDTH-2*CCIR656_ACTIVEWIDTH) + CCIR656_VOFFSET + Frame_Offset;
}


/*
**
** Function:            ConfigDescriptorChains_Output
**
** Description:         Configure the MDMA descriptor chains
**
**
*/
void ConfigDescriptorChains_Output()
{
	char *lOutputBuffer;

	lOutputBuffer = (char*)YUV_Buffer_Address[YUVBufferReadIndex];	
	
	// source Y 1st half
	memdma1_descriptor_data[0].Large.StartAddress = lOutputBuffer;
	// source U 1st half
	memdma1_descriptor_data[1].Large.StartAddress = lOutputBuffer + width*height;
	// source V 1st half
	memdma1_descriptor_data[2].Large.StartAddress = lOutputBuffer + width*height *5/4;

	// setup 2nd half of YUV source descriptor chain (MEMDMA channel 1)
	// source Y 2nd half
	memdma1_descriptor_data[3].Large.StartAddress = lOutputBuffer + width;
	// source U 2nd half
	memdma1_descriptor_data[4].Large.StartAddress = lOutputBuffer + width*height;
	// source V 2nd half
	memdma1_descriptor_data[5].Large.StartAddress = lOutputBuffer + width*height *5/4;
	
	// Destination descriptors
	memdma1_descriptor_data[6].Large.StartAddress = (void *)&(Video_Frames[Video_Frame_Completed_Number])[Start_of_active_Video_Frame[0]];
	memdma1_descriptor_data[7].Large.StartAddress = (void *)&(Video_Frames[Video_Frame_Completed_Number])[Start_of_active_Video_Frame[1]];
	memdma1_descriptor_data[8].Large.StartAddress = (void *)&(Video_Frames[Video_Frame_Completed_Number])[Start_of_active_Video_Frame[2]];

⌨️ 快捷键说明

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