嵌入式专题: 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;
}

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

时间: 2024-10-06 12:59:57

嵌入式专题: S5PV210 - H264硬件解码(MFC)的相关文章

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

嵌入式就是瞎折腾.奉献一些过时的代码,让嵌入式的兄弟少折腾一些吧. 这一篇是怎么解码的,本篇用的MPEG2VIDEO解码. 头文件 #ifndef _HW_MPV2_DECODER #define _HW_MPV2_DECODER class HwMpv2Decoder { public: HwMpv2Decoder(); ~HwMpv2Decoder(); int Open(unsigned int width, unsigned int height); void Close(); int

嵌入式专题: S5PV210 - MPEG4解码(MFC)

解码比编码要省心一些,唯一让人操心的是,在初始化的时候要用编码器生成的head数据来初始化的.就是说,在编码的时候,是生成一个head数据,这个数据是用来在解码的时候用的. #include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include "../mfc/SsbSipMfcApi.h" #include "../mfc/

嵌入式专题: UVC摄像头摄像

所谓的CMOS摄像头,驱动往往是一坨shit,想做摄像头应用,还是上UVC摄像头吧. 这个类里展示UVC摄像头的各种参数的设置.需要注意的是,如果帧率上不去,往往是由于曝光时间太长导致.这个关系是这样的,曝光越长,图片成像质量越好,但帧率自然就下去了. #ifndef _UVC_CAMERA_H #define _UVC_CAMERA_H class UvcCamera { public: UvcCamera(); ~UvcCamera(); int Open(const char* dev,

嵌入式专题: 双网卡wifi组建NAT上外网

条件: 开发板上双网卡,其中一个是usb wifi,提供wifi路由功能.另一个网口可以上外网. 目标:普通PC/手机能够连此wifi路由,上外网. 1. Wifi AP USB Wifi部分:勿用多言,此使用Realtek 8188 UC版本,这款Wifi的官方软件自带了驱动程序相应的应用软件.应该就是RTL8188C_8192C_USB_linux_v4.0.2_9000.20130911.zip这个程序包,里面有3个部分,一个是驱动,一个是hostapd,一个是wpa_supplicant

解密H264、AAC硬件解码的关键扩展数据处理

通过上一篇文章,我们用ffmpeg分离出一个多媒体容器中的音视频数据,但是很可能这些数据是不能被正确解码的.为什么呢?因为在解码这些数据之前,需要对解码器做一些配置,典型的就是目前流行的高清编码"黄金搭档"组合H264 + AAC的搭配.本文将讲述H264和AAC的关键解码配置参数的解析,如果没有这些配置信息,数据帧往往不完整,导致了解码器不能解码. H264的配置信息解析 前面我们知道,ffmpeg的avformat_find_stream_info函数可以取得音视频媒体多种,比如播

嵌入式专题: S5PV210 - MPEG4编码

我想说不台的平台,如tiny210和x210.它们的头文件是有稍微区别的. 我这个是x210下的代码.但都须要注意的是NV12T与NV12的问题,默认要求输入的图片是NV12T,经过调整之后,能够同意用NV12. 即便如此.NV12格式的图片也不好拿到啊. #include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include "../mfc/S

解密硬件解码关键技术

通过上一篇文章,我们用ffmpeg分离出一个多媒体容器中的音视频数据,但是很可能这些数据是不能被正确解码的.为什么呢?因为在解码这些数据之前,需要对解码器做一些配置,典型的就是目前流行的高清编码“黄金搭档”组合H264 + AAC的搭配.本文将讲述H264和AAC的关键解码配置参数的解析,如果没有这些配置信息,数据帧往往不完整,导致了解码器不能解码. H264的配置信息解析 前面我们知道,ffmpeg的avformat_find_stream_info函数可以取得音视频媒体多种,比如播放持续时间

H264 编解码框架简单介绍

阅读完H264/AVC 编解码器的介绍,脑海中仅仅是留下下面三条: 1.H264并没有明白规定一个编解码器怎样实现,仅仅是规定了一个编码后的视频比特流的句法,和该比特流的解码方法,这个与MPEG 类似. 2.H264和曾经的标准(如H261.H263.MPEG-1.MPEG-4)的编解码器实现流程没有太大差别,基本的不同在于各功能块的细节. 3.H264就是利用实现的复杂性获得压缩性能的明显改善.(至于复杂度的评估,以后会介绍) 以下介绍一下H264的编码器框图: 编码器採用的仍是变换和预測的混

FFMPEG实现H264的解码(从源代码角度)

农历2014年底了,将前段时间工作中研究的FFMPEG解码H264流程在此做一下整理,也算作年终技术总结了! H264解码原理: H264的原理参考另一篇博文 http://blog.csdn.net/rootusers/article/details/43563133 H264分为NAL(网络抽象层)和VCL(视频编码层) 解码器的总框架: 解码器的流程为:将NAL数据位流输入到H264的解码器中,熵解码模块解码后输出量化系数X:系数经过反量化和反变换得到残差数据R:解码器使用从码流中解码的头