h.264并行解码算法3D-Wave实现(基于多核共享内存系统)
3D-Wave算法是2D-Wave的扩展。3D-Wave相对于只在帧内并行的2D-Wave来说,多了帧间并行,不用等待前一帧完成解码后才开始下一帧的解码,而是只要宏块的帧间参考部分以及帧内依赖宏块解码完毕即可开始当前宏块的解码。由于帧间参考所用的运动向量是动态的值,因此称此算法为Dynamic 3D-Wave。
在3D-Wave算法中,宏块的帧间参考部分是指宏块进行运动补偿时需要依赖的相应参考帧的某些宏块,所依赖的这些帧间宏块当中,最右下角的那个宏块会是最晚被解码的,因此我们可以把它当作帧间依赖。另外,如果当前宏块采用的是双向预测,那么它将有两个帧间依赖。

3D-Wave实现
如前文所说,3D-Wave算法中,宏块需要分别等待帧内依赖、帧间依赖解码完成才能开始当前宏块的解码操作。由于这两个依赖的完成时间会有先后之分,因此可能会出现以下两种情况
| 情形 1 | 情形 2 | |
| step 1 | 帧间依赖解码完成 | 帧内依赖解码完成,启动解码 |
| step 2 | 帧内依赖解码完成,启动解码 | 帧间依赖解码完成 |
| step 3 | 解码宏块 | 解码宏块 |
| step 4 | 通知依赖于本宏块的其它宏块 | 通知依赖于本宏块的其它宏块 |
其中解码宏块必须由帧内依赖解码完成后一同启动,因为帧间依赖在解码完成时,并不知道哪个宏块会依赖于它,而帧内依赖由于位置是固定的,因此在帧内依赖解码完成后能直接启动解码,得到mvp(运动向量的预测值)然后求得mv,从而确定当前宏块与帧间依赖的关系,帧间依赖根据这个关系来通知当前宏块:帧间依赖解码已完成。
根据上面的分析,有如下实现方案:
用一个三位数组Ready[f][x][y]来表示某一帧的某一宏块是否解码完成;
用一个三位数组KoL[f][x][y]来表示某一帧的某一宏块的帧间依赖关系,(f,x,y)是当前宏块,KoL[f][x][y]内存放的是帧间依赖于这个宏块的其它宏块,用链表实现;

在帧间依赖先解码完成的情况下,去把Ready数组中该帧间依赖所在的位置的元素置1。待帧内依赖解码完成,当前宏块开始解码时,去查看Ready数组中帧间依赖的元素,会得知该帧间依赖已解码完成。

在帧内依赖先解码完成的情况下,当前宏块开始解码,去查看Ready数组中帧间依赖的元素时,会发现帧间依赖尚未解码完成,因此需要用KoL把当前宏块与帧间依赖关联在一起,然后解码任务会由于帧间依赖没有解码完成而被挂起。待帧间依赖解码完成,去把Ready数组中的相应元素置1,并通过KoL链表数组通知帧间依赖于该宏块的宏块,恢复解码任务。

