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

📄 a.c

📁 基于SAA7113的MPEG-4程序
💻 C
字号:

#define YUVSIZE					152064 /* CIF */

/* Size of the MPEG-4 stream buffer.
   the size used here is very rough based on the
   assuption of 384kbps stream but here reserved 
   avg. size of one second for a single frame */
#define STRMBUFSIZE (384000/8*sizeof(unsigned char)) 


#define INFILENAME              "./stream.yuv"
#define OUTFILENAME             "./stream.mpeg4"

#include <stdio.h>
#include <stdlib.h>

#include "dmablib.h"    /* dmab library is used for allocating contiguous
						   memory area with known physical bus address.
						   This memory block is needed for input image */

#include "basetype.h"
#include "MP4EncApi.h"


/************************************************************************/
int main(void)
{
	/* Encoder variables/structs */
	void*            pEncInst = NULL;
	MP4API_EncInput  encInp;
	MP4API_EncOutput encOut;

	/* Stream variables */
	unsigned int* pStrm = NULL;
	
	/* variables for linear memory */
	DMABUF_T	physMem;
	int         dmabHandle = 0;

	/* File pointers */
	FILE* fYuvInput;
	FILE* fMpeg4Output;


	int ret;
	int done = 0;
	unsigned int vop = 0;

	/*---------------------------------------------------------------*/

	/* Open input file */
	fYuvInput = fopen(INFILENAME, "rb");
	if(fYuvInput == NULL)
	{	
		printf("Cannot open YUV input file\n");
		return(-1);
	}

	/* Open output file */
	fMpeg4Output = fopen(OUTFILENAME, "wb");
	if(fMpeg4Output == NULL)
	{	
		fclose(fYuvInput);
		printf("Cannot open MPEG-4 output file\n");
		return(-1);
	}

	/* allocate linear buffer for the YUV data */

	dmabHandle = dmab_init(NULL);
	if (dmabHandle < 0)
	{
		fclose(fYuvInput);
		fclose(fMpeg4Output);
		printf("Linear memory handler init (dmab_init) failed\n");
		return(-1);

	}
	if (!dmab_get(dmabHandle, YUVSIZE, &physMem))
	{
		fclose(fYuvInput);
		fclose(fMpeg4Output);
		printf("Failed to alloc physMem\n");
		return(-1);
	}

	/* allocate mpeg4 stream buffer */
	pStrm = malloc(STRMBUFSIZE);
	if(pStrm == NULL)
	{
		printf("Cannot allocate memory for MPEG-4 stream\n");
		fclose(fYuvInput);
		fclose(fMpeg4Output);
		dmab_free(dmabHandle, &physMem);
		dmab_exit(dmabHandle);
		return(-1);
	}

	/* initialize encoder */
	pEncInst = MP4API_EncoderInit(MP4API_ENC_SCHEME_CIF_30FPS_384KB_VP);
	if(pEncInst == NULL)
	{
		printf("Cannot initialize MPEG-4 encoder\n");
		fclose(fYuvInput);
		fclose(fMpeg4Output);
		dmab_free(dmabHandle, &physMem);
		dmab_exit(dmabHandle);
		free(pStrm);
		return(-1);
	}

	
	/* configure encoder */
	/* Disable video packets */
	{
		unsigned int ret;
		MP4API_EncParam_ErrorTools	params;

		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");
			fclose(fYuvInput);
			fclose(fMpeg4Output);
			dmab_free(dmabHandle, &physMem);
			dmab_exit(dmabHandle);
			free(pStrm);
			MP4API_EncoderShutdown(pEncInst);
			return(-1);
		}
	}

	/* 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);

	printf("Stream started (%d bytes)\n", encOut.u32_Size);

	ret = fwrite( (u8*)encInp.pu32_OutputBuffer, 
		           sizeof(unsigned char), 
				   encOut.u32_Size, 
				   fMpeg4Output );

	if(ret != encOut.u32_Size)
	{
		printf("Cannot write out MPEG-4 stream\n");
		fclose(fYuvInput);
		fclose(fMpeg4Output);
		dmab_free(dmabHandle, &physMem);
		dmab_exit(dmabHandle);
		free(pStrm);
		MP4API_EncoderShutdown(pEncInst);
		return(-1);
	}

	/* The real action starts */

	/* load first yuv frame to linear memory */
	ret = fread( (unsigned char*)physMem.user, 
				 sizeof(unsigned char), 
				 YUVSIZE, 
				 fYuvInput );
	if(ret != YUVSIZE)
	{
		printf("Cannot read YUV data (%d)\n", ret);
		done = 1;
	}
	else
	{
		done = 0;
	}

	vop = 0;

	/* vop loop */
	while(!done)
	{
		/* Set encoder parameters */
		encInp.pu32_Picture      = (unsigned int*)physMem.phys;
		encInp.pu32_OutputBuffer = pStrm;
		encInp.u32_OutBufSize    = STRMBUFSIZE;

		if(vop == 0) /* First VOP */
		{
			/* First 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;
		}
		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.u32_TimeIncrement = 1;
		}

		ret = MP4API_Encode(pEncInst, &encInp, &encOut);
		
		/* No video packets used => there should always be
		   one frame ready after one encode function call.
		   NOTE: It is possible to happen buffer overflow
		   which is not error but with big buffer allocated
		   ealier it shouldn't occure and therefore it isn't 
		   handled here in this simple example */
		if(encOut.Code != MP4API_ENC_PICTURE_READY)
		{
			printf("Error in encoding\n");
			done = 1;
		}

		printf("VOP Encoded (%d bytes)\n", encOut.u32_Size);

		/* Write out the encoded stream */
		ret = fwrite( (u8*)encInp.pu32_OutputBuffer, 
					   sizeof(unsigned char), 
					   encOut.u32_Size, 
					   fMpeg4Output );

		if(ret != encOut.u32_Size)
		{
			printf("Cannot write out MPEG-4 stream\n");
			done = 1;
		}

		/* load new yuv frame to linear memory */
		ret = fread( (unsigned char*)physMem.user, 
					 sizeof(unsigned char), 
					 YUVSIZE, 
					 fYuvInput );
		if(ret != YUVSIZE)
		{
			printf("No more YUV data\n");
			done = 1;
		}

	}

	/* end stream */
	ret = MP4API_EncoderEndStream(pEncInst, &encInp, &encOut);

	printf("Strm ended (%d bytes)\n", encOut.u32_Size);

	/* Write out the stream end */
	ret = fwrite( (u8*)encInp.pu32_OutputBuffer, 
				   sizeof(unsigned char), 
				   encOut.u32_Size, 
				   fMpeg4Output );


	/* Close files, free allocated resources */
	fclose(fYuvInput);
	fclose(fMpeg4Output);
	dmab_free(dmabHandle, &physMem);
	dmab_exit(dmabHandle);
	free(pStrm);
	MP4API_EncoderShutdown(pEncInst);

	return(0);
}
/************************************************************************/


⌨️ 快捷键说明

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