⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hpel_core1.asm

📁 用于DSP的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     : 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 + -