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

📄 h264.h

📁 h.264 算法 ti dm642
💻 H
字号:
#ifndef _H264_DEFINE
#define _H264_DEFINE 1


//Baseline(4.1)
//支持720p实时编码
//ccs dm642-600mhz sdram-133mhz
//支持主流解码器解码(coreplayer,vlc,moonlight,my mpc。。)
//2008-12-10
//modified: adds a sei slice



#define Q1				1	 
#define Q2        2        
#define Q3        3
#define Q4        4
#define Q5        5
#define Q6        6
#define Q7        7
#define Q8        8
#define Q9        9
#define Q0				10 //恒定质量的图像质量级别

#define	IFrame							1
#define  PFrame							3
#define	H264_Handle				 void *
typedef struct User_parameter
{
    
    int         width;  //视频输入宽度,D1:720,要求整16象素 ,运行时修改参数,必须按文件流操作      
    int         height; //视频输入高度,D1:576,要求整16象素 ,运行时修改参数,必须按文件流操作
    int					cbr;		//cbr = 1,使能码流控制,cbr = 0,使能质量控制
    int					bitrate; //Cbr = 1, 128kbps < bitrate < 8192bps;
    											//Cbr = 0, Quality_I~~~Quality_Io,选定不同质量,(1-10)
    																//Quality_I1:表明恒定质量一般以下,为低带宽准备
    																//Quality_I0:表明恒定质量最好,为高清准备;
    
    //int					yuv_format:  //这项不填写,缺省是采用TI-yuv422格式,比如yuv422
    													
    
    unsigned  char *bufferY;		//TI-yuv422 Y分量的指针, 这个参数可以实时修改,可以直接对接ti框架的y采集指针
    unsigned  char *bufferU;		//TI-yuv422 U分量的指针,这个参数可以实时修改,可以直接对接ti框架的u采集指针
    unsigned  char *bufferV;		//TI-yuv422 V分量的指针,这个参数可以实时修改,可以直接对接ti框架的v采集指针
    
    int         iframe_interval;      //I帧间隔 25<= iframe_interval<=1000
} User_parameter;							//缺省参数:
															//width 	= 352;
															//height	= 288;
															//cbr			= 0;
															//bitrate = Q3;
															//iframe_interval = 100;

H264_Handle *H264_encoder_open   ( User_parameter *User_param);
						//return H264_Handle * 如果为0,说明内存错误
						//同时支持8个通道同时编码,每个通道都直接支持高清(qvga-1080p),所以可以一个通道编码cif另一个通道编码720p
						//return H264_Handle <=0 表示分别通道错误,要考虑是否超过8个通道或者exheap过小

int H264_Encoding(H264_Handle h264_handle,User_parameter User_param,
								char *encoderBuf, int *len, int *i_p, int * seqlen,
								int force_I);
								//return int,如果为-1,说明用户参数错误,0表示正常
								//char *encoderBuf,用户申请的Buffer,编码后的码流写入到这个buffer中
								//int *len, 编码后的码流大小
								//int *i_p, 此码流为IFrame或PFrame
								//seqlen[4],如果是PFrame,那么len等于seqlen【0】,这个数组是为了让用户实现对编码流进行各种文件容器封装
																			//如果是I_Frame,seqlen【0】存放sei(uuid) slice
																			//	 seqlen【1】存放sequence parameters slice	
																			//   seqlen【2】存放picture  parameters	slice
																			//   seqlen【3】存放a frame  slice
																			//len = seqlen【0】+seqlen【1】+seqlen【2】
								//force_I == 1,  强制当前帧编码后为I帧, cbr==0时,force_I=1同样有意义.
								//force_I == 0,  I和P帧按ip帧间隔产生相应帧(iframe_interval)
int B264_close(H264_Handle h264_handle );		
							//return int,如果为-1,内存释放错误,0表示正常		
char * H264_GetVersion();  //得到当前版本号
							
