首页 > 代码库 > 嵌入式专题: S5PV210 - H264硬件解码(MFC)

嵌入式专题: S5PV210 - H264硬件解码(MFC)

先说一下编码的例子好像找不到了,只提供一下解码的例子吧。淡疼的三星要是能以YUV420P为基本图像格式就好了,这样结合FFmpeg来开发,各种应用都比较方法。再设计一个RGB/YUV硬件转码单元,最好。

 

#include <stdio.h>#include <string.h>#include <stdlib.h>#include <unistd.h>#include "../mfc/SsbSipMfcApi.h"#include "../mfc/MfcConvert.h"int test_dec_h264(){	SSBSIP_MFC_ERROR_CODE ret = MFC_RET_OK;	// 打开	unsigned int buf_type = CACHE;	void* handle = SsbSipMfcDecOpen();	if(handle == NULL)	{		printf("failed to open mfc device!\n");		return -1;	}	printf("== SsbSipMfcDecOpen OK \n");	int maxFrameSize = 256 * 1024;	/* 得到 输入缓冲区信息 */	void* virInBuf = NULL;	void* phyInBuf = NULL;	virInBuf = SsbSipMfcDecGetInBuf(handle, &phyInBuf, maxFrameSize);	printf("== SsbSipMfcDecGetInBuf OK \n");	printf("virInBuf=%08X, phyInBuf=%08X \n", virInBuf, phyInBuf);	/* 配置: 暂不需要设置 */	// 	int configValue = 2; // the number that you want to delay	// 	SsbSipMfcDecSetConfig(handle, MFC_DEC_SETCONF_DISPLAY_DELAY,	// 		&configValue);	/* 读取初始化数据到输入缓冲区,此数据在编码的时候生成 */	FILE* fp = fopen("h264/hdr.h264", "rb");	int hdr_size = fread(virInBuf, 1, maxFrameSize, fp);	printf("init data: %d bytes \n", hdr_size);	fclose(fp);		/* 初始化 */	ret = SsbSipMfcDecInit(handle, H264_DEC, hdr_size);	if(ret != MFC_RET_OK)	{		printf("failed to init mfc!\n");		return -1;	}	else	{		/* 检查是否初始化成功 */		SSBSIP_MFC_DEC_OUTPUT_INFO out;		SSBSIP_MFC_DEC_OUTBUF_STATUS status = SsbSipMfcDecGetOutBuf(handle, &out);		if(out.img_width <= 0 || out.img_height <= 0)		{			printf("bad image size, should init again!\n");			return -1;		}	}	/* 检查输出缓冲区 */	printf("== SsbSipMfcDecInit OK \n");	SSBSIP_MFC_DEC_OUTPUT_INFO out;	SSBSIP_MFC_DEC_OUTBUF_STATUS status;	status = SsbSipMfcDecGetOutBuf(handle, &out);	printf("output: status = %d , image(%dx%d), buf(%dx%d), crop(%d,%d,%d,%d) \n", 		status, 		out.img_width, out.img_height,		out.buf_width, out.buf_height,		out.crop_left_offset, out.crop_top_offset, 		out.crop_right_offset, out.crop_bottom_offset);	printf("-------------------------------\n");	int count = 0;	while(count ++ < 100)	{		/* 打开输入数据:已经编码的mpeg4数据 */		char filename[128];		sprintf(filename, "h264/%08d.h264", count);		printf(">>> input file: %s \n", filename);		FILE* fp = fopen(filename, "rb");		int inDataLen = fread(virInBuf, 1, maxFrameSize, fp);		fclose(fp);				/* 解码 */		ret = SsbSipMfcDecExe(handle, inDataLen);		if(ret != MFC_RET_OK)		{			printf("failed decoding (%d) \n", ret);			return  -1;		}		/* 输出缓冲区 */		SSBSIP_MFC_DEC_OUTPUT_INFO out;		SSBSIP_MFC_DEC_OUTBUF_STATUS status;		status = SsbSipMfcDecGetOutBuf(handle, &out);		printf("<<< output: status = %d , image(%dx%d), buf(%dx%d), crop(%d,%d,%d,%d) \n", 			status, 			out.img_width, out.img_height,			out.buf_width, out.buf_height,			out.crop_left_offset, out.crop_top_offset, 			out.crop_right_offset, out.crop_bottom_offset);		if(status == MFC_GETOUTBUF_DISPLAY_DECODING 			|| status == MFC_GETOUTBUF_DISPLAY_ONLY)		{			printf("y_addr = %08X, cbcr_addr = %08X \n", 				out.YVirAddr, out.CVirAddr);#if 1			// 存储为NV12-T			if(1)			{				//vo.DrawNV12T(out.YPhyAddr, out.CPhyAddr);				int y_size = out.buf_width * out.buf_height;				int uv_size = y_size / 2;				char yuvname[128];				sprintf(yuvname, "nv12t/ttt%02d.nv12t", count);				FILE* fp_y = fopen(yuvname, "wb");				fwrite(out.YVirAddr, 1, y_size, fp_y);				fwrite(out.CVirAddr, 1, uv_size, fp_y);				fclose(fp_y);			}#endif#if 0			// 存储为YUV420P			if(1)			{				// tile -> linear				int y_size = out.buf_width * out.buf_height;				int uv_size = y_size / 2;				unsigned char* y = new unsigned char[y_size]; 				unsigned char* uv = new unsigned char[uv_size];				printf("y buff: %08X, %d\n", y, y_size);				//			tile_to_linenar_y((char*)out.YVirAddr, (char*)y, out.buf_width, out.buf_height);				Y_tile_to_linear_4x2(y, (unsigned char*)out.YVirAddr, out.buf_width, out.buf_height);				CbCr_tile_to_linear_4x2(uv, (unsigned char*)out.CVirAddr, out.buf_width, out.buf_height);				// 				tile_to_linear_64x32_4x2_neon(y, (unsigned char*)out.YVirAddr, out.buf_width, out.buf_height);				// 				tile_to_linear_64x32_4x2_uv_neon(uv, (unsigned char*)out.CVirAddr, out.buf_width, out.buf_height/2);				//nv_2_uv((char*)out.CVirAddr, (char*)uv , (char*)uv + y_size/4, out.buf_width, out.buf_height);				char yuvname[128];				sprintf(yuvname, "c%02d.yuv420", count);				FILE* fp_y = fopen(yuvname, "wb");				fwrite(y, 1, y_size, fp_y);				fwrite(uv, 1, uv_size, fp_y);				fclose(fp_y);				//printf("haha\n");				delete [] y;				delete [] uv;			}#endif#if 0			if(0)			{				// tile to rgb				int width = out.buf_width;				int height = out.buf_height;				Bitmap bmp;				bmp.Create(width, height, 24);				tile64x32_to_rgb24((unsigned char*)out.YVirAddr, (unsigned char*)out.CVirAddr,					bmp.m_Data,					width, height);				printf("write to bmp file \n");				char outname[128];				sprintf(outname, "%s.bmp", filename);				bmp.SaveToFile(outname);			}#endif		}	}	getchar();	// 关闭	SsbSipMfcDecClose(handle);	return 0;}