📄 full_search_mpeg2.asm
字号:
/*******************************************************************************
Copyright(c) 2000 - 2002 Analog Devices. All Rights Reserved.
Developed by Joint Development Software Application Team, IPDC, Bangalore, India
for Blackfin DSPs ( Micro Signal Architecture 1.0 specification).
By using this module you agree to the terms of the Analog Devices License
Agreement for DSP Software.
********************************************************************************
Module Name : full_search_mpeg2.asm
Label Name : __full_search_mpeg2
Version : 1.2
Change History :
Version Date Author Comments
1.2 11/18/2002 Swarnalatha Tested with VDSP++ 3.0
compiler 6.2.2 on
ADSP-21535 Rev.0.2
1.1 11/13/2002 Swarnalatha Tested with VDSP++3.0
on ADSP-21535 Rev.0.2
1.0 07/02/2001 Vijay Original
Description : The assembly function does the full search block matching to
compute the motion vectors given a target frame and a
reference frame. By suitably selecting the target frame and
the reference frame, this routine can be used to obtain the
motion vectors of a P or a B frame. The target and reference
frames have to be of the same size and should be an integer
multiple of 16. The input arguments to the function are the
target frame address, the reference frame address, the frame
size, the search area factor and the start addresses of the
motion vectors. The macro block size is fixed to be 16x16. The
search area is computed based on the search area factor. It
specifies an integer value between 1 and 3. The search range
is specified as follows:
=============================================
| Search_area_factor | Search range |
| 1 | -4 to 3.5 |
| 2 | -8 to 7.5 |
| 3 | -16 to 15.5 |
=============================================
The motion vector gives an integer offset for every macro
block in the target frame with respect to the macro blocks in
the reference frame in both vertical and horizontal
directions. Once the integer offset is computed a half pixel
correction is given in either directions (vertical and
horizontal) by interpolating adjacent macro blocks. The
resultant vectors are called half-pel motion vectors. The
motion vectors for all the macro blocks in the target frame
have been computed by grouping the macro blocks into NINE
categories based on the range within which the matching has to
be done, without crossing the frame boundary. Hence there will
be nine code-segments which compute the motion vectors for the
macro blocks in that category. These categories are pictorially
represented and the ranges allowed for them are explained in a
table :
-----------------------------------------
| | | | | |
| NW | | NORTH | | NE |
-----------------------------------------
| | | | | |
| | | | | |
----W-------------------------------E----
| E | C E N T R A L | A |
| S | | | | S |
----T-------------------------------T----
| | | | | |
| | | | | |
-----------------------------------------
| | | | | |
| SW | | SOUTH | | SE |
-----------------------------------------
================================================================================
search_area_factor (S)
================================================================================
Category S = 1 S = 2 S = 3
(vertical, horizontal) (vertical, horizontal) (vertical, horizontal)
================================================================================
NORTH-WEST (0 to 3.5, 0 to 3.5) (0 to 7.5, 0 to 7.5) (0 to 15.5, 0 to 15.5)
NORTH-EAST (0 to 3.5, -4 to 0) (0 to 7.5, -8 to 0) (0 to 15.5, -16 to 0)
SOUTH-WEST (-4 to 0, 0 to 3.5) (-8 to 0, 0 to 7.5) (-16 to 0, 0 to 15.5)
SOUTH-EAST (-4 to 0, -4 to 0) (-8 to 0, -8 to 0) (-16 to 0, -16 to 0)
NORTH (0 to 3.5, -4 to 3.5) (0 to 7.5, -8 to 7.5) (0 to 15.5, -16 to 15.5)
SOUTH (-4 to 0, -4 to 3.5) (-8 to 0, -8 to 7.5) (-16 to 0, -16 to 15.5)
WEST (-4 to 3.5, 0 to 3.5) (-8 to 7.5, 0 to 7.5) (-16 to 15.5, 0 to 15.5)
EAST (-4 to 3.5, -4 to 0) (-8 to 7.5, -16 to 0) (-16 to 15.5, -16 to 0)
CENTRAL (-4 to 3.5, -4 to 3.5)(-8 to 7.5, -8 to 7.5)(-16 to 15.5,-16 to 15.5)
================================================================================
As expected by the MPEG-2 standard the routine multiplies the
actual offset between the target macro block and a best
matching reference macro block within the search range by two.
It should also be noted that the macro blocks in the boundary
of the frame are not given the half pixel correction, but
still they are scaled by a factor of two. Thus, all target
macro blocks which underwent an integer transition will have
even motion vectors while those blocks that are offset by a
non-integer factor will have odd motion vectors.
Registers Used : R0-R7, B0-B3, P0, P1, P3-P5.
Prototype : void __full_search_mpeg2(&Target_frame, &Reference_Frame,
&mv_vertical, &mv_horizontal, rows, columns, search_factor);
Input arguments :
Target_frame - Starting address of the Target frame
Reference_Frame - Starting address of the reference frame
mv_vertical - Starting address of the motion vector
matrix (Vertical direction)
mv_horizontal - Starting address of the motion vector
matrix (Horizontal direction)
rows - No. of rows in the frame
columns - No. of columns in the frame
search_factor - Search_area_factor
Performance :
Code size : 1122 bytes (only full_search_mpeg2.asm)
======================================================================
Cycle count for the Half-pixel Motion estimation using Mean Absolute
Difference (MAD) criterion
======================================================================
S.No. Frame size Search_factor Search Range(pixels) No. of cycles
1 80 x 96 1 -4 to 3.5 1,57353
2 80 x 96 2 -8 to 7.5 5,27212
3 80 x 96 3 -16 to 15.5 19,74577
======================================================================
Cycle count mentioned above is for the test case given in test_full_search.c
file.
*******************************************************************************/
.section L1_code;
.align 8;
.global __full_search_mpeg2;
.extern __mve_core;
.extern _hpel;
__full_search_mpeg2:
[--SP] = RETS;
[--SP] = (R7:4, P5:3);
/*************************** FETCH INPUT ARGUMENTS ****************************/
B0 = R0; // Fetch the target frame address
B1 = R1; // Fetch the reference frame address
B2 = R2; // Fetch the address of motion vector along y
// direction
P3 = [SP + 44]; // Fetch the address of motion vector along x
// direction
R4 = [SP + 48]; // No. of rows in the frame
R5 = [SP + 52]; // No. of columns in the frame
R6 = [SP + 56]; // Search_area_factor
B3 = P3;
/*************************** PRELIMINARY COMPUTATIONS ************************/
SP += -52;
P3 = SP;
SP += -52;
R6 += 1;
R7 = 1;
R6 = LSHIFT R7 BY R6.L || [SP] = R5;
// Compute ...
R7 = 0x10;
R6.L = R5.L - R7.L (NS) || [SP + 4] = R6;
// [SP + 4] -> 2^(search_area_factor + 1)
R6 = R5 >>> 4 || [SP + 28] = R6;
// [SP + 28] -> (No. of columns - 16)
R6.L = R4.L - R7.L(NS) || [SP + 32] = R6;
// [SP + 32] -> (No. of columns)/16
R6 = R4 >>> 4 || [SP + 36] = R6;
// [SP + 36] -> (N0. of rows - 16)
[SP + 40] = R6; // [SP + 40] -> (No. of Rows)/16
/***************************** NORTH WEST ************************************
This code segment computes the motion vectors along the horizontal and vertical
directions for the top-left corner macro block. The motion vectors along both
the directions for this macro block cannot take negative values as such a value
will shift the macro block out of the frame boundary.
*******************************************************************************/
R0 = B1;
[SP + 16] = R0; // Starting address of the reference block
[SP + 12] = R0; // Location of the target block in the reference
// frame
R0 = B0;
[SP + 8] = R0; // Starting address of the target block
R0 = [SP + 4];
[SP + 20] = R0;
[SP + 24] = R0;
R0 = SP; // Pass the address of the structure to the function
R1 = P3;
CALL __mve_core; // Finds the best matching macro block and computes
// the motion vectors
P0 = B2;
P1 = B3;
B[P0++] = R0; // Store motion vector along vertical direction
B[P1++] = R1; // Store motion vector along horizontal direction
/***************************** NORTH EAST *************************************
This code segment computes the motion vectors along the horizontal and vertical
directions for the top-right corner macro block. For this macro block, the
motion vector along the vertical direction is always non-negative while along
the horizontal direction it is negative or zero thus giving a best match for the
target macro block within the frame boundary.
*******************************************************************************/
R6 = [SP + 4];
R6 += 1;
R1 = B0;
R0 = R1 + R5 (NS) || [SP + 20] = R6;
R0 += -16;
R0 = R0 - R1 (NS) || [SP + 8] = R0;
// Starting address of the target block
R1 = B1;
R0 = R0 + R1 (NS) || R6 = [SP + 4];
R0 = R0 - R6 (NS) || [SP + 12] = R0;
// Location of the target block in the reference
// frame
[SP + 16] = R0; // Starting address of the reference block
R0 = SP;
R1 = P3;
CALL __mve_core; // Finds the best matching macro block and computes
// the motion vectors
R6 = B2;
R7 = R5 >> 4;
R7 += -1;
R6 = R6 + R7;
P0 = R6;
R6 = B3;
R6 = R6 + R7;
P1 = R6;
B[P0++] = R0; // Store motion vector along vertical direction
R0 = 1;
R6 = [SP + 4];
B[P1++] = R1; // Store motion vector along horizontal direction
/******************************** SOUTH WEST **********************************
The motion vector along the horizontal and vertical directions for the bottom-
left corner macro block is computed by this code segment. The motion vector
along the vertical direction is negative or zero while the one along the
horizontal direction is non-negative for this macro block.
******************************************************************************/
R6 = R6 + R0 (NS) || [SP + 20] = R6;
R0 = R0 << 4 || [SP + 24] = R6;
R1 = R4 - R0;
R0 = B0;
R3 = B1;
R1 = R1.L*R5.L (IS);
R2 = R0 + R1;
R0 = R3 + R1 (NS) || R1 = [SP + 4];
R1 = R1.L*R5.L (IS) || [SP + 8] = R2;
// Starting address of the target block;
R0 = R0 - R1 (NS) || [SP + 12] = R0;
// Location of the target block in the reference
// frame
[SP + 16] = R0; // Starting address of the reference block
R0 = SP;
R1 = P3;
CALL __mve_core; // Finds the best matching macro block and computes
// the motion vectors
R2 = [SP + 36];
R2 = R2 >>> 4 || R3 = [SP + 32];
R6 = B2;
R7 = R2.L*R3.L (IS);
R6 = R6 + R7;
P0 = R6;
R6 = B3;
R6 = R6 + R7;
P1 = R6;
B[P0++] = R0; // Store motion vector along vertical direction
R6 = [SP + 4];
R6 += 1;
B[P1++] = R1; // Store motion vector along horizontal direction
/******************************* SOUTH EAST ***********************************
The motion vectors for the bottom-right corner macro block in the target frame
is computed by this code-segment. Both the vectors, i.e., along the horizontal
and vertical directions are negative or zero to avoid the crossing of frame
boundary.
*******************************************************************************/
[SP + 20] = R6;
[SP + 24] = R6;
R1 = [SP + 36];
R1 = R1.L*R5.L (IS) || R0 = [SP + 28];
R1 = R0 + R1;
R0 = B0;
R2 = R0 + R1 (NS) || R3 = [SP + 4];
R0 = B1;
R0 = R0 + R1 (NS) || [SP + 8] = R2;
// Starting address of the target block
R1 = R3.L * R5.L (IS) || [SP + 12] = R0;
// Location of the target block in the reference
// frame
R0 = R0 - R1;
R0 = R0 - R3;
[SP + 16] = R0; // Starting address of the reference block
R0 = SP;
R1 = P3;
CALL __mve_core; // Finds the best matching macro block and computes
// the motion vectors
R6 = [SP + 40];
R7 = [SP + 32];
R7.L = R7.L*R6.L (IS);
R7 += -1;
R6 = B2;
R6 = R6 + R7;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -