IMX6 VPU解码流程


前言

近期在做JPEG图像解码相关功能开发,记录IMAX6 调用芯片硬件解码功能开发过程,方便自己,也方便他人


一、IMAX6 硬解码官方流程

根据其官方文档,流程原文如下:

1. Call vpu_Init() to initialize the VPU.
2. Open a decoder instance by using vpu_DecOpen().
3. To provide the proper amount of bitstream, get the bitstream buffer address by using vpu_DecGetBitstreamBuffer().
4. After transferring the decoder input stream, inform the amount of bits transferred into the bitstream buffer by using
vpu_DecUpdateBitstreamBuffer().
5. Before starting a picture decoder operation, get the crucial parameters for decoder operations such as picture size,
frame rate, and required frame buffer size by using vpu_DecGetInitialInfo().
6. Using the returned frame buffer requirement, allocate the proper size of the frame buffers, and convey this data to i.MX
6 VPU by using vpu_DecRegisterFrameBuffer().
7. Start a picture decoder operation picture-by-picture by using vpu_DecStartOneFrame().
8. Wait for the completion of the picture decoder operation interrupt event.
9. Check the results of the decoder operation using vpu_DecGetOutputInfo().
10. After displaying nth frame buffer, clear the buffer display flag by using vpu_DecClrDispFlag().
11. If there is more bitstream to decode, go to Step 7, otherwise go to the next step.
12. Terminate the sequence operation by closing the instance by using vpu_DecClose()

总结一下,解码的主要流程有:

1、初始化模块
2、打开解码器
3、填充数据(输入一部分待解码数据)
4、根据先前填充的数据,解码器返回参数(如:解码图像长宽,输出解码内存块个数等信息)
5、根据获取到的参数注册内存参数(告诉解码器解码后的数据要放哪里)
6、填充数据(没错还要填充数据),(这一步开始就可以开始解码了)
7、开始解码
8、获取解码后的数据(第一次解码出来的图像为第3步输入图像的解码数据,第6步输入的需要下一次调用解码才能输出)
9、如果需要解码其他图像,则重复第6步骤继续解码;
10、解码完成,关闭解码器;

二、使用步骤

1.初始化

调用vpu_Init(),初始化VPU
调用vpu_DecOpen()打开解码器,
*注意!!!*打开解码器前需要调用IOGetPhyMem()IOGetVirtMem()申请内存空间,用于存放待解码数据;

2.注册解码输出内存

  • 填充数据
    打开解码器后,还需要配置解码后图像的存储空间,基于此系统要求先输入一下些原始数据;主要流程如下
1vpu_DecGetBitstreamBuffer(); //获取输入缓冲区地址及剩余可填充的空间;
2、根据获取到的数据地址信息,将待解码数据拷贝到目标地址
2vpu_DecUpdateBitstreamBuffer(); //数据填充完毕后,通知系统数据已更新
  • 获取参数

    通过 vpu_DecGetInitialInfo() 函数获取数据输出的相关参数。需要注意的是,此次输入的原始数据会在接下来调用解码函数接口时被解码。

  • 注册内存

    根据前一步获取的参数,调用IOGetPhyMem()、IOGetVirtMem()申请内存空间,并将申请到的内存地址赋值给FrameBuffer结构体变量。通过vpu_DecRegisterFrameBuffer() 注册。

3.开始解码

解码可以简单分为3步,1、数据填充 2、等待解码完成 3、获取数据;具体流程如下:

  • 数据填充
1vpu_DecGetBitstreamBuffer(); //获取输入缓冲区地址及剩余可填充的空间;
2、根据获取到的数据地址信息,将待解码数据拷贝到目标地址
2vpu_DecUpdateBitstreamBuffer(); //数据填充完毕后,通知系统数据已更新
  • 解码
1vpu_DecStartOneFrame(); 开始解码
2、检查vpu_IsBusy()状态,非忙时即解码完成
3、调用vpu_WaitForInt() 函数等待解码完成
4vpu_DecGetOutputInfo(); //获取解码输出索引,只有调用该接口,系统才会在下一次解码下一帧图像

获取数据
从 第二步中- 注册内存的虚拟地址中直接拷贝已解码的数据
测试代码段

	ret = vpu_DecStartOneFrame(handle, decparam);
	if (ret == RETCODE_JPEG_BIT_EMPTY) {
		continue;
	}
	is_waited_int = 0;
	loop_id = 0;
	while (vpu_IsBusy()) {
		if (loop_id == 50) {
			vpu_SWReset(handle, 0);
		return FALSE;
		}
		vpu_WaitForInt(100);
		is_waited_int = 1;
		loop_id ++;
	}
	if (!is_waited_int)
		vpu_WaitForInt(100);
	ret = vpu_DecGetOutputInfo(handle, &outinfo);

例程中有调用vpu_WaitForInt() 函数等待解码完成。官方文档给的解释是,解码需要时间,在这当中你可以通过调用这个函数等待解码完成,同时你可以去做其他任务;这个函数具体的作用目前我还未弄明白,有看懂的童鞋烦请指教一二;
官方原文如下

Picture decoder operations take a certain amount of time, and the application can complete other tasks while calling vpu_WaitForInt() to wait for the completion of the picture decoding operation, such as display processing of the previously decoded output. The application can use two different schemes for detecting the completion of the picture decoding operation: polling a status register or waiting for an interrupt signal. When the application uses the polling scheme, the application checks the BusyFlag Register of the BIT processor. Calling vpu_IsBusy() gives the same result.

总结

VPU硬解码大致流程总结如下:
初始化-申请内存用于存放待解码数据-申请内存用于存放解码后数据-注册内存-存1帧或多帧入待解码数据-获取解码相关信息-循环解码(填入数据-解码-获取数据)-解码完成;
需要注意的是,注册内存后存入的数据将在后续正式解码的时候被解码,也就是说在循环解码时,解码后的数据是之前未被解码的数据,而非本次被填入的数据;
CSDN上有VPU相关的编解码源码,我的工程也是根据这份源代码裁剪而来的,非常感谢原作者;链接如下:
mxc_vpu_test

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值