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 | 1525 | } else { |
| 1526 | 1526 | if (P_SLICE == pSliceHeader->eSliceType) { |
| 1527 | 1527 | pDecMbFunc = WelsDecodeMbCavlcPSlice; |
| 1528 | + } else if (B_SLICE == pSliceHeader->eSliceType) { | |
| 1529 | + pDecMbFunc = WelsDecodeMbCavlcBSlice; | |
| 1528 | 1530 | } else { //I_SLICE |
| 1529 | 1531 | pDecMbFunc = WelsDecodeMbCavlcISlice; |
| 1530 | 1532 | } |
| @@ -2342,6 +2344,448 @@ int32_t WelsDecodeMbCavlcPSlice (PWelsDecoderContext pCtx, PNalUnit pNalCur, uin · 811 unmodified lines | ||
| 2342 | 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 | 2789 | void WelsBlockFuncInit (SBlockFunc* pFunc, int32_t iCpu) { |
| 2346 | 2790 | pFunc->pWelsSetNonZeroCountFunc = WelsNonZeroCount_c; |
| 2347 | 2791 | pFunc->pWelsBlockZero16x16Func = WelsBlockZero16x16_c; |