⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mp4decvop.c

📁 audio-video-codecs.rar语音编解码器
💻 C
📖 第 1 页 / 共 5 页
字号:
            predDir = IPPVC_SCAN_HORIZONTAL;
            dcP = dcC;
        } else {
            predDir = IPPVC_SCAN_VERTICAL;
            dcP = dcA;
        }
        scan = IPPVC_SCAN_ZIGZAG;
        if (pInfo->VisualObject.VideoObject.VideoObjectPlane.alternate_vertical_scan_flag)
            scan = IPPVC_SCAN_VERTICAL;
        else if (ac_pred_flag)
            scan = predDir;
        // decode coeffs
        if (dcVLC) {
            if (ippiDecodeDCIntra_MPEG4_1u16s(&pInfo->bufptr, &pInfo->bitoff, coeff, (blockNum < 4) ? IPPVC_BLOCK_LUMA : IPPVC_BLOCK_CHROMA) != ippStsNoErr) {
                mp4_Error("Error: decoding DC coefficient of Intra block");
                return MP4_STATUS_ERROR;
            }
        }
        if (pat & pm) {
            if (ippiDecodeCoeffsIntra_MPEG4_1u16s(&pInfo->bufptr, &pInfo->bitoff, coeff, &lnz, 0, dcVLC, scan) != ippStsNoErr) {
                mp4_Error("Error: decoding coefficients of Intra block");
                return MP4_STATUS_ERROR;
            }
            mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTRA_AC);
        } else {
            if (dcVLC)
                sDC = coeff[0];
            mp4_Zero64_16s(coeff);
            mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTRA_DC);
            lnz = 0;
            if (dcVLC)
                coeff[0] = sDC;
        }
        // predict DC
        dcScaler = (blockNum < 4) ? mp4_DCScalerLuma[quant] : mp4_DCScalerChroma[quant];
        dc = coeff[0] + mp4_DivIntraDC(dcP, dcScaler);
        mp4_CLIP(dc, -2048, 2047);
        coeff[0] = (Ipp16s)dc;
        // predict AC
        nz = 0;
        if (ac_pred_flag) {
            if (predDir == IPPVC_SCAN_HORIZONTAL && (bCurr->predC->dct_dc >= 0)) {
                predAcC = bCurr->predC->dct_acC;
                predQuantC = (blockNum == 2 || blockNum == 3) ? quant : pInfo->VisualObject.VideoObject.IntraPredBuff.quant[x+1];
                if (predQuantC == quant)
                    for (k = 1; k < 8; k ++) {
                        coeff[k] = (Ipp16s)(coeff[k] + predAcC[k]);
                        if (coeff[k]) {
                            mp4_CLIP(coeff[k], -2048, 2047);
                            nz = 1;
                        }
                    }
                else
                    for (k = 1; k < 8; k ++) {
                        coeff[k] = (Ipp16s)(coeff[k] + mp4_DivIntraAC(predAcC[k] * predQuantC, quant));
                        if (coeff[k]) {
                            mp4_CLIP(coeff[k], -2048, 2047);
                            nz = 1;
                        }
                    }
            } else if (predDir == IPPVC_SCAN_VERTICAL && (bCurr->predA->dct_dc >= 0)) {
                predAcA = bCurr->predA->dct_acA;
                predQuantA = (blockNum == 1 || blockNum == 3) ? quant : pInfo->VisualObject.VideoObject.IntraPredBuff.quant[x];
                if (predQuantA == quant)
                    for (k = 1; k < 8; k ++) {
                        coeff[k*8] = (Ipp16s)(coeff[k*8] + predAcA[k]);
                        if (coeff[k*8]) {
                            mp4_CLIP(coeff[k*8], -2048, 2047);
                            nz = 1;
                        }
                    }
                else
                    for (k = 1; k < 8; k ++) {
                        coeff[k*8] = (Ipp16s)(coeff[k*8] + mp4_DivIntraAC(predAcA[k] * predQuantA, quant));
                        if (coeff[k*8]) {
                            mp4_CLIP(coeff[k*8], -2048, 2047);
                            nz = 1;
                        }
                    }
            }
        }
        // copy predicted AC for future Prediction
        for (k = 1; k < 8; k ++) {
            bCurr[6].dct_acC[k] = coeff[k];
            bCurr[6].dct_acA[k] = coeff[k*8];
        }
        if ((nz | lnz) || (pInfo->VisualObject.VideoObject.quant_type == 1)) {
            ippiQuantInvIntra_MPEG4_16s_C1I(coeff, 63, pInfo->VisualObject.VideoObject.QuantInvIntraSpec, quant, (blockNum < 4) ? IPPVC_BLOCK_LUMA : IPPVC_BLOCK_CHROMA);
            lnz = 63;
        } else {
            k = coeff[0] * dcScaler;
            mp4_CLIP(k, -2048, 2047);
            coeff[0] = (Ipp16s)k;
        }
        // copy DC for future Prediction
        if (blockNum >= 3)
            pInfo->VisualObject.VideoObject.IntraPredBuff.dcB[blockNum].dct_dc = bCurr[6].dct_dc;
        bCurr[6].dct_dc = coeff[0];
        // copy quant
        if (blockNum == 5)
            pInfo->VisualObject.VideoObject.IntraPredBuff.quant[x+1] = (Ipp8u)quant;
        lastNZ[blockNum] = lnz;
        pm >>= 1;
        coeff += 64;
    }
    return MP4_STATUS_OK;
}

mp4_Status mp4_DecodeInterMB(mp4_Info *pInfo, Ipp16s *coeffMB, Ipp32s quant, Ipp32s pat, Ipp32s scan)
{
    Ipp32s   i, lnz, pm = 32;
    Ipp16s *coeff = coeffMB;

    for (i = 0; i < 6; i ++) {
        if ((pat) & pm) {
            if (ippiReconstructCoeffsInter_MPEG4_1u16s(&pInfo->bufptr, &pInfo->bitoff, coeff, &lnz, pInfo->VisualObject.VideoObject.reversible_vlc, scan, pInfo->VisualObject.VideoObject.QuantInvInterSpec, quant) != ippStsNoErr) {
                mp4_Error("Error: decoding coefficients of Inter block");
                return MP4_STATUS_ERROR;
            }
            if (pInfo->VisualObject.VideoObject.quant_type == 0 || (coeff[63] == 0)) {
                if (lnz != 0) {
                    if (scan == IPPVC_SCAN_ZIGZAG) {
                        if ((lnz <= 4) && (coeff[16] == 0))
                            ippiDCT8x8Inv_2x2_16s_C1I(coeff);
                        else if ((lnz <= 13) && (coeff[32] == 0))
                            ippiDCT8x8Inv_4x4_16s_C1I(coeff);
                        else
                            ippiDCT8x8Inv_16s_C1I(coeff);
                    } else {  // IPPVC_SCAN_VERTICAL
                        if ((lnz <= 5) && (coeff[16] == 0) && (coeff[24] == 0))
                            ippiDCT8x8Inv_2x2_16s_C1I(coeff);
                        else if (lnz <= 9)
                            ippiDCT8x8Inv_4x4_16s_C1I(coeff);
                        else
                            ippiDCT8x8Inv_16s_C1I(coeff);
                    }
                } else {
                    mp4_Set64_16s((Ipp16s)((coeff[0] + 4) >> 3), coeff);
                }
            } else {
                ippiDCT8x8Inv_16s_C1I(coeff);
            }
            mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTER_C);
        } else {
            mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTER_NC);
        }
        pm >>= 1;
        coeff += 64;
    }
    return MP4_STATUS_OK;
}

void mp4_DCTInvCoeffsInterMB(mp4_Info *pInfo, Ipp16s *coeffMB, Ipp32s lastNZ[], Ipp32s pat, Ipp32s scan)
{
    Ipp32s   i, lnz, pm = 32;
    Ipp16s *coeff = coeffMB;

    for (i = 0; i < 6; i ++) {
        if ((pat) & pm) {
            if (pInfo->VisualObject.VideoObject.quant_type == 0 || (coeff[63] == 0)) {
                lnz = lastNZ[i];
                if (lnz != 0) {
                    if (scan == IPPVC_SCAN_ZIGZAG) {
                        if ((lnz <= 4) && (coeff[16] == 0))
                            ippiDCT8x8Inv_2x2_16s_C1I(coeff);
                        else if ((lnz <= 13) && (coeff[32] == 0))
                            ippiDCT8x8Inv_4x4_16s_C1I(coeff);
                        else
                            ippiDCT8x8Inv_16s_C1I(coeff);
                    } else {  // IPPVC_SCAN_VERTICAL
                        if ((lnz <= 5) && (coeff[16] == 0) && (coeff[24] == 0))
                            ippiDCT8x8Inv_2x2_16s_C1I(coeff);
                        else if (lnz <= 9)
                            ippiDCT8x8Inv_4x4_16s_C1I(coeff);
                        else
                            ippiDCT8x8Inv_16s_C1I(coeff);
                    }
                } else {
                    mp4_Set64_16s((Ipp16s)((coeff[0] + 4) >> 3), coeff);
                }
            } else {
                ippiDCT8x8Inv_16s_C1I(coeff);
            }
        }
        pm >>= 1;
        coeff += 64;
    }
}