伪代码如下
void decode_mb(int x, int y, int f, bool mv_pred_done, int RMB_start)
{
/*
*一个宏块由于“挂起”与“恢复”,可能会重复执行decode_mb,
*而求mvp等步骤只需要执行一次
*/
if(!mv_pred_done)
{
/* 求mvp */
Motion_Vector_Prediction(x, y);
/* 通过mvp得到mv,得到帧间依赖,帧间依赖可能不止一个 */
RMB_List = RMB_Calculation(x, y);
} /* 遍历帧间依赖,如果有依赖没解码完成,应该“挂起”,即return */
for(i = RMB_List.start; i<RMB_List.last; i++)
{
(g,u,v) = get_frame_number_and_MB_coord(RMB_List.rmb[i]);
if(!Ready[g][u][v])
{
/* 有依赖没解码完成,把当前MB加入到它的KoL */
Subscribe(Kol[g][u][v], x, y, f, i+1);
/* “挂起” */
return;
}
} /* 实际的宏块重建工作 */
Picture_Prediction(x, y);
Deblocking_Info(x, y);
Deblocking_Filter(x, y); Ready[f][x][y] = true; /* 恢复帧间依赖于本MB的MB */
for(each quadruple(u, v, g, start) in KoL[f][x][y])
tp_submit(decode_mb, u, v, g, ture, start); /*
*from 2D-Wave
*decrement dependency counters and tail submit
*/
if(y < WIDTH-1){
atomic_dec(dep_count[x][y+1]);
if(dep_count[x][y+1] == 0)
tp_submit(decode_mb, x, y+1, f, false, 0);
}
if(x < HEIGHT-1 && y != 0){
atomic_dec(dep_count[x+1][y-1]);
if(dep_count[x+1][y-1] == 0)
tp_submit(decode_mb, x+1, y-1, f, false, 0);
}
}
优化
优化思路与2D-Wave算法一样,尽可能使得一个核心解码相邻宏块。
void decode_mb(int x, int y, int f, bool mv_pred_done, int RMB_start)
{
down_left_avail = 0;
right_avail = 0; do{
/*
*一个宏块由于“挂起”与“恢复”,可能会重复执行decode_mb,
*而求mvp等步骤只需要执行一次
*/
if(!mv_pred_done)
{
/* 求mvp */
Motion_Vector_Prediction(x, y);
/* 通过mvp得到mv,得到帧间依赖,帧间依赖可能不止一个 */
RMB_List = RMB_Calculation(x, y);
} /* 遍历帧间依赖,如果有依赖没解码完成,应该“挂起”,即return */
for(i = RMB_List.start; i<RMB_List.last; i++)
{
(g,u,v) = get_frame_number_and_MB_coord(RMB_List.rmb[i]);
if(!Ready[g][u][v])
{
/* 有依赖没解码完成,把当前MB加入到它的KoL */
Subscribe(Kol[g][u][v], x, y, f, i+1);
/* “挂起” */
return;
}
} /* 实际的宏块重建工作 */
Picture_Prediction(x, y);
Deblocking_Info(x, y);
Deblocking_Filter(x, y); Ready[f][x][y] = true; /* 恢复帧间依赖于本MB的MB */
for(each quadruple(u, v, g, start) in KoL[f][x][y])
tp_submit(decode_mb, u, v, g, ture, start); /*
*from 2D-Wave
*decrement dependency counters and tail submit
*/
if(y < WIDTH-1){
atomic_dec(dep_count[x][y+1]);
if(dep_count[x][y+1] == 0)
right_avail = 1;
}
if(x < HEIGHT-1 && y != 0){
atomic_dec(dep_count[x+1][y-1]);
if(dep_count[x+1][y-1] == 0)
right_avail = 1;
} /* give priority to right MB */
if(down_left_avail && right_avail)
{
tp_submit(decode_mb, x+1, y-1, f, false, 0);
y++;
mv_pred_done = false;
}
else if(down_left_avail)
{
x++; y--;
mv_pred_done = false;
}
else if(right_avail)
{
y++;
mv_pred_down = false;
}
}while(down_left_avail || right_avail);
}
没资源时挂起任务,有资源时恢复任务,这是一种常见的任务同步需求。我们这里由于假设任务是非抢占类型的,即一个任务不能中间停止,只能从开头执行结束,因此用return代替挂起,重启任务代替恢复。如果在一般的操作系统上实现的话,有各种各样的同步工具,如semaphore、lock、Event等。
关于h.264并行解码算法的更详细分析请参考Ben Juurlink · Mauricio Alvarez-Mesa · Chi Ching Chi · Arnaldo Azevedo · Cor Meenderinck · Alex Ramirez:《Scalable Parallel Programming Applied to H.264/AVC Decoding》
h.264并行解码算法3D-Wave实现(基于多核共享内存系统)的更多相关文章
- h.264并行解码算法2D-Wave实现(基于多核共享内存系统)
cache-coherent shared-memory system 我们最平常使用的很多x86.arm芯片都属于多核共享内存系统,这种系统表现为多个核心能直接对同一内存进行读写访问.尽管内存的存取 ...
- h.264并行解码算法2D-Wave实现(基于多核非共享内存系统)
在<Scalable Parallel Programming Applied to H.264/AVC Decoding>书中,作者基于双芯片18核的Cell BE系统实现了2D-Wav ...
- h.264并行解码算法分析
并行算法类型可以分为两类 Function-level Decomposition,按照功能模块进行并行 Data-level Decomposition,按照数据划分进行并行 Function-le ...
- h.264并行熵解码
在前面讨论并行解码的章节中,我们专注于讨论解码的宏块重建部分,甚至把宏块重建描述成宏块解码,这是因为在解码工作中,宏块重建确实占了相当大的比重,不过解码还包含其它的部分,按照解码流程可粗略分为: 读取 ...
- 让dcef3支持mp3和h.264 mp4解码播放
嵌入式Chromium框架(简称CEF) 是一个由Marshall Greenblatt在2008建立的开源项目,它主要目的是开发一个基于Google Chromium的Webbrowser控件.CE ...
- h.264硬件解码
// H264HWDecoder.m // H264EncoderDecoder // // Created by lujunjie on 2016/11/28. // Copyright © 201 ...
- 音视频编解码技术(一):MPEG-4/H.264 AVC 编解码标准
一.H264 概述 H.264,通常也被称之为H.264/AVC(或者H.264/MPEG-4 AVC或MPEG-4/H.264 AVC) 1. H.264视频编解码的意义 H.264的出现就是为了创 ...
- 【视频编解码·学习笔记】2. H.264简介
一.H.264视频编码标准 H.264视频编码标准是ITU-T与MPEG合作产生的又一巨大成果,自颁布之日起就在业界产生了巨大影响.严格地讲,H.264标准是属于MPEG-4家族的一部分,即MPEG- ...
- H.264视频的RTP荷载格式
Status of This Memo This document specifies an Internet standards track protocol for the Internet ...
随机推荐
- Xcode 5 安装coco2d-iphone
从http://www.cocos2d-iphone.org/download/下载并解压缩最新版本的cocos2d,默认情况下会保存在 /Users/XXX/Downloads/cocos2d-ip ...
- linux之ioctl函数解析
[lingyun@localhost ioctl_1]$ ls ipconfig.c [lingyun@localhost ioctl_1]$ cat ipconfig.c /*********** ...
- CentOS 6.7平台Hadoop 1.2.1环境搭建
本教程使用Vultr的VPS搭建,主要实现HDFS和MapReduce两个功能. master.hadoop - 45.32.90.100 slave1.hadoop - 45.32.92.47 sl ...
- 关于jquery获取服务器端xml数据
其实这个很简单,但是有时候简单的东西会让你犯一些低级错误. 今天写了个spring mvc 的服务器端接口,主要是用来共享一些数据库数据. 请求字段:http://localhost:8080/XXX ...
- 隐藏元素的宽高无法通过原生js获取的问题
1.起源:移动app项目中,页面加载时需要加载国家下拉列表,将隐藏的透明浮层和一个显示加载过程中的框 显示出来,隐藏的透明浮层设置宽高都是100%即可,而这个加载提示框需要先得出它的宽高,然后再根据页 ...
- Universal-Image-Loader 使用步骤
开源框架利与弊 开源框架给开发者提供了便利,避免了重复造轮子,但是却隐藏了一些开发上的细节,如果不关注其内部实现,那么将不利于开发人员掌握核心技术,当然也谈不上更好的使用它,计划分析项目的集成使用和低 ...
- SQL Server 中WITH (NOLOCK)
with(nolock)的功能: 1: 指定允许脏读.不发布共享锁来阻止其他事务修改当前事务读取的数据,其他事务设置的排他锁不会阻碍当前事务读取锁定数据.允许脏读可能产生较多的并发操作,但其代价是读取 ...
- WEB系统开发方向
1. UI框架:要可以结合jquery+自定义服务器控件开发一套UI框架: 2.WEB报表设计器:用js开发一套可以自定义报表设计器: 3.WEB自定义表单+工作流设计器: 4.WEB打印组件: 5. ...
- tomcat上servlet程序的配置与处理servlet请求过程
手动配置: tomcat服务器下web项目的基本目录结构 |-tomcat根目录 |-webapps |-WebRoot : web应用的根目录 |-静态资源(html+css+js+image+ve ...
- dx环境搭建
我使用的是vs2012+DXSDK_Jun10 DXSDK_Jun10下载地址http://download.microsoft.com/download/A/E/7/AE743F1F-632B-48 ...