设为首页 加入收藏

TOP

14.2.3 DM642下XviD CODEC优化(2)
2013-10-07 00:41:51 来源: 作者: 【 】 浏览:67
Tags:14.2.3 DM642 XviD CODEC 优化

14.2.3  DM642下XviD CODEC优化(2)

此函数处理数据同样规整,存储区没有依赖性。源和目标地址均为图像空间,源地址不对齐,目标地址对齐。线性汇编优化如下。

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;   interpolate8x8_halfpel_v_asm_dm642       ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.sect ".text:_interpolate8x8_halfpel_v_asm_dm642"
.global _interpolate8x8_halfpel_v_asm_dm642
_interpolate8x8_halfpel_v_asm_dm642  .cproc A_dst0, B_src0, A_stride,B_stride
.no_mdep          ;存储区无依赖性
.reg B_dst7_7654:B_dst7_3210, B_dst6_7654:B_dst6_3210
;;
.reg B_src8_7654:B_src8_3210, B_src7_7654:B_src7_3210
;;
.reg A_src2_7654:A_src2_3210, A_src1_7654:A_src1_3210
.reg A_src0_7654:A_src0_3210
.reg  B_dst1, A_src1, A_i, A_pitch,AB_stride
.reg cst_32, B_pitch,BA_stride
SHR  B_stride,   3,    A_pitch
SHR  A_stride,  3,   B_pitch
SHL  B_stride,  2,   AB_stride
SHL  A_stride,  2,   BA_stride
ADD  B_src0,  AB_stride,  A_src1
ADD  A_dst0,  BA_stride, B_dst1
LDNDW   .D2T1   *B_src0++[A_pitch],  A_src0_7654:A_src0_3210   ;读取8字节
LDNDW   .D2T1   *B_src0++[A_pitch], A_src1_7654:A_src1_3210   ;读取8字节
;;
 AVGU4   A_src0_7654,  A_src1_7654,  A_dst0_7654 ;求4对字节平均
 AVGU4   A_src0_3210,  A_src1_3210,  A_dst0_3210 ;求4对字节平均
STDW   .D1T1   A_dst0_7654:A_dst0_3210,  *A_dst0++[B_pitch]    ;存储8字节
;;
.return
.endproc

上述代码中首先使用不对齐指令读取数据,然后求平均,最后存储结果。

3.斜角插值补偿

斜角插值即对水平和垂直方向的4个像素求平均。或者理解为图像块先做水平插值,然后对插值后的新图像块做垂直插值,最后形成的新图像块即为斜角插值。C语言代码实现如下。

void interpolate8x8_halfpel_hv(uint8_t* const dst, const uint8_t* const src, 
const uint32_t stride, const uint32_t rounding)
{
uint32_t j;
int r = 2- rounding;
for (j = 0; j < 8*stride; j+=stride)
{
dst[j+0]=(uint8_t)((src[j+0]+src[j+1]+src[j+stride+0]+src[j+stride+1]+r)>>2);
//4个像素求平均
dst[j+1]=(uint8_t)((src[j+1]+src[j+2]+src[j+stride+1]+src[j+stride+2]+r)>>2);
//4个像素求平均
dst[j+2]=(uint8_t)((src[j+2]+src[j+3]+src[j+stride+2]+src[j+stride+3]+r)>>2);
//4个像素求平均
dst[j+3]=(uint8_t)((src[j+3]+src[j+4]+src[j+stride+3]+src[j+stride+4]+r)>>2);
//4个像素求平均
dst[j+4]=(uint8_t)((src[j+4]+src[j+5]+src[j+stride+4]+src[j+stride+5]+r)>>2);
//4个像素求平均
dst[j+5]=(uint8_t)((src[j+5]+src[j+6]+src[j+stride+5]+src[j+stride+6]+r)>>2);
//4个像素求平均
dst[j+6]=(uint8_t)((src[j+6]+src[j+7]+src[j+stride+6]+src[j+stride+7]+r)>>2);
//4个像素求平均
dst[j+7]=(uint8_t)((src[j+7]+src[j+8]+src[j+stride+7]+src[j+stride+8]+r)>>2);
//4个像素求平均
}
}