/*
//  decode mcbpc and set MBtype and ChromaPattern
*/
mp4_Status mp4_DecodeMCBPC_P(mp4_Info* pInfo, Ipp32s *mbType, Ipp32s *mbPattern, Ipp32s stat)
{
    Ipp32u      code;
    Ipp32s      type, pattern;

    code = mp4_ShowBits9(pInfo, 9);
    if (code >= 256) {
        type = IPPVC_MBTYPE_INTER;
        pattern = 0;
        mp4_FlushBits(pInfo, 1);
    } else {
        type = mp4_PVOPmb_type[code];
        pattern = mp4_PVOPmb_cbpc[code];
        mp4_FlushBits(pInfo, mp4_PVOPmb_bits[code]);
    }
    if (code == 0) {
        mp4_Error("Error: decoding MCBPC");
        return MP4_STATUS_ERROR;
    }
    *mbType = type;
    *mbPattern = pattern;
    if (stat) {
        if (type == IPPVC_MBTYPE_INTER)
            mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_INTER);
        else if (type == IPPVC_MBTYPE_INTER_Q)
            mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_INTER_Q);
        else if (type == IPPVC_MBTYPE_INTRA)
            mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_INTRA);
        else if (type == IPPVC_MBTYPE_INTRA_Q)
            mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_INTRA_Q);
        else if (type == IPPVC_MBTYPE_INTER4V)
            mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_INTER4V);
    }
    return MP4_STATUS_OK;
}

mp4_Status mp4_PredictDecode1MV(mp4_Info *pInfo, mp4_MacroBlock *MBcurr, Ipp32s y, Ipp32s x)
{
    IppMotionVector *mvLeft, *mvTop, *mvRight, *mvCurr;
    Ipp32s           mbInRow = pInfo->VisualObject.VideoObject.MacroBlockPerRow;
    Ipp32s           fcode = pInfo->VisualObject.VideoObject.VideoObjectPlane.fcode_forward;
    Ipp32s           resync_marker_disable = pInfo->VisualObject.VideoObject.resync_marker_disable;

    // block 0
    mvCurr = MBcurr[0].mv;
    mvLeft  = MBcurr[-1].mv;
    mvTop   = MBcurr[-mbInRow].mv;
    mvRight = MBcurr[-mbInRow+1].mv;
    if (resync_marker_disable) {
        if ((y | x) == 0) {
            mvCurr[0].dx = mvCurr[0].dy = 0;
        } else if (x == 0) {
            mvCurr[0].dx = mp4_Median(0, mvTop[2].dx, mvRight[2].dx);
            mvCurr[0].dy = mp4_Median(0, mvTop[2].dy, mvRight[2].dy);
        } else if (y == 0) {
            mvCurr[0] = mvLeft[1];
        } else if (x == mbInRow - 1) {
            mvCurr[0].dx = mp4_Median(0, mvLeft[1].dx, mvTop[2].dx);
            mvCurr[0].dy = mp4_Median(0, mvLeft[1].dy, mvTop[2].dy);
        } else {
            mvCurr[0].dx = mp4_Median(mvLeft[1].dx, mvTop[2].dx, mvRight[2].dx);
            mvCurr[0].dy = mp4_Median(mvLeft[1].dy, mvTop[2].dy, mvRight[2].dy);
        }
    } else {
        Ipp32s   validLeft, validTop, validRight;

        if (x > 0)
            validLeft = MBcurr[-1].validPred;
        else
            validLeft = 0;
        if (y > 0)
            validTop = MBcurr[-mbInRow].validPred;
        else
            validTop = 0;
        if ((y > 0) && (x < mbInRow - 1))
            validRight = MBcurr[-mbInRow+1].validPred;
        else
            validRight = 0;
        switch ((validLeft << 2) | (validTop << 1) | validRight) {
        case 7:
            mvCurr[0].dx = mp4_Median(mvLeft[1].dx, mvTop[2].dx, mvRight[2].dx);
            mvCurr[0].dy = mp4_Me

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -