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

解码比编码要省心一些,唯一让人操心的是,在初始化的时候要用编码器生成的head数据来初始化的。就是说,在编码的时候,是生成一个head数据,这个数据是用来在解码的时候用的。

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

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

#include "Bitmap.h"
#include "../mm/MMClock.h"
#include "../vout/Vout.h"

int test_dec_mpeg4()
{
	Vout vo;
	vo.Open(640,480, 640, 480);

	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("a00.mpeg4", "rb");
	int hdr_size = fread(virInBuf, 1, maxFrameSize, fp);
	printf("init data: %d bytes \n", hdr_size);
	fclose(fp);	

	/* 初始化 */
	ret = SsbSipMfcDecInit(handle, MPEG4_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 ++ < 2)
	{
		/* 打开输入数据:已经编码的mpeg4数据 */
		char filename[128];
		sprintf(filename, "a%02d.mpeg4", 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);

			//vo.DrawNV12T(out.YPhyAddr, out.CPhyAddr);
			vo.DrawNV12T(out.YVirAddr, out.CVirAddr);

			sleep(1);

#if 0
			// 存储为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, "t%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();
	vo.Close();

	// 关闭
	SsbSipMfcDecClose(handle);

	return 0;
}

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

时间: 2024-10-12 11:51:31

嵌入式专题: S5PV210 - MPEG4解码(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 - H264硬件解码(MFC)

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

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

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

MFC的本质

一.引言 上一专题中,纯手动地完成了一个Windows应用程序,然而,在实际开发中,我们大多数都是使用已有的类库来开发Windows应用程序.MFC(Microsoft Foundation Class, 微软基础类库)是微软为了简化程序员的开发工作而将Windows API 封装到C++类中,利用这些类,程序员可以有效地完成Windows平台下应用程序的开发.本专题将详细剖析它. 二.利用向导创建一个MFC程序 用于帮助有效地开发Windows应用程序的类库除了MFC外,还有其他开源类库提供,

深入浅出话VC++——MFC的本质

本文为转载,为阅读方便,部分内容作出修改. 一.引言 在实际开发中,我们大多数都是使用已有的类库来开发Windows应用程序. MFC(Microsoft Foundation Class, 微软基础类库)是微软为了简化程序员的开发工作而将Windows API 封装到C++类中,利用这些类,程序员可以有效地完成Windows平台下应用程序的开发.本专题将详细剖析它. 二.利用向导创建一个MFC程序 用于帮助有效地开发Windows应用程序的类库除了MFC外,还有其他开源类库提供,比如说QT,只

DAVINCI DM3730开发攻略——应用程序例程分析

过完2015年春节回来了,利用上班前的几天时间,先把这篇文章写完,本来是先写<DAVINCI DM3730开发攻略--linux-2.6.32移植>,但是那篇文章涉及内核的东西太多,不太好写,而本人已经很长时间没写新文章了,先发布这篇文章.后来想了想,从应用程序使用的角度分析,再一步一步深入内核里边去,也许更好. 前面几篇DM3730开发攻略讲到:一个DAVINCI  DM3730板子程序由xload,uboot, linux-2.6.32或者(linux-2.6.37),文件系统rootfs

竞赛列表

学科竞赛获奖统计范围为: 全国大学生电子设计竞赛 全国大学生电子设计竞赛嵌入式专题竞赛 “挑战杯”全国大学生科技作品竞赛 “挑战杯”全国大学生创业计划大赛 中国“互联网+”大学生创新创业大赛 中国创新创业大赛 全国大学生机械创新设计大赛 全国周培源大学生力学竞赛 全国大学生结构设计竞赛 国际大学生机械设计竞赛 美国大学生程序设计竞赛(ACM) 美国数学模型竞赛(MCM) 全国大学生数学建模竞赛 全国大学生广告艺术设计大赛 全国大学生英语竞赛 全国大学生英语演讲竞赛 全国大学生化学实验竞赛 全国大