码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2014-07-12 23:16:22      阅读:245      评论:0      收藏:0      [点我收藏+]

标签:数据   os   width   io   line   rgb   

先说一下编码的例子好像找不到了,只提供一下解码的例子吧。淡疼的三星要是能以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;
}


 

嵌入式专题: S5PV210 - H264硬件解码(MFC),布布扣,bubuko.com

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

标签:数据   os   width   io   line   rgb   

原文地址:http://blog.csdn.net/iamshaofa/article/details/37693417

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!