斜角插值补偿主要还是求值平均。线性汇编优化过程如下。

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;   interpolate8x8_halfpel_hv_asm_dm642          ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.sect ".text:_interpolate8x8_halfpel_hv_asm_dm642"
.global _interpolate8x8_halfpel_hv_asm_dm642
_interpolate8x8_halfpel_hv_asm_dm642  .cproc
A_dst0, B_src0, A_stride,B_stride
.no_mdep                     ;存储区无依赖性
.reg  A_dst1,B_src1,B_src2
.reg  A_i,A_pitch,B_pitch
.reg  A_1111,B_1111,A_22,B_22
.reg  A_7654:A_3210,A_8765:A_4321, B_7654:B_3210,B_8765:B_4321
.reg  C_7654:C_3210,C_8765:C_4321, D_7654:D_3210,E_7654:E_3210
.reg  A_0,A_1,A_2,A_3,A_4,A_5,A_6,A_7
.reg  C_1010,C_3232,C_5454,C_7676,C_2121,C_4343,C_6565,C_8787
.reg  A_76,A_54,A_32,A_10,B_76,B_54,B_32,B_10
.reg C_76,C_54,C_32,C_10,D_76,D_54,D_32,D_10
.reg E_76,E_54,E_32,E_10,F_76,F_54,F_32,F_10 
ADD  B_src0, B_stride, B_src1
ADD  B_src1, B_stride, B_src2
ADD A_dst0, A_stride, A_dst1
SHR B_stride, 2, B_pitch
SHR A_stride, 2, A_pitch
MVKL  0x01010101, A_1111      ;用来点积,实质是相加
MVKH  0x01010101, A_1111
MVKL  0x00020002, A_22         ;用来右移
MVKH  0x00020002, A_22
MV     A_22,  B_22
MV      A_1111,  B_1111
MVK  3, A_i
LOOP_HV_88: .trip 4,4,4
LDNDW  *+B_src2(1),        C_8765:C_4321  ;地址不对齐读取8字节数据
LDNDW  *B_src2++[B_pitch],   C_7654:C_3210
LDNDW  *+B_src1(1),        B_8765:B_4321
LDNDW  *B_src1++[B_pitch],   B_7654:B_3210
LDNDW *+B_src0(1),        A_8765:A_4321
LDNDW  *B_src0++[B_pitch],   A_7654:A_3210
PACK2 A_3210, B_3210, C_1010 ;打包低16位
PACKH2 B_3210, A_3210, C_3232 ;打包高16位
PACK2  A_7654, B_7654, C_5454
PACKH2  B_7654, A_7654, C_7676
PACK2  A_4321, B_4321, C_2121
PACKH2  B_4321, A_4321, C_4343
PACK2  A_8765, B_8765, C_6565
PACKH2  B_8765, A_8765, C_8787
;;
DOTPU4  C_1010, A_1111, A_0  ;与1点积,即4个元素相加
DOTPU4  C_2121, A_1111, A_1
DOTPU4  C_3232, A_1111, A_2
DOTPU4  C_4343, A_1111, A_3
DOTPU4 C_5454, A_1111, A_4
DOTPU4 C_6565, A_1111, A_5
DOTPU4 C_7676, A_1111, A_6
DOTPU4 C_8787, A_1111, A_7
;;
PACK2  A_1, A_0, A_10          ;低16位打包
PACK2  A_3, A_2, A_32
PACK2  A_5, A_4, A_54
PACK2  A_7, A_6, A_76
;;
ADD2  A_22, A_10, C_10  ;两个16位数分别加2
ADD2  A_22, A_32, C_32
ADD2  A_22, A_54, C_54
ADD2  A_22, A_76, C_76
;;
SHRU2 C_10, A_22, E_10  ;两个16位数分别右移2位
SHRU2 C_32, A_22, E_32
SHRU2 C_54, A_22, E_54
SHRU2 C_76, A_22, E_76
;;
PACKL4  E_32, E_10, D_3210 ;偶位字节提取组合成一个新数
PACKL4  E_76, E_54, D_7654
;;
STDW D_7654:D_3210, *A_dst0++[A_pitch] ;存储8字节结果
;;[A_i] BDEC  LOOP_HV_88, A_i
.return
.endproc

从以上线性汇编优化的过程分析可以看出,数据打包处理提高效率,编排使软件流水提高指令并行度。其他核心模块的汇编优化都可以根据这个指导思想来实现函数的高效运行。

根据DM642的处理能力,实现4路CIF或1路D1的MPEG-4 SP视频编码是完全可行的,前提是核心模块都作了汇编优化。

【责任编辑:云霞 TEL:(010)68476606】

回书目   上一节   下一节

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇14.3.2 VC平台下编译和运行XviD C.. 下一篇14.2.3 DM642下XviD CODEC优化(1..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: