History

add decoder cabac support and add UT

dong zhang committed 12 years ago

Commit cf857451 parent c7b505132 files · +2615 −470Browse files

Showing the changes to codec/decoder/core/src/decode_slice.cpp (1 of 32 files). Show all

Unified · Split

codec/decoder/core/src/decode_slice.cpp+696−96
@@ -44,6 +44,7 @@ · 43 unmodified lines
44#include "decode_slice.h"44#include "decode_slice.h"
45 45
46#include "parse_mb_syn_cavlc.h"46#include "parse_mb_syn_cavlc.h"
47#include "parse_mb_syn_cabac.h"
47#include "rec_mb.h"48#include "rec_mb.h"
48#include "mv_pred.h"49#include "mv_pred.h"
49 50
@@ -318,6 +319,576 @@ void WelsChromaDcIdct (int16_t* pBlock) { · 268 unmodified lines
318 pBlk[iStride1] = (iE - iB) >> 1;319 pBlk[iStride1] = (iE - iB) >> 1;
319}320}
320 321
322void WelsMap4x4NeighToSampleNormal (PWelsNeighAvail pNeighAvail, int32_t* pSampleAvail) {
323 if (pNeighAvail->iLeftAvail) { //left
324 pSampleAvail[ 6] =
325 pSampleAvail[12] =
326 pSampleAvail[18] =
327 pSampleAvail[24] = 1;
328 }
329 if (pNeighAvail->iLeftTopAvail) { //top_left
330 pSampleAvail[0] = 1;
331 }
332 if (pNeighAvail->iTopAvail) { //top
333 pSampleAvail[1] =
334 pSampleAvail[2] =
335 pSampleAvail[3] =
336 pSampleAvail[4] = 1;
337 }
338 if (pNeighAvail->iRightTopAvail) { //top_right
339 pSampleAvail[5] = 1;
340 }
341}
342
343void WelsMap4x4NeighToSampleConstrain1 (PWelsNeighAvail pNeighAvail, int32_t* pSampleAvail) {
344 if (pNeighAvail->iLeftAvail && IS_INTRA (pNeighAvail->iLeftType)) { //left
345 pSampleAvail[ 6] =
346 pSampleAvail[12] =
347 pSampleAvail[18] =
348 pSampleAvail[24] = 1;
349 }
350 if (pNeighAvail->iLeftTopAvail && IS_INTRA (pNeighAvail->iLeftTopType)) { //top_left
351 pSampleAvail[0] = 1;
352 }
353 if (pNeighAvail->iTopAvail && IS_INTRA (pNeighAvail->iTopType)) { //top
354 pSampleAvail[1] =
355 pSampleAvail[2] =
356 pSampleAvail[3] =
357 pSampleAvail[4] = 1;
358 }
359 if (pNeighAvail->iRightTopAvail && IS_INTRA (pNeighAvail->iRightTopType)) { //top_right
360 pSampleAvail[5] = 1;
361 }
362}
363void WelsMap16x16NeighToSampleNormal (PWelsNeighAvail pNeighAvail, uint8_t* pSampleAvail) {
364 if (pNeighAvail->iLeftAvail) {
365 *pSampleAvail = (1 << 2);
366 }
367 if (pNeighAvail->iLeftTopAvail) {
368 *pSampleAvail |= (1 << 1);
369 }
370 if (pNeighAvail->iTopAvail) {
371 *pSampleAvail |= 1;
372 }
373}
374
375void WelsMap16x16NeighToSampleConstrain1 (PWelsNeighAvail pNeighAvail, uint8_t* pSampleAvail) {
376 if (pNeighAvail->iLeftAvail && IS_INTRA (pNeighAvail->iLeftType)) {
377 *pSampleAvail = (1 << 2);
378 }
379 if (pNeighAvail->iLeftTopAvail && IS_INTRA (pNeighAvail->iLeftTopType)) {
380 *pSampleAvail |= (1 << 1);
381 }
382 if (pNeighAvail->iTopAvail && IS_INTRA (pNeighAvail->iTopType)) {
383 *pSampleAvail |= 1;
384 }
385}
386
387int32_t ParseIntra4x4Mode (PWelsDecoderContext pCtx, PWelsNeighAvail pNeighAvail, int8_t* pIntraPredMode,
388 PBitStringAux pBs,
389 PDqLayer pCurDqLayer) {
390 int32_t iSampleAvail[5 * 6] = { 0 }; //initialize as 0
391 int32_t iMbXy = pCurDqLayer->iMbXyIndex;
392 int32_t iFinalMode, i;
393
394 uint8_t uiNeighAvail = 0;
395 uint32_t uiCode;
396 int32_t iCode;
397 pCtx->pMap4x4NeighToSampleFunc (pNeighAvail, iSampleAvail);
398 uiNeighAvail = (iSampleAvail[6] << 2) | (iSampleAvail[0] << 1) | (iSampleAvail[1]);
399 for (i = 0; i < 16; i++) {
400 int32_t iPrevIntra4x4PredMode = 0;
401 if (pCurDqLayer->sLayerInfo.pPps->bEntropyCodingModeFlag) {
402 WELS_READ_VERIFY (ParseIntraPredModeLumaCabac (pCtx, iCode));
403 iPrevIntra4x4PredMode = iCode;
404 } else {
405 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode));
406 iPrevIntra4x4PredMode = uiCode;
407 }
408 const int32_t kiPredMode = PredIntra4x4Mode (pIntraPredMode, i);
409
410 int8_t iBestMode;
411 if (pCurDqLayer->sLayerInfo.pPps->bEntropyCodingModeFlag) {
412 if (iPrevIntra4x4PredMode == -1)
413 iBestMode = kiPredMode;
414 else
415 iBestMode = iPrevIntra4x4PredMode + (iPrevIntra4x4PredMode >= kiPredMode);
416 } else {
417 if (iPrevIntra4x4PredMode) {
418 iBestMode = kiPredMode;
419 } else {
420 WELS_READ_VERIFY (BsGetBits (pBs, 3, &uiCode));
421 iBestMode = uiCode + (uiCode >= kiPredMode);
422 }
423 }
424
425 iFinalMode = CheckIntra4x4PredMode (&iSampleAvail[0], &iBestMode, i);
426 if (iFinalMode == ERR_INVALID_INTRA4X4_MODE) {
427 return ERR_INFO_INVALID_I4x4_PRED_MODE;
428 }
429
430 pCurDqLayer->pIntra4x4FinalMode[iMbXy][g_kuiScan4[i]] = iFinalMode;
431
432 pIntraPredMode[g_kuiScan8[i]] = iBestMode;
433
434 iSampleAvail[g_kuiCache30ScanIdx[i]] = 1;
435 }
436 ST32 (&pCurDqLayer->pIntraPredMode[iMbXy][0], LD32 (&pIntraPredMode[1 + 8 * 4]));
437 pCurDqLayer->pIntraPredMode[iMbXy][4] = pIntraPredMode[4 + 8 * 1];
438 pCurDqLayer->pIntraPredMode[iMbXy][5] = pIntraPredMode[4 + 8 * 2];
439 pCurDqLayer->pIntraPredMode[iMbXy][6] = pIntraPredMode[4 + 8 * 3];
440 if (pCurDqLayer->sLayerInfo.pPps->bEntropyCodingModeFlag) {
441 WELS_READ_VERIFY (ParseIntraPredModeChromaCabac (pCtx, uiNeighAvail, iCode));
442 if (iCode > MAX_PRED_MODE_ID_CHROMA) {
443 return ERR_INFO_INVALID_I_CHROMA_PRED_MODE;
444 }
445 pCurDqLayer->pChromaPredMode[iMbXy] = iCode;
446 } else {
447 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //intra_chroma_pred_mode
448 if (uiCode > MAX_PRED_MODE_ID_CHROMA) {
449 return ERR_INFO_INVALID_I_CHROMA_PRED_MODE;
450 }
451 pCurDqLayer->pChromaPredMode[iMbXy] = uiCode;
452 }
453
454 if (-1 == pCurDqLayer->pChromaPredMode[iMbXy]
455 || CheckIntraChromaPredMode (uiNeighAvail, &pCurDqLayer->pChromaPredMode[iMbXy])) {
456 return ERR_INFO_INVALID_I_CHROMA_PRED_MODE;
457 }
458
459 return ERR_NONE;
460}
461
462int32_t ParseIntra16x16Mode (PWelsDecoderContext pCtx, PWelsNeighAvail pNeighAvail, PBitStringAux pBs,
463 PDqLayer pCurDqLayer) {
464 int32_t iMbXy = pCurDqLayer->iMbXyIndex;
465 uint8_t uiNeighAvail = 0; //0x07 = 0 1 1 1, means left, top-left, top avail or not. (1: avail, 0: unavail)
466 uint32_t uiCode;
467 int32_t iCode;
468 pCtx->pMap16x16NeighToSampleFunc (pNeighAvail, &uiNeighAvail);
469
470 if (CheckIntra16x16PredMode (uiNeighAvail,
471 &pCurDqLayer->pIntraPredMode[iMbXy][7])) { //invalid iPredMode, must stop decoding
472 return ERR_INFO_INVALID_I16x16_PRED_MODE;
473 }
474 if (pCurDqLayer->sLayerInfo.pPps->bEntropyCodingModeFlag) {
475 WELS_READ_VERIFY (ParseIntraPredModeChromaCabac (pCtx, uiNeighAvail, iCode));
476 if (iCode > MAX_PRED_MODE_ID_CHROMA) {
477 return ERR_INFO_INVALID_I_CHROMA_PRED_MODE;
478 }
479 pCurDqLayer->pChromaPredMode[iMbXy] = iCode;
480 } else {
481 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //intra_chroma_pred_mode
482 if (uiCode > MAX_PRED_MODE_ID_CHROMA) {
483 return ERR_INFO_INVALID_I_CHROMA_PRED_MODE;
484 }
485 pCurDqLayer->pChromaPredMode[iMbXy] = uiCode;
486 }
487 if (-1 == pCurDqLayer->pChromaPredMode[iMbXy]
488 || CheckIntraChromaPredMode (uiNeighAvail, &pCurDqLayer->pChromaPredMode[iMbXy])) {
489 return ERR_INFO_INVALID_I_CHROMA_PRED_MODE;
490 }
491
492 return ERR_NONE;
493}
494
495int32_t WelsDecodeMbCabacISliceBaseMode0 (PWelsDecoderContext pCtx, uint32_t& uiEosFlag) {
496 PDqLayer pCurLayer = pCtx->pCurDqLayer;
497 PBitStringAux pBsAux = pCurLayer->pBitStringAux;
498 PSlice pSlice = &pCurLayer->sLayerInfo.sSliceInLayer;
499 PSliceHeader pSliceHeader = &pSlice->sSliceHeaderExt.sSliceHeader;
500 SWelsNeighAvail sNeighAvail;
501 int32_t iScanIdxStart = pSlice->sSliceHeaderExt.uiScanIdxStart;
502 int32_t iScanIdxEnd = pSlice->sSliceHeaderExt.uiScanIdxEnd;
503 int32_t iMbXy = pCurLayer->iMbXyIndex;
504 int32_t iMbMode, i;
505 uint32_t uiMbType = 0, uiCbp = 0, uiCbpLuma = 0, uiCbpChroma = 0;
506
507 ENFORCE_STACK_ALIGN_1D (uint8_t, pNonZeroCount, 48, 16);
508
509 pCurLayer->pInterPredictionDoneFlag[iMbXy] = 0;
510 pCurLayer->pResidualPredFlag[iMbXy] = pSlice->sSliceHeaderExt.bDefaultResidualPredFlag;
511 GetNeighborAvailMbType (&sNeighAvail, pCurLayer);
512 WELS_READ_VERIFY (ParseMBTypeISliceCabac (pCtx, &sNeighAvail, uiMbType));
513 if (uiMbType > 25) {
514 return ERR_INFO_INVALID_MB_TYPE;
515 } else if (25 == uiMbType) { //I_PCM
516 WELS_READ_VERIFY (ParseIPCMInfoCabac (pCtx));
517 WELS_READ_VERIFY (ParseEndOfSliceCabac (pCtx, uiEosFlag));
518 if (uiEosFlag) {
519 RestoreCabacDecEngineToBS (pCtx->pCabacDecEngine, pCtx->pCurDqLayer->pBitStringAux);
520 }
521 return ERR_NONE;
522 } else if (0 == uiMbType) { //I4x4
523 ENFORCE_STACK_ALIGN_1D (int8_t, pIntraPredMode, 48, 16);
524 pCurLayer->pMbType[iMbXy] = MB_TYPE_INTRA4x4;
525 pCtx->pFillInfoCacheIntra4x4Func (&sNeighAvail, pNonZeroCount, pIntraPredMode, pCurLayer);
526 WELS_READ_VERIFY (ParseIntra4x4Mode (pCtx, &sNeighAvail, pIntraPredMode, pBsAux, pCurLayer));
527 //get uiCbp for I4x4
528 WELS_READ_VERIFY (ParseCbpInfoCabac (pCtx, &sNeighAvail, uiCbp));
529 pCurLayer->pCbp[iMbXy] = uiCbp;
530 uiCbpChroma = uiCbp >> 4;
531 uiCbpLuma = uiCbp & 15;
532 } else { //I16x16;
533 pCurLayer->pMbType[iMbXy] = MB_TYPE_INTRA16x16;
534 pCurLayer->pIntraPredMode[iMbXy][7] = (uiMbType - 1) & 3;
535 pCurLayer->pCbp[iMbXy] = g_kuiI16CbpTable[ (uiMbType - 1) >> 2];
536 uiCbpChroma = pCurLayer->pCbp[iMbXy] >> 4;
537 uiCbpLuma = pCurLayer->pCbp[iMbXy] & 15;
538 WelsFillCacheNonZeroCount (&sNeighAvail, pNonZeroCount, pCurLayer);
539 WELS_READ_VERIFY (ParseIntra16x16Mode (pCtx, &sNeighAvail, pBsAux, pCurLayer));
540 }
541 iMbMode = BASE_MB;
542
543 memset (pCurLayer->pScaledTCoeff[iMbXy], 0, 384 * sizeof (pCurLayer->pScaledTCoeff[iMbXy][0]));
544 ST32 (&pCurLayer->pNzc[iMbXy][0], 0);
545 ST32 (&pCurLayer->pNzc[iMbXy][4], 0);
546 ST32 (&pCurLayer->pNzc[iMbXy][8], 0);
547 ST32 (&pCurLayer->pNzc[iMbXy][12], 0);
548 ST32 (&pCurLayer->pNzc[iMbXy][16], 0);
549 ST32 (&pCurLayer->pNzc[iMbXy][20], 0);
550 pCurLayer->pCbfDc[iMbXy] = 0;
551
552 if (pCurLayer->pCbp[iMbXy] == 0 && IS_INTRA4x4 (pCurLayer->pMbType[iMbXy])) {
553 pCurLayer->pLumaQp[iMbXy] = pSlice->iLastMbQp;
554 pCurLayer->pChromaQp[iMbXy] = g_kuiChromaQpTable[WELS_CLIP3 ((pCurLayer->pLumaQp[iMbXy] +
555 pSliceHeader->pPps->iChromaQpIndexOffset), 0, 51)];
556 }
557
558 if (pCurLayer->pCbp[iMbXy] || MB_TYPE_INTRA16x16 == pCurLayer->pMbType[iMbXy]) {
559 int32_t iQpDelta, iId8x8, iId4x4;
560 WELS_READ_VERIFY (ParseDeltaQpCabac (pCtx, iQpDelta));
561 if (iQpDelta > 25 || iQpDelta < -26) {//out of iQpDelta range
562 return ERR_INFO_INVALID_QP;
563 }
564 pCurLayer->pLumaQp[iMbXy] = (pSlice->iLastMbQp + iQpDelta + 52) % 52; //update last_mb_qp
565 pSlice->iLastMbQp = pCurLayer->pLumaQp[iMbXy];
566 pCurLayer->pChromaQp[iMbXy] = g_kuiChromaQpTable[WELS_CLIP3 ((pSlice->iLastMbQp +
567 pSliceHeader->pPps->iChromaQpIndexOffset), 0, 51)];
568 if (MB_TYPE_INTRA16x16 == pCurLayer->pMbType[iMbXy]) {
569 //step1: Luma DC
570 WELS_READ_VERIFY (ParseResidualBlockCabac (&sNeighAvail, pNonZeroCount, pBsAux, 0, 16, g_kuiLumaDcZigzagScan,
571 I16_LUMA_DC, pCurLayer->pScaledTCoeff[iMbXy], pCurLayer->pLumaQp[iMbXy], pCtx));
572 //step2: Luma AC
573 if (uiCbpLuma) {
574 for (i = 0; i < 16; i++) {
575 WELS_READ_VERIFY (ParseResidualBlockCabac (&sNeighAvail, pNonZeroCount, pBsAux, i,
576 iScanIdxEnd - WELS_MAX (iScanIdxStart, 1) + 1, g_kuiZigzagScan + WELS_MAX (iScanIdxStart, 1), I16_LUMA_AC,
577 pCurLayer->pScaledTCoeff[iMbXy] + (i << 4), pCurLayer->pLumaQp[iMbXy], pCtx));
578 }
579 ST32 (&pCurLayer->pNzc[iMbXy][0], LD32 (&pNonZeroCount[1 + 8 * 1]));
580 ST32 (&pCurLayer->pNzc[iMbXy][4], LD32 (&pNonZeroCount[1 + 8 * 2]));
581 ST32 (&pCurLayer->pNzc[iMbXy][8], LD32 (&pNonZeroCount[1 + 8 * 3]));
582 ST32 (&pCurLayer->pNzc[iMbXy][12], LD32 (&pNonZeroCount[1 + 8 * 4]));
583 } else { //pNonZeroCount = 0
584 ST32 (&pCurLayer->pNzc[iMbXy][0], 0);
585 ST32 (&pCurLayer->pNzc[iMbXy][4], 0);
586 ST32 (&pCurLayer->pNzc[iMbXy][8], 0);
587 ST32 (&pCurLayer->pNzc[iMbXy][12], 0);
588 }
589 } else { //non-MB_TYPE_INTRA16x16
590 for (iId8x8 = 0; iId8x8 < 4; iId8x8++) {
591 if (uiCbpLuma & (1 << iId8x8)) {
592 int32_t iIdx = (iId8x8 << 2);
593 for (iId4x4 = 0; iId4x4 < 4; iId4x4++) {
594 //Luma (DC and AC decoding together)
595 WELS_READ_VERIFY (ParseResidualBlockCabac (&sNeighAvail, pNonZeroCount, pBsAux, iIdx, iScanIdxEnd - iScanIdxStart + 1,
596 g_kuiZigzagScan + iScanIdxStart, LUMA_DC_AC, pCurLayer->pScaledTCoeff[iMbXy] + (iIdx << 4), pCurLayer->pLumaQp[iMbXy],
597 pCtx));
598 iIdx++;
599 }
600 } else {
601 ST16 (&pNonZeroCount[g_kCacheNzcScanIdx[ (iId8x8 << 2)]], 0);
602 ST16 (&pNonZeroCount[g_kCacheNzcScanIdx[ (iId8x8 << 2) + 2]], 0);
603 }
604 }
605 ST32 (&pCurLayer->pNzc[iMbXy][0], LD32 (&pNonZeroCount[1 + 8 * 1]));
606 ST32 (&pCurLayer->pNzc[iMbXy][4], LD32 (&pNonZeroCount[1 + 8 * 2]));
607 ST32 (&pCurLayer->pNzc[iMbXy][8], LD32 (&pNonZeroCount[1 + 8 * 3]));
608 ST32 (&pCurLayer->pNzc[iMbXy][12], LD32 (&pNonZeroCount[1 + 8 * 4]));
609 }
610
611 //chroma
612 //step1: DC
613 if (1 == uiCbpChroma || 2 == uiCbpChroma) {
614 //Cb Cr
615 WELS_READ_VERIFY (ParseResidualBlockCabac (&sNeighAvail, pNonZeroCount, pBsAux, 16 + (0 << 2), 4, g_kuiChromaDcScan,
616 CHROMA_DC_V, pCurLayer->pScaledTCoeff[iMbXy] + 256 + (0 << 6), pCurLayer->pChromaQp[iMbXy], pCtx));
617 WELS_READ_VERIFY (ParseResidualBlockCabac (&sNeighAvail, pNonZeroCount, pBsAux, 16 + (1 << 2), 4, g_kuiChromaDcScan,
618 CHROMA_DC_U, pCurLayer->pScaledTCoeff[iMbXy] + 256 + (1 << 6), pCurLayer->pChromaQp[iMbXy], pCtx));
619 }
620
621 //step2: AC
622 if (2 == uiCbpChroma) {
623 for (i = 0; i < 2; i++) { //Cb Cr
624 int32_t iResProperty = i ? CHROMA_AC_V : CHROMA_AC_U;
625 int32_t iIdx = 16 + (i << 2);
626 for (iId4x4 = 0; iId4x4 < 4; iId4x4++) {
627 WELS_READ_VERIFY (ParseResidualBlockCabac (&sNeighAvail, pNonZeroCount, pBsAux, iIdx,
628 iScanIdxEnd - WELS_MAX (iScanIdxStart, 1) + 1, g_kuiZigzagScan + WELS_MAX (iScanIdxStart, 1), iResProperty,
629 pCurLayer->pScaledTCoeff[iMbXy] + (iIdx << 4), pCurLayer->pChromaQp[iMbXy], pCtx));
630 iIdx++;
631 }
632 }
633 ST16 (&pCurLayer->pNzc[iMbXy][16], LD16 (&pNonZeroCount[6 + 8 * 1]));
634 ST16 (&pCurLayer->pNzc[iMbXy][20], LD16 (&pNonZeroCount[6 + 8 * 2]));
635 ST16 (&pCurLayer->pNzc[iMbXy][18], LD16 (&pNonZeroCount[6 + 8 * 4]));
636 ST16 (&pCurLayer->pNzc[iMbXy][22], LD16 (&pNonZeroCount[6 + 8 * 5]));
637 } else {
638 ST16 (&pCurLayer->pNzc[iMbXy][16], 0);
639 ST16 (&pCurLayer->pNzc[iMbXy][20], 0);
640 ST16 (&pCurLayer->pNzc[iMbXy][18], 0);
641 ST16 (&pCurLayer->pNzc[iMbXy][22], 0);
642 }
643 } else {
644 ST32 (&pCurLayer->pNzc[iMbXy][0], 0);
645 ST32 (&pCurLayer->pNzc[iMbXy][4], 0);
646 ST32 (&pCurLayer->pNzc[iMbXy][8], 0);
647 ST32 (&pCurLayer->pNzc[iMbXy][12], 0);
648 ST32 (&pCurLayer->pNzc[iMbXy][16], 0);
649 ST32 (&pCurLayer->pNzc[iMbXy][20], 0);
650 }
651
652 WELS_READ_VERIFY (ParseEndOfSliceCabac (pCtx, uiEosFlag));
653 if (uiEosFlag) {
654 RestoreCabacDecEngineToBS (pCtx->pCabacDecEngine, pCtx->pCurDqLayer->pBitStringAux);
655 }
656 return ERR_NONE;
657}
658
659int32_t WelsDecodeMbCabacISlice (PWelsDecoderContext pCtx, PNalUnit pNalCur, uint32_t& uiEosFlag) {
660 WELS_READ_VERIFY (WelsDecodeMbCabacISliceBaseMode0 (pCtx, uiEosFlag));
661 return ERR_NONE;
662}
663
664int32_t WelsDecodeMbCabacPSliceBaseMode0 (PWelsDecoderContext pCtx, PWelsNeighAvail pNeighAvail, uint32_t& uiEosFlag) {
665 PDqLayer pCurLayer = pCtx->pCurDqLayer;
666 PBitStringAux pBsAux = pCurLayer->pBitStringAux;
667 PSlice pSlice = &pCurLayer->sLayerInfo.sSliceInLayer;
668 PSliceHeader pSliceHeader = &pSlice->sSliceHeaderExt.sSliceHeader;
669
670 int32_t iScanIdxStart = pSlice->sSliceHeaderExt.uiScanIdxStart;
671 int32_t iScanIdxEnd = pSlice->sSliceHeaderExt.uiScanIdxEnd;
672 int32_t iMbXy = pCurLayer->iMbXyIndex;
673
674 int32_t iMbMode, i;
675 uint32_t uiMbType = 0, uiCbp = 0, uiCbpLuma = 0, uiCbpChroma = 0;
676
677 ENFORCE_STACK_ALIGN_1D (uint8_t, pNonZeroCount, 48, 16);
678
679 pCurLayer->pInterPredictionDoneFlag[iMbXy] = 0;
680
681 WELS_READ_VERIFY (ParseMBTypePSliceCabac (pCtx, pNeighAvail, uiMbType));
682 // uiMbType = 4 is not allowded.
683 if (uiMbType < 4) { //Inter mode
684 int16_t pMotionVector[LIST_A][30][MV_A];
685 int16_t pMvdCache[LIST_A][30][MV_A];
686 int8_t pRefIndex[LIST_A][30];
687 pCurLayer->pMbType[iMbXy] = g_ksInterMbTypeInfo[uiMbType].iType;
688 WelsFillCacheInterCabac (pNeighAvail, pNonZeroCount, pMotionVector, pMvdCache, pRefIndex, pCurLayer);
689 WELS_READ_VERIFY (ParseInterMotionInfoCabac (pCtx, pNeighAvail, pNonZeroCount, pMotionVector, pMvdCache, pRefIndex));
690 iMbMode = BASE_MB;
691 pCurLayer->pInterPredictionDoneFlag[iMbXy] = 0;
692 } else { //Intra mode
693 uiMbType -= 5;
694 if (uiMbType > 25) {
695 return ERR_INFO_INVALID_MB_TYPE;
696 }
697
698 if (25 == uiMbType) { //I_PCM
699 WELS_READ_VERIFY (ParseIPCMInfoCabac (pCtx));
700 WELS_READ_VERIFY (ParseEndOfSliceCabac (pCtx, uiEosFlag));
701 if (uiEosFlag) {
702 RestoreCabacDecEngineToBS (pCtx->pCabacDecEngine, pCtx->pCurDqLayer->pBitStringAux);
703 }
704 return ERR_NONE;
705 } else { //normal Intra mode
706 if (0 == uiMbType) { //Intra4x4
707 ENFORCE_STACK_ALIGN_1D (int8_t, pIntraPredMode, 48, 16);
708 pCurLayer->pMbType[iMbXy] = MB_TYPE_INTRA4x4;
709 pCtx->pFillInfoCacheIntra4x4Func (pNeighAvail, pNonZeroCount, pIntraPredMode, pCurLayer);
710 WELS_READ_VERIFY (ParseIntra4x4Mode (pCtx, pNeighAvail, pIntraPredMode, pBsAux, pCurLayer));
711 } else { //Intra16x16
712 pCurLayer->pMbType[iMbXy] = MB_TYPE_INTRA16x16;
713 pCurLayer->pIntraPredMode[iMbXy][7] = (uiMbType - 1) & 3;
714 pCurLayer->pCbp[iMbXy] = g_kuiI16CbpTable[ (uiMbType - 1) >> 2];
715 uiCbpChroma = pCurLayer->pCbp[iMbXy] >> 4;
716 uiCbpLuma = pCurLayer->pCbp[iMbXy] & 15;
717 WelsFillCacheNonZeroCount (pNeighAvail, pNonZeroCount, pCurLayer);
718 WELS_READ_VERIFY (ParseIntra16x16Mode (pCtx, pNeighAvail, pBsAux, pCurLayer));
719 }
720 iMbMode = BASE_MB;
721 }
722 }
723
724 if (MB_TYPE_INTRA16x16 != pCurLayer->pMbType[iMbXy]) {
725 WELS_READ_VERIFY (ParseCbpInfoCabac (pCtx, pNeighAvail, uiCbp));
726 pCurLayer->pCbp[iMbXy] = uiCbp;
727 uiCbpChroma = pCurLayer->pCbp[iMbXy] >> 4;
728 uiCbpLuma = pCurLayer->pCbp[iMbXy] & 15;
729 }
730
731 pCtx->sBlockFunc.pWelsBlockZero16x16Func (pCurLayer->pScaledTCoeff[iMbXy], 16);
732 pCtx->sBlockFunc.pWelsBlockZero8x8Func (pCurLayer->pScaledTCoeff[iMbXy] + 256, 8);
733 pCtx->sBlockFunc.pWelsBlockZero8x8Func (pCurLayer->pScaledTCoeff[iMbXy] + 256 + 64, 8);
734
735 ST32 (&pCurLayer->pNzc[iMbXy][0], 0);
736 ST32 (&pCurLayer->pNzc[iMbXy][4], 0);
737 ST32 (&pCurLayer->pNzc[iMbXy][8], 0);
738 ST32 (&pCurLayer->pNzc[iMbXy][12], 0);
739 ST32 (&pCurLayer->pNzc[iMbXy][16], 0);
740 ST32 (&pCurLayer->pNzc[iMbXy][20], 0);
741
742 if (pCurLayer->pCbp[iMbXy] || MB_TYPE_INTRA16x16 == pCurLayer->pMbType[iMbXy]) {
743 int32_t iQpDelta, iId8x8, iId4x4;
744
745 WELS_READ_VERIFY (ParseDeltaQpCabac (pCtx, iQpDelta));
746 pCurLayer->pLumaQp[iMbXy] = (pSlice->iLastMbQp + iQpDelta + 52) % 52; //update last_mb_qp
747 pSlice->iLastMbQp = pCurLayer->pLumaQp[iMbXy];
748 pCurLayer->pChromaQp[iMbXy] = g_kuiChromaQpTable[WELS_CLIP3 (pSlice->iLastMbQp +
749 pSliceHeader->pPps->iChromaQpIndexOffset, 0, 51)];
750
751 if (MB_TYPE_INTRA16x16 == pCurLayer->pMbType[iMbXy]) {
752 //step1: Luma DC
753 WELS_READ_VERIFY (ParseResidualBlockCabac (pNeighAvail, pNonZeroCount, pBsAux, 0, 16, g_kuiLumaDcZigzagScan,
754 I16_LUMA_DC, pCurLayer->pScaledTCoeff[iMbXy], pCurLayer->pLumaQp[iMbXy], pCtx));
755 //step2: Luma AC
756 if (uiCbpLuma) {
757 for (i = 0; i < 16; i++) {
758 WELS_READ_VERIFY (ParseResidualBlockCabac (pNeighAvail, pNonZeroCount, pBsAux, i, iScanIdxEnd - WELS_MAX (iScanIdxStart,
759 1) + 1, g_kuiZigzagScan + WELS_MAX (iScanIdxStart, 1), I16_LUMA_AC, pCurLayer->pScaledTCoeff[iMbXy] + (i << 4),
760 pCurLayer->pLumaQp[iMbXy], pCtx));
761 }
762 ST32 (&pCurLayer->pNzc[iMbXy][0], LD32 (&pNonZeroCount[1 + 8 * 1]));
763 ST32 (&pCurLayer->pNzc[iMbXy][4], LD32 (&pNonZeroCount[1 + 8 * 2]));
764 ST32 (&pCurLayer->pNzc[iMbXy][8], LD32 (&pNonZeroCount[1 + 8 * 3]));
765 ST32 (&pCurLayer->pNzc[iMbXy][12], LD32 (&pNonZeroCount[1 + 8 * 4]));
766 } else {
767 ST32 (&pCurLayer->pNzc[iMbXy][0], 0);
768 ST32 (&pCurLayer->pNzc[iMbXy][4], 0);
769 ST32 (&pCurLayer->pNzc[iMbXy][8], 0);
770 ST32 (&pCurLayer->pNzc[iMbXy][12], 0);
771 }
772 } else { //non-MB_TYPE_INTRA16x16
773 for (iId8x8 = 0; iId8x8 < 4; iId8x8++) {
774 if (uiCbpLuma & (1 << iId8x8)) {
775 int32_t iIdx = (iId8x8 << 2);
776 for (iId4x4 = 0; iId4x4 < 4; iId4x4++) {
777 //Luma (DC and AC decoding together)
778 WELS_READ_VERIFY (ParseResidualBlockCabac (pNeighAvail, pNonZeroCount, pBsAux, iIdx, iScanIdxEnd - iScanIdxStart + 1,
779 g_kuiZigzagScan + iScanIdxStart, LUMA_DC_AC, pCurLayer->pScaledTCoeff[iMbXy] + (iIdx << 4), pCurLayer->pLumaQp[iMbXy],
780 pCtx));
781 iIdx++;
782 }
783 } else {
784 ST16 (&pNonZeroCount[g_kCacheNzcScanIdx[iId8x8 << 2]], 0);
785 ST16 (&pNonZeroCount[g_kCacheNzcScanIdx[ (iId8x8 << 2) + 2]], 0);
786 }
787 }
788 ST32 (&pCurLayer->pNzc[iMbXy][0], LD32 (&pNonZeroCount[1 + 8 * 1]));
789 ST32 (&pCurLayer->pNzc[iMbXy][4], LD32 (&pNonZeroCount[1 + 8 * 2]));
790 ST32 (&pCurLayer->pNzc[iMbXy][8], LD32 (&pNonZeroCount[1 + 8 * 3]));
791 ST32 (&pCurLayer->pNzc[iMbXy][12], LD32 (&pNonZeroCount[1 + 8 * 4]));
792 }
793
794 //chroma
795 //step1: DC
796 if (1 == uiCbpChroma || 2 == uiCbpChroma) {
797 for (i = 0; i < 2; i++) {
798 int32_t iResProperty = i ? CHROMA_DC_V : CHROMA_DC_U;
799 WELS_READ_VERIFY (ParseResidualBlockCabac (pNeighAvail, pNonZeroCount, pBsAux, 16 + (i << 2), 4, g_kuiChromaDcScan,
800 iResProperty, pCurLayer->pScaledTCoeff[iMbXy] + 256 + (i << 6), pCurLayer->pChromaQp[iMbXy], pCtx));
801 }
802 }
803 //step2: AC
804 if (2 == uiCbpChroma) {
805 for (i = 0; i < 2; i++) {
806 int32_t iResProperty = i ? CHROMA_AC_V : CHROMA_AC_U;
807 int32_t index = 16 + (i << 2);
808 for (iId4x4 = 0; iId4x4 < 4; iId4x4++) {
809 WELS_READ_VERIFY (ParseResidualBlockCabac (pNeighAvail, pNonZeroCount, pBsAux, index,
810 iScanIdxEnd - WELS_MAX (iScanIdxStart, 1) + 1, g_kuiZigzagScan + WELS_MAX (iScanIdxStart, 1),
811 iResProperty, pCurLayer->pScaledTCoeff[iMbXy] + (index << 4), pCurLayer->pChromaQp[iMbXy], pCtx));
812 index++;
813 }
814 }
815 ST16 (&pCurLayer->pNzc[iMbXy][16], LD16 (&pNonZeroCount[6 + 8 * 1]));
816 ST16 (&pCurLayer->pNzc[iMbXy][20], LD16 (&pNonZeroCount[6 + 8 * 2]));
817 ST16 (&pCurLayer->pNzc[iMbXy][18], LD16 (&pNonZeroCount[6 + 8 * 4]));
818 ST16 (&pCurLayer->pNzc[iMbXy][22], LD16 (&pNonZeroCount[6 + 8 * 5]));
819 } else {
820 ST32 (&pCurLayer->pNzc[iMbXy][16], 0);
821 ST32 (&pCurLayer->pNzc[iMbXy][20], 0);
822 }
823 } else {
824 pCurLayer->pLumaQp[iMbXy] = pSlice->iLastMbQp;
825 pCurLayer->pChromaQp[iMbXy] = g_kuiChromaQpTable[WELS_CLIP3 (pCurLayer->pLumaQp[iMbXy] +
826 pSliceHeader->pPps->iChromaQpIndexOffset, 0, 51)];
827 }
828
829 WELS_READ_VERIFY (ParseEndOfSliceCabac (pCtx, uiEosFlag));
830 if (uiEosFlag) {
831 RestoreCabacDecEngineToBS (pCtx->pCabacDecEngine, pCtx->pCurDqLayer->pBitStringAux);
832 }
833
834 return ERR_NONE;
835}
836
837int32_t WelsDecodeMbCabacPSlice (PWelsDecoderContext pCtx, PNalUnit pNalCur, uint32_t& uiEosFlag) {
838 PDqLayer pCurLayer = pCtx->pCurDqLayer;
839 PSlice pSlice = &pCurLayer->sLayerInfo.sSliceInLayer;
840 PSliceHeader pSliceHeader = &pSlice->sSliceHeaderExt.sSliceHeader;
841 uint32_t uiCode;
842 int32_t iMbXy = pCurLayer->iMbXyIndex;
843 int32_t i;
844 SWelsNeighAvail uiNeighAvail;
845 pCurLayer->pCbp[iMbXy] = 0;
846 pCurLayer->pCbfDc[iMbXy] = 0;
847 pCurLayer->pChromaPredMode[iMbXy] = C_PRED_DC;
848
849 GetNeighborAvailMbType (&uiNeighAvail, pCurLayer);
850 WELS_READ_VERIFY (ParseSkipFlagCabac (pCtx, &uiNeighAvail, uiCode));
851 if (uiCode) {
852 int16_t pMv[2] = {0};
853 pCurLayer->pMbType[iMbXy] = MB_TYPE_SKIP;
854 ST32 (&pCurLayer->pNzc[iMbXy][0], 0);
855 ST32 (&pCurLayer->pNzc[iMbXy][4], 0);
856 ST32 (&pCurLayer->pNzc[iMbXy][8], 0);
857 ST32 (&pCurLayer->pNzc[iMbXy][12], 0);
858 ST32 (&pCurLayer->pNzc[iMbXy][16], 0);
859 ST32 (&pCurLayer->pNzc[iMbXy][20], 0);
860
861 pCurLayer->pInterPredictionDoneFlag[iMbXy] = 0;
862 memset (pCurLayer->pRefIndex[0][iMbXy], 0, sizeof (int8_t) * 16);
863
864 //predict mv
865 PredPSkipMvFromNeighbor (pCurLayer, pMv);
866 for (i = 0; i < 16; i++) {
867 ST32 (pCurLayer->pMv[0][iMbXy][i], * (uint32_t*)pMv);
868 ST32 (pCurLayer->pMvd[0][iMbXy][i], 0);
869 }
870
871 if (!pSlice->sSliceHeaderExt.bDefaultResidualPredFlag) {
872 memset (pCurLayer->pScaledTCoeff[iMbXy], 0, 384 * sizeof (int16_t));
873 }
874
875 //reset rS
876 pCurLayer->pLumaQp[iMbXy] = pSlice->iLastMbQp; //??????????????? dqaunt of previous mb
877 pCurLayer->pChromaQp[iMbXy] = g_kuiChromaQpTable[WELS_CLIP3 (pCurLayer->pLumaQp[iMbXy] +
878 pSliceHeader->pPps->iChromaQpIndexOffset, 0, 51)];
879
880 //for neighboring CABAC usage
881 pSlice->iLastDeltaQp = 0;
882
883 WELS_READ_VERIFY (ParseEndOfSliceCabac (pCtx, uiEosFlag));
884
885 return ERR_NONE;
886 }
887
888 WELS_READ_VERIFY (WelsDecodeMbCabacPSliceBaseMode0 (pCtx, &uiNeighAvail, uiEosFlag));
889 return ERR_NONE;
890}
891
321int32_t WelsDecodeSlice (PWelsDecoderContext pCtx, bool bFirstSliceInLayer, PNalUnit pNalCur) {892int32_t WelsDecodeSlice (PWelsDecoderContext pCtx, bool bFirstSliceInLayer, PNalUnit pNalCur) {
322 PDqLayer pCurLayer = pCtx->pCurDqLayer;893 PDqLayer pCurLayer = pCtx->pCurDqLayer;
323 PFmo pFmo = pCtx->pFmo;894 PFmo pFmo = pCtx->pFmo;
@@ -329,34 +900,50 @@ int32_t WelsDecodeSlice (PWelsDecoderContext pCtx, bool bFirstSliceInLayer, PNal · 5 unmodified lines
329 PSliceHeader pSliceHeader = &pSliceHeaderExt->sSliceHeader;900 PSliceHeader pSliceHeader = &pSliceHeaderExt->sSliceHeader;
330 int32_t iMbX, iMbY;901 int32_t iMbX, iMbY;
331 const int32_t kiCountNumMb = pSliceHeader->pSps->uiTotalMbCount; //need to be correct when fmo or multi slice902 const int32_t kiCountNumMb = pSliceHeader->pSps->uiTotalMbCount; //need to be correct when fmo or multi slice
332 PBitStringAux pBs = pCurLayer->pBitStringAux;903 uint32_t uiEosFlag = 0;
333 intX_t iUsedBits = 0;904 PWelsDecMbFunc pDecMbFunc;
334
335 PWelsDecMbCavlcFunc pDecMbCavlcFunc;
336 905
337 pSlice->iTotalMbInCurSlice = 0; //initialize at the starting of slice decoding.906 pSlice->iTotalMbInCurSlice = 0; //initialize at the starting of slice decoding.
338 907
339 if (P_SLICE == pSliceHeader->eSliceType) {908 if (pCtx->pPps->bEntropyCodingModeFlag) {
340 pDecMbCavlcFunc = WelsDecodeMbCavlcPSlice;909 if (pSlice->sSliceHeaderExt.bAdaptiveMotionPredFlag ||
341 } else { //I_SLICE910 pSlice->sSliceHeaderExt.bAdaptiveBaseModeFlag ||
342 pDecMbCavlcFunc = WelsDecodeMbCavlcISlice;911 pSlice->sSliceHeaderExt.bAdaptiveResidualPredFlag) {
912 WelsLog (& (pCtx->sLogCtx), WELS_LOG_ERROR,
913 "WelsDecodeSlice()::::ILP flag exist, not supported with CABAC enabled!");
914 pCtx->iErrorCode |= dsBitstreamError;
915 return dsBitstreamError;
916 }
917 if (P_SLICE == pSliceHeader->eSliceType)
918 pDecMbFunc = WelsDecodeMbCabacPSlice;
919 else //I_SLICE. B_SLICE not supported now
920 pDecMbFunc = WelsDecodeMbCabacISlice;
921 } else {
922 if (P_SLICE == pSliceHeader->eSliceType) {
923 pDecMbFunc = WelsDecodeMbCavlcPSlice;
924 } else { //I_SLICE
925 pDecMbFunc = WelsDecodeMbCavlcISlice;
926 }
343 }927 }
344 928
345 if (pSliceHeader->pPps->bConstainedIntraPredFlag) {929 if (pSliceHeader->pPps->bConstainedIntraPredFlag) {
346 pCtx->pFillInfoCacheIntra4x4Func = WelsFillCacheConstrain1Intra4x4;930 pCtx->pFillInfoCacheIntra4x4Func = WelsFillCacheConstrain1Intra4x4;
347 pCtx->pParseIntra4x4ModeFunc = ParseIntra4x4ModeConstrain1;931 pCtx->pMap4x4NeighToSampleFunc = WelsMap4x4NeighToSampleConstrain1;
348 pCtx->pParseIntra16x16ModeFunc = ParseIntra16x16ModeConstrain1;932 pCtx->pMap16x16NeighToSampleFunc = WelsMap16x16NeighToSampleConstrain1;
349 } else {933 } else {
350 pCtx->pFillInfoCacheIntra4x4Func = WelsFillCacheConstrain0Intra4x4;934 pCtx->pFillInfoCacheIntra4x4Func = WelsFillCacheConstrain0Intra4x4;
351 pCtx->pParseIntra4x4ModeFunc = ParseIntra4x4ModeConstrain0;935 pCtx->pMap4x4NeighToSampleFunc = WelsMap4x4NeighToSampleNormal;
352 pCtx->pParseIntra16x16ModeFunc = ParseIntra16x16ModeConstrain0;936 pCtx->pMap16x16NeighToSampleFunc = WelsMap16x16NeighToSampleNormal;
353 }937 }
354 938
355 pCtx->eSliceType = pSliceHeader->eSliceType;939 pCtx->eSliceType = pSliceHeader->eSliceType;
356
357 if (pCurLayer->sLayerInfo.pPps->bEntropyCodingModeFlag == 1) {940 if (pCurLayer->sLayerInfo.pPps->bEntropyCodingModeFlag == 1) {
358 //CABAC encoding is unsupported yet!941 int32_t iQp = pSlice->sSliceHeaderExt.sSliceHeader.iSliceQp;
359 return -1;942 int32_t iCabacInitIdc = pSlice->sSliceHeaderExt.sSliceHeader.iCabacInitIdc;
943 WelsCabacContextInit (pCtx, pSlice->eSliceType, iCabacInitIdc, iQp);
944 //InitCabacCtx (pCtx->pCabacCtx, pSlice->eSliceType, iCabacInitIdc, iQp);
945 pSlice->iLastDeltaQp = 0;
946 WELS_READ_VERIFY (InitCabacDecEngineFromBS (pCtx->pCabacDecEngine, pCtx->pCurDqLayer->pBitStringAux));
360 }947 }
361 948
362 iNextMbXyIndex = pSliceHeader->iFirstMbInSlice;949 iNextMbXyIndex = pSliceHeader->iFirstMbInSlice;
@@ -398,31 +985,21 @@ int32_t WelsDecodeSlice (PWelsDecoderContext pCtx, bool bFirstSliceInLayer, PNal · 35 unmodified lines
398 }985 }
399 986
400 pCurLayer->pSliceIdc[iNextMbXyIndex] = iSliceIdc;987 pCurLayer->pSliceIdc[iNextMbXyIndex] = iSliceIdc;
401 iRet = pDecMbCavlcFunc (pCtx, pNalCur);988 iRet = pDecMbFunc (pCtx, pNalCur, uiEosFlag);
402 989
403 if (iRet != ERR_NONE) {990 if (iRet != ERR_NONE) {
404 return iRet;991 return iRet;
405 }992 }
406 993
407 ++pSlice->iTotalMbInCurSlice;994 ++pSlice->iTotalMbInCurSlice;
408 995 if (uiEosFlag) { //end of slice
996 break;
997 }
409 if (pSliceHeader->pPps->uiNumSliceGroups > 1) {998 if (pSliceHeader->pPps->uiNumSliceGroups > 1) {
410 iNextMbXyIndex = FmoNextMb (pFmo, iNextMbXyIndex);999 iNextMbXyIndex = FmoNextMb (pFmo, iNextMbXyIndex);
411 } else {1000 } else {
412 ++iNextMbXyIndex;1001 ++iNextMbXyIndex;
413 }1002 }
414
415 // check whether there is left bits to read next time in case multiple slices
416 iUsedBits = ((pBs->pCurBuf - pBs->pStartBuf) << 3) - (16 - pBs->iLeftBits);
417 if (iUsedBits == pBs->iBits && 0 >= pCurLayer->sLayerInfo.sSliceInLayer.iMbSkipRun) { // slice boundary
418 break;
419 }
420 if (iUsedBits > pBs->iBits) { //When BS incomplete, as long as find it, SHOULD stop decoding to avoid mosaic or crash.
421 WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING,
422 "WelsDecodeSlice()::::pBs incomplete, iUsedBits:%" PRId64" > pBs->iBits:%d, MUST stop decoding.",
423 (int64_t) iUsedBits, pBs->iBits);
424 return -1;
425 }
426 iMbX = iNextMbXyIndex % pCurLayer->iMbWidth;1003 iMbX = iNextMbXyIndex % pCurLayer->iMbWidth;
427 iMbY = iNextMbXyIndex / pCurLayer->iMbWidth;1004 iMbY = iNextMbXyIndex / pCurLayer->iMbWidth;
428 pCurLayer->iMbX = iMbX;1005 pCurLayer->iMbX = iMbX;
@@ -440,7 +1017,7 @@ int32_t WelsActualDecodeMbCavlcISlice (PWelsDecoderContext pCtx) { · 11 unmodified lines
440 PSlice pSlice = &pCurLayer->sLayerInfo.sSliceInLayer;1017 PSlice pSlice = &pCurLayer->sLayerInfo.sSliceInLayer;
441 PSliceHeader pSliceHeader = &pSlice->sSliceHeaderExt.sSliceHeader;1018 PSliceHeader pSliceHeader = &pSlice->sSliceHeaderExt.sSliceHeader;
442 1019
443 SNeighAvail sNeighAvail;1020 SWelsNeighAvail sNeighAvail;
444 1021
445 int32_t iScanIdxStart = pSlice->sSliceHeaderExt.uiScanIdxStart;1022 int32_t iScanIdxStart = pSlice->sSliceHeaderExt.uiScanIdxStart;
446 int32_t iScanIdxEnd = pSlice->sSliceHeaderExt.uiScanIdxEnd;1023 int32_t iScanIdxEnd = pSlice->sSliceHeaderExt.uiScanIdxEnd;
@@ -455,11 +1032,11 @@ int32_t WelsActualDecodeMbCavlcISlice (PWelsDecoderContext pCtx) { · 8 unmodified lines
455 int32_t iCode;1032 int32_t iCode;
456 1033
457 ENFORCE_STACK_ALIGN_1D (uint8_t, pNonZeroCount, 48, 16);1034 ENFORCE_STACK_ALIGN_1D (uint8_t, pNonZeroCount, 48, 16);
458 1035 GetNeighborAvailMbType (&sNeighAvail, pCurLayer);
459 pCurLayer->pInterPredictionDoneFlag[iMbXy] = 0;1036 pCurLayer->pInterPredictionDoneFlag[iMbXy] = 0;
460 pCurLayer->pResidualPredFlag[iMbXy] = pSlice->sSliceHeaderExt.bDefaultResidualPredFlag;1037 pCurLayer->pResidualPredFlag[iMbXy] = pSlice->sSliceHeaderExt.bDefaultResidualPredFlag;
461 1038
462 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //mb_type1039 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //uiMbType
463 uiMbType = uiCode;1040 uiMbType = uiCode;
464 if (uiMbType > 25) {1041 if (uiMbType > 25) {
465 return ERR_INFO_INVALID_MB_TYPE;1042 return ERR_INFO_INVALID_MB_TYPE;
@@ -508,20 +1085,18 @@ int32_t WelsActualDecodeMbCavlcISlice (PWelsDecoderContext pCtx) { · 42 unmodified lines
508 }1085 }
509 1086
510 pBs->pCurBuf += 384;1087 pBs->pCurBuf += 384;
511 InitReadBits (pBs);
512 1088
513 //step 3: update QP and pNonZeroCount1089 //step 3: update QP and pNonZeroCount
514 pCurLayer->pLumaQp[iMbXy] = 0;1090 pCurLayer->pLumaQp[iMbXy] = 0;
515 pCurLayer->pChromaQp[iMbXy] = 0;1091 pCurLayer->pChromaQp[iMbXy] = 0;
516 memset (pNzc, 16, sizeof (pCurLayer->pNzc[iMbXy])); //Rec. 9.2.1 for PCM, nzc=161092 memset (pNzc, 16, sizeof (pCurLayer->pNzc[iMbXy])); //Rec. 9.2.1 for PCM, nzc=16
1093 WELS_READ_VERIFY(InitReadBits (pBs, 0));
517 return 0;1094 return 0;
518 } else if (0 == uiMbType) { //reference to JM1095 } else if (0 == uiMbType) { //reference to JM
519 ENFORCE_STACK_ALIGN_1D (int8_t, pIntraPredMode, 48, 16);1096 ENFORCE_STACK_ALIGN_1D (int8_t, pIntraPredMode, 48, 16);
520 pCurLayer->pMbType[iMbXy] = MB_TYPE_INTRA4x4;1097 pCurLayer->pMbType[iMbXy] = MB_TYPE_INTRA4x4;
521 pCtx->pFillInfoCacheIntra4x4Func (&sNeighAvail, pNonZeroCount, pIntraPredMode, pCurLayer);1098 pCtx->pFillInfoCacheIntra4x4Func (&sNeighAvail, pNonZeroCount, pIntraPredMode, pCurLayer);
522 if (pCtx->pParseIntra4x4ModeFunc (&sNeighAvail, pIntraPredMode, pBs, pCurLayer)) {1099 WELS_READ_VERIFY (ParseIntra4x4Mode (pCtx, &sNeighAvail, pIntraPredMode, pBs, pCurLayer));
523 return -1;
524 }
525 1100
526 //uiCbp1101 //uiCbp
527 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //coded_block_pattern1102 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //coded_block_pattern
@@ -542,9 +1117,7 @@ int32_t WelsActualDecodeMbCavlcISlice (PWelsDecoderContext pCtx) { · 14 unmodified lines
542 uiCbpC = pCurLayer->pCbp[iMbXy] >> 4;1117 uiCbpC = pCurLayer->pCbp[iMbXy] >> 4;
543 uiCbpL = pCurLayer->pCbp[iMbXy] & 15;1118 uiCbpL = pCurLayer->pCbp[iMbXy] & 15;
544 WelsFillCacheNonZeroCount (&sNeighAvail, pNonZeroCount, pCurLayer);1119 WelsFillCacheNonZeroCount (&sNeighAvail, pNonZeroCount, pCurLayer);
545 if (pCtx->pParseIntra16x16ModeFunc (&sNeighAvail, pBs, pCurLayer)) {1120 WELS_READ_VERIFY (ParseIntra16x16Mode (pCtx, &sNeighAvail, pBs, pCurLayer));
546 return -1;
547 }
548 }1121 }
549 1122
550 memset (pCurLayer->pScaledTCoeff[iMbXy], 0, 384 * sizeof (pCurLayer->pScaledTCoeff[iMbXy][0]));1123 memset (pCurLayer->pScaledTCoeff[iMbXy], 0, 384 * sizeof (pCurLayer->pScaledTCoeff[iMbXy][0]));
@@ -572,19 +1145,7 @@ int32_t WelsActualDecodeMbCavlcISlice (PWelsDecoderContext pCtx) { · 21 unmodified lines
572 return ERR_INFO_INVALID_QP;1145 return ERR_INFO_INVALID_QP;
573 }1146 }
574 1147
575 pCurLayer->pLumaQp[iMbXy] = pSlice->iLastMbQp + iQpDelta; //update iLastMbQp1148 pCurLayer->pLumaQp[iMbXy] = (pSlice->iLastMbQp + iQpDelta + 52) % 52; //update last_mb_qp
576 //refer to JVT-X201wcm1.doc equation(7-35)
577 if ((unsigned) (pCurLayer->pLumaQp[iMbXy]) > 51) {
578 if (pCurLayer->pLumaQp[iMbXy] < 0) {
579 pCurLayer->pLumaQp[iMbXy] += 52;
580 } else {
581 pCurLayer->pLumaQp[iMbXy] -= 52;
582 }
583 }
584 //QP should be in the range of [0, 51]
585 if (pCurLayer->pLumaQp[iMbXy] < 0 || pCurLayer->pLumaQp[iMbXy] > 51) {
586 return ERR_INFO_INVALID_QP;
587 }
588 pSlice->iLastMbQp = pCurLayer->pLumaQp[iMbXy];1149 pSlice->iLastMbQp = pCurLayer->pLumaQp[iMbXy];
589 pCurLayer->pChromaQp[iMbXy] = g_kuiChromaQpTable[WELS_CLIP3 (pSlice->iLastMbQp +1150 pCurLayer->pChromaQp[iMbXy] = g_kuiChromaQpTable[WELS_CLIP3 (pSlice->iLastMbQp +
590 pSliceHeader->pPps->iChromaQpIndexOffset, 0,1151 pSliceHeader->pPps->iChromaQpIndexOffset, 0,
@@ -673,14 +1234,14 @@ int32_t WelsActualDecodeMbCavlcISlice (PWelsDecoderContext pCtx) { · 82 unmodified lines
673 return 0;1234 return 0;
674}1235}
675 1236
676int32_t WelsDecodeMbCavlcISlice (PWelsDecoderContext pCtx, PNalUnit pNalCur) {1237int32_t WelsDecodeMbCavlcISlice (PWelsDecoderContext pCtx, PNalUnit pNalCur, uint32_t& uiEosFlag) {
677 PDqLayer pCurLayer = pCtx->pCurDqLayer;1238 PDqLayer pCurLayer = pCtx->pCurDqLayer;
678 PBitStringAux pBs = pCurLayer->pBitStringAux;1239 PBitStringAux pBs = pCurLayer->pBitStringAux;
679 PSliceHeaderExt pSliceHeaderExt = &pCurLayer->sLayerInfo.sSliceInLayer.sSliceHeaderExt;1240 PSliceHeaderExt pSliceHeaderExt = &pCurLayer->sLayerInfo.sSliceInLayer.sSliceHeaderExt;
680 int32_t iBaseModeFlag;1241 int32_t iBaseModeFlag;
681 int32_t iRet = 0; //should have the return value to indicate decoding error or not, It's NECESSARY--2010.4.151242 int32_t iRet = 0; //should have the return value to indicate decoding error or not, It's NECESSARY--2010.4.15
682 uint32_t uiCode;1243 uint32_t uiCode;
683 1244 intX_t iUsedBits;
684 if (pSliceHeaderExt->bAdaptiveBaseModeFlag == 1) {1245 if (pSliceHeaderExt->bAdaptiveBaseModeFlag == 1) {
685 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //base_mode_flag1246 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //base_mode_flag
686 iBaseModeFlag = uiCode;1247 iBaseModeFlag = uiCode;
@@ -698,6 +1259,19 @@ int32_t WelsDecodeMbCavlcISlice (PWelsDecoderContext pCtx, PNalUnit pNalCur) { · 11 unmodified lines
698 return iRet;1259 return iRet;
699 }1260 }
700 1261
1262 // check whether there is left bits to read next time in case multiple slices
1263 iUsedBits = ((pBs->pCurBuf - pBs->pStartBuf) << 3) - (16 - pBs->iLeftBits);
1264 // sub 1, for stop bit
1265 if ((iUsedBits == (pBs->iBits - 1)) && (0 >= pCurLayer->sLayerInfo.sSliceInLayer.iMbSkipRun)) { // slice boundary
1266 uiEosFlag = 1;
1267 }
1268 if (iUsedBits > (pBs->iBits -
1269 1)) { //When BS incomplete, as long as find it, SHOULD stop decoding to avoid mosaic or crash.
1270 WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING,
1271 "WelsDecodeMbCavlcISlice()::::pBs incomplete, iUsedBits:%"PRId64" > pBs->iBits:%d, MUST stop decoding.",
1272 (int64_t) iUsedBits, pBs->iBits);
1273 return -1;
1274 }
701 return 0;1275 return 0;
702}1276}
703 1277
@@ -708,11 +1282,10 @@ int32_t WelsActualDecodeMbCavlcPSlice (PWelsDecoderContext pCtx) { · 4 unmodified lines
708 PSlice pSlice = &pCurLayer->sLayerInfo.sSliceInLayer;1282 PSlice pSlice = &pCurLayer->sLayerInfo.sSliceInLayer;
709 PSliceHeader pSliceHeader = &pSlice->sSliceHeaderExt.sSliceHeader;1283 PSliceHeader pSliceHeader = &pSlice->sSliceHeaderExt.sSliceHeader;
710 1284
711 SNeighAvail sNeighAvail;
712
713 int32_t iScanIdxStart = pSlice->sSliceHeaderExt.uiScanIdxStart;1285 int32_t iScanIdxStart = pSlice->sSliceHeaderExt.uiScanIdxStart;
714 int32_t iScanIdxEnd = pSlice->sSliceHeaderExt.uiScanIdxEnd;1286 int32_t iScanIdxEnd = pSlice->sSliceHeaderExt.uiScanIdxEnd;
715 1287
1288 SWelsNeighAvail sNeighAvail;
716 int32_t iMbX = pCurLayer->iMbX;1289 int32_t iMbX = pCurLayer->iMbX;
717 int32_t iMbY = pCurLayer->iMbY;1290 int32_t iMbY = pCurLayer->iMbY;
718 const int32_t iMbXy = pCurLayer->iMbXyIndex;1291 const int32_t iMbXy = pCurLayer->iMbXyIndex;
@@ -721,15 +1294,13 @@ int32_t WelsActualDecodeMbCavlcPSlice (PWelsDecoderContext pCtx) { · 2 unmodified lines
721 uint32_t uiMbType = 0, uiCbp = 0, uiCbpL = 0, uiCbpC = 0;1294 uint32_t uiMbType = 0, uiCbp = 0, uiCbpL = 0, uiCbpC = 0;
722 uint32_t uiCode;1295 uint32_t uiCode;
723 int32_t iCode;1296 int32_t iCode;
724 1297 GetNeighborAvailMbType (&sNeighAvail, pCurLayer);
725 ENFORCE_STACK_ALIGN_1D (uint8_t, pNonZeroCount, 48, 16);1298 ENFORCE_STACK_ALIGN_1D (uint8_t, pNonZeroCount, 48, 16);
726 pCurLayer->pInterPredictionDoneFlag[iMbXy] = 0;//2009.10.231299 pCurLayer->pInterPredictionDoneFlag[iMbXy] = 0;//2009.10.23
727 1300 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //uiMbType
728 WELS_READ_VERIFY (BsGetUe (pBs, &uiCode)); //mb_type
729 uiMbType = uiCode;1301 uiMbType = uiCode;
730 if (uiMbType < 5) { //inter MB type1302 if (uiMbType < 5) { //inter MB type
731 int16_t iMotionVector[LIST_A][30][MV_A];1303 int16_t iMotionVector[LIST_A][30][MV_A];
732
733 int8_t iRefIndex[LIST_A][30];1304 int8_t iRefIndex[LIST_A][30];
734 pCurLayer->pMbType[iMbXy] = g_ksInterMbTypeInfo[uiMbType].iType;1305 pCurLayer->pMbType[iMbXy] = g_ksInterMbTypeInfo[uiMbType].iType;
735 WelsFillCacheInter (&sNeighAvail, pNonZeroCount, iMotionVector, iRefIndex, pCurLayer);1306 WelsFillCacheInter (&sNeighAvail, pNonZeroCount, iMotionVector, iRefIndex, pCurLayer);
@@ -800,7 +1371,6 @@ int32_t WelsActualDecodeMbCavlcPSlice (PWelsDecoderContext pCtx) { · 64 unmodified lines
800 }1371 }
801 1372
802 pBs->pCurBuf += 384;1373 pBs->pCurBuf += 384;
803 InitReadBits (pBs);
804 1374
805 //step 3: update QP and pNonZeroCount1375 //step 3: update QP and pNonZeroCount
806 pCurLayer->pLumaQp[iMbXy] = 0;1376 pCurLayer->pLumaQp[iMbXy] = 0;
@@ -812,13 +1382,14 @@ int32_t WelsActualDecodeMbCavlcPSlice (PWelsDecoderContext pCtx) { · 5 unmodified lines
812 ST32A4 (&pNzc[12], 0x10101010);1382 ST32A4 (&pNzc[12], 0x10101010);
813 ST32A4 (&pNzc[16], 0x10101010);1383 ST32A4 (&pNzc[16], 0x10101010);
814 ST32A4 (&pNzc[20], 0x10101010);1384 ST32A4 (&pNzc[20], 0x10101010);
1385 WELS_READ_VERIFY (InitReadBits (pBs, 0));
815 return 0;1386 return 0;
816 } else {1387 } else {
817 if (0 == uiMbType) {1388 if (0 == uiMbType) {
818 ENFORCE_STACK_ALIGN_1D (int8_t, pIntraPredMode, 48, 16);1389 ENFORCE_STACK_ALIGN_1D (int8_t, pIntraPredMode, 48, 16);
819 pCurLayer->pMbType[iMbXy] = MB_TYPE_INTRA4x4;1390 pCurLayer->pMbType[iMbXy] = MB_TYPE_INTRA4x4;
820 pCtx->pFillInfoCacheIntra4x4Func (&sNeighAvail, pNonZeroCount, pIntraPredMode, pCurLayer);1391 pCtx->pFillInfoCacheIntra4x4Func (&sNeighAvail, pNonZeroCount, pIntraPredMode, pCurLayer);
821 if (pCtx->pParseIntra4x4ModeFunc (&sNeighAvail, pIntraPredMode, pBs, pCurLayer)) {1392 if (ParseIntra4x4Mode (pCtx, &sNeighAvail, pIntraPredMode, pBs, pCurLayer)) {
822 return -1;1393 return -1;
823 }1394 }
824 } else { //I_PCM exclude, we can ignore it1395 } else { //I_PCM exclude, we can ignore it
@@ -828,7 +1399,7 @@ int32_t WelsActualDecodeMbCavlcPSlice (PWelsDecoderContext pCtx) { · 3 unmodified lines
828 uiCbpC = pCurLayer->pCbp[iMbXy] >> 4;1399 uiCbpC = pCurLayer->pCbp[iMbXy] >> 4;
829 uiCbpL = pCurLayer->pCbp[iMbXy] & 15;1400 uiCbpL = pCurLayer->pCbp[iMbXy] & 15;
830 WelsFillCacheNonZeroCount (&sNeighAvail, pNonZeroCount, pCurLayer);1401 WelsFillCacheNonZeroCount (&sNeighAvail, pNonZeroCount, pCurLayer);
831 if (pCtx->pParseIntra16x16ModeFunc (&sNeighAvail, pBs, pCurLayer)) {1402 if (ParseIntra16x16Mode (pCtx, &sNeighAvail, pBs, pCurLayer)) {
832 return -1;1403 return -1;
833 }1404 }
834 }1405 }
@@ -877,19 +1448,7 @@ int32_t WelsActualDecodeMbCavlcPSlice (PWelsDecoderContext pCtx) { · 42 unmodified lines
877 return ERR_INFO_INVALID_QP;1448 return ERR_INFO_INVALID_QP;
878 }1449 }
879 1450
880 pCurLayer->pLumaQp[iMbXy] = pSlice->iLastMbQp + iQpDelta; //update iLastMbQp1451 pCurLayer->pLumaQp[iMbXy] = (pSlice->iLastMbQp + iQpDelta + 52) % 52; //update last_mb_qp
881 //refer to JVT-X201wcm1.doc equation(7-35)
882 if ((unsigned) (pCurLayer->pLumaQp[iMbXy]) > 51) {
883 if (pCurLayer->pLumaQp[iMbXy] < 0) {
884 pCurLayer->pLumaQp[iMbXy] += 52;
885 } else {
886 pCurLayer->pLumaQp[iMbXy] -= 52;
887 }
888 }
889 //QP should be in the range of [0, 51]
890 if (pCurLayer->pLumaQp[iMbXy] < 0 || pCurLayer->pLumaQp[iMbXy] > 51) {
891 return ERR_INFO_INVALID_QP;
892 }
893 pSlice->iLastMbQp = pCurLayer->pLumaQp[iMbXy];1452 pSlice->iLastMbQp = pCurLayer->pLumaQp[iMbXy];
894 pCurLayer->pChromaQp[iMbXy] = g_kuiChromaQpTable[WELS_CLIP3 (pSlice->iLastMbQp +1453 pCurLayer->pChromaQp[iMbXy] = g_kuiChromaQpTable[WELS_CLIP3 (pSlice->iLastMbQp +
895 pSliceHeader->pPps->iChromaQpIndexOffset, 0,1454 pSliceHeader->pPps->iChromaQpIndexOffset, 0,
@@ -978,12 +1537,12 @@ int32_t WelsActualDecodeMbCavlcPSlice (PWelsDecoderContext pCtx) { · 82 unmodified lines
978 return 0;1537 return 0;
979}1538}
980 1539
981int32_t WelsDecodeMbCavlcPSlice (PWelsDecoderContext pCtx, PNalUnit pNalCur) {1540int32_t WelsDecodeMbCavlcPSlice (PWelsDecoderContext pCtx, PNalUnit pNalCur, uint32_t& uiEosFlag) {
982 PDqLayer pCurLayer = pCtx->pCurDqLayer;1541 PDqLayer pCurLayer = pCtx->pCurDqLayer;
983 PBitStringAux pBs = pCurLayer->pBitStringAux;1542 PBitStringAux pBs = pCurLayer->pBitStringAux;
984 PSlice pSlice = &pCurLayer->sLayerInfo.sSliceInLayer;1543 PSlice pSlice = &pCurLayer->sLayerInfo.sSliceInLayer;
985 PSliceHeader pSliceHeader = &pSlice->sSliceHeaderExt.sSliceHeader;1544 PSliceHeader pSliceHeader = &pSlice->sSliceHeaderExt.sSliceHeader;
986 1545 intX_t iUsedBits;
987 const int32_t iMbXy = pCurLayer->iMbXyIndex;1546 const int32_t iMbXy = pCurLayer->iMbXyIndex;
988 int8_t* pNzc = pCurLayer->pNzc[iMbXy];1547 int8_t* pNzc = pCurLayer->pNzc[iMbXy];
989 int32_t iBaseModeFlag, i;1548 int32_t iBaseModeFlag, i;
@@ -996,7 +1555,6 @@ int32_t WelsDecodeMbCavlcPSlice (PWelsDecoderContext pCtx, PNalUnit pNalCur) { · 6 unmodified lines
996 if (-1 == pSlice->iMbSkipRun) {1555 if (-1 == pSlice->iMbSkipRun) {
997 return -1;1556 return -1;
998 }1557 }
999
1000 }1558 }
1001 if (pSlice->iMbSkipRun--) {1559 if (pSlice->iMbSkipRun--) {
1002 int16_t iMv[2];1560 int16_t iMv[2];
@@ -1031,27 +1589,37 @@ int32_t WelsDecodeMbCavlcPSlice (PWelsDecoderContext pCtx, PNalUnit pNalCur) { · 28 unmodified lines
1031 }1589 }
1032 1590
1033 pCurLayer->pCbp[iMbXy] = 0;1591 pCurLayer->pCbp[iMbXy] = 0;
1034
1035 return 0;
1036 }
1037
1038 if (pSlice->sSliceHeaderExt.bAdaptiveBaseModeFlag == 1) {
1039 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //base_mode_flag
1040 iBaseModeFlag = uiCode;
1041 } else {1592 } else {
1042 iBaseModeFlag = pSlice->sSliceHeaderExt.bDefaultBaseModeFlag;1593 if (pSlice->sSliceHeaderExt.bAdaptiveBaseModeFlag == 1) {
1594 WELS_READ_VERIFY (BsGetOneBit (pBs, &uiCode)); //base_mode_flag
1595 iBaseModeFlag = uiCode;
1596 } else {
1597 iBaseModeFlag = pSlice->sSliceHeaderExt.bDefaultBaseModeFlag;
1598 }
1599 if (!iBaseModeFlag) {
1600 iRet = WelsActualDecodeMbCavlcPSlice (pCtx);
1601 } else {
1602 WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "iBaseModeFlag (%d) != 0, inter-layer prediction not supported.",
1603 iBaseModeFlag);
1604 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_UNSUPPORTED_ILP);
1605 }
1606 if (iRet) { //occur error when parsing, MUST STOP decoding
1607 return iRet;
1608 }
1043 }1609 }
1044 if (!iBaseModeFlag) {1610 // check whether there is left bits to read next time in case multiple slices
1045 iRet = WelsActualDecodeMbCavlcPSlice (pCtx);1611 iUsedBits = ((pBs->pCurBuf - pBs->pStartBuf) << 3) - (16 - pBs->iLeftBits);
1046 } else {1612 // sub 1, for stop bit
1047 WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING, "iBaseModeFlag (%d) != 0, inter-layer prediction not supported.",1613 if ((iUsedBits == (pBs->iBits - 1)) && (0 >= pCurLayer->sLayerInfo.sSliceInLayer.iMbSkipRun)) { // slice boundary
1048 iBaseModeFlag);1614 uiEosFlag = 1;
1049 return GENERATE_ERROR_NO (ERR_LEVEL_SLICE_HEADER, ERR_INFO_UNSUPPORTED_ILP);
1050 }1615 }
1051 if (iRet) { //occur error when parsing, MUST STOP decoding1616 if (iUsedBits > (pBs->iBits -
1052 return iRet;1617 1)) { //When BS incomplete, as long as find it, SHOULD stop decoding to avoid mosaic or crash.
1618 WelsLog (& (pCtx->sLogCtx), WELS_LOG_WARNING,
1619 "WelsDecodeMbCavlcISlice()::::pBs incomplete, iUsedBits:%"PRId64" > pBs->iBits:%d, MUST stop decoding.",
1620 (int64_t) iUsedBits, pBs->iBits);
1621 return -1;
1053 }1622 }
1054
1055 return 0;1623 return 0;
1056}1624}
1057 1625
@@ -1069,6 +1637,21 @@ void WelsBlockFuncInit (SBlockFunc* pFunc, int32_t iCpu) { · 11 unmodified lines
1069 pFunc->pWelsSetNonZeroCountFunc = SetNonZeroCount_AArch64_neon;1637 pFunc->pWelsSetNonZeroCountFunc = SetNonZeroCount_AArch64_neon;
1070 }1638 }
1071#endif1639#endif
1640
1641 pFunc->pWelsBlockZero16x16Func = WelsBlockZero16x16_c;
1642 pFunc->pWelsBlockZero8x8Func = WelsBlockZero8x8_c;
1643 //TO DO add neon and X86
1644#ifdef HAVE_NEON
1645 if (iCpu & WELS_CPU_NEON) {
1646
1647 }
1648#endif
1649
1650#ifdef HAVE_NEON_AARCH64
1651 if (iCpu & WELS_CPU_NEON) {
1652
1653 }
1654#endif
1072}1655}
1073 1656
1074void SetNonZeroCount_c (int8_t* pNonZeroCount) {1657void SetNonZeroCount_c (int8_t* pNonZeroCount) {
@@ -1079,4 +1662,21 @@ void SetNonZeroCount_c (int8_t* pNonZeroCount) { · 4 unmodified lines
1079 }1662 }
1080}1663}
1081 1664
1665void WelsBlockInit (int16_t* pBlock, int iW, int iH, int iStride, uint8_t uiVal) {
1666 int32_t i;
1667 int16_t* pDst = pBlock;
1668
1669 for (i = 0; i < iH; i++) {
1670 memset (pDst, uiVal, iW * sizeof (int16_t));
1671 pDst += iStride;
1672 }
1673}
1674void WelsBlockZero16x16_c (int16_t* pBlock, int32_t iStride) {
1675 WelsBlockInit (pBlock, 16, 16, iStride, 0);
1676}
1677
1678void WelsBlockZero8x8_c (int16_t* pBlock, int32_t iStride) {
1679 WelsBlockInit (pBlock, 8, 8, iStride, 0);
1680}
1681
1082} // namespace WelsDec1682} // namespace WelsDec

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t