📄 hpel_core1.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_core1.asm
Label Name : __hpel_core1
Version : 1.0
Change History :
Version Date Author Comments
1.0 07/02/2001 Vijay Original
Description : The assembly function is used by the half pixelation routine
to compute the average of two ADJACENT macroblocks which need
not be word aligned. The starting addresses of the macroblocks
are passed in I0 and I1 and the averaged result is stored in
a buffer pointed to by I3. The MAD between the averaged
(interpolated) block and the target block is then computed. If
the interpolated block has a lower value of MAD than the
previously observed minimum an offset of +1 or -1 is added to
the integer motion vector in the corresponding direction. This
is called the half-pixel correction.
Prototype : void _hpel_core1(struct *input_parameters, int *temp_array1);
Input : The input to this routine is a pointer to a structure
containing the following elements and a temporary array of
size 260. The content of the temporary array will be used by
the hpel_core2 routine.
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
}input_parameters;
Registers used : R0-R3, R7, I0-I3, M1, M3, L0, L1, L3, P1, P2, LC0.
Performance :
Code size : 282 Bytes.
*******************************************************************************/
.section L1_code;
.align 8;
.global __hpel_core1;
__hpel_core1:
L0 = 0;
L1 = 0;
L3 = 0;
P1 = R0;
I3 = R1;
I2 = R1;
[--SP] = R7;
MNOP || R1 = [P1 + 16]; // Current hpel offset for the vertical motion
// vector
MNOP || R3 = [P1 + 32]; // Horizontal size of the video frame
R1 = R1.L * R3.L (IS) || R0 = [P1 + 4];
// R0 -> Address of the block having least MAD
R2 = R0 + R1 (NS) || R1 = [P1 + 20];
// R1 -> Current hpel offset for the horizontal
// motion vector
I0 = R0;
R2 = R2 + R1;
I1 = R2;
P2 = 16; // Loop ctr(for 16 rows) is initialized
R3 += -16;
M1 = R3; // COLUMNS - 16
R3 += 4;
M3 = R3; // COLUMNS - 12
/************************** AVERAGE ADJACENT BLOCKS *************************/
LSETUP(ST_LOOP,END_LOOP) LC0=P2;
DISALGNEXCPT || R0 = [I0++] || R2 =[I1++];
// Fetch 1st words of the two blocks(if disligned,
// contains partial data
ST_LOOP:
DISALGNEXCPT || R1 = [I0++] || R3 =[I1++];
// Fetch 2nd words(will contain remaining part of
// 1st word)
R7 = BYTEOP1P(R1:0,R3:2) || R0 = [I0++] || R2 =[I1++];
// Average(R0,R2) and fetch 3rd word
R7 = BYTEOP1P(R1:0,R3:2)(R) || R1 = [I0++] || [I3++] = R7 ;
// Average(R1,R3), fetch 4th data and store previous
// result
DISALGNEXCPT || R3 =[I1++] || [I3++] = R7;
// Fetch 4th data and store previous result
R7 = BYTEOP1P(R1:0,R3:2) || R0 = [I0++M1] || R2 =[I1++M1];
// Average (R0,R2), fetch 5th word and modify
// pointers
R7 = BYTEOP1P(R1:0,R3:2)(R) || R0 = [I0++] || [I3++] = R7 ;
// Average (R1,R3), fetch 1st word of next row and
// store
END_LOOP:
DISALGNEXCPT || R2 =[I1++] || [I3++] = R7;
// Fetch 1st word of next row and store previous
// result
/************************* MEAN ABSOLUTE DIFFERENCE ***************************/
R0 = [P1 + 36];
I0 = R0; // Fetch the start address of the target block
I1 = I2; // Fetch the start address of the reference block
A1=A0=0 || R0 = [I0++] || R2 = [I1++];
// Initialize accumulators to zero and fetch the
// first data from the two blocks
LSETUP (MAD_START, MAD_END) LC0=P2;
MAD_START:
SAA (R1:0,R3:2) || R1 = [I0++] || R3 = [I1++];
// Compute absolute difference and accumulate
SAA (R1:0,R3:2) (R) || R0 = [I0++] || R2 = [I1++];
// |
SAA (R1:0,R3:2) || R1 = [I0 ++ M3] || R3 = [I1++];
// After fetch of 4th word of target blk, pointer
// made to point next row
MAD_END:
SAA (R1:0,R3:2) (R) || R0 = [I0++] || R2 = [I1++];
// |
R3=A1.L+A1.H,R2=A0.L+A0.H;
R0 = R2 + R3 (NS) || R3 = [P1];
// Add the accumulated values in both MACs
/*************************** MINIMUM MAD COMPUTATION ***********************/
CC = R0 <= R3; // Check if the latest MAD or MSE is less than the
// previous ones
IF CC JUMP LESS_OR_EQUAL;
// If latest MAD is not lesser, then return
R7 = [SP++];
RTS;
LESS_OR_EQUAL:
CC = R0 < R3;
IF !CC JUMP EQUAL; // If MAD is lesser jump to 'LESS'
[P1] = R0; // If latest MAD is less, then store it as the
// minimum MAD
R0 = [P1 + 16];
[P1 + 24] = R0;
R0 = [P1 + 20];
[P1 + 28] = R0;
R7 = [SP++];
RTS;
EQUAL:
R2 = [P1 + 12]; // Horizontal-vector before half pixel estimation
R1 = [P1 + 28];
R1 = R2 + R1 (NS) || R3 = [P1 + 8];
// Half pixel estimation for Horizontal-vector added
// to X-vector
R0 = [P1 + 24];
R0 = R3 + R0; // Half pixel estimation for Vertical-vector added
// to Y-vector
A1 = R1.L*R1.L (IS) || R1 = [P1 + 20];
A1 += R0.L*R0.L (IS) || R0 = [P1 + 16];
// Distance to previous best match from reference
// block
R0 = R0 + R3;
R1 = R1 + R2;
A0 = R0.L*R0.L (IS); // Distance to current best match from reference
// block
A0 += R1.L*R1.L (IS);
CC = A0 < A1;
IF !CC JUMP FINISH;
R0 = [P1 + 16];
[P1 + 24] = R0;
R0 = [P1 + 20];
[P1 + 28] = R0;
FINISH:
R7 = [SP++];
RTS;
__hpel_core1.end:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -