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

📄 mp4decvop.c

📁 audio-video-codecs.rar语音编解码器
💻 C
📖 第 1 页 / 共 5 页
字号:
    }
    *mvdy = mvd;
    return MP4_STATUS_OK;
}

mp4_Status mp4_DecodeMV(mp4_Info *pInfo, IppMotionVector *mv, Ipp32s fcode)
{
    Ipp32s  mvdx, mvdy, range, range2, dx, dy;

    if (mp4_DecodeMVD(pInfo, &mvdx, &mvdy, fcode) != MP4_STATUS_OK)
        return MP4_STATUS_ERROR;
    range = 16 << fcode;
    range2 = range + range;
    dx = mv->dx + mvdx;
    if (dx < -range)
        dx += range2;
    else if (dx >= range)
        dx -= range2;
    mv->dx = (Ipp16s)dx;
    dy = mv->dy + mvdy;
    if (dy < -range)
        dy += range2;
    else if (dy >= range)
        dy -= range2;
    mv->dy = (Ipp16s)dy;
    return MP4_STATUS_OK;
}

mp4_Status mp4_Decode4MV(mp4_Info *pInfo, IppMotionVector *mv, Ipp32s fcode)
{
    Ipp32s  i, mvdx, mvdy, range, range2, dx, dy;

    range = 16 << fcode;
    range2 = range + range;
    for (i = 0; i < 4; i ++) {
        if (mp4_DecodeMVD(pInfo, &mvdx, &mvdy, fcode) != MP4_STATUS_OK)
            return MP4_STATUS_ERROR;
        dx = mv[i].dx + mvdx;
        if (dx < -range)
            dx += range2;
        else if (dx >= range)
            dx -= range2;
        mv[i].dx = (Ipp16s)dx;
        dy = mv[i].dy + mvdy;
        if (dy < -range)
            dy += range2;
        else if (dy >= range)
            dy -= range2;
        mv[i].dy = (Ipp16s)dy;
    }
    return MP4_STATUS_OK;
}

mp4_Status mp4_DecodeMV_Direct(mp4_Info *pInfo, IppMotionVector mvC[4], IppMotionVector mvForw[4], IppMotionVector mvBack[4], Ipp32s TRB, Ipp32s TRD, Ipp32s modb, Ipp32s comb_type)
{
    Ipp32s  mvdx, mvdy, i;

    if (modb == 2) {
        if (comb_type != IPPVC_MBTYPE_INTER4V) {
            mvForw[0].dx = mvForw[1].dx = mvForw[2].dx = mvForw[3].dx = (Ipp16s)((TRB * mvC[0].dx) / TRD);
            mvForw[0].dy = mvForw[1].dy = mvForw[2].dy = mvForw[3].dy = (Ipp16s)((TRB * mvC[0].dy) / TRD);
            mvBack[0].dx = mvBack[1].dx = mvBack[2].dx = mvBack[3].dx = (Ipp16s)(((TRB - TRD) * mvC[0].dx) / TRD);
            mvBack[0].dy = mvBack[1].dy = mvBack[2].dy = mvBack[3].dy = (Ipp16s)(((TRB - TRD) * mvC[0].dy) / TRD);
        } else
            for (i = 0; i < 4; i ++) {
                mvForw[i].dx = (Ipp16s)((TRB * mvC[i].dx) / TRD);
                mvForw[i].dy = (Ipp16s)((TRB * mvC[i].dy) / TRD);
                mvBack[i].dx = (Ipp16s)(((TRB - TRD) * mvC[i].dx) / TRD);
                mvBack[i].dy = (Ipp16s)(((TRB - TRD) * mvC[i].dy) / TRD);
            }
    } else {
        if (mp4_DecodeMVD(pInfo, &mvdx, &mvdy, 1) != MP4_STATUS_OK)
            return MP4_STATUS_ERROR;
        if (comb_type != IPPVC_MBTYPE_INTER4V) {
            mvForw[0].dx = mvForw[1].dx = mvForw[2].dx = mvForw[3].dx = (Ipp16s)((TRB * mvC[0].dx) / TRD + mvdx);
            mvForw[0].dy = mvForw[1].dy = mvForw[2].dy = mvForw[3].dy = (Ipp16s)((TRB * mvC[0].dy) / TRD + mvdy);
            if (mvdx == 0)
                mvBack[0].dx = mvBack[1].dx = mvBack[2].dx = mvBack[3].dx = (Ipp16s)(((TRB - TRD) * mvC[0].dx) / TRD);
            else
                mvBack[0].dx = mvBack[1].dx = mvBack[2].dx = mvBack[3].dx = (Ipp16s)(mvForw[0].dx - mvC[0].dx);
            if (mvdy == 0)
                mvBack[0].dy = mvBack[1].dy = mvBack[2].dy = mvBack[3].dy = (Ipp16s)(((TRB - TRD) * mvC[0].dy) / TRD);
            else
                mvBack[0].dy = mvBack[1].dy = mvBack[2].dy = mvBack[3].dy = (Ipp16s)(mvForw[0].dy - mvC[0].dy);
        } else
            for (i = 0; i < 4; i++) {
                mvForw[i].dx = (Ipp16s)((TRB * mvC[i].dx) / TRD + mvdx);
                mvForw[i].dy = (Ipp16s)((TRB * mvC[i].dy) / TRD + mvdy);
                if (mvdx == 0)
                    mvBack[i].dx = (Ipp16s)(((TRB - TRD) * mvC[i].dx) / TRD);
                else
                    mvBack[i].dx = (Ipp16s)(mvForw[i].dx - mvC[i].dx);
                if (mvdy == 0)
                    mvBack[i].dy = (Ipp16s)(((TRB - TRD) * mvC[i].dy) / TRD);
                else
                    mvBack[i].dy = (Ipp16s)(mvForw[i].dy - mvC[i].dy);
            }
    }
    return MP4_STATUS_OK;
}

