嵌入式专题: S5PV210 - MPEG4编码

我想说不台的平台,如tiny210和x210,它们的头文件是有略微差别的。我这个是x210下的代码。但都需要注意的是NV12T与NV12的问题,默认要求输入的图片是NV12T,经过调整之后,可以允许用NV12。

即便如此,NV12格式的图片也不好拿到啊。


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

#include "../mfc/SsbSipMfcApi.h"
#include "../mfc/MfcConvert.h"
#include "../mm/MMClock.h"

int test_enc_mpeg4()
{
	MMClock clock;
	clock.Adjust(1000);

	SSBSIP_MFC_ERROR_CODE ret = MFC_RET_OK;
	
	// 打开
	unsigned int buf_type = CACHE;
	void* handle = SsbSipMfcEncOpen();
	if(handle == NULL)
	{
		printf("failed to open mfc device!\n");
		return -1;
	}
	printf("== SsbSipMfcDecOpen OK \n");

	int img_width = 640;
	int img_height = 480;

	// 初始化
	SSBSIP_MFC_ENC_MPEG4_PARAM param;
	memset(¶m, 0, sizeof(param));
	param.codecType = MPEG4_ENC;
	param.SourceWidth = img_width;
	param.SourceHeight = img_height;
	param.FrameMap = NV12_LINEAR; // 使用linear

	param.IDRPeriod = 20;  // 可以大于3吗?
	param.SliceMode = 0;
	param.SliceArgument = 1;
	param.RandomIntraMBRefresh = 0; // ?

	// 不使用frame based rate control
	param.EnableFRMRateControl = 1;
	param.TimeIncreamentRes = 1000;
	param.VopTimeIncreament = 40;
	param.Bitrate = 4000000;

	param.FrameQp = 1;
	param.FrameQp_P = 1;
	param.FrameQp_B = 1;
	param.QSCodeMax = 45;
	param.QSCodeMin = 20;
	param.CBRPeriodRf = 2;

	// 不使用自定义padding
	param.PadControlOn = 0;
	param.LumaPadVal = 0;
	param.CbPadVal = 0;
	param.CrPadVal = 0;

	param.ProfileIDC = 66;
	param.LevelIDC = 22;
	param.NumberBFrames = 0;
	param.DisableQpelME = 0;

	if(SsbSipMfcEncInit(handle, ¶m) != MFC_RET_OK)
	{
		printf("failed to init encoder !\n");
		return -1;
	}

	/* 得到输入缓冲区地址 */
	SSBSIP_MFC_ENC_INPUT_INFO inbuf;
	if(SsbSipMfcEncGetInBuf (handle, &inbuf) != MFC_RET_OK)
	{
		printf("failed to get in buf !\n");
		return 0;
	}

	printf("in buf: Y (addr=%08X, size=%d), CbCr (addr=%08X, size=%d) \n"
		, inbuf.YVirAddr, inbuf.YSize
		, inbuf.CVirAddr, inbuf.CSize
		);

	/* 得到header */
	SSBSIP_MFC_ENC_OUTPUT_INFO outbuf;
	ret = SsbSipMfcEncGetOutBuf (handle, &outbuf);
	if(ret != MFC_RET_OK)
	{
		printf("failed to get output (%d) \n", ret);
		return -1;
	}
	printf("saving header: %d bytes \n", outbuf.headerSize);
	if(1)
	{
		FILE* fp = fopen("a00.mpeg4", "wb");
		fwrite(outbuf.StrmVirAddr, 1, outbuf.headerSize, fp);
		fclose(fp);
	}

	int y_size = img_width * img_height;
	int c_size = y_size / 2;

	/* 读取图像 */
	FILE* fp = fopen("k00.nv12", "rb");
	int n1 = fread(inbuf.YVirAddr, 1, y_size, fp);
	int n2 = fread(inbuf.CVirAddr, 1, c_size, fp);
	printf("read bytes: n1=%d, n2=%d \n", n1, n2);

	int count = 0;
	while(count ++ < 3)
	{
		printf("... times: %d , now %d ...\n", count, (int) clock.PtsTime());

		/* 编码 */
		ret = SsbSipMfcEncExe(handle);
		if(ret != MFC_RET_OK)
		{
			printf("failed encoding (%d) \n", ret);
			return -1;
		}

		/* 输出结果 */
		SSBSIP_MFC_ENC_OUTPUT_INFO outbuf;
		ret = SsbSipMfcEncGetOutBuf (handle, &outbuf);
		if(ret != MFC_RET_OK)
		{
			printf("failed to get output (%d) \n", ret);
			return -1;
		}

		printf("output: frame type=%d, size=%d, header size=%d \n"
			, outbuf.frameType
			, outbuf.dataSize
			, outbuf.headerSize);

		/* 保存成文件*/
		char filename[128];
		sprintf(filename, "a%02d.mpeg4", count);

		FILE* fp = fopen(filename, "wb");
		fwrite(outbuf.StrmVirAddr, 1, outbuf.dataSize, fp);
		fclose(fp);

	}
	

	SsbSipMfcEncClose(handle);

	return 0;
}


你可能感兴趣的:(嵌入式专题: S5PV210 - MPEG4编码)