xvid搜索算法

 

今天看了下xvid的搜索算法,总结一下。

xvid_me_AdvDiamondSearch,顾名思义是高级钻石搜索算法。它所使用的搜索模板是大钻石。

*

     *     *

* * *

     *     *

*

   (图1)

如图1所示,大钻石搜索模板一共有8个方向:left , right, top, down, left-top, left-down, right-top, right-down

由于图像的坐标系如图2所示:

x -->

y

|

v

(图2)

xvid中将这8个方向分加用以下数字表示

Top(4)

 

TL(5)  TR(6 )

 

Left(1) Right(2)

 

DL(9)  DR(10)

 

Down(8)

 

而这个算法的主要思想是:

 

bDirection代表sad满足条件的方向,

 

算法在初始化时,bDirection被设为255,以确保先对left, right, top, down四个方向都进行一遍搜索。然后查看iDirection是否非零,非零则说明有更好的方向,将该方向记录到bDirection中,然后更新坐标(x,y), 再在(x,y)进行与bDirection方向正交的搜索。同样,如果搜到更好的方向,也相应更新bDirection和(x,y)。

 

如果*iDirection为0

那么说明已经搜索到了一个局部的最小点了。但这个点不一定是全局最小。

所以在退出之前还要在斜线方向上进行搜索(left-top, left-down, right-top, right-down)。

具体搜索哪些方向是要看情况的。

 

//xvid 高级钻石搜索算法

 1 void
 2 xvid_me_AdvDiamondSearch(int x, int y, SearchData * const data,
 3                          int bDirection, CheckFunc * const CheckCandidate)
 4 {
 5
 6 /* directions: 1 - left (x-1); 2 - right (x+1), 4 - up (y-1); 8 - down (y+1) */
 7
 8     unsigned int * const iDirection = &data->dir;
 9
10     for(;;) { /* forever */
11         *iDirection = 0;
12         if (bDirection & 1) CHECK_CANDIDATE(x - iDiamondSize, y, 1); //left
13         if (bDirection & 2) CHECK_CANDIDATE(x + iDiamondSize, y, 2); //right
14         if (bDirection & 4) CHECK_CANDIDATE(x, y - iDiamondSize, 4); //top
15         if (bDirection & 8) CHECK_CANDIDATE(x, y + iDiamondSize, 8); //down
16
17         /* now we're doing diagonal checks near our candidate */
18
19         if (*iDirection) {        /* if anything found */
20             bDirection = *iDirection;
21             *iDirection = 0;
22             x = data->currentMV->x; y = data->currentMV->y;
23             if (bDirection & 3) {    /* our candidate is left or right */
24                 CHECK_CANDIDATE(x, y + iDiamondSize, 8);
25                 CHECK_CANDIDATE(x, y - iDiamondSize, 4);
26             } else {         /* what remains here is up or down */
27                 CHECK_CANDIDATE(x + iDiamondSize, y, 2);
28                 CHECK_CANDIDATE(x - iDiamondSize, y, 1);
29             }
30
31             if (*iDirection) {
32                 bDirection += *iDirection;
33                 x = data->currentMV->x; y = data->currentMV->y;
34             }
35         } else {              /* about to quit, eh? not so fast.... */
36             switch (bDirection) { //HKY: bDirection: the best direction
37             case 2:
38                 CHECK_CANDIDATE(x + iDiamondSize, y - iDiamondSize, 2 + 4);
39                 CHECK_CANDIDATE(x + iDiamondSize, y + iDiamondSize, 2 + 8);
40                 break;
41             case 1:
42                 CHECK_CANDIDATE(x - iDiamondSize, y - iDiamondSize, 1 + 4);
43                 CHECK_CANDIDATE(x - iDiamondSize, y + iDiamondSize, 1 + 8);
44                 break;
45             case 2 + 4:
46                 CHECK_CANDIDATE(x - iDiamondSize, y - iDiamondSize, 1 + 4);
47                 CHECK_CANDIDATE(x + iDiamondSize, y - iDiamondSize, 2 + 4);
48                 CHECK_CANDIDATE(x + iDiamondSize, y + iDiamondSize, 2 + 8);
49                 break;
50             case 4:
51                 CHECK_CANDIDATE(x + iDiamondSize, y - iDiamondSize, 2 + 4);
52                 CHECK_CANDIDATE(x - iDiamondSize, y - iDiamondSize, 1 + 4);
53                 break;
54             case 8:
55                 CHECK_CANDIDATE(x + iDiamondSize, y + iDiamondSize, 2 + 8);
56                 CHECK_CANDIDATE(x - iDiamondSize, y + iDiamondSize, 1 + 8);
57                 break;
58             case 1 + 4:
59                 CHECK_CANDIDATE(x - iDiamondSize, y + iDiamondSize, 1 + 8);
60                 CHECK_CANDIDATE(x - iDiamondSize, y - iDiamondSize, 1 + 4);
61                 CHECK_CANDIDATE(x + iDiamondSize, y - iDiamondSize, 2 + 4);
62                 break;
63             case 2 + 8:
64                 CHECK_CANDIDATE(x + iDiamondSize, y - iDiamondSize, 2 + 4);
65                 CHECK_CANDIDATE(x + iDiamondSize, y + iDiamondSize, 2 + 8);
66                 CHECK_CANDIDATE(x - iDiamondSize, y + iDiamondSize, 1 + 8);
67                 break;
68             case 1 + 8:
69                 CHECK_CANDIDATE(x - iDiamondSize, y - iDiamondSize, 1 + 4);
70                 CHECK_CANDIDATE(x - iDiamondSize, y + iDiamondSize, 1 + 8);
71                 CHECK_CANDIDATE(x + iDiamondSize, y + iDiamondSize, 2 + 8);
72                 break;
73             default:     /* 1+2+4+8 == we didn't find anything at all */
74                 CHECK_CANDIDATE(x - iDiamondSize, y - iDiamondSize, 1 + 4);
75                 CHECK_CANDIDATE(x - iDiamondSize, y + iDiamondSize, 1 + 8);
76                 CHECK_CANDIDATE(x + iDiamondSize, y - iDiamondSize, 2 + 4);
77                 CHECK_CANDIDATE(x + iDiamondSize, y + iDiamondSize, 2 + 8);
78                 break;
79             }
80             if (!*iDirection) break;     /* ok, the end. really */
81             bDirection = *iDirection;
82             x = data->currentMV->x; y = data->currentMV->y;
83         }
84     }
85 }
86

你可能感兴趣的:(xvid搜索算法)