mp4_Status mp4_DecodeMV_DirectField(mp4_Info *pInfo, Ipp32s mb_ftfr, Ipp32s mb_fbfr, IppMotionVector *mvTop, IppMotionVector *mvBottom, IppMotionVector *mvForwTop, IppMotionVector *mvForwBottom, IppMotionVector *mvBackTop, IppMotionVector *mvBackBottom, Ipp32s TRB, Ipp32s TRD, Ipp32s modb)
{
    // field direct mode
    Ipp32s  TRDt, TRDb, TRBt, TRBb, deltaTop, deltaBottom, mvdx, mvdy;

    deltaTop = mb_ftfr;
    deltaBottom = mb_fbfr - 1;
    if (pInfo->VisualObject.VideoObject.VideoObjectPlane.top_field_first) {
        deltaTop = -deltaTop;
        deltaBottom = -deltaBottom;
    }
    TRDt = mp4_DivRoundInf(TRD, pInfo->VisualObject.VideoObject.Tframe) * 2 + deltaTop;
    TRDb = mp4_DivRoundInf(TRD, pInfo->VisualObject.VideoObject.Tframe) * 2 + deltaBottom;
    TRBt = mp4_DivRoundInf(TRB, pInfo->VisualObject.VideoObject.Tframe) * 2 + deltaTop;
    TRBb = mp4_DivRoundInf(TRB, pInfo->VisualObject.VideoObject.Tframe) * 2 + deltaBottom;
    if (modb == 2) {
        // delta == 0
        mvdx = mvdy = 0;
    } else {
        if (mp4_DecodeMVD(pInfo, &mvdx, &mvdy, 1) != MP4_STATUS_OK)
            return MP4_STATUS_ERROR;
    }
    mvForwTop->dx = (Ipp16s)((TRBt * mvTop->dx) / TRDt + mvdx);
    if (mvdx == 0)
        mvBackTop->dx = (Ipp16s)(((TRBt - TRDt) * mvTop->dx) / TRDt);
    else
        mvBackTop->dx = (Ipp16s)(mvForwTop->dx - mvTop->dx);
    mvForwTop->dy = (Ipp16s)((TRBt * mvTop->dy * 2) / TRDt + mvdy);
    if (mvdy == 0)
        mvBackTop->dy = (Ipp16s)(((TRBt - TRDt) * mvTop->dy * 2) / TRDt);
    else
        mvBackTop->dy = (Ipp16s)(mvForwTop->dy - mvTop->dy * 2);
    mvForwBottom->dx = (Ipp16s)((TRBb * mvBottom->dx) / TRDb + mvdx);
    if (mvdx == 0)
        mvBackBottom->dx = (Ipp16s)(((TRBb - TRDb) * mvBottom->dx) / TRDb);
    else
        mvBackBottom->dx = (Ipp16s)(mvForwBottom->dx - mvBottom->dx);
    mvForwBottom->dy = (Ipp16s)((TRBb * mvBottom->dy * 2) / TRDb + mvdy);
    if (mvdy == 0)
        mvBackBottom->dy = (Ipp16s)(((TRBb - TRDb) * mvBottom->dy * 2) / TRDb);
    else
        mvBackBottom->dy = (Ipp16s)(mvForwBottom->dy - mvBottom->dy * 2);
    mvForwTop->dy >>= 1;
    mvBackTop->dy >>= 1;
    mvForwBottom->dy >>= 1;
    mvBackBottom->dy >>= 1;
    return MP4_STATUS_OK;
}

