📄 a.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,
¶ms,
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 + -