📄 hpel_fs.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 : hpel_fs.asm
Label Name : __hpel
Version : 1.0
Change History :
Version Date Author Comments
1.0 07/02/2001 Vijay Original
Description : The assembly function is used by the motion estimation routine
to give a half pixel correction to the integer pixel motion
vector. This will check whether any interpolated blocks with
half pixel accuracy in all the 8 directions of the integer
pixel motion vector is having a lesser MAD. If it finds a
block with better MAD, it adds an offset to the X and Y
ectors and will make that MAD as the current MAD. If X-vector
is at the extreme negative end of the search range, the half
pixel estimations with X-offset = -1 are skipped. Similarly,
if Y-vector is at the extreme negative end of the search
range, half pixel estimations with Y-offset = -1 are skipped.
Prototype : void _hpel(struct *input_parameters);
Input : The input to this routine is a pointer to a structure
containing the following elements
Structure :
struct {
int least_mad;
-> The value of the least MAD after searching the
search window fully
unsigned char *add_least_mad;
-> Address of the block having the least MAD
int vert_mv;
-> Vertical integer motion vector
int hor_mv;
-> Horizontal integer motion vector
int curr_ver_mv_off;
-> Current hpel offset for the vertical motion
vector
int curr_hor_mv_off;
-> Current hpel offset for the horizontal motion
vector
int prev_ver_mv_off;
-> Previous hpel offset for the vertical motion
vector
int prev_hor_mv_off;
-> Previous hpel offset for the horizontal motion
vector
int hor_size;
-> Horizontal size of the video frame
unsigned char *tgt_blk_add;
-> Start address of the target block
int scaled_left_search_boundary;
-> 2*2^(search_factor + 1);
}input_parameters;
The first four elements of the structure are obtained from the
output structure of the mve_core routine. The next four
elements are modified by this routine. The last three elements
should have the appropriate values which can be obtained from
the elements of the input structure of the mve_core routine.
Registers used : R0-R7, P0, P4, P5.
Performance :
Code size : 240 Bytes.
*******************************************************************************/
.section L1_code;
.align 8;
.global _hpel;
.extern __hpel_core2;
.extern __hpel_core1;
_hpel:
[--SP] = (R7:4, P5:4);
P4 = R0;
[--SP] = RETS;
P0 = 260;
SP -= P0;
R7 = SP; // Address of the first temporary buffer
SP -= P0;
P5 = SP; // Address of the second temporary buffer
R0 = R0 - R0 (NS) || R6 = [P4 + 40];
R6 = R0 - R6 (NS) || R4 = [P4 + 8];
R5 = [P4 + 12];
CC = R5 == R6;
IF CC JUMP BRANCH1;
/********************* HOR_OFFSET = -1 VER_OFFSET = 0 *******************/
R0 = -1;
R0 = R0 - R0 (NS) || [P4 + 20] = R0;
[P4 + 16] = R0;
R0 = P4;
R1 = R7;
CALL __hpel_core1; // Averages and stores into buffer
// Finds MAD between averaged block(buffer1) and
// target block
BRANCH1:
CC = R4 == R6; // If Vertical-offset == R6, skip 2nd,3rd,4th hpel
// estimations(with Y = -1)
IF CC JUMP BRANCH4;
CC = R5 == R6;
IF CC JUMP BRANCH2;
/**************************** HOR_OFFSET = -1 VER_OFFSET = -1 **************/
R0 = -1;
[P4 + 20] = R0;
[P4 + 16] = R0;
R0 = P4;
R1 = R7;
R2 = P5;
CALL __hpel_core2; // Averages and stores into buffer
/******************** HOR_OFFSET = 0 VER_OFFSET = -1 **********************/
BRANCH2:
R0 = -1;
R0 = R0 - R0 (NS) || [P4 + 16] = R0;
[P4 + 20] = R0;
R0 = P4;
R1 = R7;
CALL __hpel_core1; // Averages and stores into buffer
// Finds MAD between averaged block(buffer1) and
// target block
/************************ HOR_OFFSET = 1 VER_OFFSET = -1 *****************/
R0 = -1;
R0 = R0.L * R0.L (IS) || [P4 + 16] = R0;
[P4 + 20] = R0;
R0 = P4;
R1 = R7;
R2 = P5;
CALL __hpel_core2; // Averages and stores into buffer
/********************** HOR_OFFSET = 1 VER_OFFSET = 0 ***********************/
BRANCH4:
R0 = 1;
R0 = R0 - R0 (NS) || [P4 + 20] = R0;
[P4 + 16] = R0;
R0 = P4;
R1 = R7;
CALL __hpel_core1; // Averages and stores into buffer
// Finds MAD between averaged block(buffer1) and
// target block
/************************** HOR_OFFSET = 1 VER_OFFSET = 1 ****************/
R0 = 1;
[P4 + 16] = R0;
[P4 + 20] = R0;
R0 = P4;
R1 = R7;
R2 = P5;
CALL __hpel_core2; // Averages and stores into buffer
/*************************** HOR_OFFSET = 0 VER_OFFSET = 1 ***************/
R0 = 1;
R0 = R0 - R0 (NS) || [P4 + 16] = R0;
[P4 + 20] = R0;
R0 = P4;
R1 = R7;
CALL __hpel_core1; // Averages and stores into buffer
// Finds MAD between averaged block(buffer1) and
// target block
/************************* HOR_OFFSET = -1 VER_OFFSET = 1 ******************/
CC = R5 == R6; // If Horizontal-offset == R6, skip last hpel
// estimation(X = -1, Y = 1)
IF CC JUMP BRANCH8;
R0 = -1;
R0 = R0.L * R0.L (IS) || [P4 + 20] = R0;
[P4 + 16] = R0;
R0 = P4;
R1 = R7;
R2 = P5;
CALL __hpel_core2; // Averages and stores into buffer
BRANCH8:
R1 = [P4 + 12]; // Horizontal-vector before half pixel estimation
R2 = [P4 + 28];
R1 = R1 + R2 (NS) || R0 = [P4 + 8];
// Half pixel estimation for Horizontal-vector added
// to X-vector
R2 = [P4 + 24];
R0 = R0 + R2; // Half pixel estimation for Vertical-vector added
// to Y-vector
P0 = 260;
SP = SP + P0;
SP = SP + P0;
RETS = [SP++];
(R7:4, P5:4) = [SP++]; // Retrieve call save register
RTS;
NOP;
_hpel.end:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -