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

📄 libmp4enc.c

📁 基于SAA7113的MPEG-4程序
💻 C
字号:
#include <stdio.h>#include <stdlib.h>#include <fcntl.h>#include <sys/mman.h>#include <sys/socket.h>#include <netinet/in.h>#include <sys/types.h>#include <unistd.h>//#include "yuv2yuv.h"#include "dmablib.h"    #include "basetype.h"#include "libmp4enc.h"#include "MP4EncApi.h"#define STRMBUFSIZE     100*1024   /* Encoder variables/structs */MP4API_EncInput  encInp;MP4API_EncOutput encOut;/* Stream variables */unsigned int* pStrm = NULL;	/* variables for linear memory */DMABUF_T	physMem;int         dmabHandle = 0;int max_iframe_interval;int y_max,x_max;/************************************************************************/void* wkads_mp4_encoder_init(MP4API_EncScheme  encode_scheme){	int ret,i;	int done = 0;	unsigned int vop = 0;	static int iFrame = 0;	void*   pEncInst = NULL;	MP4API_EncParam_ErrorTools	params;	switch(encode_scheme){		case MP4API_ENC_SCHEME_QCIF_15FPS_64KB_PLAIN:		case MP4API_ENC_SCHEME_QCIF_15FPS_64KB_VP:		case MP4API_ENC_SCHEME_QCIF_10FPS_32KB_VP:		case MP4API_ENC_SCHEME_QCIF_30FPS_128KB_VP:		case MP4API_ENC_SCHEME_QCIF_15FPS_64KB_SVH:			y_max = 144;			x_max = 176;			break;					case MP4API_ENC_SCHEME_CIF_15FPS_128KB_VP:		case MP4API_ENC_SCHEME_CIF_15FPS_384KB_VP:		case MP4API_ENC_SCHEME_CIF_15FPS_384KB_PLAIN:		case MP4API_ENC_SCHEME_CIF_30FPS_384KB_VP:		case MP4API_ENC_SCHEME_CIF_15FPS_384KB_SVH:			y_max = 288;			x_max = 352;			break;			case MP4API_ENC_SCHEME_QVGA_15FPS_384KB_VP:			y_max = 240;			x_max = 320;			break;		default:			printf("Sorry,the format could't be supported!\n");			return 0;	}				/* allocate linear buffer for the YUV data */	dmabHandle = dmab_init(NULL,1);	if (dmabHandle < 0)	{		printf("Linear memory handler init (dmab_init) failed\n");		return;	}	if (!dmab_get(dmabHandle, x_max*y_max*3/2, &physMem))	{		printf("Failed to alloc physMem\n");		return;	}		/* allocate mpeg4 stream buffer */	pStrm = malloc(STRMBUFSIZE);	if(pStrm == NULL)	{		printf("Cannot allocate memory for MPEG-4 stream\n");		dmab_free(dmabHandle, &physMem);		dmab_exit(dmabHandle);		return;	}	/* initialize encoder */	pEncInst = MP4API_EncoderInit(encode_scheme);		if(pEncInst == NULL)	{		printf("Cannot initialize MPEG-4 encoder\n");		dmab_free(dmabHandle, &physMem);		dmab_exit(dmabHandle);		free(pStrm);		return;	}	/* configure encoder */	/* Disable video packets */	params.u8_VideoPacketsEnable  = 0; /* disabled */	params.u8_DataPartitionEnable = 0; /* disabled */	params.u8_RVlcEnable          = 0; /* disabled */	ret = MP4API_EncoderConfig(pEncInst,&params, 				MP4API_ENC_PID_ERROR_TOOLS);	if(ret)	{		printf("Cannot reconfigure MPEG-4 encoder\n");		dmab_free(dmabHandle, &physMem);		dmab_exit(dmabHandle);		free(pStrm);		MP4API_EncoderShutdown(pEncInst);		return;	}		return pEncInst;}int wkads_mp4_encode_start_stream(void *pEncInst,unsigned char *pOutput){	int ret;	/* Start stream */	encInp.pu32_Picture      = (unsigned int*)physMem.phys;	encInp.u32_TimeIncrement = 0;	encInp.pu32_OutputBuffer = pStrm;	encInp.u32_OutBufSize    = STRMBUFSIZE;	encInp.VopCodingType = MP4API_ENC_VOP_CODING_TYPE_INTRA; /* 1st = intra */	ret = MP4API_EncoderStartStream(pEncInst, &encInp, &encOut);	memcpy(pOutput,(u8 *)encInp.pu32_OutputBuffer,encOut.u32_Size);				return encOut.u32_Size;	}int wkads_mp4_encoder_config(void *pEncInst,mp4_encoder_para *para){	u32	tmp;	u32	bps = para->bitrate;	u32	rvlc = para->rvlc;	u32     dp = para->dp; 	u32	qp = para->qp;	u32     vp_size = para->vp_size;	u32	cir = para->cir;	u32	fps = para->fps;	int	mode = para->mode;	u32	prp = para->prp;	u32	fourmotionvector = para->mv4;	u32	ac_predict = para->ac_pre;	u32     frm_skip = para->frm_skip;		MP4API_EncParam_CameraStabilization	cs;	MP4API_EncParam_RateControl		rc;	MP4API_EncParam_PictureSize		ps;	MP4API_EncParam_ErrorTools		errt;	MP4API_EncParam_ShortVideoHeader	svht;	MP4API_EncParam_CompressionParameters	cp;		int	rt;		max_iframe_interval = para->i_frame_interval;			/* set cir */			MP4API_EncParam_CyclicIntraRefresh	cir_cfg;		MP4API_EncoderGetInfo(pEncInst, &cir_cfg, MP4API_ENC_PID_CYCLIC_INTRA_REFRESH);		if (cir){			cir_cfg.u32_CirEnable = 1;			cir_cfg.u32_IntraPerVop = cir;		}		else		{			cir_cfg.u32_CirEnable = 0;			cir_cfg.u32_IntraPerVop = 0;		}				rt= MP4API_EncoderConfig(pEncInst, &cir_cfg,MP4API_ENC_PID_CYCLIC_INTRA_REFRESH);		if (rt)		{			printf("enccfg cir %d err %X\n", cir, rt);		}		/* set rate control and set default QP */	MP4API_EncoderGetInfo(pEncInst, &rc, MP4API_ENC_PID_RATE_CTRL);	rc.u32_RateCtrlEnable = para->rc;	if (bps)	{		rc.u32_TargetBitRate = bps * 1000;	}	/* vbv setting */	if(bps)	{	/* cbr mode */		if(bps >= 384)		{			if(bps <= 2000)			{			/* main profile level 2 */			        rc.vbv_params.u32_Set = 1; 			        rc.vbv_params.u32_BufSize = 80*16384; 			        rc.vbv_params.u32_InitOccupancy = 80*170*64;			}			else			{				printf("CBR bit rate is too high!\n");			}		}	}	else 	{	/* vbr mode */		if(qp <= 5)		{			/* main profile level 2 */		        rc.vbv_params.u32_Set = 1; 		        rc.vbv_params.u32_BufSize = 80*16384; 		        rc.vbv_params.u32_InitOccupancy = 80*170*64;		}	}		/* ac prediction */	if(ac_predict)	{				MP4API_EncoderGetInfo(pEncInst, &cp, MP4API_ENC_PID_COMPRESSION_PARAMS);		cp.u8_AcPredictionEnable = ac_predict;		rt = MP4API_EncoderConfig(pEncInst, &cp, MP4API_ENC_PID_COMPRESSION_PARAMS);		if (rt)		{			printf("enccfg cp err %X\n", rt);		}	}		/* frame rate */	if (fps)	{		rc.u32_TargetFrameRate = fps;	}	else	{		fps = rc.u32_TargetFrameRate;	}	/* default qp */	if (qp)	{		rc.u32_DefaultQuantParameter = qp;	}	/* frame skip */	if(frm_skip)	{		rc.u32_FrameSkipEnable = 1;	}	else	{		rc.u32_FrameSkipEnable = 0;	}		/* 4MV */	if(fourmotionvector)	{		rc.u32_FourMotionVectorsEnable = 1;	}	else	{		rc.u32_FourMotionVectorsEnable = 0;	}	/* time resolution must be set before RC */	if (mode < 2)	{		tmp = fps;		rt = MP4API_EncoderConfig(pEncInst, &tmp, MP4API_ENC_PID_TIME_RESOLUTION);		if (rt)		{			printf("enccfg res %d err %X\n", tmp, rt);		}	}		/* Rate ctrl setting */	rt = MP4API_EncoderConfig(pEncInst, &rc, MP4API_ENC_PID_RATE_CTRL);	if (rt)	{		printf("enccfg rc err %X\n", rt);	}		/* VP size */	MP4API_EncoderGetInfo(pEncInst, &tmp, MP4API_ENC_PID_VIDEO_PACKET_SIZE);	if (vp_size)	{		tmp = vp_size;	}	rt = MP4API_EncoderConfig(pEncInst, &tmp, MP4API_ENC_PID_VIDEO_PACKET_SIZE);	if (rt)	{		printf("enccfg vpsize %d err %X\n", tmp, rt);	}#if 0	MP4API_EncoderGetInfo(pEncInst, &errt, MP4API_ENC_PID_ERROR_TOOLS);	if ((mode == 1 && !errt.u8_VideoPacketsEnable) ||		(mode != 1 && errt.u8_VideoPacketsEnable))	{		errt.u8_VideoPacketsEnable ^= 1;		rt = MP4API_EncoderConfig(pEncInst, &errt,MP4API_ENC_PID_ERROR_TOOLS);		if (rt)		{			printf("enccfg vpmode %d err %X\n",	errt.u8_VideoPacketsEnable, rt);		}	}			/* error tools */	if(dp || rvlc)	{		if(errt.u8_VideoPacketsEnable)		{		/* dp and rvlc can be used in conjunction with vp only */			MP4API_EncoderGetInfo(pEncInst, &errt, MP4API_ENC_PID_ERROR_TOOLS);			errt.u8_DataPartitionEnable &= dp;			errt.u8_RVlcEnable &= dp&rvlc;			MP4API_EncoderConfig(pEncInst, &errt, MP4API_ENC_PID_ERROR_TOOLS);		}		else		{			dp = 0;			rvlc = 0;		}	}#endif	/* preprocessing */	if(prp){		tmp = prp;		rt = MP4API_EncoderConfig(pEncInst, &tmp,	MP4API_ENC_PID_PREPROCESSING_ENABLE);	}	if (rt)	{		printf("enccfg prpen %d err %X\n", tmp, rt);	}	/* camera stabilization */#if 0	MP4API_EncoderGetInfo(pEncInst, &cs, MP4API_ENC_PID_CAM_STAB);	cs.u32_CamStabEnable = 1;	cs.u32_FrameWidth = 352;	cs.u32_FrameHeight = 288;	rt = MP4API_EncoderConfig(pEncInst, &cs, MP4API_ENC_PID_CAM_STAB);	if (rt)	{		printf("enccfg camstab %d err %X\n", cs.u32_CamStabEnable, rt);	}#endif		return 0;	}int wkads_mp4_encode(void *pEncInst,  unsigned char* pInput,  unsigned char* pOutput){	static int iFrame = 0;	static int vop = 0;	int ret,donae;	static int count = 0;	static int first = 1;	//yuv4222yuv420(x_max,y_max,pInput,(unsigned char*)physMem.user);	memcpy((unsigned char*)physMem.user, pInput, x_max*y_max*3/2);	//physMem.user = pInput;		/* Set encoder parameters */	encInp.pu32_Picture      = (unsigned int*)physMem.phys;	encInp.pu32_OutputBuffer = (unsigned int *)pOutput;	//encInp.pu32_OutputBuffer = pStrm;	encInp.u32_OutBufSize    = STRMBUFSIZE;	iFrame++;	if(first)		count++;	        if(iFrame == max_iframe_interval){	    vop = 0;	    iFrame = 0;        }	if(count < 50)		vop = 0;	else		first = 0;	    	if(vop == 0) /* First VOP */	{		/*aterst VOP must be always intra coded */		encInp.VopCodingType = MP4API_ENC_VOP_CODING_TYPE_INTRA;		/* No previous VOPs => no time passed from prev */		encInp.u32_TimeIncrement = 0;		vop = 1;	}	else	{		/* After first frame always use predicted inter frames.		   OK here but in real life there should be also some		   intra frames every now and then to enable jumpping		   in the stream (player seek) */		encInp.VopCodingType = MP4API_ENC_VOP_CODING_TYPE_INTER;		//encInp.VopCodingType = MP4API_ENC_VOP_CODING_TYPE_INTRA;		encInp.u32_TimeIncrement = 1;	}	ret = MP4API_Encode(pEncInst, &encInp, &encOut);	if(encOut.Code != MP4API_ENC_PICTURE_READY){		//encInp.VopCodingType = MP4API_ENC_VOP_CODING_TYPE_INTRA;		printf("Error in encoding!\n");	}	if(encOut.Code != 0){		encInp.VopCodingType = MP4API_ENC_VOP_CODING_TYPE_INTRA;		//printf("Error in encoding!\n");	}	//memcpy(pOutput,(u8 *)encInp.pu32_OutputBuffer,encOut.u32_Size);	return encOut.u32_Size;}int wkads_mp4_encoder_destroy(void *pEncInst,unsigned char *pOutput){	int ret;		/* end stream */	ret = MP4API_EncoderEndStream(pEncInst, &encInp, &encOut);	memcpy(pOutput,(u8*)encInp.pu32_OutputBuffer,encOut.u32_Size);	/* Close files, free allocated resources */	dmab_free(dmabHandle, &physMem);	dmab_exit(dmabHandle);	free(pStrm);	MP4API_EncoderShutdown(pEncInst);	return encOut.u32_Size;}

⌨️ 快捷键说明

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