/*static*/ void mp4_ExpandFrameReplicate(Ipp8u *pSrcDstPlane, Ipp32s frameWidth, Ipp32s frameHeight, Ipp32s expandPels, Ipp32s step)
{
    Ipp8u   *pDst1, *pDst2, *pSrc1, *pSrc2;
    Ipp32s  i, j;
    Ipp32u  t1, t2;

    pDst1 = pSrcDstPlane + step * expandPels;
    pDst2 = pDst1 + frameWidth + expandPels;
    if (expandPels == 8) {
        for (i = 0; i < frameHeight; i ++) {
            t1 = pDst1[8] + (pDst1[8] << 8);
            t2 = pDst2[-1] + (pDst2[-1] << 8);
            t1 = (t1 << 16) + t1;
            t2 = (t2 << 16) + t2;
            ((Ipp32u*)pDst1)[0] = t1;
            ((Ipp32u*)pDst1)[1] = t1;
            ((Ipp32u*)pDst2)[0] = t2;
            ((Ipp32u*)pDst2)[1] = t2;
            pDst1 += step;
            pDst2 += step;
        }
    } else if (expandPels == 16) {
        for (i = 0; i < frameHeight; i ++) {
            t1 = pDst1[16] + (pDst1[16] << 8);
            t2 = pDst2[-1] + (pDst2[-1] << 8);
            t1 = (t1 << 16) + t1;
            t2 = (t2 << 16) + t2;
            ((Ipp32u*)pDst1)[0] = t1;
            ((Ipp32u*)pDst1)[1] = t1;
            ((Ipp32u*)pDst1)[2] = t1;
            ((Ipp32u*)pDst1)[3] = t1;
            ((Ipp32u*)pDst2)[0] = t2;
            ((Ipp32u*)pDst2)[1] = t2;
            ((Ipp32u*)pDst2)[2] = t2;
            ((Ipp32u*)pDst2)[3] = t2;
            pDst1 += step;
            pDst2 += step;
        }
    } else {
        for (i = 0; i < frameHeight; i ++) {
            ippsSet_8u(pDst1[expandPels], pDst1, expandPels);
            ippsSet_8u(pDst2[-1], pDst2, expandPels);
            pDst1 += step;
            pDst2 += step;
        }
    }
    pDst1 = pSrcDstPlane;
    pSrc1 = pSrcDstPlane + expandPels * step;
    pDst2 = pSrc1 + frameHeight * step;
    pSrc2 = pDst2 - step;
    j = frameWidth + 2 * expandPels;
    for (i = 0; i < expandPels; i ++) {
        ippsCopy_8u(pSrc1, pDst1, j);
        ippsCopy_8u(pSrc2, pDst2, j);
        pDst1 += step;
        pDst2 += step;
    }
}