/*							
内存资源使用规则:
添加连接文件,连接文件定义如下
SECTIONS
{
	h264parameterb   > H264Buffer
    h264parameterc 	 > H264Buffer
	h264parameterd    > H264Buffer
	L2BuffersAligns8byte > H264Data
 
}							
DM642片上sdram为256KB,
用户能使用的大小为:ISRAM=0x8000; 定义base=0x00000,	len = 0x8000;(主要为用户函数使用和h264编码使用栈(1kbyte)
另外用户必须配置32KB cache,定义如下:
		CSL_init();
    CACHE_clean(CACHE_L2ALL, 0, 0);
    CACHE_setL2Mode(CACHE_32KCACHE);			//必须为32K
    CACHE_enableCaching(CACHE_EMIFA_CE00);
    CACHE_enableCaching(CACHE_EMIFA_CE01);
    
       用户使用必须用这段代码加入自己的工程
除去上面用户定义的DM642片上的sdram外,其余256K-32K(Cache)-32K(stack+_inHeap) = 192K都为H264所用。
算法的H264Buffer占64KB,h264在运行中栈的大小为2KB,
堆大小按D1的象素为例,720*576*1.5*3*4约等于7MB(H264要动态申请的空间)。
在这H264-96KB内存分配中,通过CDB文件,在MEM - Memery Section Manger必须按下列规则
创建内存段

//cache:         base:0x038000	len:0x08000   //32KB  可以不分配,实际上对应CACHE_setL2Mode(CACHE_32KCACHE)函数
H264Buffer:	  base:0x028000	len:0x010000   //64KB
H264Data:		 base:0x8000	len:0x20000 //128KB
ISRAM:        base:0x000000	len:0x08000      //32KB
SDRAM:			base:0x80000000 len:

高级选项:上面H264Buffer和H264Data空间段可以动态的调整,比如说项目只用到实时编码720p或者1080i,
              那只需要打开1个handle,那么H264Data空间可以进行自由的调整,L2BuffersAligns8byte是以16KB对齐的
              每个handle只需要16KB空间,那么H264Data只需开16KB空间就可以了,那么ISRAM可以开大CACHE_32KCACHE也可以开大。
              当然,这必须你要cache分配的机制,它是至上向下分配的,如果CACHE_64KCACHE,那么256KB的高64KB分配给cache,
              所以,这时的空间分配为:
              {cdb内存分配表:
              		//cache:         base:0x030000	len:0x010000   //64KB  可以不分配,实际上对于CACHE_setL2Mode(CACHE_32KCACHE)函数
							H264Buffer:	  base:0x020000	  len:0x010000   //64KB
							H264Data:		 base:0x1c000	    len:0x4000 //16KB
							ISRAM:        base:0x000000	len:0x1c000      //112KB
							SDRAM:			base:0x80000000 len:
            }


另外,必须在CDB文件的Scheduling的PRD - Perodic Function Manager下创建
一个周期定时入口函数,定义如下:
HPrd:period(ticks):100  ,mode选continuous,  function:_H264TimerTick, arg0: 0, arg1:0



									
C代码参考用法:		
#include "h264_define.h"								
void EncodeTskFxn(void)
{
		User_parameter User_param;
    H264_Handle h;
    int 		seqlen[3];
    User_param.bitrate = Q1;  //质量最差
		User_param.cbr =	 0;						//恒定质量
		User_param.height = 576;
		User_param.width  = 720;
		User_param.iframe_interval = 250;
		h = H264_encoder_open( &User_param ) ;
	for(;;)	
		.....
		User_param.bufferY = Y;  //当前采集Y分量数据指针
    User_param.bufferU = U;	//当前采集U分量数据指针
   	User_param.bufferV = V;	//当前采集V分量数据指针
   	
   	H264_Encoding(h,User_param,encoderBuf, &i_file, &i_p, int *seqlen,0);
   	.....
   }	
   	H264_close(h );
}    

#include "h264_define.h"								
void EncodeTskFxn(void)
{
		User_parameter User_param;
    H264_Handle h;
    int 		seqlen[3];
    User_param.bitrate = 1024;(当前码流设置为1024kbps)
		User_param.cbr =	 1;
		User_param.height = 576;
		User_param.width  = 720;
		User_param.iframe_interval = 250;
		h = H264_encoder_open( User_param ) ;
	for(;;)	
		.....
		User_param.bufferY = Y;  //当前采集Y分量数据指针
    User_param.bufferU = U;	//当前采集U分量数据指针
   	User_param.bufferV = V;	//当前采集V分量数据指针
   	
   	H264_Encoding(h,User_param,encoderBuf, &i_file, &i_p, int *seqlen,0);
   	.....
   }	
   	H264_close(h );
}    
*/	
#endif

⌨️ 快捷键说明

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