Home | History | Annotate | Download | only in src
      1 ;//
      2 ;// Copyright (C) 2007-2008 ARM Limited
      3 ;//
      4 ;// Licensed under the Apache License, Version 2.0 (the "License");
      5 ;// you may not use this file except in compliance with the License.
      6 ;// You may obtain a copy of the License at
      7 ;//
      8 ;//      http://www.apache.org/licenses/LICENSE-2.0
      9 ;//
     10 ;// Unless required by applicable law or agreed to in writing, software
     11 ;// distributed under the License is distributed on an "AS IS" BASIS,
     12 ;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 ;// See the License for the specific language governing permissions and
     14 ;// limitations under the License.
     15 ;//
     16 ; **********
     17 ; *
     18 ; * File Name:  omxVCM4P2_PredictReconCoefIntra_s.s
     19 ; * OpenMAX DL: v1.0.2
     20 ; * Revision:   9641
     21 ; * Date:       Thursday, February 7, 2008
     22 ; *
     23 ; *
     24 ; *
     25 ; *
     26 ; * Description:
     27 ; * Contains module for DC/AC coefficient prediction
     28 ; *
     29 ; *
     30 ; * Function: omxVCM4P2_PredictReconCoefIntra
     31 ; *
     32 ; * Description:
     33 ; * Performs adaptive DC/AC coefficient prediction for an intra block. Prior
     34 ; * to the function call, prediction direction (predDir) should be selected
     35 ; * as specified in subclause 7.4.3.1 of ISO/IEC 14496-2.
     36 ; *
     37 ; * Remarks:
     38 ; *
     39 ; * Parameters:
     40 ; * [in]  pSrcDst      pointer to the coefficient buffer which contains the
     41 ; *                    quantized coefficient residuals (PQF) of the current
     42 ; *                    block; must be aligned on a 4-byte boundary. The
     43 ; *                    output coefficients are saturated to the range
     44 ; *                    [-2048, 2047].
     45 ; * [in]  pPredBufRow  pointer to the coefficient row buffer; must be aligned
     46 ; *                    on a 4-byte boundary.
     47 ; * [in]  pPredBufCol  pointer to the coefficient column buffer; must be
     48 ; *                    aligned on a 4-byte boundary.
     49 ; * [in]  curQP        quantization parameter of the current block. curQP may
     50 ; *                    equal to predQP especially when the current block and
     51 ; *                    the predictor block are in the same macroblock.
     52 ; * [in]  predQP       quantization parameter of the predictor block
     53 ; * [in]  predDir      indicates the prediction direction which takes one
     54 ; *                    of the following values:
     55 ; *                    OMX_VIDEO_HORIZONTAL    predict horizontally
     56 ; *                    OMX_VIDEO_VERTICAL        predict vertically
     57 ; * [in]  ACPredFlag   a flag indicating if AC prediction should be
     58 ; *                    performed. It is equal to ac_pred_flag in the bit
     59 ; *                    stream syntax of MPEG-4
     60 ; * [in]  videoComp    video component type (luminance, chrominance or
     61 ; *                    alpha) of the current block
     62 ; * [out] pSrcDst      pointer to the coefficient buffer which contains
     63 ; *                    the quantized coefficients (QF) of the current
     64 ; *                    block
     65 ; * [out] pPredBufRow  pointer to the updated coefficient row buffer
     66 ; * [out] pPredBufCol  pointer to the updated coefficient column buffer
     67 ; * Return Value:
     68 ; * OMX_Sts_NoErr - no error
     69 ; * OMX_Sts_BadArgErr - Bad arguments
     70 ; * - At least one of the pointers is NULL: pSrcDst, pPredBufRow, or pPredBufCol.
     71 ; * - At least one the following cases: curQP <= 0, predQP <= 0, curQP >31,
     72 ; *   predQP > 31, preDir exceeds [1,2].
     73 ; * - At least one of the pointers pSrcDst, pPredBufRow, or pPredBufCol is not
     74 ; *   4-byte aligned.
     75 ; *
     76 ; *********
     77 
     78         INCLUDE omxtypes_s.h
     79         INCLUDE armCOMM_s.h
     80 
     81        M_VARIANTS ARM1136JS
     82 
     83 
     84 
     85        IMPORT        armVCM4P2_Reciprocal_QP_S32
     86        IMPORT        armVCM4P2_Reciprocal_QP_S16
     87        IMPORT        armVCM4P2_DCScaler
     88 
     89 
     90 
     91         IF ARM1136JS
     92 
     93 
     94 ;// Input Arguments
     95 
     96 pSrcDst          RN 0
     97 pPredBufRow      RN 1
     98 pPredBufCol      RN 2
     99 curQP            RN 3
    100 QP               RN 3
    101 predQP           RN 4
    102 predDir          RN 5
    103 ACPredFlag       RN 6
    104 videoComp        RN 7
    105 
    106 ;// Local Variables
    107 
    108 temp2            RN 5
    109 negCurQP         RN 7
    110 negdcScaler      RN 7
    111 tempPred         RN 8
    112 
    113 dcScaler         RN 4
    114 CoeffTable       RN 9
    115 absCoeffDC       RN 9
    116 temp3            RN 6
    117 absCoeffAC       RN 6
    118 
    119 shortVideoHeader RN 9
    120 predCoeffTable   RN 10
    121 Count            RN 10
    122 temp1            RN 12
    123 index            RN 12
    124 Rem              RN 14
    125 temp             RN 11
    126 Return           RN 0
    127 
    128 
    129 
    130        M_START   omxVCM4P2_PredictReconCoefIntra,r12
    131 
    132        ;// Assigning pointers to Input arguments on Stack
    133 
    134        M_ARG           predQPonStack,4
    135        M_ARG           predDironStack,4
    136        M_ARG           ACPredFlagonStack,4
    137        M_ARG           videoComponStack,4
    138 
    139        ;// DC Prediction
    140 
    141        M_LDR           videoComp,videoComponStack                     ;// Load videoComp From Stack
    142 
    143        M_LDR           predDir,predDironStack                         ;// Load Prediction direction
    144 
    145        ;// dcScaler Calculation
    146 
    147        LDR             index, =armVCM4P2_DCScaler
    148        ADD             index,index,videoComp,LSL #5
    149        LDRB            dcScaler,[index,QP]
    150 
    151 
    152 calDCVal
    153 
    154 
    155        LDR             predCoeffTable, =armVCM4P2_Reciprocal_QP_S16   ;// Loading the table with entries 32767/(1 to 63)
    156 
    157        CMP             predDir,#2                                     ;// Check if the Prediction direction is vertical
    158 
    159        ;// Caulucate temp pred by performing Division
    160 
    161        LDREQSH         absCoeffDC,[pPredBufRow]                       ;// If vetical load the coeff from Row Prediction Buffer
    162        LDRNESH         absCoeffDC,[pPredBufCol]                       ;// If horizontal load the coeff from column Prediction Buffer
    163 
    164        RSB             negdcScaler,dcScaler,#0                        ;// negdcScaler=-dcScaler
    165 
    166        MOV             temp1,absCoeffDC                               ;// temp1=prediction coeff
    167        CMP             temp1,#0
    168        RSBLT           absCoeffDC,temp1,#0                            ;//absCoeffDC=abs(temp1)
    169 
    170        ADD             temp,dcScaler,dcScaler
    171        LDRH            temp,[predCoeffTable,temp]                     ;// Load value from coeff table for performing division using multiplication
    172 
    173        SMULBB          tempPred,temp,absCoeffDC                       ;// tempPred=pPredBufRow(Col)[0]*32767/dcScaler
    174        ADD             temp3,dcScaler,#1
    175        LSR             tempPred,tempPred,#15                          ;// tempPred=pPredBufRow(Col)[0]/dcScaler
    176        LSR             temp3,temp3,#1                                 ;// temp3=round(dcScaler/2)
    177 
    178        MLA             Rem,negdcScaler,tempPred,absCoeffDC            ;// Rem = pPredBufRow(Col)[0]-tempPred*dcScaler
    179 
    180 
    181        LDRH            temp,[pPredBufCol]
    182        CMP             Rem,temp3
    183        ADDGE           tempPred,#1                                    ;// If Rem>=round(dcScaler/2);tempPred=tempPred+1
    184        CMP             temp1,#0
    185        RSBLT           tempPred,tempPred,#0                            ;/ if pPredBufRow(Col)[0]<0; tempPred=-tempPred
    186 
    187 
    188        STRH            temp,[pPredBufRow,#-16]
    189 
    190        LDRH            temp,[pSrcDst]                                 ;// temp=pSrcDst[0]
    191        M_LDR           ACPredFlag,ACPredFlagonStack
    192        ADD             temp,temp,tempPred                             ;// temp=pSrcDst[0]+tempPred
    193        SSAT16          temp,#12,temp                                  ;// clip temp to [-2048,2047]
    194 
    195        SMULBB          temp1,temp,dcScaler                            ;// temp1=clipped(pSrcDst[0])*dcScaler
    196        M_LDR           predQP,predQPonStack
    197        STRH            temp,[pSrcDst]
    198        CMP             ACPredFlag,#1                                  ;// Check if the AC prediction flag is set or not
    199        STRH            temp1,[pPredBufCol]                            ;// store temp1 to pPredBufCol
    200 
    201        ;// AC Prediction
    202 
    203 
    204        BNE             Exit                                           ;// If not set Exit
    205 
    206        LDR             predCoeffTable, =armVCM4P2_Reciprocal_QP_S32   ;// Loading the table with entries 0x1ffff/(1 to 63)
    207        MOV             temp1,#4
    208        MUL             temp1,curQP,temp1
    209        CMP             predDir,#2                                     ;// Check the Prediction direction
    210        RSB             negCurQP,curQP,#0
    211        LDR             CoeffTable,[predCoeffTable,temp1]              ;// CoeffTable=0x1ffff/curQP
    212        ADD             curQP,curQP,#1                                 ;// curQP=curQP+1
    213        LSR             curQP,curQP,#1                                 ;// curQP=round(curQP/2)
    214        MOV             Count,#2                                       ;// Initializing the Loop Count
    215        BNE             Horizontal                                     ;// If the Prediction direction is horizontal branch to Horizontal
    216 
    217 
    218 
    219 loop1
    220        ;// Calculate tempPred
    221 
    222        LDRSH           absCoeffAC,[pPredBufRow,Count]                 ;// absCoeffAC=pPredBufRow[i], 1=<i<=7
    223        MOV             temp1,absCoeffAC
    224        CMP             temp1,#0                                       ;// compare pPredBufRow[i] with zero, 1=<i<=7
    225        RSBLT           absCoeffAC,temp1,#0                            ;// absCoeffAC= abs(pPredBufRow[i])
    226 
    227        SMULBB          absCoeffAC,absCoeffAC,predQP                   ;// temp1=pPredBufRow[i]*predQP
    228        MUL             tempPred,absCoeffAC,CoeffTable                 ;// tempPred=pPredBufRow[i]*predQP*0x1ffff/curQP
    229        LSR             tempPred,tempPred,#17
    230 
    231        MLA             Rem,negCurQP,tempPred,absCoeffAC               ;// Rem=abs(pPredBufRow[i])-tempPred*curQP
    232        LDRH            temp,[pSrcDst,Count]                           ;// temp=pSrcDst[i],1<=i<8
    233 
    234        CMP             Rem,curQP
    235        ADDGE           tempPred,#1                                    ;// if Rem>=round(curQP/2); tempPred=tempPred+1
    236        CMP             temp1,#0
    237        RSBLT           tempPred,tempPred,#0                           ;// if pPredBufRow[i]<0 ; tempPred=-tempPred
    238 
    239        ;// Update source and Row Prediction buffers
    240 
    241        ADD             temp,temp,tempPred                             ;// temp=tempPred+pSrcDst[i]
    242        SSAT16          temp,#12,temp                                  ;// Clip temp to [-2048,2047]
    243        STRH            temp,[pSrcDst,Count]
    244        STRH            temp,[pPredBufRow,Count]                       ;// pPredBufRow[i]=temp
    245        ADD             Count,Count,#2                                 ;// i=i+1
    246        CMP             Count,#16                                      ;// compare if i=8
    247        BLT             loop1
    248        B               Exit                                           ;// Branch to exit
    249 
    250 Horizontal
    251 
    252        MOV             Count,#16                                      ;// Initializing i=8
    253 
    254 loop2
    255 
    256        LSR             temp2,Count,#3                                 ;// temp2=i>>3
    257 
    258        ;// Calculate tempPred
    259 
    260        LDRH            absCoeffAC,[pPredBufCol,temp2]                 ;// absCoefAC=pPredBufCol[i>>3]
    261        MOV             temp1,absCoeffAC
    262        CMP             temp1,#0                                       ;// compare pPredBufRow[i] with zero, 1=<i<=7
    263        RSBLT           absCoeffAC,temp1,#0                            ;// absCoeffAC=abs(pPredBufCol[i>>3])
    264 
    265        SMULBB          absCoeffAC,absCoeffAC,predQP                   ;// temp1=pPredBufCol[i>>3]*predQP
    266        MUL             tempPred,absCoeffAC,CoeffTable                 ;// tempPred=pPredBufCol[i>>3]*predQP*0x1ffff/curQP
    267        LSR             tempPred,tempPred,#17                          ;// tempPred=pPredBufCol[i>>3]*predQP/curQP
    268 
    269        MLA             Rem,negCurQP,tempPred,absCoeffAC
    270        LDRH            temp,[pSrcDst,Count]                           ;// temp=pSrcDst[i]
    271 
    272        CMP             Rem,curQP                                      ;// Compare Rem with round(curQP/2)
    273        ADDGE           tempPred,#1                                    ;// tempPred=tempPred+1 if Rem>=round(curQP/2)
    274        CMP             temp1,#0
    275        RSBLT           tempPred,tempPred,#0                           ;// if pPredBufCol[i>>3 <0 tempPred=-tempPred
    276 
    277        ;// Update source and Row Prediction buffers
    278 
    279        ADD             temp,temp,tempPred                             ;// temp=pSrcDst[i]+tempPred
    280        SSAT16          temp,#12,temp                                  ;// Clip temp to [-2048,2047]
    281        STRH            temp,[pSrcDst,Count]                           ;// pSrcDst[0]= clipped value
    282        STRH            temp,[pPredBufCol,temp2]                       ;// pPredBufCol[i>>3]=temp
    283        ADD             Count,Count,#16                                ;// i=i+8
    284        CMP             Count,#128                                     ;// compare i with 64
    285        BLT             loop2
    286 
    287 
    288 Exit
    289 
    290        MOV             Return,#OMX_Sts_NoErr
    291 
    292        M_END
    293        ENDIF
    294        END
    295 
    296 
    297 
    298