void mp4_PadFrame(mp4_Info* pInfo)
{
#if 0
    /*
    //  padding VOP (for not complete blocks padd by
    //      0 for DivX(tm) 5.0 AVI streams
    //      128 for QuickTime(tm) MP4 streams
    //      replication for other
    */
    Ipp32s  wL, hL, wC, hC, i;

    //if (pInfo->VisualObject.VideoObject.short_video_header)
    //    return;
    wL = pInfo->VisualObject.VideoObject.width;
    hL = pInfo->VisualObject.VideoObject.height;
    wC = pInfo->VisualObject.VideoObject.width >> 1;
    hC = pInfo->VisualObject.VideoObject.height >> 1;
    if ((pInfo->VisualObject.VideoObject.width & 15 || pInfo->VisualObject.VideoObject.height & 15) &&
        ((pInfo->ftype == 1 && pInfo->ftype_f == 0) || (pInfo->ftype == 2 && pInfo->ftype_f == 1))) {
        Ipp8u     pad = (Ipp8u)(pInfo->ftype == 1 ? 128 : 0);

        if (pInfo->VisualObject.VideoObject.width & 15) {
            Ipp8u *p;
            // pad one col
            p = pInfo->VisualObject.cFrame.pY + pInfo->VisualObject.VideoObject.width;
            for (i = 0; i < pInfo->VisualObject.VideoObject.height; i ++) {
                *p = pad;
                p += pInfo->VisualObject.cFrame.stepY;
            }
            p = pInfo->VisualObject.cFrame.pCb + (pInfo->VisualObject.VideoObject.width >> 1);
            for (i = 0; i < pInfo->VisualObject.VideoObject.height >> 1; i ++) {
                *p = pad;
                p += pInfo->VisualObject.cFrame.stepCb;
            }
            p = pInfo->VisualObject.cFrame.pCr + (pInfo->VisualObject.VideoObject.width >> 1);
            for (i = 0; i < pInfo->VisualObject.VideoObject.height >> 1; i ++) {
                *p = pad;
                p += pInfo->VisualObject.cFrame.stepCr;
            }
            wL ++;
            wC ++;
        }
        if (pInfo->VisualObject.VideoObject.height & 15) {
            // pad one row
            ippsSet_8u(pad, pInfo->VisualObject.cFrame.pY + pInfo->VisualObject.cFrame.stepY * pInfo->VisualObject.VideoObject.height, pInfo->VisualObject.VideoObject.width);
            ippsSet_8u(pad, pInfo->VisualObject.cFrame.pCb + pInfo->VisualObject.cFrame.stepCb * (pInfo->VisualObject.VideoObject.height >> 1), pInfo->VisualObject.VideoObject.width >> 1);
            ippsSet_8u(pad, pInfo->VisualObject.cFrame.pCr + pInfo->VisualObject.cFrame.stepCr * (pInfo->VisualObject.VideoObject.height >> 1), pInfo->VisualObject.VideoObject.width >> 1);
            hL ++;
            hC ++;
        }
    }
#else
    /*
    //  padding VOP for not complete blocks
    //  replication from macroblock boundary for DIVX and MP4 and from frame boundary for other
    */
    Ipp32s  wL, hL, wC, hC;

    if ((pInfo->ftype == 1 && pInfo->ftype_f == 0) || (pInfo->ftype == 2 && pInfo->ftype_f == 1)) {
        wL = pInfo->VisualObject.VideoObject.MacroBlockPerRow * 16;
        hL = pInfo->VisualObject.VideoObject.MacroBlockPerCol * 16;
    } else {
        wL = pInfo->VisualObject.VideoObject.width;
        hL = pInfo->VisualObject.VideoObject.height;
    }

⌨️ 快捷键说明

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