Showing the changes to codec/encoder/core/src/md.cpp (1 of 308 files). Show all
Unified · Split
| @@ -0,0 +1,1034 @@ | ||
| 1 | +/*! | |
| 2 | + * \copy | |
| 3 | + * Copyright (c) 2009-2013, Cisco Systems | |
| 4 | + * All rights reserved. | |
| 5 | + * | |
| 6 | + * Redistribution and use in source and binary forms, with or without | |
| 7 | + * modification, are permitted provided that the following conditions | |
| 8 | + * are met: | |
| 9 | + * | |
| 10 | + * * Redistributions of source code must retain the above copyright | |
| 11 | + * notice, this list of conditions and the following disclaimer. | |
| 12 | + * | |
| 13 | + * * Redistributions in binary form must reproduce the above copyright | |
| 14 | + * notice, this list of conditions and the following disclaimer in | |
| 15 | + * the documentation and/or other materials provided with the | |
| 16 | + * distribution. | |
| 17 | + * | |
| 18 | + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
| 19 | + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
| 20 | + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | |
| 21 | + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | |
| 22 | + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | |
| 23 | + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | |
| 24 | + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
| 25 | + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |
| 26 | + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
| 27 | + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | |
| 28 | + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| 29 | + * POSSIBILITY OF SUCH DAMAGE. | |
| 30 | + * | |
| 31 | + * | |
| 32 | + * \file md.c | |
| 33 | + * | |
| 34 | + * \brief mode decision | |
| 35 | + * | |
| 36 | + * \date 2009.05.14 Created | |
| 37 | + * | |
| 38 | + ************************************************************************************* | |
| 39 | + */ | |
| 40 | + | |
| 41 | +#include <string.h> | |
| 42 | +#include "ls_defines.h" | |
| 43 | +#include "encoder_context.h" | |
| 44 | +#include "svc_enc_slice_segment.h" | |
| 45 | +#include "md.h" | |
| 46 | +#include "mc.h" | |
| 47 | +#include "mv_pred.h" | |
| 48 | +#include "cpu_core.h" | |
| 49 | +#include "svc_enc_golomb.h" | |
| 50 | +#include "sample.h" | |
| 51 | +#include "array_stack_align.h" | |
| 52 | + | |
| 53 | +namespace WelsSVCEnc { | |
| 54 | +#define INTRA_VARIANCE_SAD_THRESHOLD 150 | |
| 55 | +#define INTER_VARIANCE_SAD_THRESHOLD 20 | |
| 56 | + | |
| 57 | +//fill cache of neighbor MB, containing pNonZeroCount, sample_avail, pIntra4x4PredMode | |
| 58 | +void FillNeighborCacheIntra(SMbCache* pMbCache, SMB* pCurMb, int32_t iMbWidth) | |
| 59 | +{ | |
| 60 | + uint32_t uiNeighborAvail = pCurMb->uiNeighborAvail; | |
| 61 | + uint32_t uiNeighborIntra = 0; | |
| 62 | + | |
| 63 | + if (uiNeighborAvail & LEFT_MB_POS) //LEFT MB | |
| 64 | + { | |
| 65 | + int8_t* pLeftMbNonZeroCount = pCurMb->pNonZeroCount - MB_LUMA_CHROMA_BLOCK4x4_NUM; | |
| 66 | + pMbCache->iNonZeroCoeffCount[8] = pLeftMbNonZeroCount[ 3]; | |
| 67 | + pMbCache->iNonZeroCoeffCount[16] = pLeftMbNonZeroCount[ 7]; | |
| 68 | + pMbCache->iNonZeroCoeffCount[24] = pLeftMbNonZeroCount[11]; | |
| 69 | + pMbCache->iNonZeroCoeffCount[32] = pLeftMbNonZeroCount[15]; | |
| 70 | + | |
| 71 | + pMbCache->iNonZeroCoeffCount[ 13] = pLeftMbNonZeroCount[17]; | |
| 72 | + pMbCache->iNonZeroCoeffCount[21] = pLeftMbNonZeroCount[21]; | |
| 73 | + pMbCache->iNonZeroCoeffCount[37] = pLeftMbNonZeroCount[19]; | |
| 74 | + pMbCache->iNonZeroCoeffCount[45] = pLeftMbNonZeroCount[23]; | |
| 75 | + | |
| 76 | + uiNeighborIntra |= LEFT_MB_POS; | |
| 77 | + | |
| 78 | + if ( IS_INTRA4x4((pCurMb-1)->uiMbType ) ) | |
| 79 | + { | |
| 80 | + int8_t* pLeftMbIntra4x4PredMode = pCurMb->pIntra4x4PredMode - INTRA_4x4_MODE_NUM; | |
| 81 | + pMbCache->iIntraPredMode[8] = pLeftMbIntra4x4PredMode[4]; | |
| 82 | + pMbCache->iIntraPredMode[16] = pLeftMbIntra4x4PredMode[5]; | |
| 83 | + pMbCache->iIntraPredMode[24] = pLeftMbIntra4x4PredMode[6]; | |
| 84 | + pMbCache->iIntraPredMode[32] = pLeftMbIntra4x4PredMode[3]; | |
| 85 | + } | |
| 86 | + else// if ( 0 == constrained_intra_pred_flag || IS_INTRA16x16((pCurMb-1)->uiMbType )) | |
| 87 | + { | |
| 88 | + pMbCache->iIntraPredMode[8] = | |
| 89 | + pMbCache->iIntraPredMode[16] = | |
| 90 | + pMbCache->iIntraPredMode[24] = | |
| 91 | + pMbCache->iIntraPredMode[32] = 2; //DC | |
| 92 | + } | |
| 93 | + } | |
| 94 | + else | |
| 95 | + { | |
| 96 | + pMbCache->iNonZeroCoeffCount[ 8] = | |
| 97 | + pMbCache->iNonZeroCoeffCount[16] = | |
| 98 | + pMbCache->iNonZeroCoeffCount[24] = | |
| 99 | + pMbCache->iNonZeroCoeffCount[32] = -1;//unavailable | |
| 100 | + pMbCache->iNonZeroCoeffCount[13] = | |
| 101 | + pMbCache->iNonZeroCoeffCount[21] = | |
| 102 | + pMbCache->iNonZeroCoeffCount[37] = | |
| 103 | + pMbCache->iNonZeroCoeffCount[45] = -1;//unavailable | |
| 104 | + | |
| 105 | + pMbCache->iIntraPredMode[8] = | |
| 106 | + pMbCache->iIntraPredMode[16] = | |
| 107 | + pMbCache->iIntraPredMode[24] = | |
| 108 | + pMbCache->iIntraPredMode[32] = -1;//unavailable | |
| 109 | + } | |
| 110 | + | |
| 111 | + if (uiNeighborAvail & TOP_MB_POS)//TOP MB | |
| 112 | + { | |
| 113 | + SMB* pTopMb = pCurMb - iMbWidth; | |
| 114 | + ST32(&pMbCache->iNonZeroCoeffCount[1], LD32(&pTopMb->pNonZeroCount[12])); | |
| 115 | + | |
| 116 | + ST16(&pMbCache->iNonZeroCoeffCount[6], LD16(&pTopMb->pNonZeroCount[20])); | |
| 117 | + ST16(&pMbCache->iNonZeroCoeffCount[30], LD16(&pTopMb->pNonZeroCount[22])); | |
| 118 | + | |
| 119 | + uiNeighborIntra |= TOP_MB_POS; | |
| 120 | + | |
| 121 | + if ( IS_INTRA4x4( pTopMb->uiMbType ) ) | |
| 122 | + { | |
| 123 | + ST32(pMbCache->iIntraPredMode+1, LD32(&pTopMb->pIntra4x4PredMode[0])); | |
| 124 | + } | |
| 125 | + else// if ( 0 == constrained_intra_pred_flag || IS_INTRA16x16( pTopMb->uiMbType )) | |
| 126 | + { | |
| 127 | + const uint32_t kuiDc32 = 0x02020202; | |
| 128 | + ST32( pMbCache->iIntraPredMode+1 , kuiDc32 ); | |
| 129 | + } | |
| 130 | + } | |
| 131 | + else | |
| 132 | + { | |
| 133 | + const uint32_t kuiUnavail32 = 0xffffffff; | |
| 134 | + ST32( pMbCache->iIntraPredMode+1 , kuiUnavail32 ); | |
| 135 | + ST32( &pMbCache->iNonZeroCoeffCount[1], kuiUnavail32 ); | |
| 136 | + | |
| 137 | + ST16( &pMbCache->iNonZeroCoeffCount[6], 0xffff ); | |
| 138 | + ST16( &pMbCache->iNonZeroCoeffCount[30], 0xffff ); | |
| 139 | + } | |
| 140 | + | |
| 141 | + if (uiNeighborAvail & TOPLEFT_MB_POS) | |
| 142 | + { | |
| 143 | + uiNeighborIntra |= 0x04; | |
| 144 | + } | |
| 145 | + | |
| 146 | + | |
| 147 | + if (uiNeighborAvail & TOPRIGHT_MB_POS) | |
| 148 | + { | |
| 149 | + uiNeighborIntra |= 0x08; | |
| 150 | + } | |
| 151 | + pMbCache->uiNeighborIntra = uiNeighborIntra; | |
| 152 | +} | |
| 153 | +//fill cache of neighbor MB, containing motion_vector and uiRefIndex | |
| 154 | +void FillNeighborCacheInterWithoutBGD(SMbCache* pMbCache, SMB* pCurMb, int32_t iMbWidth, int8_t *pVaaBgMbFlag) | |
| 155 | +{ | |
| 156 | + uint32_t uiNeighborAvail = pCurMb->uiNeighborAvail; | |
| 157 | + SMB* pLeftMb = pCurMb -1 ; | |
| 158 | + SMB* pTopMb = pCurMb -iMbWidth; | |
| 159 | + SMB* pLeftTopMb = pCurMb - iMbWidth - 1 ; | |
| 160 | + SMB* iRightTopMb = pCurMb -iMbWidth + 1 ; | |
| 161 | + SMVComponentUnit *pMvComp = &pMbCache->sMvComponents; | |
| 162 | + if( (uiNeighborAvail & LEFT_MB_POS) && IS_SVC_INTER(pLeftMb->uiMbType) ) | |
| 163 | + { | |
| 164 | + pMvComp->sMotionVectorCache[ 6] = pLeftMb->sMv[ 3]; | |
| 165 | + pMvComp->sMotionVectorCache[12] = pLeftMb->sMv[ 7]; | |
| 166 | + pMvComp->sMotionVectorCache[18] = pLeftMb->sMv[11]; | |
| 167 | + pMvComp->sMotionVectorCache[24] = pLeftMb->sMv[15]; | |
| 168 | + pMvComp->iRefIndexCache[ 6] = pLeftMb->pRefIndex[1]; | |
| 169 | + pMvComp->iRefIndexCache[12] = pLeftMb->pRefIndex[1]; | |
| 170 | + pMvComp->iRefIndexCache[18] = pLeftMb->pRefIndex[3]; | |
| 171 | + pMvComp->iRefIndexCache[24] = pLeftMb->pRefIndex[3]; | |
| 172 | + pMbCache->iSadCost[3] = pLeftMb->pSadCost[0]; | |
| 173 | + | |
| 174 | + if ( pLeftMb->uiMbType == MB_TYPE_SKIP ) | |
| 175 | + { | |
| 176 | + pMbCache->bMbTypeSkip[3] = 1; | |
| 177 | + pMbCache->iSadCostSkip[3] = pMbCache->pEncSad[-1]; | |
| 178 | + } | |
| 179 | + else | |
| 180 | + { | |
| 181 | + pMbCache->bMbTypeSkip[3] = 0; | |
| 182 | + pMbCache->iSadCostSkip[3] = 0; | |
| 183 | + } | |
| 184 | + } | |
| 185 | + else //avail or non-inter | |
| 186 | + { | |
| 187 | + ST32(&pMvComp->sMotionVectorCache[ 6], 0); | |
| 188 | + ST32(&pMvComp->sMotionVectorCache[12], 0); | |
| 189 | + ST32(&pMvComp->sMotionVectorCache[18], 0); | |
| 190 | + ST32(&pMvComp->sMotionVectorCache[24], 0); | |
| 191 | + pMvComp->iRefIndexCache[ 6] = | |
| 192 | + pMvComp->iRefIndexCache[12] = | |
| 193 | + pMvComp->iRefIndexCache[18] = | |
| 194 | + pMvComp->iRefIndexCache[24] = (uiNeighborAvail & LEFT_MB_POS) ? REF_NOT_IN_LIST : REF_NOT_AVAIL; | |
| 195 | + pMbCache->iSadCost[3] = 0; | |
| 196 | + pMbCache->bMbTypeSkip[3] = 0; | |
| 197 | + pMbCache->iSadCostSkip[3] = 0; | |
| 198 | + } | |
| 199 | + | |
| 200 | + if ( (uiNeighborAvail & TOP_MB_POS) && IS_SVC_INTER(pTopMb->uiMbType) ) //TOP MB | |
| 201 | + { | |
| 202 | + ST64(&pMvComp->sMotionVectorCache[1], LD64(&pTopMb->sMv[12])); | |
| 203 | + ST64(&pMvComp->sMotionVectorCache[3], LD64(&pTopMb->sMv[14])); | |
| 204 | + pMvComp->iRefIndexCache[1] = pTopMb->pRefIndex[2]; | |
| 205 | + pMvComp->iRefIndexCache[2] = pTopMb->pRefIndex[2]; | |
| 206 | + pMvComp->iRefIndexCache[3] = pTopMb->pRefIndex[3]; | |
| 207 | + pMvComp->iRefIndexCache[4] = pTopMb->pRefIndex[3]; | |
| 208 | + pMbCache->iSadCost[1] = pTopMb->pSadCost[0]; | |
| 209 | + | |
| 210 | + if ( pTopMb->uiMbType == MB_TYPE_SKIP ) | |
| 211 | + { | |
| 212 | + pMbCache->bMbTypeSkip[1] = 1; | |
| 213 | + pMbCache->iSadCostSkip[1] = pMbCache->pEncSad[-iMbWidth]; | |
| 214 | + } | |
| 215 | + else | |
| 216 | + { | |
| 217 | + pMbCache->bMbTypeSkip[1] = 0; | |
| 218 | + pMbCache->iSadCostSkip[1] = 0; | |
| 219 | + } | |
| 220 | + } | |
| 221 | + else //unavail | |
| 222 | + { | |
| 223 | + ST64(&pMvComp->sMotionVectorCache[1], 0); | |
| 224 | + ST64(&pMvComp->sMotionVectorCache[3], 0); | |
| 225 | + pMvComp->iRefIndexCache[1] = | |
| 226 | + pMvComp->iRefIndexCache[2] = | |
| 227 | + pMvComp->iRefIndexCache[3] = | |
| 228 | + pMvComp->iRefIndexCache[4] = (uiNeighborAvail & TOP_MB_POS) ? REF_NOT_IN_LIST : REF_NOT_AVAIL; | |
| 229 | + pMbCache->iSadCost[1] = 0; | |
| 230 | + | |
| 231 | + pMbCache->bMbTypeSkip[1] = 0; | |
| 232 | + pMbCache->iSadCostSkip[1] = 0; | |
| 233 | + } | |
| 234 | + | |
| 235 | + if ( (uiNeighborAvail & TOPLEFT_MB_POS) && IS_SVC_INTER(pLeftTopMb->uiMbType) ) //LEFT_TOP MB | |
| 236 | + { | |
| 237 | + pMvComp->sMotionVectorCache[0] = pLeftTopMb->sMv[15]; | |
| 238 | + pMvComp->iRefIndexCache[0] = pLeftTopMb->pRefIndex[3]; | |
| 239 | + pMbCache->iSadCost[0] = pLeftTopMb->pSadCost[0]; | |
| 240 | + | |
| 241 | + if ( pLeftTopMb->uiMbType == MB_TYPE_SKIP ) | |
| 242 | + { | |
| 243 | + pMbCache->bMbTypeSkip[0] = 1; | |
| 244 | + pMbCache->iSadCostSkip[0] = pMbCache->pEncSad[-iMbWidth-1]; | |
| 245 | + } | |
| 246 | + else | |
| 247 | + { | |
| 248 | + pMbCache->bMbTypeSkip[0] = 0; | |
| 249 | + pMbCache->iSadCostSkip[0] = 0; | |
| 250 | + } | |
| 251 | + } | |
| 252 | + else //unavail | |
| 253 | + { | |
| 254 | + ST32(&pMvComp->sMotionVectorCache[0], 0); | |
| 255 | + pMvComp->iRefIndexCache[0] = (uiNeighborAvail & TOPLEFT_MB_POS) ? REF_NOT_IN_LIST : REF_NOT_AVAIL; | |
| 256 | + pMbCache->iSadCost[0] = 0; | |
| 257 | + pMbCache->bMbTypeSkip[0] = 0; | |
| 258 | + pMbCache->iSadCostSkip[0] = 0; | |
| 259 | + } | |
| 260 | + | |
| 261 | + if ((uiNeighborAvail & TOPRIGHT_MB_POS) && IS_SVC_INTER(iRightTopMb->uiMbType) ) //RIGHT_TOP MB | |
| 262 | + { | |
| 263 | + pMvComp->sMotionVectorCache[5] = iRightTopMb->sMv[12]; | |
| 264 | + pMvComp->iRefIndexCache[5] = iRightTopMb->pRefIndex[2]; | |
| 265 | + pMbCache->iSadCost[2] = iRightTopMb->pSadCost[0]; | |
| 266 | + | |
| 267 | + if ( iRightTopMb->uiMbType == MB_TYPE_SKIP ) | |
| 268 | + { | |
| 269 | + pMbCache->bMbTypeSkip[2] = 1; | |
| 270 | + pMbCache->iSadCostSkip[2] = pMbCache->pEncSad[-iMbWidth+1]; | |
| 271 | + } | |
| 272 | + else | |
| 273 | + { | |
| 274 | + pMbCache->bMbTypeSkip[2] = 0; | |
| 275 | + pMbCache->iSadCostSkip[2] = 0; | |
| 276 | + } | |
| 277 | + } | |
| 278 | + else //unavail | |
| 279 | + { | |
| 280 | + ST32(&pMvComp->sMotionVectorCache[5], 0); | |
| 281 | + pMvComp->iRefIndexCache[5] = (uiNeighborAvail & TOPRIGHT_MB_POS) ? REF_NOT_IN_LIST : REF_NOT_AVAIL; | |
| 282 | + pMbCache->iSadCost[2] = 0; | |
| 283 | + pMbCache->bMbTypeSkip[2] = 0; | |
| 284 | + pMbCache->iSadCostSkip[2] = 0; | |
| 285 | + } | |
| 286 | + | |
| 287 | + //right-top 4*4 pBlock unavailable | |
| 288 | + ST32(&pMvComp->sMotionVectorCache[ 9], 0); | |
| 289 | + ST32(&pMvComp->sMotionVectorCache[21], 0); | |
| 290 | + ST32(&pMvComp->sMotionVectorCache[11], 0); | |
| 291 | + ST32(&pMvComp->sMotionVectorCache[17], 0); | |
| 292 | + ST32(&pMvComp->sMotionVectorCache[23], 0); | |
| 293 | + pMvComp->iRefIndexCache[ 9] = | |
| 294 | + pMvComp->iRefIndexCache[11] = | |
| 295 | + pMvComp->iRefIndexCache[17] = | |
| 296 | + pMvComp->iRefIndexCache[21] = | |
| 297 | + pMvComp->iRefIndexCache[23] = REF_NOT_AVAIL; | |
| 298 | +} | |
| 299 | + | |
| 300 | +void FillNeighborCacheInterWithBGD(SMbCache* pMbCache, SMB* pCurMb, int32_t iMbWidth, int8_t *pVaaBgMbFlag) | |
| 301 | +{ | |
| 302 | + uint32_t uiNeighborAvail = pCurMb->uiNeighborAvail; | |
| 303 | + SMB* pLeftMb = pCurMb -1 ; | |
| 304 | + SMB* pTopMb = pCurMb -iMbWidth; | |
| 305 | + SMB* pLeftTopMb = pCurMb - iMbWidth - 1 ; | |
| 306 | + SMB* iRightTopMb = pCurMb -iMbWidth + 1 ; | |
| 307 | + SMVComponentUnit *pMvComp = &pMbCache->sMvComponents; | |
| 308 | + | |
| 309 | + if( (uiNeighborAvail & LEFT_MB_POS) && IS_SVC_INTER(pLeftMb->uiMbType) ) | |
| 310 | + { | |
| 311 | + pMvComp->sMotionVectorCache[ 6] = pLeftMb->sMv[ 3]; | |
| 312 | + pMvComp->sMotionVectorCache[12] = pLeftMb->sMv[ 7]; | |
| 313 | + pMvComp->sMotionVectorCache[18] = pLeftMb->sMv[11]; | |
| 314 | + pMvComp->sMotionVectorCache[24] = pLeftMb->sMv[15]; | |
| 315 | + pMvComp->iRefIndexCache[ 6] = pLeftMb->pRefIndex[1]; | |
| 316 | + pMvComp->iRefIndexCache[12] = pLeftMb->pRefIndex[1]; | |
| 317 | + pMvComp->iRefIndexCache[18] = pLeftMb->pRefIndex[3]; | |
| 318 | + pMvComp->iRefIndexCache[24] = pLeftMb->pRefIndex[3]; | |
| 319 | + pMbCache->iSadCost[3] = pLeftMb->pSadCost[0]; | |
| 320 | + | |
| 321 | + if ( pLeftMb->uiMbType == MB_TYPE_SKIP && pVaaBgMbFlag[-1] == 0) | |
| 322 | + { | |
| 323 | + pMbCache->bMbTypeSkip[3] = 1; | |
| 324 | + pMbCache->iSadCostSkip[3] = pMbCache->pEncSad[-1]; | |
| 325 | + } | |
| 326 | + else | |
| 327 | + { | |
| 328 | + pMbCache->bMbTypeSkip[3] = 0; | |
| 329 | + pMbCache->iSadCostSkip[3] = 0; | |
| 330 | + } | |
| 331 | + } | |
| 332 | + else //avail or non-inter | |
| 333 | + { | |
| 334 | + ST32(&pMvComp->sMotionVectorCache[ 6], 0); | |
| 335 | + ST32(&pMvComp->sMotionVectorCache[12], 0); | |
| 336 | + ST32(&pMvComp->sMotionVectorCache[18], 0); | |
| 337 | + ST32(&pMvComp->sMotionVectorCache[24], 0); | |
| 338 | + pMvComp->iRefIndexCache[ 6] = | |
| 339 | + pMvComp->iRefIndexCache[12] = | |
| 340 | + pMvComp->iRefIndexCache[18] = | |
| 341 | + pMvComp->iRefIndexCache[24] = (uiNeighborAvail & LEFT_MB_POS) ? REF_NOT_IN_LIST : REF_NOT_AVAIL; | |
| 342 | + pMbCache->iSadCost[3] = 0; | |
| 343 | + pMbCache->bMbTypeSkip[3] = 0; | |
| 344 | + pMbCache->iSadCostSkip[3] = 0; | |
| 345 | + } | |
| 346 | + | |
| 347 | + if ( (uiNeighborAvail & TOP_MB_POS) && IS_SVC_INTER(pTopMb->uiMbType) ) //TOP MB | |
| 348 | + { | |
| 349 | + ST64(&pMvComp->sMotionVectorCache[1], LD64(&pTopMb->sMv[12])); | |
| 350 | + ST64(&pMvComp->sMotionVectorCache[3], LD64(&pTopMb->sMv[14])); | |
| 351 | + pMvComp->iRefIndexCache[1] = pTopMb->pRefIndex[2]; | |
| 352 | + pMvComp->iRefIndexCache[2] = pTopMb->pRefIndex[2]; | |
| 353 | + pMvComp->iRefIndexCache[3] = pTopMb->pRefIndex[3]; | |
| 354 | + pMvComp->iRefIndexCache[4] = pTopMb->pRefIndex[3]; | |
| 355 | + pMbCache->iSadCost[1] = pTopMb->pSadCost[0]; | |
| 356 | + if ( pTopMb->uiMbType == MB_TYPE_SKIP && pVaaBgMbFlag[-iMbWidth] == 0 ) | |
| 357 | + { | |
| 358 | + pMbCache->bMbTypeSkip[1] = 1; | |
| 359 | + pMbCache->iSadCostSkip[1] = pMbCache->pEncSad[-iMbWidth]; | |
| 360 | + } | |
| 361 | + else | |
| 362 | + { | |
| 363 | + pMbCache->bMbTypeSkip[1] = 0; | |
| 364 | + pMbCache->iSadCostSkip[1] = 0; | |
| 365 | + } | |
| 366 | + } | |
| 367 | + else //unavail | |
| 368 | + { | |
| 369 | + ST64(&pMvComp->sMotionVectorCache[1], 0); | |
| 370 | + ST64(&pMvComp->sMotionVectorCache[3], 0); | |
| 371 | + pMvComp->iRefIndexCache[1] = | |
| 372 | + pMvComp->iRefIndexCache[2] = | |
| 373 | + pMvComp->iRefIndexCache[3] = | |
| 374 | + pMvComp->iRefIndexCache[4] = (uiNeighborAvail & TOP_MB_POS) ? REF_NOT_IN_LIST : REF_NOT_AVAIL; | |
| 375 | + pMbCache->iSadCost[1] = 0; | |
| 376 | + pMbCache->bMbTypeSkip[1] = 0; | |
| 377 | + pMbCache->iSadCostSkip[1] = 0; | |
| 378 | + } | |
| 379 | + | |
| 380 | + | |
| 381 | + if ( (uiNeighborAvail & TOPLEFT_MB_POS) && IS_SVC_INTER(pLeftTopMb->uiMbType) ) //LEFT_TOP MB | |
| 382 | + { | |
| 383 | + pMvComp->sMotionVectorCache[0] = pLeftTopMb->sMv[15]; | |
| 384 | + pMvComp->iRefIndexCache[0] = pLeftTopMb->pRefIndex[3]; | |
| 385 | + pMbCache->iSadCost[0] = pLeftTopMb->pSadCost[0]; | |
| 386 | + | |
| 387 | + if ( pLeftTopMb->uiMbType == MB_TYPE_SKIP && pVaaBgMbFlag[-iMbWidth-1] == 0 ) | |
| 388 | + { | |
| 389 | + pMbCache->bMbTypeSkip[0] = 1; | |
| 390 | + pMbCache->iSadCostSkip[0] = pMbCache->pEncSad[-iMbWidth-1]; | |
| 391 | + } | |
| 392 | + else | |
| 393 | + { | |
| 394 | + pMbCache->bMbTypeSkip[0] = 0; | |
| 395 | + pMbCache->iSadCostSkip[0] = 0; | |
| 396 | + } | |
| 397 | + } | |
| 398 | + else //unavail | |
| 399 | + { | |
| 400 | + ST32(&pMvComp->sMotionVectorCache[0], 0); | |
| 401 | + pMvComp->iRefIndexCache[0] = (uiNeighborAvail & TOPLEFT_MB_POS) ? REF_NOT_IN_LIST : REF_NOT_AVAIL; | |
| 402 | + pMbCache->iSadCost[0] = 0; | |
| 403 | + pMbCache->bMbTypeSkip[0] = 0; | |
| 404 | + pMbCache->iSadCostSkip[0] = 0; | |
| 405 | + } | |
| 406 | + | |
| 407 | + if ((uiNeighborAvail & TOPRIGHT_MB_POS) && IS_SVC_INTER(iRightTopMb->uiMbType) ) //RIGHT_TOP MB | |
| 408 | + { | |
| 409 | + pMvComp->sMotionVectorCache[5] = iRightTopMb->sMv[12]; | |
| 410 | + pMvComp->iRefIndexCache[5] = iRightTopMb->pRefIndex[2]; | |
| 411 | + pMbCache->iSadCost[2] = iRightTopMb->pSadCost[0]; | |
| 412 | + | |
| 413 | + if ( iRightTopMb->uiMbType == MB_TYPE_SKIP && pVaaBgMbFlag[-iMbWidth+1] == 0 ) | |
| 414 | + { | |
| 415 | + pMbCache->bMbTypeSkip[2] = 1; | |
| 416 | + pMbCache->iSadCostSkip[2] = pMbCache->pEncSad[-iMbWidth+1]; | |
| 417 | + } | |
| 418 | + else | |
| 419 | + { | |
| 420 | + pMbCache->bMbTypeSkip[2] = 0; | |
| 421 | + pMbCache->iSadCostSkip[2] = 0; | |
| 422 | + } | |
| 423 | + } | |
| 424 | + else //unavail | |
| 425 | + { | |
| 426 | + ST32(&pMvComp->sMotionVectorCache[5], 0); | |
| 427 | + pMvComp->iRefIndexCache[5] = (uiNeighborAvail & TOPRIGHT_MB_POS) ? REF_NOT_IN_LIST : REF_NOT_AVAIL; | |
| 428 | + pMbCache->iSadCost[2] = 0; | |
| 429 | + pMbCache->bMbTypeSkip[2] = 0; | |
| 430 | + pMbCache->iSadCostSkip[2] = 0; | |
| 431 | + } | |
| 432 | + | |
| 433 | + //right-top 4*4 pBlock unavailable | |
| 434 | + ST32(&pMvComp->sMotionVectorCache[ 9], 0); | |
| 435 | + ST32(&pMvComp->sMotionVectorCache[21], 0); | |
| 436 | + ST32(&pMvComp->sMotionVectorCache[11], 0); | |
| 437 | + ST32(&pMvComp->sMotionVectorCache[17], 0); | |
| 438 | + ST32(&pMvComp->sMotionVectorCache[23], 0); | |
| 439 | + pMvComp->iRefIndexCache[ 9] = | |
| 440 | + pMvComp->iRefIndexCache[11] = | |
| 441 | + pMvComp->iRefIndexCache[17] = | |
| 442 | + pMvComp->iRefIndexCache[21] = | |
| 443 | + pMvComp->iRefIndexCache[23] = REF_NOT_AVAIL; | |
| 444 | +} | |
| 445 | + | |
| 446 | +void InitFillNeighborCacheInterFunc( SWelsFuncPtrList *pFuncList, const int32_t kiFlag ) | |
| 447 | +{ | |
| 448 | + pFuncList->pfFillInterNeighborCache = kiFlag ? FillNeighborCacheInterWithBGD : FillNeighborCacheInterWithoutBGD; | |
| 449 | +} | |
| 450 | + | |
| 451 | +void UpdateMbMv_c( SMVUnitXY *pMvBuffer, const SMVUnitXY ksMv ) | |
| 452 | +{ | |
| 453 | + int32_t k = 0; | |
| 454 | + for (; k < MB_BLOCK4x4_NUM; k += 4) | |
| 455 | + { | |
| 456 | + pMvBuffer[k ] = | |
| 457 | + pMvBuffer[k+1] = | |
| 458 | + pMvBuffer[k+2] = | |
| 459 | + pMvBuffer[k+3] = ksMv; | |
| 460 | + } | |
| 461 | +} | |
| 462 | + | |
| 463 | + | |
| 464 | +uint8_t MdInterAnalysisVaaInfo_c( int32_t *pSad8x8 ) | |
| 465 | +{ | |
| 466 | + int32_t iSadBlock[4], iAverageSadBlock[4]; | |
| 467 | + int32_t iAverageSad, iVarianceSad; | |
| 468 | + | |
| 469 | + iSadBlock[0] = pSad8x8[0]; | |
| 470 | + iAverageSad = iSadBlock[0]; | |
| 471 | + | |
| 472 | + iSadBlock[1] = pSad8x8[1]; | |
| 473 | + iAverageSad += iSadBlock[1]; | |
| 474 | + | |
| 475 | + iSadBlock[2] = pSad8x8[2]; | |
| 476 | + iAverageSad += iSadBlock[2]; | |
| 477 | + | |
| 478 | + iSadBlock[3] = pSad8x8[3]; | |
| 479 | + iAverageSad += iSadBlock[3]; | |
| 480 | + | |
| 481 | + iAverageSad = iAverageSad >> 2; | |
| 482 | + | |
| 483 | + iAverageSadBlock[0] = (iSadBlock[0] >> 6) - (iAverageSad >> 6); | |
| 484 | + iVarianceSad = iAverageSadBlock[0] * iAverageSadBlock[0]; | |
| 485 | + | |
| 486 | + iAverageSadBlock[1] = (iSadBlock[1] >> 6) - (iAverageSad >> 6); | |
| 487 | + iVarianceSad += iAverageSadBlock[1] * iAverageSadBlock[1]; | |
| 488 | + | |
| 489 | + iAverageSadBlock[2] = (iSadBlock[2] >> 6) - (iAverageSad >> 6); | |
| 490 | + iVarianceSad += iAverageSadBlock[2] * iAverageSadBlock[2]; | |
| 491 | + | |
| 492 | + iAverageSadBlock[3] = (iSadBlock[3] >> 6) - (iAverageSad >> 6); | |
| 493 | + iVarianceSad += iAverageSadBlock[3] * iAverageSadBlock[3]; | |
| 494 | + | |
| 495 | + if ( iVarianceSad < INTER_VARIANCE_SAD_THRESHOLD ) | |
| 496 | + { | |
| 497 | + return 15; | |
| 498 | + } | |
| 499 | + | |
| 500 | + uint8_t uiMbSign = 0; | |
| 501 | + if (iSadBlock[0] > iAverageSad) | |
| 502 | + uiMbSign |= 0x08; | |
| 503 | + if (iSadBlock[1] > iAverageSad) | |
| 504 | + uiMbSign |= 0x04; | |
| 505 | + if (iSadBlock[2] > iAverageSad) | |
| 506 | + uiMbSign |= 0x02; | |
| 507 | + if (iSadBlock[3] > iAverageSad) | |
| 508 | + uiMbSign |= 0x01; | |
| 509 | + return ( uiMbSign ); | |
| 510 | +} | |
| 511 | + | |
| 512 | +static inline int32_t AnalysisVaaInfoIntra_c( uint8_t *pDataY, const int32_t kiLineSize ) | |
| 513 | +{ | |
| 514 | + ENFORCE_STACK_ALIGN_1D(uint16_t, uiAvgBlock, 16, 16) | |
| 515 | + uint16_t *pBlock = &uiAvgBlock[0]; | |
| 516 | + uint8_t *pEncData = pDataY; | |
| 517 | + const int32_t kiLineSize2 = kiLineSize << 1; | |
| 518 | + const int32_t kiLineSize3 = kiLineSize + kiLineSize2; | |
| 519 | + const int32_t kiLineSize4 = kiLineSize << 2; | |
| 520 | + int32_t i = 0, j = 0, num = 0; | |
| 521 | + int32_t iSumAvg = 0, iSumSqr = 0; | |
| 522 | + | |
| 523 | +// analysis_vaa_info_intra_core_c( pDataY, iLineSize, pBlock ); | |
| 524 | + for ( ; j < 16; j += 4 ) | |
| 525 | + { | |
| 526 | + num = 0; | |
| 527 | + for ( i = 0; i < 16; i += 4, num ++ ) | |
| 528 | + { | |
| 529 | + pBlock[num] = pEncData[i ] + pEncData[i+1 ] + pEncData[i+2 ] + pEncData[i+3 ]; | |
| 530 | + pBlock[num] += pEncData[i+kiLineSize ] + pEncData[i+kiLineSize+1 ] + pEncData[i+kiLineSize+2 ] + pEncData[i+kiLineSize+3 ]; | |
| 531 | + pBlock[num] += pEncData[i+kiLineSize2] + pEncData[i+kiLineSize2+1] + pEncData[i+kiLineSize2+2] + pEncData[i+kiLineSize2+3]; | |
| 532 | + pBlock[num] += pEncData[i+kiLineSize3] + pEncData[i+kiLineSize3+1] + pEncData[i+kiLineSize3+2] + pEncData[i+kiLineSize3+3]; | |
| 533 | + pBlock[num] >>= 4; | |
| 534 | + } | |
| 535 | + pBlock += 4; | |
| 536 | + pEncData += kiLineSize4; | |
| 537 | + } | |
| 538 | + | |
| 539 | + pBlock = &uiAvgBlock[0]; | |
| 540 | + i = 4; | |
| 541 | + for ( ; i > 0; --i ) | |
| 542 | + { | |
| 543 | + iSumAvg += pBlock[0] + pBlock[1] + pBlock[2] + pBlock[3]; | |
| 544 | + iSumSqr += pBlock[0] * pBlock[0] + pBlock[1] * pBlock[1] + pBlock[2] * pBlock[2] + pBlock[3] * pBlock[3]; | |
| 545 | + | |
| 546 | + pBlock += 4; | |
| 547 | + } | |
| 548 | + | |
| 549 | + | |
| 550 | + return /*variance =*/ (iSumSqr - ((iSumAvg * iSumAvg) >> 4)); | |
| 551 | +} | |
| 552 | + | |
| 553 | +// for pfGetVarianceFromIntraVaa function ptr adaptive by CPU features, 6/7/2010 | |
| 554 | +void InitIntraAnalysisVaaInfo( SWelsFuncPtrList *pFuncList, const uint32_t kuiCpuFlag ) | |
| 555 | +{ | |
| 556 | + pFuncList->pfGetVarianceFromIntraVaa = AnalysisVaaInfoIntra_c; | |
| 557 | + pFuncList->pfGetMbSignFromInterVaa = MdInterAnalysisVaaInfo_c; | |
| 558 | + pFuncList->pfUpdateMbMv = UpdateMbMv_c; | |
| 559 | + | |
| 560 | +#if defined(X86_ASM) | |
| 561 | + if ( (kuiCpuFlag & WELS_CPU_SSE2) == WELS_CPU_SSE2 ) | |
| 562 | + { | |
| 563 | + pFuncList->pfGetVarianceFromIntraVaa = AnalysisVaaInfoIntra_sse2; | |
| 564 | + pFuncList->pfGetMbSignFromInterVaa = MdInterAnalysisVaaInfo_sse2; | |
| 565 | + pFuncList->pfUpdateMbMv = UpdateMbMv_sse2; | |
| 566 | + } | |
| 567 | + if ( (kuiCpuFlag & WELS_CPU_SSSE3) == WELS_CPU_SSSE3 ) | |
| 568 | + { | |
| 569 | + pFuncList->pfGetVarianceFromIntraVaa = AnalysisVaaInfoIntra_ssse3; | |
| 570 | + } | |
| 571 | + if ( (kuiCpuFlag & WELS_CPU_SSE41) == WELS_CPU_SSE41 ) | |
| 572 | + { | |
| 573 | + pFuncList->pfGetMbSignFromInterVaa = MdInterAnalysisVaaInfo_sse41; | |
| 574 | + } | |
| 575 | +#endif//X86_ASM | |
| 576 | +} | |
| 577 | + | |
| 578 | +BOOL_T MdIntraAnalysisVaaInfo( sWelsEncCtx* pEncCtx, uint8_t* pEncMb ) | |
| 579 | +{ | |
| 580 | + | |
| 581 | + SDqLayer* pCurDqLayer = pEncCtx->pCurDqLayer; | |
| 582 | + const int32_t kiLineSize = pCurDqLayer->iEncStride[0]; | |
| 583 | + const int32_t kiVariance = pEncCtx->pFuncList->pfGetVarianceFromIntraVaa( pEncMb, kiLineSize ); | |
| 584 | + return (kiVariance >= INTRA_VARIANCE_SAD_THRESHOLD); | |
| 585 | +} | |
| 586 | + | |
| 587 | +void InitMeRefinePointer(SMeRefinePointer* pMeRefine, SMbCache* pMbCache, int32_t iStride) | |
| 588 | +{ | |
| 589 | + pMeRefine->pHalfPixH = &pMbCache->pBufferInterPredMe[0] + iStride; | |
| 590 | + pMeRefine->pHalfPixV = &pMbCache->pBufferInterPredMe[640] + iStride; | |
| 591 | + | |
| 592 | + pMeRefine->pQuarPixBest= &pMbCache->pBufferInterPredMe[1280] + iStride; | |
| 593 | + pMeRefine->pQuarPixTmp = &pMbCache->pBufferInterPredMe[1920] + iStride; | |
| 594 | +} | |
| 595 | +typedef struct TagQuarParams | |
| 596 | +{ | |
| 597 | + int32_t iBestCost; | |
| 598 | + int32_t iBestHalfPix; | |
| 599 | + int32_t iStrideA; | |
| 600 | + int32_t iStrideB; | |
| 601 | + uint8_t * pRef; | |
| 602 | + uint8_t * pSrcB[4]; | |
| 603 | + uint8_t * pSrcA[4]; | |
| 604 | + int32_t iLms[4]; | |
| 605 | + int32_t iBestQuarPix; | |
| 606 | +}SQuarRefineParams; | |
| 607 | + | |
| 608 | +#define SWITCH_BEST_TMP_BUF(prev_best, curr_best){\ | |
| 609 | + pParams->iBestCost = iCurCost;\ | |
| 610 | + pTmp = prev_best;\ | |
| 611 | + prev_best = curr_best;\ | |
| 612 | + curr_best = pTmp;\ | |
| 613 | +} | |
| 614 | +#define CALC_COST(me_buf, lm) ( pFunc->sSampleDealingFuncs.pfMeCost[kuiPixel](pEncMb, iStrideEnc, me_buf, ME_REFINE_BUF_STRIDE) + lm ) | |
| 615 | + | |
| 616 | +inline void MeRefineQuarPixel( SWelsFuncPtrList *pFunc, SWelsME* pMe, SMeRefinePointer* pMeRefine, const int32_t kiWidth, const int32_t kiHeight,SQuarRefineParams *pParams, int32_t iStrideEnc ) | |
| 617 | +{ | |
| 618 | + PWelsSampleAveragingFunc *pSampleAvg = pFunc->sMcFuncs.pfSampleAveraging; | |
| 619 | + const int32_t kiAvgIndex = kiWidth >> 4; | |
| 620 | + int32_t iCurCost; | |
| 621 | + uint8_t *pEncMb = pMe->pEncMb; | |
| 622 | + uint8_t *pTmp = NULL; | |
| 623 | + const uint8_t kuiPixel = pMe->uiPixel; | |
| 624 | + | |
| 625 | + pSampleAvg[kiAvgIndex](pMeRefine->pQuarPixTmp, ME_REFINE_BUF_STRIDE, pParams->pSrcA[0], ME_REFINE_BUF_STRIDE,pParams->pSrcB[0], pParams->iStrideA, kiHeight); | |
| 626 | + | |
| 627 | + iCurCost = CALC_COST(pMeRefine->pQuarPixTmp,pParams->iLms[0]); | |
| 628 | + if (iCurCost < pParams->iBestCost) | |
| 629 | + { | |
| 630 | + pParams->iBestQuarPix = ME_QUAR_PIXEL_TOP; | |
| 631 | + SWITCH_BEST_TMP_BUF(pMeRefine->pQuarPixBest,pMeRefine->pQuarPixTmp); | |
| 632 | + } | |
| 633 | + //=========================(0, 1)=======================// | |
| 634 | + pSampleAvg[kiAvgIndex](pMeRefine->pQuarPixTmp, ME_REFINE_BUF_STRIDE, pParams->pSrcA[1], | |
| 635 | + ME_REFINE_BUF_STRIDE,pParams->pSrcB[1], pParams->iStrideA, kiHeight); | |
| 636 | + iCurCost = CALC_COST(pMeRefine->pQuarPixTmp,pParams->iLms[1]); | |
| 637 | + if (iCurCost < pParams->iBestCost) | |
| 638 | + { | |
| 639 | + pParams->iBestQuarPix = ME_QUAR_PIXEL_BOTTOM; | |
| 640 | + SWITCH_BEST_TMP_BUF(pMeRefine->pQuarPixBest,pMeRefine->pQuarPixTmp); | |
| 641 | + } | |
| 642 | + //==========================(-1, 0)=========================// | |
| 643 | + pSampleAvg[kiAvgIndex](pMeRefine->pQuarPixTmp, ME_REFINE_BUF_STRIDE,pParams->pSrcA[2], | |
| 644 | + ME_REFINE_BUF_STRIDE,pParams->pSrcB[2], pParams->iStrideB, kiHeight); | |
| 645 | + iCurCost = CALC_COST(pMeRefine->pQuarPixTmp,pParams->iLms[2]); | |
| 646 | + if (iCurCost < pParams->iBestCost) | |
| 647 | + { | |
| 648 | + pParams->iBestQuarPix = ME_QUAR_PIXEL_LEFT; | |
| 649 | + SWITCH_BEST_TMP_BUF(pMeRefine->pQuarPixBest,pMeRefine->pQuarPixTmp); | |
| 650 | + } | |
| 651 | + //==========================(1, 0)=========================// | |
| 652 | + pSampleAvg[kiAvgIndex](pMeRefine->pQuarPixTmp, ME_REFINE_BUF_STRIDE,pParams->pSrcA[3], | |
| 653 | + ME_REFINE_BUF_STRIDE, pParams->pSrcB[3], pParams->iStrideB, kiHeight); | |
| 654 | + | |
| 655 | + iCurCost = CALC_COST(pMeRefine->pQuarPixTmp,pParams->iLms[3]); | |
| 656 | + if (iCurCost < pParams->iBestCost) | |
| 657 | + { | |
| 658 | + pParams->iBestQuarPix = ME_QUAR_PIXEL_RIGHT; | |
| 659 | + SWITCH_BEST_TMP_BUF(pMeRefine->pQuarPixBest,pMeRefine->pQuarPixTmp); | |
| 660 | + } | |
| 661 | +} | |
| 662 | + | |
| 663 | +void MeRefineFracPixel(sWelsEncCtx* pEncCtx, uint8_t* pMemPredInterMb, SWelsME* pMe, | |
| 664 | + SMeRefinePointer* pMeRefine, int32_t iWidth, int32_t iHeight) | |
| 665 | +{ | |
| 666 | + SWelsFuncPtrList *pFunc= pEncCtx->pFuncList; | |
| 667 | + int16_t iMvx = pMe->sMv.iMvX; | |
| 668 | + int16_t iMvy = pMe->sMv.iMvY; | |
| 669 | + | |
| 670 | + int16_t iHalfMvx = iMvx; | |
| 671 | + int16_t iHalfMvy = iMvy; | |
| 672 | + const int32_t kiStrideEnc = pEncCtx->pCurDqLayer->iEncStride[0]; | |
| 673 | + const int32_t kiStrideRef = pEncCtx->pCurDqLayer->pRefPic->iLineSize[0]; | |
| 674 | + | |
| 675 | + uint8_t* pEncData = pMe->pEncMb; | |
| 676 | + uint8_t* pRef = pMe->pRefMb;//091010 | |
| 677 | + | |
| 678 | + int32_t iBestQuarPix = ME_NO_BEST_QUAR_PIXEL; | |
| 679 | + | |
| 680 | + SQuarRefineParams sParams; | |
| 681 | + static int32_t iMvQuarAddX[10] = {0,0,-1,1,0,0,0,-1,1,0}; | |
| 682 | + int32_t *pMvQuarAddY = iMvQuarAddX + 3; | |
| 683 | + uint8_t* pBestPredInter = pRef; | |
| 684 | + int32_t iInterBlk4Stride = ME_REFINE_BUF_STRIDE; | |
| 685 | + | |
| 686 | + int32_t iBestCost; | |
| 687 | + int32_t iCurCost; | |
| 688 | + int32_t iBestHalfPix; | |
| 689 | + | |
| 690 | + if ((pFunc->sSampleDealingFuncs.pfMeCost == pFunc->sSampleDealingFuncs.pfSampleSatd) && (pFunc->sSampleDealingFuncs.pfMdCost == pFunc->sSampleDealingFuncs.pfSampleSatd)) | |
| 691 | + { | |
| 692 | + iBestCost = pMe->uSadPredISatd.uiSatd + COST_MVD(pMe->pMvdCost, iMvx - pMe->sMvp.iMvX, iMvy - pMe->sMvp.iMvY); | |
| 693 | + } | |
| 694 | + else | |
| 695 | + { | |
| 696 | + iBestCost = pFunc->sSampleDealingFuncs.pfMeCost[pMe->uiPixel]( pEncData, kiStrideEnc, pRef, kiStrideRef ) + | |
| 697 | + COST_MVD(pMe->pMvdCost, iMvx - pMe->sMvp.iMvX, iMvy - pMe->sMvp.iMvY); | |
| 698 | + } | |
| 699 | + | |
| 700 | + iBestHalfPix = REFINE_ME_NO_BEST_HALF_PIXEL; | |
| 701 | + | |
| 702 | + pFunc->sMcFuncs.pfLumaHalfpelVer( pRef-kiStrideRef, kiStrideRef, pMeRefine->pHalfPixV, ME_REFINE_BUF_STRIDE, iWidth, iHeight+1 ); | |
| 703 | + | |
| 704 | + //step 1: get [iWidth][iHeight+1] half pixel from vertical filter | |
| 705 | + //===========================(0, -2)==============================// | |
| 706 | + iCurCost = pFunc->sSampleDealingFuncs.pfMeCost[pMe->uiPixel](pEncData, kiStrideEnc, pMeRefine->pHalfPixV, ME_REFINE_BUF_STRIDE) + | |
| 707 | + COST_MVD( pMe->pMvdCost, iMvx - pMe->sMvp.iMvX, iMvy - 2 - pMe->sMvp.iMvY ); | |
| 708 | + if(iCurCost < iBestCost) | |
| 709 | + { | |
| 710 | + iBestCost = iCurCost; | |
| 711 | + iBestHalfPix = REFINE_ME_HALF_PIXEL_TOP; | |
| 712 | + pBestPredInter = pMeRefine->pHalfPixV; | |
| 713 | + } | |
| 714 | + //===========================(0, 2)==============================// | |
| 715 | + iCurCost = pFunc->sSampleDealingFuncs.pfMeCost[pMe->uiPixel](pEncData, kiStrideEnc, pMeRefine->pHalfPixV+ME_REFINE_BUF_STRIDE, ME_REFINE_BUF_STRIDE) + | |
| 716 | + COST_MVD( pMe->pMvdCost, iMvx - pMe->sMvp.iMvX, iMvy + 2 - pMe->sMvp.iMvY ); | |
| 717 | + if(iCurCost < iBestCost) | |
| 718 | + { | |
| 719 | + iBestCost = iCurCost; | |
| 720 | + iBestHalfPix = REFINE_ME_HALF_PIXEL_BOTTOM; | |
| 721 | + pBestPredInter = pMeRefine->pHalfPixV+ME_REFINE_BUF_STRIDE; | |
| 722 | + } | |
| 723 | + pFunc->sMcFuncs.pfLumaHalfpelHor( pRef-1, kiStrideRef, pMeRefine->pHalfPixH, ME_REFINE_BUF_STRIDE, iWidth+1, iHeight ); | |
| 724 | + //step 2: get [iWidth][iHeight+1] half pixel from horizon filter | |
| 725 | + | |
| 726 | + //===========================(-2, 0)==============================// | |
| 727 | + iCurCost = pFunc->sSampleDealingFuncs.pfMeCost[pMe->uiPixel](pEncData, kiStrideEnc, pMeRefine->pHalfPixH, ME_REFINE_BUF_STRIDE) + | |
| 728 | + COST_MVD( pMe->pMvdCost, iMvx - 2 - pMe->sMvp.iMvX, iMvy - pMe->sMvp.iMvY ); | |
| 729 | + if(iCurCost < iBestCost) | |
| 730 | + { | |
| 731 | + iBestCost = iCurCost; | |
| 732 | + iBestHalfPix = REFINE_ME_HALF_PIXEL_LEFT; | |
| 733 | + pBestPredInter = pMeRefine->pHalfPixH; | |
| 734 | + } | |
| 735 | + //===========================(2, 0)===============================// | |
| 736 | + iCurCost = pFunc->sSampleDealingFuncs.pfMeCost[pMe->uiPixel](pEncData, kiStrideEnc, pMeRefine->pHalfPixH+1, ME_REFINE_BUF_STRIDE) + | |
| 737 | + COST_MVD( pMe->pMvdCost, iMvx + 2 - pMe->sMvp.iMvX, iMvy - pMe->sMvp.iMvY ); | |
| 738 | + if(iCurCost < iBestCost) | |
| 739 | + { | |
| 740 | + iBestCost = iCurCost; | |
| 741 | + iBestHalfPix = REFINE_ME_HALF_PIXEL_RIGHT; | |
| 742 | + pBestPredInter = pMeRefine->pHalfPixH+1; | |
| 743 | + } | |
| 744 | + | |
| 745 | + sParams.iBestCost = iBestCost; | |
| 746 | + sParams.iBestHalfPix = iBestHalfPix; | |
| 747 | + sParams.pRef = pRef; | |
| 748 | + sParams.iBestQuarPix = ME_NO_BEST_QUAR_PIXEL; | |
| 749 | + | |
| 750 | + //step 5: if no best half-pixel prediction, try quarter pixel prediction | |
| 751 | + // if yes, must get [X+1][X+1] half-pixel from (2, 2) horizontal and vertical filter | |
| 752 | + if (REFINE_ME_NO_BEST_HALF_PIXEL == iBestHalfPix) | |
| 753 | + { | |
| 754 | + sParams.iStrideA = kiStrideRef; | |
| 755 | + sParams.iStrideB = kiStrideRef; | |
| 756 | + sParams.pSrcA[0] = pMeRefine->pHalfPixV; | |
| 757 | + sParams.pSrcA[1] = pMeRefine->pHalfPixV+ME_REFINE_BUF_STRIDE; | |
| 758 | + sParams.pSrcA[2] = pMeRefine->pHalfPixH; | |
| 759 | + sParams.pSrcA[3] = pMeRefine->pHalfPixH+1; | |
| 760 | + | |
| 761 | + sParams.pSrcB[0] = sParams.pSrcB[1] = sParams.pSrcB[2] = sParams.pSrcB[3] = pRef; | |
| 762 | + | |
| 763 | + sParams.iLms[0] = COST_MVD( pMe->pMvdCost, iHalfMvx - pMe->sMvp.iMvX, iHalfMvy - 1 - pMe->sMvp.iMvY ); | |
| 764 | + sParams.iLms[1] = COST_MVD( pMe->pMvdCost, iHalfMvx - pMe->sMvp.iMvX, iHalfMvy + 1 - pMe->sMvp.iMvY ); | |
| 765 | + sParams.iLms[2] = COST_MVD( pMe->pMvdCost, iHalfMvx - 1 - pMe->sMvp.iMvX, iHalfMvy - pMe->sMvp.iMvY ); | |
| 766 | + sParams.iLms[3] = COST_MVD( pMe->pMvdCost, iHalfMvx + 1 - pMe->sMvp.iMvX, iHalfMvy - pMe->sMvp.iMvY ); | |
| 767 | + } | |
| 768 | + else //must get [X+1][X+1] half-pixel from (2, 2) horizontal and vertical filter | |
| 769 | + { | |
| 770 | + switch(iBestHalfPix) | |
| 771 | + { | |
| 772 | + case REFINE_ME_HALF_PIXEL_LEFT: | |
| 773 | + { | |
| 774 | + pMeRefine->pHalfPixHV = pMeRefine->pHalfPixV;//reuse pBuffer, here only h&hv | |
| 775 | + pFunc->sMcFuncs.pfLumaHalfpelCen( pRef-1-kiStrideRef, kiStrideRef, pMeRefine->pHalfPixHV,ME_REFINE_BUF_STRIDE,iWidth+1, iHeight+1 ); | |
| 776 | + | |
| 777 | + iHalfMvx -= 2; | |
| 778 | + sParams.iStrideA = ME_REFINE_BUF_STRIDE; | |
| 779 | + sParams.iStrideB = kiStrideRef; | |
| 780 | + sParams.pSrcA[0] = pMeRefine->pHalfPixH; | |
| 781 | + sParams.pSrcA[3] = sParams.pSrcA[2] = sParams.pSrcA[1] = sParams.pSrcA[0]; | |
| 782 | + sParams.pSrcB[0] = pMeRefine->pHalfPixHV; | |
| 783 | + sParams.pSrcB[1] = pMeRefine->pHalfPixHV+ME_REFINE_BUF_STRIDE; | |
| 784 | + sParams.pSrcB[2] = pRef - 1; | |
| 785 | + sParams.pSrcB[3] = pRef; | |
| 786 | + | |
| 787 | + }break; | |
| 788 | + case REFINE_ME_HALF_PIXEL_RIGHT: | |
| 789 | + { | |
| 790 | + pMeRefine->pHalfPixHV = pMeRefine->pHalfPixV;//reuse pBuffer, here only h&hv | |
| 791 | + pFunc->sMcFuncs.pfLumaHalfpelCen( pRef-1-kiStrideRef, kiStrideRef, pMeRefine->pHalfPixHV,ME_REFINE_BUF_STRIDE,iWidth+1, iHeight+1 ); | |
| 792 | + iHalfMvx += 2; | |
| 793 | + sParams.iStrideA = ME_REFINE_BUF_STRIDE; | |
| 794 | + sParams.iStrideB = kiStrideRef; | |
| 795 | + sParams.pSrcA[0] = pMeRefine->pHalfPixH+1; | |
| 796 | + sParams.pSrcA[3] = sParams.pSrcA[2] = sParams.pSrcA[1] = sParams.pSrcA[0]; | |
| 797 | + sParams.pSrcB[0] = pMeRefine->pHalfPixHV+1; | |
| 798 | + sParams.pSrcB[1] = pMeRefine->pHalfPixHV+1+ ME_REFINE_BUF_STRIDE; | |
| 799 | + sParams.pSrcB[2] = pRef; | |
| 800 | + sParams.pSrcB[3] = pRef + 1; | |
| 801 | + }break; | |
| 802 | + case REFINE_ME_HALF_PIXEL_TOP: | |
| 803 | + { | |
| 804 | + pMeRefine->pHalfPixHV = pMeRefine->pHalfPixH;//reuse pBuffer, here only v&hv | |
| 805 | + pFunc->sMcFuncs.pfLumaHalfpelCen( pRef-1-kiStrideRef, kiStrideRef, pMeRefine->pHalfPixHV,ME_REFINE_BUF_STRIDE,iWidth+1, iHeight+1 ); | |
| 806 | + | |
| 807 | + iHalfMvy -= 2; | |
| 808 | + sParams.iStrideA = kiStrideRef; | |
| 809 | + sParams.iStrideB = ME_REFINE_BUF_STRIDE; | |
| 810 | + sParams.pSrcA[0] = pMeRefine->pHalfPixV; | |
| 811 | + sParams.pSrcA[3] = sParams.pSrcA[2] = sParams.pSrcA[1] = sParams.pSrcA[0]; | |
| 812 | + sParams.pSrcB[0] = pRef - kiStrideRef; | |
| 813 | + sParams.pSrcB[1] = pRef; | |
| 814 | + sParams.pSrcB[2] = pMeRefine->pHalfPixHV; | |
| 815 | + sParams.pSrcB[3] = pMeRefine->pHalfPixHV+1; | |
| 816 | + }break; | |
| 817 | + case REFINE_ME_HALF_PIXEL_BOTTOM: | |
| 818 | + { | |
| 819 | + pMeRefine->pHalfPixHV = pMeRefine->pHalfPixH;//reuse pBuffer, here only v&hv | |
| 820 | + pFunc->sMcFuncs.pfLumaHalfpelCen( pRef-1-kiStrideRef, kiStrideRef, pMeRefine->pHalfPixHV,ME_REFINE_BUF_STRIDE,iWidth+1, iHeight+1 ); | |
| 821 | + iHalfMvy += 2; | |
| 822 | + sParams.iStrideA = kiStrideRef; | |
| 823 | + sParams.iStrideB = ME_REFINE_BUF_STRIDE; | |
| 824 | + sParams.pSrcA[0] = pMeRefine->pHalfPixV + ME_REFINE_BUF_STRIDE; | |
| 825 | + sParams.pSrcA[3] = sParams.pSrcA[2] = sParams.pSrcA[1] = sParams.pSrcA[0]; | |
| 826 | + sParams.pSrcB[0] = pRef; | |
| 827 | + sParams.pSrcB[1] = pRef + kiStrideRef; | |
| 828 | + sParams.pSrcB[2] = pMeRefine->pHalfPixHV + ME_REFINE_BUF_STRIDE; | |
| 829 | + sParams.pSrcB[3] = pMeRefine->pHalfPixHV + ME_REFINE_BUF_STRIDE + 1; | |
| 830 | + }break; | |
| 831 | + default: | |
| 832 | + break; | |
| 833 | + } | |
| 834 | + sParams.iLms[0] = COST_MVD( pMe->pMvdCost, iHalfMvx - pMe->sMvp.iMvX, iHalfMvy - 1 - pMe->sMvp.iMvY ); | |
| 835 | + sParams.iLms[1] = COST_MVD( pMe->pMvdCost, iHalfMvx - pMe->sMvp.iMvX, iHalfMvy + 1 - pMe->sMvp.iMvY ); | |
| 836 | + sParams.iLms[2] = COST_MVD( pMe->pMvdCost, iHalfMvx - 1 - pMe->sMvp.iMvX, iHalfMvy - pMe->sMvp.iMvY ); | |
| 837 | + sParams.iLms[3] = COST_MVD( pMe->pMvdCost, iHalfMvx + 1 - pMe->sMvp.iMvX, iHalfMvy - pMe->sMvp.iMvY ); | |
| 838 | + } | |
| 839 | + MeRefineQuarPixel(pFunc, pMe, pMeRefine, iWidth, iHeight, &sParams, kiStrideEnc); | |
| 840 | + | |
| 841 | + if(iBestCost > sParams.iBestCost) | |
| 842 | + { | |
| 843 | + pBestPredInter = pMeRefine->pQuarPixBest; | |
| 844 | + iBestCost = sParams.iBestCost; | |
| 845 | + } | |
| 846 | + iBestQuarPix = sParams.iBestQuarPix; | |
| 847 | + | |
| 848 | + //update final best MV | |
| 849 | + pMe->sMv.iMvX = iHalfMvx + iMvQuarAddX[iBestQuarPix]; | |
| 850 | + pMe->sMv.iMvY = iHalfMvy + pMvQuarAddY[iBestQuarPix]; | |
| 851 | + pMe->uiSatdCost = iBestCost; | |
| 852 | + | |
| 853 | + //No half or quarter pixel best, so do MC with integer pixel MV | |
| 854 | + if ( iBestHalfPix+iBestQuarPix == NO_BEST_FRAC_PIX ) | |
| 855 | + { | |
| 856 | + pBestPredInter = pRef; | |
| 857 | + iInterBlk4Stride = kiStrideRef; | |
| 858 | + } | |
| 859 | + if ( MB_WIDTH_LUMA == iWidth && MB_HEIGHT_LUMA == iHeight ) //P16x16 | |
| 860 | + { | |
| 861 | + pFunc->pfCopy16x16NotAligned( pMemPredInterMb, MB_WIDTH_LUMA, pBestPredInter, iInterBlk4Stride ); // dst can be align with 16 bytes, but not sure at pSrc, 12/29/2011 | |
| 862 | + } | |
| 863 | + else if ( MB_WIDTH_LUMA == iWidth && MB_HEIGHT_CHROMA == iHeight ) //P16x8 | |
| 864 | + { | |
| 865 | + pFunc->pfCopy16x8NotAligned( pMemPredInterMb, MB_WIDTH_LUMA, pBestPredInter, iInterBlk4Stride ); // dst can be align with 16 bytes, but not sure at pSrc, 12/29/2011 | |
| 866 | + } | |
| 867 | + else if ( MB_WIDTH_CHROMA == iWidth && MB_HEIGHT_LUMA == iHeight ) //P8x16 | |
| 868 | + { | |
| 869 | + pFunc->pfCopy8x16Aligned( pMemPredInterMb, MB_WIDTH_LUMA, pBestPredInter, iInterBlk4Stride ); | |
| 870 | + } | |
| 871 | + else //P8x8 | |
| 872 | + { | |
| 873 | + pFunc->pfCopy8x8Aligned( pMemPredInterMb, MB_WIDTH_LUMA, pBestPredInter, iInterBlk4Stride ); | |
| 874 | + } | |
| 875 | +} | |
| 876 | + | |
| 877 | +void InitBlkStrideWithRef(int32_t* pBlkStride, const int32_t kiStrideRef) | |
| 878 | +{ | |
| 879 | + static const uint8_t kuiStrideX[16] = | |
| 880 | + { | |
| 881 | + 0, 4 , 0, 4 , | |
| 882 | + 8, 12, 8, 12, | |
| 883 | + 0, 4 , 0, 4 , | |
| 884 | + 8, 12, 8, 12 | |
| 885 | + }; | |
| 886 | + static const uint8_t kuiStrideY[16] = | |
| 887 | + { | |
| 888 | + 0, 0, 4 , 4 , | |
| 889 | + 0, 0, 4 , 4 , | |
| 890 | + 8, 8, 12, 12, | |
| 891 | + 8, 8, 12, 12 | |
| 892 | + }; | |
| 893 | + int32_t i; | |
| 894 | + | |
| 895 | + for (i = 0; i < 16; i+=4) | |
| 896 | + { | |
| 897 | + pBlkStride[i ] = kuiStrideX[i ] + kuiStrideY[i ] * kiStrideRef; | |
| 898 | + pBlkStride[i+1] = kuiStrideX[i+1] + kuiStrideY[i+1] * kiStrideRef; | |
| 899 | + pBlkStride[i+2] = kuiStrideX[i+2] + kuiStrideY[i+2] * kiStrideRef; | |
| 900 | + pBlkStride[i+3] = kuiStrideX[i+3] + kuiStrideY[i+3] * kiStrideRef; | |
| 901 | + } | |
| 902 | +} | |
| 903 | + | |
| 904 | +/* | |
| 905 | + * iMvdSz = (648*2+1) or (972*2+1); | |
| 906 | + */ | |
| 907 | +void MvdCostInit( uint16_t* pMvdCostInter, const int32_t kiMvdSz ) | |
| 908 | +{ | |
| 909 | + const int32_t kiSz = kiMvdSz >> 1; | |
| 910 | + uint16_t *pNegMvd = pMvdCostInter; | |
| 911 | + uint16_t *pPosMvd = pMvdCostInter+kiSz+1; | |
| 912 | + const int32_t *kpQpLambda= &g_kiQpCostTable[0]; | |
| 913 | + int32_t i,j; | |
| 914 | + | |
| 915 | + for( i = 0; i < 52; ++ i ) | |
| 916 | + { | |
| 917 | + const uint16_t kiLambda = kpQpLambda[i]; | |
| 918 | + int32_t iNegSe = -kiSz; | |
| 919 | + int32_t iPosSe = 1; | |
| 920 | + | |
| 921 | + for (j = 0; j < kiSz; j += 4) | |
| 922 | + { | |
| 923 | + *pNegMvd++ = kiLambda * BsSizeSE(iNegSe++); | |
| 924 | + *pNegMvd++ = kiLambda * BsSizeSE(iNegSe++); | |
| 925 | + *pNegMvd++ = kiLambda * BsSizeSE(iNegSe++); | |
| 926 | + *pNegMvd++ = kiLambda * BsSizeSE(iNegSe++); | |
| 927 | + | |
| 928 | + *pPosMvd++ = kiLambda * BsSizeSE(iPosSe++); | |
| 929 | + *pPosMvd++ = kiLambda * BsSizeSE(iPosSe++); | |
| 930 | + *pPosMvd++ = kiLambda * BsSizeSE(iPosSe++); | |
| 931 | + *pPosMvd++ = kiLambda * BsSizeSE(iPosSe++); | |
| 932 | + } | |
| 933 | + *pNegMvd = kiLambda; | |
| 934 | + pNegMvd += kiSz+1; | |
| 935 | + pPosMvd += kiSz+1; | |
| 936 | + } | |
| 937 | +} | |
| 938 | + | |
| 939 | +void PredictSad( int8_t* pRefIndexCache, int32_t* pSadCostCache, int32_t uiRef, int32_t * pSadPred ) | |
| 940 | +{ | |
| 941 | + const int32_t kiRefB = pRefIndexCache[1];//top g_uiCache12_8x8RefIdx[0] - 4 | |
| 942 | + int32_t iRefC = pRefIndexCache[5];//top-right g_uiCache12_8x8RefIdx[0] - 2 | |
| 943 | + const int32_t kiRefA = pRefIndexCache[6];//left g_uiCache12_8x8RefIdx[0] - 1 | |
| 944 | + const int32_t kiSadB = pSadCostCache[1]; | |
| 945 | + int32_t iSadC = pSadCostCache[2]; | |
| 946 | + const int32_t kiSadA = pSadCostCache[3]; | |
| 947 | + | |
| 948 | + int32_t iCount; | |
| 949 | + | |
| 950 | + if( iRefC == REF_NOT_AVAIL ) | |
| 951 | + { | |
| 952 | + iRefC = pRefIndexCache[0];//top-left g_uiCache12_8x8RefIdx[0] - 4 - 1 | |
| 953 | + iSadC = pSadCostCache[0]; | |
| 954 | + } | |
| 955 | + | |
| 956 | + if( kiRefB == REF_NOT_AVAIL && iRefC == REF_NOT_AVAIL && kiRefA != REF_NOT_AVAIL ) | |
| 957 | + { | |
| 958 | + * pSadPred = kiSadA; | |
| 959 | + } | |
| 960 | + else | |
| 961 | + { | |
| 962 | + iCount = (uiRef == kiRefA)<<MB_LEFT_BIT; | |
| 963 | + iCount |= (uiRef == kiRefB)<<MB_TOP_BIT; | |
| 964 | + iCount |= (uiRef == iRefC)<<MB_TOPRIGHT_BIT; | |
| 965 | + switch(iCount) | |
| 966 | + { | |
| 967 | + case LEFT_MB_POS:// A | |
| 968 | + *pSadPred = kiSadA; | |
| 969 | + break; | |
| 970 | + case TOP_MB_POS:// B | |
| 971 | + *pSadPred = kiSadB; | |
| 972 | + break; | |
| 973 | + case TOPRIGHT_MB_POS:// C or D | |
| 974 | + *pSadPred = iSadC; | |
| 975 | + break; | |
| 976 | + default: | |
| 977 | + *pSadPred = WELS_MEDIAN( kiSadA, kiSadB, iSadC ); | |
| 978 | + break; | |
| 979 | + } | |
| 980 | + } | |
| 981 | + | |
| 982 | +#define REPLACE_SAD_MULTIPLY(x) ((x) - (x>>3) + (x >>5)) // it's 0.90625, very close with 0.9 | |
| 983 | + iCount = (*pSadPred)<<6; // here *64 will not overflow. SAD range 0~ 255*256(max 2^16), int32_t is enough | |
| 984 | + *pSadPred = (REPLACE_SAD_MULTIPLY(iCount) + 32)>>6; | |
| 985 | +#undef REPLACE_SAD_MULTIPLY | |
| 986 | +} | |
| 987 | + | |
| 988 | + | |
| 989 | +void PredictSadSkip( int8_t* pRefIndexCache, bool_t* pMbSkipCache, int32_t* pSadCostCache, int32_t uiRef, int32_t * iSadPredSkip ) | |
| 990 | +{ | |
| 991 | + const int32_t kiRefB = pRefIndexCache[1];//top g_uiCache12_8x8RefIdx[0] - 4 | |
| 992 | + int32_t iRefC = pRefIndexCache[5];//top-right g_uiCache12_8x8RefIdx[0] - 2 | |
| 993 | + const int32_t kiRefA = pRefIndexCache[6];//left g_uiCache12_8x8RefIdx[0] - 1 | |
| 994 | + const int32_t kiSadB = (pMbSkipCache[1]==1 ? pSadCostCache[1] : 0); | |
| 995 | + int32_t iSadC = (pMbSkipCache[2]==1 ? pSadCostCache[2] : 0); | |
| 996 | + const int32_t kiSadA = (pMbSkipCache[3]==1 ? pSadCostCache[3] : 0); | |
| 997 | + int32_t iRefSkip = pMbSkipCache[2]; | |
| 998 | + | |
| 999 | + int32_t iCount = 0; | |
| 1000 | + | |
| 1001 | + if( iRefC == REF_NOT_AVAIL ) | |
| 1002 | + { | |
| 1003 | + iRefC = pRefIndexCache[0];//top-left g_uiCache12_8x8RefIdx[0] - 4 - 1 | |
| 1004 | + iSadC = (pMbSkipCache[0]==1 ? pSadCostCache[0] : 0); | |
| 1005 | + iRefSkip = pMbSkipCache[0]; | |
| 1006 | + } | |
| 1007 | + | |
| 1008 | + if( kiRefB == REF_NOT_AVAIL && iRefC == REF_NOT_AVAIL && kiRefA != REF_NOT_AVAIL ) | |
| 1009 | + { | |
| 1010 | + * iSadPredSkip = kiSadA; | |
| 1011 | + } | |
| 1012 | + else | |
| 1013 | + { | |
| 1014 | + iCount = ((uiRef == kiRefA) && (pMbSkipCache[3]==1))<<MB_LEFT_BIT; | |
| 1015 | + iCount |= ((uiRef == kiRefB) && (pMbSkipCache[1]==1))<<MB_TOP_BIT; | |
| 1016 | + iCount |= ((uiRef == iRefC) && (iRefSkip==1))<<MB_TOPRIGHT_BIT; | |
| 1017 | + switch(iCount) | |
| 1018 | + { | |
| 1019 | + case LEFT_MB_POS:// A | |
| 1020 | + *iSadPredSkip = kiSadA; | |
| 1021 | + break; | |
| 1022 | + case TOP_MB_POS:// B | |
| 1023 | + *iSadPredSkip = kiSadB; | |
| 1024 | + break; | |
| 1025 | + case TOPRIGHT_MB_POS:// C or D | |
| 1026 | + *iSadPredSkip = iSadC; | |
| 1027 | + break; | |
| 1028 | + default: | |
| 1029 | + *iSadPredSkip = WELS_MEDIAN( kiSadA, kiSadB, iSadC ); | |
| 1030 | + break; | |
| 1031 | + } | |
| 1032 | + } | |
| 1033 | +} | |
| 1034 | +} | |