Showing the changes to codec/decoder/core/src/decode_slice.cpp (1 of 9 files). Show all
Unified · Split
| @@ -1525,6 +1525,8 @@ int32_t WelsDecodeSlice (PWelsDecoderContext pCtx, bool bFirstSliceInLayer, PNal · 1524 unmodified lines | |||
| 1525 | } else { | 1525 | } else { |
| 1526 | if (P_SLICE == pSliceHeader->eSliceType) { | 1526 | if (P_SLICE == pSliceHeader->eSliceType) { |
| 1527 | pDecMbFunc = WelsDecodeMbCavlcPSlice; | 1527 | pDecMbFunc = WelsDecodeMbCavlcPSlice; |
| 1528 | } else if (B_SLICE == pSliceHeader->eSliceType) { | ||
| 1529 | pDecMbFunc = WelsDecodeMbCavlcBSlice; | ||
| 1528 | } else { //I_SLICE | 1530 | } else { //I_SLICE |
| 1529 | pDecMbFunc = WelsDecodeMbCavlcISlice; | 1531 | pDecMbFunc = WelsDecodeMbCavlcISlice; |
| 1530 | } | 1532 | } |
| @@ -2342,6 +2344,448 @@ int32_t WelsDecodeMbCavlcPSlice (PWelsDecoderContext pCtx, PNalUnit pNalCur, uin · 811 unmodified lines | |||
| 2342 | return ERR_NONE; | 2344 | return ERR_NONE; |
| 2343 | } | 2345 | } |
| 2344 | 2346 | ||
| 2347 | int32_t WelsDecodeMbCavlcBSlice (PWelsDecoderContext pCtx, PNalUnit pNalCur, uint32_t& uiEosFlag) { | ||
| 2348 | PDqLayer pCurLayer = pCtx->pCurDqLayer; | ||
| 2349 | PBitStringAux pBs = pCurLayer->pBitStringAux; | ||
| 2350 | PSlice pSlice = &pCurLayer->sLayerInfo.sSliceInLayer; | ||
| 2351 | PSliceHeader pSliceHeader = &pSlice->sSliceHeaderExt.sSliceHeader; | ||
| 2352 | PPicture* ppRefPicL0 = pCtx->sRefPic.pRefList[LIST_0]; | ||
| 2353 | PPicture* ppRefPicL1 = pCtx->sRefPic.pRefList[LIST_1]; | ||
| 2354 | intX_t iUsedBits; | ||
| 2355 | const int32_t iMbXy = pCurLayer->iMbXyIndex; | ||
| 2356 | int8_t* pNzc = pCurLayer->pNzc[iMbXy]; | ||
| 2357 | int32_t iBaseModeFlag, i; | ||
| 2358 | int32_t iRet = 0; //should have the return value to indicate decoding error or not, It's NECESSARY--2010.4.15 | ||
| 2359 | uint32_t uiCode; | ||
| 2360 | |||
| 2361 | pCurLayer->pNoSubMbPartSizeLessThan8x8Flag[iMbXy] = true; | ||
| 2362 | pCurLayer->pTransformSize8x8Flag[iMbXy] = false; | ||
| 2363 | |||
| 2364 | if (-1 == pSlice->iMbSkipRun) { | ||
| 2365 | WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //mb_skip_run | ||
| 2366 | pSlice->iMbSkipRun = uiCode; | ||
| 2367 | if (-1 == pSlice->iMbSkipRun) { | ||
| 2368 | return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_INVALID_MB_SKIP_RUN); | ||
| 2369 | } | ||
| 2370 | } | ||
| 2371 | if (pSlice->iMbSkipRun--) { | ||
| 2372 | int16_t iMv[LIST_A][2] = { { 0, 0 }, { 0, 0 } }; | ||
| 2373 | int8_t ref[LIST_A] = { 0 }; | ||
| 2374 | |||
| 2375 | pCurLayer->pMbType[iMbXy] = MB_TYPE_SKIP | MB_TYPE_DIRECT; | ||
| 2376 | ST32A4 (&pNzc[0], 0); | ||
| 2377 | ST32A4 (&pNzc[4], 0); | ||
| 2378 | ST32A4 (&pNzc[8], 0); | ||
| 2379 | ST32A4 (&pNzc[12], 0); | ||
| 2380 | ST32A4 (&pNzc[16], 0); | ||
| 2381 | ST32A4 (&pNzc[20], 0); | ||
| 2382 | |||
| 2383 | pCurLayer->pInterPredictionDoneFlag[iMbXy] = 0; | ||
| 2384 | memset (pCurLayer->pRefIndex[LIST_0][iMbXy], 0, sizeof (int8_t) * 16); | ||
| 2385 | memset (pCurLayer->pRefIndex[LIST_1][iMbXy], 0, sizeof (int8_t) * 16); | ||
| 2386 | pCtx->bMbRefConcealed = pCtx->bRPLRError || pCtx->bMbRefConcealed || ! (ppRefPicL0[0] && ppRefPicL0[0]->bIsComplete) | ||
| 2387 | || ! (ppRefPicL1[0] && ppRefPicL1[0]->bIsComplete); | ||
| 2388 | //predict iMv | ||
| 2389 | if (pSliceHeader->iDirectSpatialMvPredFlag) { | ||
| 2390 | |||
| 2391 | //predict direct spatial mv | ||
| 2392 | SubMbType subMbType; | ||
| 2393 | int32_t ret = PredMvBDirectSpatial (pCtx, iMv, ref, subMbType); | ||
| 2394 | if (ret != ERR_NONE) { | ||
| 2395 | return ret; | ||
| 2396 | } | ||
| 2397 | } else { | ||
| 2398 | //temporal direct mode | ||
| 2399 | ComputeColocated (pCtx); | ||
| 2400 | int32_t ret = PredBDirectTemporal (pCtx, iMv, ref); | ||
| 2401 | if (ret != ERR_NONE) { | ||
| 2402 | return ret; | ||
| 2403 | } | ||
| 2404 | } | ||
| 2405 | |||
| 2406 | //if (!pSlice->sSliceHeaderExt.bDefaultResidualPredFlag) { | ||
| 2407 | // memset (pCurLayer->pScaledTCoeff[iMbXy], 0, 384 * sizeof (int16_t)); | ||
| 2408 | //} | ||
| 2409 | |||
| 2410 | //reset rS | ||
| 2411 | if (!pSlice->sSliceHeaderExt.bDefaultResidualPredFlag || | ||
| 2412 | (pNalCur->sNalHeaderExt.uiQualityId == 0 && pNalCur->sNalHeaderExt.uiDependencyId == 0)) { | ||
| 2413 | pCurLayer->pLumaQp[iMbXy] = pSlice->iLastMbQp; | ||
| 2414 | for (i = 0; i < 2; i++) { | ||
| 2415 | pCurLayer->pChromaQp[iMbXy][i] = g_kuiChromaQpTable[WELS_CLIP3 (pCurLayer->pLumaQp[iMbXy] + | ||
| 2416 | pSliceHeader->pPps->iChromaQpIndexOffset[i], 0, 51)]; | ||
| 2417 | } | ||
| 2418 | } | ||
| 2419 | |||
| 2420 | pCurLayer->pCbp[iMbXy] = 0; | ||
| 2421 | } else { | ||
| 2422 | if (pSlice->sSliceHeaderExt.bAdaptiveBaseModeFlag == 1) { | ||
| 2423 | WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //base_mode_flag | ||
| 2424 | iBaseModeFlag = uiCode; | ||
| 2425 | } else { | ||
| 2426 | iBaseModeFlag = pSlice->sSliceHeaderExt.bDefaultBaseModeFlag; | ||
| 2427 | } | ||
| 2428 | if (!iBaseModeFlag) { | ||
| 2429 | iRet = WelsActualDecodeMbCavlcBSlice (pCtx); | ||
| 2430 | } else { | ||
| 2431 | WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "iBaseModeFlag (%d) != 0, inter-layer prediction not supported.", | ||
| 2432 | iBaseModeFlag); | ||
| 2433 | return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_UNSUPPORTED_ILP); | ||
| 2434 | } | ||
| 2435 | if (iRet) { //occur error when parsing, MUST STOP decoding | ||
| 2436 | return iRet; | ||
| 2437 | } | ||
| 2438 | } | ||
| 2439 | // check whether there is left bits to read next time in case multiple slices | ||
| 2440 | iUsedBits = ((pBs->pCurBuf - pBs->pStartBuf) << 3) - (16 - pBs->iLeftBits); | ||
| 2441 | // sub 1, for stop bit | ||
| 2442 | if ((iUsedBits == (pBs->iBits - 1)) && (0 >= pCurLayer->sLayerInfo.sSliceInLayer.iMbSkipRun)) { // slice boundary | ||
| 2443 | uiEosFlag = 1; | ||
| 2444 | } | ||
| 2445 | if (iUsedBits > (pBs->iBits - | ||
| 2446 | 1)) { //When BS incomplete, as long as find it, SHOULD stop decoding to avoid mosaic or crash. | ||
| 2447 | WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, | ||
| 2448 | "WelsDecodeMbCavlcISlice()::::pBs incomplete, iUsedBits:%" PRId64 " > pBs->iBits:%d, MUST stop decoding.", | ||
| 2449 | (int64_t)iUsedBits, pBs->iBits); | ||
| 2450 | return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_BS_INCOMPLETE); | ||
| 2451 | } | ||
| 2452 | return ERR_NONE; | ||
| 2453 | } | ||
| 2454 | |||
| 2455 | int32_t WelsActualDecodeMbCavlcBSlice (PWelsDecoderContext pCtx) { | ||
| 2456 | SVlcTable* pVlcTable = &pCtx->sVlcTable; | ||
| 2457 | PDqLayer pCurLayer = pCtx->pCurDqLayer; | ||
| 2458 | PBitStringAux pBs = pCurLayer->pBitStringAux; | ||
| 2459 | PSlice pSlice = &pCurLayer->sLayerInfo.sSliceInLayer; | ||
| 2460 | PSliceHeader pSliceHeader = &pSlice->sSliceHeaderExt.sSliceHeader; | ||
| 2461 | |||
| 2462 | int32_t iScanIdxStart = pSlice->sSliceHeaderExt.uiScanIdxStart; | ||
| 2463 | int32_t iScanIdxEnd = pSlice->sSliceHeaderExt.uiScanIdxEnd; | ||
| 2464 | |||
| 2465 | SWelsNeighAvail sNeighAvail; | ||
| 2466 | int32_t iMbX = pCurLayer->iMbX; | ||
| 2467 | int32_t iMbY = pCurLayer->iMbY; | ||
| 2468 | const int32_t iMbXy = pCurLayer->iMbXyIndex; | ||
| 2469 | int8_t* pNzc = pCurLayer->pNzc[iMbXy]; | ||
| 2470 | int32_t i; | ||
| 2471 | int32_t iRet = ERR_NONE; | ||
| 2472 | uint32_t uiMbType = 0, uiCbp = 0, uiCbpL = 0, uiCbpC = 0; | ||
| 2473 | uint32_t uiCode; | ||
| 2474 | int32_t iCode; | ||
| 2475 | int32_t iMbResProperty; | ||
| 2476 | |||
| 2477 | GetNeighborAvailMbType (&sNeighAvail, pCurLayer); | ||
| 2478 | ENFORCE_STACK_ALIGN_1D (uint8_t, pNonZeroCount, 48, 16); | ||
| 2479 | pCurLayer->pInterPredictionDoneFlag[iMbXy] = 0;//2009.10.23 | ||
| 2480 | WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //uiMbType | ||
| 2481 | uiMbType = uiCode; | ||
| 2482 | if (uiMbType < 23) { //inter MB type | ||
| 2483 | int16_t iMotionVector[LIST_A][30][MV_A]; | ||
| 2484 | int8_t iRefIndex[LIST_A][30]; | ||
| 2485 | pCurLayer->pMbType[iMbXy] = g_ksInterBMbTypeInfo[uiMbType].iType; | ||
| 2486 | WelsFillCacheInter (&sNeighAvail, pNonZeroCount, iMotionVector, iRefIndex, pCurLayer); | ||
| 2487 | |||
| 2488 | if ((iRet = ParseInterBInfo (pCtx, iMotionVector, iRefIndex, pBs)) != ERR_NONE) { | ||
| 2489 | return iRet;//abnormal | ||
| 2490 | } | ||
| 2491 | |||
| 2492 | if (pSlice->sSliceHeaderExt.bAdaptiveResidualPredFlag == 1) { | ||
| 2493 | WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //residual_prediction_flag | ||
| 2494 | pCurLayer->pResidualPredFlag[iMbXy] = uiCode; | ||
| 2495 | } else { | ||
| 2496 | pCurLayer->pResidualPredFlag[iMbXy] = pSlice->sSliceHeaderExt.bDefaultResidualPredFlag; | ||
| 2497 | } | ||
| 2498 | |||
| 2499 | if (pCurLayer->pResidualPredFlag[iMbXy] == 0) { | ||
| 2500 | pCurLayer->pInterPredictionDoneFlag[iMbXy] = 0; | ||
| 2501 | } else { | ||
| 2502 | WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "residual_pred_flag = 1 not supported."); | ||
| 2503 | return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_UNSUPPORTED_ILP); | ||
| 2504 | } | ||
| 2505 | } else { //intra MB type | ||
| 2506 | uiMbType -= 23; | ||
| 2507 | if (uiMbType > 25) | ||
| 2508 | return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_INVALID_MB_TYPE); | ||
| 2509 | if (!pCtx->pSps->uiChromaFormatIdc && ((uiMbType >= 5 && uiMbType <= 12) || (uiMbType >= 17 && uiMbType <= 24))) | ||
| 2510 | return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_INVALID_MB_TYPE); | ||
| 2511 | |||
| 2512 | if (25 == uiMbType) { | ||
| 2513 | WelsLog (& (pCtx->sLogCtx), WELS_LOG_DEBUG, "I_PCM mode exists in P slice!"); | ||
| 2514 | int32_t iDecStrideL = pCurLayer->pDec->iLinesize[0]; | ||
| 2515 | int32_t iDecStrideC = pCurLayer->pDec->iLinesize[1]; | ||
| 2516 | |||
| 2517 | int32_t iOffsetL = (iMbX + iMbY * iDecStrideL) << 4; | ||
| 2518 | int32_t iOffsetC = (iMbX + iMbY * iDecStrideC) << 3; | ||
| 2519 | |||
| 2520 | uint8_t* pDecY = pCurLayer->pDec->pData[0] + iOffsetL; | ||
| 2521 | uint8_t* pDecU = pCurLayer->pDec->pData[1] + iOffsetC; | ||
| 2522 | uint8_t* pDecV = pCurLayer->pDec->pData[2] + iOffsetC; | ||
| 2523 | |||
| 2524 | uint8_t* pTmpBsBuf; | ||
| 2525 | |||
| 2526 | int32_t i; | ||
| 2527 | int32_t iCopySizeY = (sizeof (uint8_t) << 4); | ||
| 2528 | int32_t iCopySizeUV = (sizeof (uint8_t) << 3); | ||
| 2529 | |||
| 2530 | int32_t iIndex = ((-pBs->iLeftBits) >> 3) + 2; | ||
| 2531 | |||
| 2532 | pCurLayer->pMbType[iMbXy] = MB_TYPE_INTRA_PCM; | ||
| 2533 | |||
| 2534 | //step 1: locating bit-stream pointer [must align into integer byte] | ||
| 2535 | pBs->pCurBuf -= iIndex; | ||
| 2536 | |||
| 2537 | //step 2: copy pixel from bit-stream into fdec [reconstruction] | ||
| 2538 | pTmpBsBuf = pBs->pCurBuf; | ||
| 2539 | if (!pCtx->pParam->bParseOnly) { | ||
| 2540 | for (i = 0; i < 16; i++) { //luma | ||
| 2541 | memcpy (pDecY, pTmpBsBuf, iCopySizeY); | ||
| 2542 | pDecY += iDecStrideL; | ||
| 2543 | pTmpBsBuf += 16; | ||
| 2544 | } | ||
| 2545 | |||
| 2546 | for (i = 0; i < 8; i++) { //cb | ||
| 2547 | memcpy (pDecU, pTmpBsBuf, iCopySizeUV); | ||
| 2548 | pDecU += iDecStrideC; | ||
| 2549 | pTmpBsBuf += 8; | ||
| 2550 | } | ||
| 2551 | for (i = 0; i < 8; i++) { //cr | ||
| 2552 | memcpy (pDecV, pTmpBsBuf, iCopySizeUV); | ||
| 2553 | pDecV += iDecStrideC; | ||
| 2554 | pTmpBsBuf += 8; | ||
| 2555 | } | ||
| 2556 | } | ||
| 2557 | |||
| 2558 | pBs->pCurBuf += 384; | ||
| 2559 | |||
| 2560 | //step 3: update QP and pNonZeroCount | ||
| 2561 | pCurLayer->pLumaQp[iMbXy] = 0; | ||
| 2562 | pCurLayer->pChromaQp[iMbXy][0] = pCurLayer->pChromaQp[iMbXy][1] = 0; | ||
| 2563 | //Rec. 9.2.1 for PCM, nzc=16 | ||
| 2564 | ST32A4 (&pNzc[0], 0x10101010); | ||
| 2565 | ST32A4 (&pNzc[4], 0x10101010); | ||
| 2566 | ST32A4 (&pNzc[8], 0x10101010); | ||
| 2567 | ST32A4 (&pNzc[12], 0x10101010); | ||
| 2568 | ST32A4 (&pNzc[16], 0x10101010); | ||
| 2569 | ST32A4 (&pNzc[20], 0x10101010); | ||
| 2570 | WELS_READ_VERIFY (InitReadBits (pBs, 0)); | ||
| 2571 | return ERR_NONE; | ||
| 2572 | } else { | ||
| 2573 | if (0 == uiMbType) { | ||
| 2574 | ENFORCE_STACK_ALIGN_1D (int8_t, pIntraPredMode, 48, 16); | ||
| 2575 | pCurLayer->pMbType[iMbXy] = MB_TYPE_INTRA4x4; | ||
| 2576 | if (pCtx->pPps->bTransform8x8ModeFlag) { | ||
| 2577 | WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //transform_size_8x8_flag | ||
| 2578 | pCurLayer->pTransformSize8x8Flag[iMbXy] = !!uiCode; | ||
| 2579 | if (pCurLayer->pTransformSize8x8Flag[iMbXy]) { | ||
| 2580 | uiMbType = pCurLayer->pMbType[iMbXy] = MB_TYPE_INTRA8x8; | ||
| 2581 | } | ||
| 2582 | } | ||
| 2583 | if (!pCurLayer->pTransformSize8x8Flag[iMbXy]) { | ||
| 2584 | pCtx->pFillInfoCacheIntraNxNFunc (&sNeighAvail, pNonZeroCount, pIntraPredMode, pCurLayer); | ||
| 2585 | WELS_READ_VERIFY (ParseIntra4x4Mode (pCtx, &sNeighAvail, pIntraPredMode, pBs, pCurLayer)); | ||
| 2586 | } else { | ||
| 2587 | pCtx->pFillInfoCacheIntraNxNFunc (&sNeighAvail, pNonZeroCount, pIntraPredMode, pCurLayer); | ||
| 2588 | WELS_READ_VERIFY (ParseIntra8x8Mode (pCtx, &sNeighAvail, pIntraPredMode, pBs, pCurLayer)); | ||
| 2589 | } | ||
| 2590 | } else { //I_PCM exclude, we can ignore it | ||
| 2591 | pCurLayer->pMbType[iMbXy] = MB_TYPE_INTRA16x16; | ||
| 2592 | pCurLayer->pTransformSize8x8Flag[iMbXy] = false; | ||
| 2593 | pCurLayer->pNoSubMbPartSizeLessThan8x8Flag[iMbXy] = true; | ||
| 2594 | pCurLayer->pIntraPredMode[iMbXy][7] = (uiMbType - 1) & 3; | ||
| 2595 | pCurLayer->pCbp[iMbXy] = g_kuiI16CbpTable[ (uiMbType - 1) >> 2]; | ||
| 2596 | uiCbpC = pCtx->pSps->uiChromaFormatIdc ? pCurLayer->pCbp[iMbXy] >> 4 : 0; | ||
| 2597 | uiCbpL = pCurLayer->pCbp[iMbXy] & 15; | ||
| 2598 | WelsFillCacheNonZeroCount (&sNeighAvail, pNonZeroCount, pCurLayer); | ||
| 2599 | if ((iRet = ParseIntra16x16Mode (pCtx, &sNeighAvail, pBs, pCurLayer)) != ERR_NONE) { | ||
| 2600 | return iRet; | ||
| 2601 | } | ||
| 2602 | } | ||
| 2603 | } | ||
| 2604 | } | ||
| 2605 | |||
| 2606 | if (MB_TYPE_INTRA16x16 != pCurLayer->pMbType[iMbXy]) { | ||
| 2607 | WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //coded_block_pattern | ||
| 2608 | uiCbp = uiCode; | ||
| 2609 | { | ||
| 2610 | if (pCtx->pSps->uiChromaFormatIdc && (uiCbp > 47)) | ||
| 2611 | return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_INVALID_CBP); | ||
| 2612 | if (!pCtx->pSps->uiChromaFormatIdc && (uiCbp > 15)) | ||
| 2613 | return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_INVALID_CBP); | ||
| 2614 | if (MB_TYPE_INTRA4x4 == pCurLayer->pMbType[iMbXy] || MB_TYPE_INTRA8x8 == pCurLayer->pMbType[iMbXy]) { | ||
| 2615 | |||
| 2616 | uiCbp = pCtx->pSps->uiChromaFormatIdc ? g_kuiIntra4x4CbpTable[uiCbp] : g_kuiIntra4x4CbpTable400[uiCbp]; | ||
| 2617 | } else //inter | ||
| 2618 | uiCbp = pCtx->pSps->uiChromaFormatIdc ? g_kuiInterCbpTable[uiCbp] : g_kuiInterCbpTable400[uiCbp]; | ||
| 2619 | } | ||
| 2620 | |||
| 2621 | pCurLayer->pCbp[iMbXy] = uiCbp; | ||
| 2622 | uiCbpC = pCurLayer->pCbp[iMbXy] >> 4; | ||
| 2623 | uiCbpL = pCurLayer->pCbp[iMbXy] & 15; | ||
| 2624 | |||
| 2625 | // Need modification when B picutre add in | ||
| 2626 | bool bNeedParseTransformSize8x8Flag = | ||
| 2627 | (((pCurLayer->pMbType[iMbXy] >= MB_TYPE_16x16 && pCurLayer->pMbType[iMbXy] <= MB_TYPE_8x16) | ||
| 2628 | || pCurLayer->pNoSubMbPartSizeLessThan8x8Flag[iMbXy]) | ||
| 2629 | && (pCurLayer->pMbType[iMbXy] != MB_TYPE_INTRA8x8) | ||
| 2630 | && (pCurLayer->pMbType[iMbXy] != MB_TYPE_INTRA4x4) | ||
| 2631 | && (uiCbpL > 0) | ||
| 2632 | && (pCtx->pPps->bTransform8x8ModeFlag)); | ||
| 2633 | |||
| 2634 | if (bNeedParseTransformSize8x8Flag) { | ||
| 2635 | WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //transform_size_8x8_flag | ||
| 2636 | pCurLayer->pTransformSize8x8Flag[iMbXy] = !!uiCode; | ||
| 2637 | } | ||
| 2638 | } | ||
| 2639 | |||
| 2640 | ST32A4 (&pNzc[0], 0); | ||
| 2641 | ST32A4 (&pNzc[4], 0); | ||
| 2642 | ST32A4 (&pNzc[8], 0); | ||
| 2643 | ST32A4 (&pNzc[12], 0); | ||
| 2644 | ST32A4 (&pNzc[16], 0); | ||
| 2645 | ST32A4 (&pNzc[20], 0); | ||
| 2646 | if (pCurLayer->pCbp[iMbXy] == 0 && !IS_INTRA16x16 (pCurLayer->pMbType[iMbXy]) && !IS_I_BL (pCurLayer->pMbType[iMbXy])) { | ||
| 2647 | pCurLayer->pLumaQp[iMbXy] = pSlice->iLastMbQp; | ||
| 2648 | for (i = 0; i < 2; i++) { | ||
| 2649 | pCurLayer->pChromaQp[iMbXy][i] = g_kuiChromaQpTable[WELS_CLIP3 (pCurLayer->pLumaQp[iMbXy] + | ||
| 2650 | pSliceHeader->pPps->iChromaQpIndexOffset[i], 0, 51)]; | ||
| 2651 | } | ||
| 2652 | } | ||
| 2653 | |||
| 2654 | if (pCurLayer->pCbp[iMbXy] || MB_TYPE_INTRA16x16 == pCurLayer->pMbType[iMbXy]) { | ||
| 2655 | int32_t iQpDelta, iId8x8, iId4x4; | ||
| 2656 | memset (pCurLayer->pScaledTCoeff[iMbXy], 0, MB_COEFF_LIST_SIZE * sizeof (int16_t)); | ||
| 2657 | WELS_READ_VERIFY (BsGetSe (pBs, &iCode)); //mb_qp_delta | ||
| 2658 | iQpDelta = iCode; | ||
| 2659 | |||
| 2660 | if (iQpDelta > 25 || iQpDelta < -26) { //out of iQpDelta range | ||
| 2661 | return GENERATE_ERROR_NO (ERR_LEVEL_MB_DATA, ERR_INFO_INVALID_QP); | ||
| 2662 | } | ||
| 2663 | |||
| 2664 | pCurLayer->pLumaQp[iMbXy] = (pSlice->iLastMbQp + iQpDelta + 52) % 52; //update last_mb_qp | ||
| 2665 | pSlice->iLastMbQp = pCurLayer->pLumaQp[iMbXy]; | ||
| 2666 | for (i = 0; i < 2; i++) { | ||
| 2667 | pCurLayer->pChromaQp[iMbXy][i] = g_kuiChromaQpTable[WELS_CLIP3 (pSlice->iLastMbQp + | ||
| 2668 | pSliceHeader->pPps->iChromaQpIndexOffset[i], 0, | ||
| 2669 | 51)]; | ||
| 2670 | } | ||
| 2671 | |||
| 2672 | BsStartCavlc (pBs); | ||
| 2673 | |||
| 2674 | if (MB_TYPE_INTRA16x16 == pCurLayer->pMbType[iMbXy]) { | ||
| 2675 | //step1: Luma DC | ||
| 2676 | if ((iRet = WelsResidualBlockCavlc (pVlcTable, pNonZeroCount, pBs, 0, 16, g_kuiLumaDcZigzagScan, I16_LUMA_DC, | ||
| 2677 | pCurLayer->pScaledTCoeff[iMbXy], pCurLayer->pLumaQp[iMbXy], pCtx)) != ERR_NONE) { | ||
| 2678 | return iRet;//abnormal | ||
| 2679 | } | ||
| 2680 | //step2: Luma AC | ||
| 2681 | if (uiCbpL) { | ||
| 2682 | for (i = 0; i < 16; i++) { | ||
| 2683 | if ((iRet = WelsResidualBlockCavlc (pVlcTable, pNonZeroCount, pBs, i, iScanIdxEnd - WELS_MAX (iScanIdxStart, 1) + 1, | ||
| 2684 | g_kuiZigzagScan + WELS_MAX (iScanIdxStart, 1), I16_LUMA_AC, pCurLayer->pScaledTCoeff[iMbXy] + (i << 4), | ||
| 2685 | pCurLayer->pLumaQp[iMbXy], pCtx)) != ERR_NONE) { | ||
| 2686 | return iRet;//abnormal | ||
| 2687 | } | ||
| 2688 | } | ||
| 2689 | ST32A4 (&pNzc[0], LD32 (&pNonZeroCount[1 + 8 * 1])); | ||
| 2690 | ST32A4 (&pNzc[4], LD32 (&pNonZeroCount[1 + 8 * 2])); | ||
| 2691 | ST32A4 (&pNzc[8], LD32 (&pNonZeroCount[1 + 8 * 3])); | ||
| 2692 | ST32A4 (&pNzc[12], LD32 (&pNonZeroCount[1 + 8 * 4])); | ||
| 2693 | } | ||
| 2694 | } else { //non-MB_TYPE_INTRA16x16 | ||
| 2695 | if (pCurLayer->pTransformSize8x8Flag[iMbXy]) { | ||
| 2696 | for (iId8x8 = 0; iId8x8 < 4; iId8x8++) { | ||
| 2697 | iMbResProperty = (IS_INTRA (pCurLayer->pMbType[iMbXy])) ? LUMA_DC_AC_INTRA_8 : LUMA_DC_AC_INTER_8; | ||
| 2698 | if (uiCbpL & (1 << iId8x8)) { | ||
| 2699 | int32_t iIndex = (iId8x8 << 2); | ||
| 2700 | for (iId4x4 = 0; iId4x4 < 4; iId4x4++) { | ||
| 2701 | if ((iRet = WelsResidualBlockCavlc8x8 (pVlcTable, pNonZeroCount, pBs, iIndex, iScanIdxEnd - iScanIdxStart + 1, | ||
| 2702 | g_kuiZigzagScan8x8 + iScanIdxStart, iMbResProperty, pCurLayer->pScaledTCoeff[iMbXy] + (iId8x8 << 6), iId4x4, | ||
| 2703 | pCurLayer->pLumaQp[iMbXy], pCtx)) != ERR_NONE) { | ||
| 2704 | return iRet; | ||
| 2705 | } | ||
| 2706 | iIndex++; | ||
| 2707 | } | ||
| 2708 | } else { | ||
| 2709 | ST16 (&pNonZeroCount[g_kuiCache48CountScan4Idx[iId8x8 << 2]], 0); | ||
| 2710 | ST16 (&pNonZeroCount[g_kuiCache48CountScan4Idx[ (iId8x8 << 2) + 2]], 0); | ||
| 2711 | } | ||
| 2712 | } | ||
| 2713 | ST32A4 (&pNzc[0], LD32 (&pNonZeroCount[1 + 8 * 1])); | ||
| 2714 | ST32A4 (&pNzc[4], LD32 (&pNonZeroCount[1 + 8 * 2])); | ||
| 2715 | ST32A4 (&pNzc[8], LD32 (&pNonZeroCount[1 + 8 * 3])); | ||
| 2716 | ST32A4 (&pNzc[12], LD32 (&pNonZeroCount[1 + 8 * 4])); | ||
| 2717 | } else { // Normal T4x4 | ||
| 2718 | for (iId8x8 = 0; iId8x8 < 4; iId8x8++) { | ||
| 2719 | iMbResProperty = (IS_INTRA (pCurLayer->pMbType[iMbXy])) ? LUMA_DC_AC_INTRA : LUMA_DC_AC_INTER; | ||
| 2720 | if (uiCbpL & (1 << iId8x8)) { | ||
| 2721 | int32_t iIndex = (iId8x8 << 2); | ||
| 2722 | for (iId4x4 = 0; iId4x4 < 4; iId4x4++) { | ||
| 2723 | //Luma (DC and AC decoding together) | ||
| 2724 | if ((iRet = WelsResidualBlockCavlc (pVlcTable, pNonZeroCount, pBs, iIndex, iScanIdxEnd - iScanIdxStart + 1, | ||
| 2725 | g_kuiZigzagScan + iScanIdxStart, iMbResProperty, pCurLayer->pScaledTCoeff[iMbXy] + (iIndex << 4), | ||
| 2726 | pCurLayer->pLumaQp[iMbXy], pCtx)) != ERR_NONE) { | ||
| 2727 | return iRet;//abnormal | ||
| 2728 | } | ||
| 2729 | iIndex++; | ||
| 2730 | } | ||
| 2731 | } else { | ||
| 2732 | ST16 (&pNonZeroCount[g_kuiCache48CountScan4Idx[iId8x8 << 2]], 0); | ||
| 2733 | ST16 (&pNonZeroCount[g_kuiCache48CountScan4Idx[ (iId8x8 << 2) + 2]], 0); | ||
| 2734 | } | ||
| 2735 | } | ||
| 2736 | ST32A4 (&pNzc[0], LD32 (&pNonZeroCount[1 + 8 * 1])); | ||
| 2737 | ST32A4 (&pNzc[4], LD32 (&pNonZeroCount[1 + 8 * 2])); | ||
| 2738 | ST32A4 (&pNzc[8], LD32 (&pNonZeroCount[1 + 8 * 3])); | ||
| 2739 | ST32A4 (&pNzc[12], LD32 (&pNonZeroCount[1 + 8 * 4])); | ||
| 2740 | } | ||
| 2741 | } | ||
| 2742 | |||
| 2743 | |||
| 2744 | //chroma | ||
| 2745 | //step1: DC | ||
| 2746 | if (1 == uiCbpC || 2 == uiCbpC) { | ||
| 2747 | for (i = 0; i < 2; i++) { //Cb Cr | ||
| 2748 | if (IS_INTRA (pCurLayer->pMbType[iMbXy])) | ||
| 2749 | iMbResProperty = i ? CHROMA_DC_V : CHROMA_DC_U; | ||
| 2750 | else | ||
| 2751 | iMbResProperty = i ? CHROMA_DC_V_INTER : CHROMA_DC_U_INTER; | ||
| 2752 | |||
| 2753 | if ((iRet = WelsResidualBlockCavlc (pVlcTable, pNonZeroCount, pBs, 16 + (i << 2), 4, g_kuiChromaDcScan, iMbResProperty, | ||
| 2754 | pCurLayer->pScaledTCoeff[iMbXy] + 256 + (i << 6), pCurLayer->pChromaQp[iMbXy][i], pCtx)) != ERR_NONE) { | ||
| 2755 | return iRet;//abnormal | ||
| 2756 | } | ||
| 2757 | } | ||
| 2758 | } else { | ||
| 2759 | } | ||
| 2760 | //step2: AC | ||
| 2761 | if (2 == uiCbpC) { | ||
| 2762 | for (i = 0; i < 2; i++) { //Cb Cr | ||
| 2763 | if (IS_INTRA (pCurLayer->pMbType[iMbXy])) | ||
| 2764 | iMbResProperty = i ? CHROMA_AC_V : CHROMA_AC_U; | ||
| 2765 | else | ||
| 2766 | iMbResProperty = i ? CHROMA_AC_V_INTER : CHROMA_AC_U_INTER; | ||
| 2767 | |||
| 2768 | int32_t iIndex = 16 + (i << 2); | ||
| 2769 | for (iId4x4 = 0; iId4x4 < 4; iId4x4++) { | ||
| 2770 | if ((iRet = WelsResidualBlockCavlc (pVlcTable, pNonZeroCount, pBs, iIndex, iScanIdxEnd - WELS_MAX (iScanIdxStart, | ||
| 2771 | 1) + 1, g_kuiZigzagScan + WELS_MAX (iScanIdxStart, 1), iMbResProperty, pCurLayer->pScaledTCoeff[iMbXy] + (iIndex << 4), | ||
| 2772 | pCurLayer->pChromaQp[iMbXy][i], pCtx)) != ERR_NONE) { | ||
| 2773 | return iRet;//abnormal | ||
| 2774 | } | ||
| 2775 | iIndex++; | ||
| 2776 | } | ||
| 2777 | } | ||
| 2778 | ST16A2 (&pNzc[16], LD16A2 (&pNonZeroCount[6 + 8 * 1])); | ||
| 2779 | ST16A2 (&pNzc[20], LD16A2 (&pNonZeroCount[6 + 8 * 2])); | ||
| 2780 | ST16A2 (&pNzc[18], LD16A2 (&pNonZeroCount[6 + 8 * 4])); | ||
| 2781 | ST16A2 (&pNzc[22], LD16A2 (&pNonZeroCount[6 + 8 * 5])); | ||
| 2782 | } | ||
| 2783 | BsEndCavlc (pBs); | ||
| 2784 | } | ||
| 2785 | |||
| 2786 | return ERR_NONE; | ||
| 2787 | } | ||
| 2788 | |||
| 2345 | void WelsBlockFuncInit (SBlockFunc* pFunc, int32_t iCpu) { | 2789 | void WelsBlockFuncInit (SBlockFunc* pFunc, int32_t iCpu) { |
| 2346 | pFunc->pWelsSetNonZeroCountFunc = WelsNonZeroCount_c; | 2790 | pFunc->pWelsSetNonZeroCountFunc = WelsNonZeroCount_c; |
| 2347 | pFunc->pWelsBlockZero16x16Func = WelsBlockZero16x16_c; | 2791 | pFunc->pWelsBlockZero16x16Func = WelsBlockZero16x16_c; |