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 ...
随机推荐
- WCF - REST服务
WCF REST服务 一个基于REST的WEB服务操作请求只需要体现两点 一是资源的唯一标识 二是操作类型 资源的唯一标识通过URI来完成 而操作类型通过HTTP方法(GET/HEAD POST PU ...
- CentOS远程系统管理之VNC
写这篇有摘自他人的地方,如若侵犯请立即告知,第一时间下降!! 现在比较好用的用的广泛的是SSH和PUTTY,通过这些客户端来管理LINUX服务器的,下面主要介绍另一款VNC软件,主要由两个部分组成:V ...
- sulime-text 3 安装以及使用
sublime-text 3 使用了有一段时间了,虽然不是很熟悉,但是已经爱上它了,但是对这个编辑器还是一知半解,所以现在记录下,希望以后能永久的使用这个编辑器. 一,调用 控制台 使用命令 ctrl ...
- U3D C#脚本的生命周期
MonoBehaviour是每个脚本的基类. 每个Javascript脚本自动继承MonoBehaviour,使用C#或Boo时,需要显式继承MonoBehaviour. 一开始实例化,直到结束实例被 ...
- 评论一下现有几个开源IM框架(Msn/QQ/Fetion/Gtalk...)
转载:http://www.cnblogs.com/zc22/archive/2010/05/30/1747300.html 前言 ---------------- 这阵子,在集成通讯框架, 由于不想 ...
- NFC简介
NFC简介 NFC是Near Field Communication缩写,即近距离无线通讯技术.由飞利浦和索尼公司共同开发的NFC是一种非接触式识别和互联技术,可以在移动设备.消费类电子产品.PC 和 ...
- SQL学习:查询的用法(1)
在SQL servre的使用中,查询的用法是最多的.最重要的,也是最难学习的,因此掌握查询的用法很重要. 先将表的示例上图 员工表: 部门表: ...
- 连接远程LINUX服务器
远程登陆linux服务器需要下载一个软件,非常好用,名字是SecureCRT5,百度搜索有很多,如果下载不到可以联系我 运行安装包,一路下一步就可以了 安装好后,运行该软件 点击左上角第二 ...
- jquery之分页插件smartpaginator
今天推荐一个分页工具条插件:Smart Paginator,这个插件用途还是很广的,而且可定制性相当不错,目前内置三种颜色,有需要的话,可以自己改css定制颜色 1.如何使用Smart Paginat ...
- 关于Apple设备私有的apple-touch-icon属性详解
以前我们用过favicon在浏览器给网站进行身份标识,用法如下: <link href="http://image.feeliu.com/web/favicon.ico" r ...