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

📄 mp4_enc_vop.cpp

📁 audio-video-codecs.rar语音编解码器
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/* ///////////////////////////////////////////////////////////////////////
//
//               INTEL CORPORATION PROPRIETARY INFORMATION
//  This software is supplied under the terms of a license agreement or
//  nondisclosure agreement with Intel Corporation and may not be copied
//  or disclosed except in accordance with the terms of that agreement.
//        Copyright (c) 2003-2007 Intel Corporation. All Rights Reserved.
//
//  Description:    class ippVideoEncoderMPEG4 (encode VOPs)
//
*/

#include "umc_defs.h"

#if defined (UMC_ENABLE_MPEG4_VIDEO_ENCODER)

#include <stdio.h>
#include "mp4_enc.hpp"

#pragma warning(disable : 981)      // operands are evaluated in unspecified order
#pragma warning(disable : 279)      // controlling expression is constant
#pragma warning(disable : 4127)     // conditional expression is constant

#define VIDEOPACKETS_LE_MAX

namespace MPEG4_ENC
{

inline void mp4_ComputeChromaMV(const IppMotionVector *mvLuma, IppMotionVector *mvChroma)
{
    mvChroma->dx = (Ipp16s)mp4_Div2Round(mvLuma->dx);
    mvChroma->dy = (Ipp16s)mp4_Div2Round(mvLuma->dy);
}

inline void mp4_ComputeChromaMVQ(const IppMotionVector *mvLuma, IppMotionVector *mvChroma)
{
    Ipp32s  dx, dy;

    dx = mp4_Div2(mvLuma->dx);
    dy = mp4_Div2(mvLuma->dy);
    mvChroma->dx = (Ipp16s)mp4_Div2Round(dx);
    mvChroma->dy = (Ipp16s)mp4_Div2Round(dy);
}

static void mp4_Set8x8_8u(Ipp8u *p, Ipp32s step, Ipp8u level)
{
    Ipp32u  val;

    val = level + (level <<  8);
    val += val << 16;
    ((Ipp32u*)p)[0] = val; ((Ipp32u*)p)[1] = val; p += step;
    ((Ipp32u*)p)[0] = val; ((Ipp32u*)p)[1] = val; p += step;
    ((Ipp32u*)p)[0] = val; ((Ipp32u*)p)[1] = val; p += step;
    ((Ipp32u*)p)[0] = val; ((Ipp32u*)p)[1] = val; p += step;
    ((Ipp32u*)p)[0] = val; ((Ipp32u*)p)[1] = val; p += step;
    ((Ipp32u*)p)[0] = val; ((Ipp32u*)p)[1] = val; p += step;
    ((Ipp32u*)p)[0] = val; ((Ipp32u*)p)[1] = val; p += step;
    ((Ipp32u*)p)[0] = val; ((Ipp32u*)p)[1] = val;
}

inline Ipp16s mp4_Median(Ipp16s a, Ipp16s b, Ipp16s c)
{
    if (a > b) {
        Ipp16s  t = a; a = b; b = t;
    }
    return (b <= c) ? b : (c >= a) ? c : a;
}

inline void mp4_MV_GetDiff(IppMotionVector *mvC, IppMotionVector *mvP, Ipp32s fMin, Ipp32s fMax, Ipp32s fRange)
{
    Ipp32s  mvDx, mvDy;

    mvDx = mvC->dx - mvP->dx;
    mvDy = mvC->dy - mvP->dy;
    if (mvDx < fMin)
        mvDx += fRange;
    else if (mvDx > fMax)
        mvDx -= fRange;
    if (mvDy < fMin)
        mvDy += fRange;
    else if (mvDy > fMax)
        mvDy -= fRange;
    mvP->dx = (Ipp16s)mvDx;
    mvP->dy = (Ipp16s)mvDy;
}

#define mp4_SetPatternInter(pattern, nzCount) \
    pattern = 0; \
    pattern |= (nzCount[0] > 0) ? 32 : 0; \
    pattern |= (nzCount[1] > 0) ? 16 : 0; \
    pattern |= (nzCount[2] > 0) ?  8 : 0; \
    pattern |= (nzCount[3] > 0) ?  4 : 0; \
    pattern |= (nzCount[4] > 0) ?  2 : 0; \
    pattern |= (nzCount[5] > 0) ?  1 : 0

#define mp4_SetPatternIntra(pattern, nzCount, coeff, use_intra_dc_vlc) \
    pattern = 0; \
    if (use_intra_dc_vlc) { \
        Ipp32s  i, pm = 32; \
        for (i = 0; i < 6; i ++) { \
            if ((nzCount[i] > 1) || ((nzCount[i] == 1) && (coeff[i*64] == 0))) \
                pattern |= pm; \
            pm >>= 1; \
        } \
    } else { \
        pattern |= (nzCount[0] > 0) ? 32 : 0; \
        pattern |= (nzCount[1] > 0) ? 16 : 0; \
        pattern |= (nzCount[2] > 0) ?  8 : 0; \
        pattern |= (nzCount[3] > 0) ?  4 : 0; \
        pattern |= (nzCount[4] > 0) ?  2 : 0; \
        pattern |= (nzCount[5] > 0) ?  1 : 0; \
    }

inline void mp4_NonZeroCount(Ipp16s *coeff, Ipp32s *nzCount)
{
    Ipp32s i;
    Ipp32u c;
    for (i = 0; i < 6; i ++) {
        ippiCountZeros8x8_16s_C1(coeff+i*64, &c);
        nzCount[i] = 64 - c;
    }
}


static int mp4_TrellisQuant(Ipp16s* tcoeff, Ipp16s* qcoeff, int quant, Ipp8u* qMatrix, const Ipp8u* scan, int nzc)
{
    return nzc;
}


inline void mp4_EncodeZeroBitsAlign(ippBitStream &cBS)
{
    if (cBS.mBitOff != 0)
        cBS.PutBits(0, 8 - cBS.mBitOff);
}

inline void mp4_EncodeStuffingBitsAlign(ippBitStream &cBS)
{
    cBS.PutBits(0xFF >> (cBS.mBitOff + 1), 8 - cBS.mBitOff);
}

inline void mp4_EncodeMarkerDC(ippBitStream &cBS)
{
    cBS.PutBits(0x6B001, 19); // 110 1011 0000 0000 0001
}

inline void mp4_EncodeMarkerMV(ippBitStream &cBS)
{
    cBS.PutBits(0x1F001, 17); //   1 1111 0000 0000 0001
}

inline void mp4_EncodeDquant(ippBitStream &cBS, Ipp32s dquant)
{
    if (dquant != -2)
        cBS.PutBits(dquant + 1, 2);
    else
        cBS.PutBits(1, 2);
}

inline void mp4_EncodeMCBPC_I(ippBitStream &cBS, Ipp32s mbtype, Ipp32s mcbpc)
{
    if (mbtype == IPPVC_MBTYPE_INTRA) {
        if (mcbpc == 0)
            cBS.PutBit(1);
        else
            cBS.PutBits(mcbpc, 3);
    } else {
        if (mcbpc == 0)
            cBS.PutBits(1, 4);
        else
            cBS.PutBits(mcbpc, 6);
    }
}

inline void mp4_EncodeCBPY_I(ippBitStream &cBS, Ipp32s pat)
{
    cBS.PutBits(mp4_VLC_CBPY_TB8[pat].code, mp4_VLC_CBPY_TB8[pat].len);
}

inline void mp4_EncodeMCBPC_P(ippBitStream &cBS, Ipp32s mbtype, Ipp32s pat)
{
    cBS.PutBits(mp4_VLC_MCBPC_TB7[mbtype*4+pat].code, mp4_VLC_MCBPC_TB7[mbtype*4+pat].len);
}

inline void mp4_EncodeCBPY_P(ippBitStream &cBS, Ipp32s mbtype, Ipp32s pat)
{
    if (mbtype <= IPPVC_MBTYPE_INTER4V)
        pat = 15 - pat;
    cBS.PutBits(mp4_VLC_CBPY_TB8[pat].code, mp4_VLC_CBPY_TB8[pat].len);
}

static void mp4_EncodeMV(ippBitStream &cBS, IppMotionVector *mv, Ipp32s fcode, Ipp32s mbType)
{
    Ipp32s  i, nMV = (mbType == IPPVC_MBTYPE_INTER4V) ? 4 : 1;

    for (i = 0; i < nMV; i ++) {
        if (fcode == 1) {
            cBS.PutBits(mp4_VLC_MVD_TB12[mv[i].dx+32].code, mp4_VLC_MVD_TB12[mv[i].dx+32].len);
            cBS.PutBits(mp4_VLC_MVD_TB12[mv[i].dy+32].code, mp4_VLC_MVD_TB12[mv[i].dy+32].len);
        } else {
            Ipp32s f, a, b;

            f = fcode - 1;
            if (mv[i].dx == 0) {
                cBS.PutBits(mp4_VLC_MVD_TB12[32].code, mp4_VLC_MVD_TB12[32].len);
            } else {
                if (mv[i].dx > 0) {
                    a = ((mv[i].dx - 1) >> f) + 1;
                    b = mv[i].dx - 1 - ((a - 1) << f);
                } else {
                    a = ((-mv[i].dx - 1) >> f) + 1;
                    b = -mv[i].dx - 1 - ((a - 1) << f);
                    a = -a;
                }
                cBS.PutBits(mp4_VLC_MVD_TB12[a+32].code, mp4_VLC_MVD_TB12[a+32].len);
                cBS.PutBits(b, f);
            }
            if (mv[i].dy == 0) {
                cBS.PutBits(mp4_VLC_MVD_TB12[32].code, mp4_VLC_MVD_TB12[32].len);
            } else {
                if (mv[i].dy > 0) {
                    a = ((mv[i].dy - 1) >> f) + 1;
                    b = mv[i].dy - 1 - ((a - 1) << f);
                } else {
                    a = ((-mv[i].dy - 1) >> f) + 1;
                    b = -mv[i].dy - 1 - ((a - 1) << f);
                    a = -a;
                }
                cBS.PutBits(mp4_VLC_MVD_TB12[a+32].code, mp4_VLC_MVD_TB12[a+32].len);
                cBS.PutBits(b, f);
            }
        }
    }
}

inline void mp4_EncodeMacroBlockIntra_H263(ippBitStream &cBS, Ipp16s *coeffMB, Ipp32s pattern, Ipp32s *nzCount)
{
    Ipp32s  i, pm = 32;

    for (i = 0; i < 6; i ++) {
        ippiEncodeDCIntra_H263_16s1u(coeffMB[i*64], &cBS.mPtr, &cBS.mBitOff);
        if (pattern & pm)
            ippiEncodeCoeffsIntra_H263_16s1u(coeffMB+i*64, &cBS.mPtr, &cBS.mBitOff, nzCount[i] - 1, 0, 0, IPPVC_SCAN_ZIGZAG);
        pm >>= 1;
    }
}

inline void mp4_EncodeMacroBlockInter_H263(ippBitStream &cBS, Ipp16s *coeffMB, Ipp32s pattern, Ipp32s *nzCount)
{
    Ipp32s  i, pm = 32;

    for (i = 0; i < 6; i ++) {
        if (pattern & pm)
            ippiEncodeCoeffsInter_H263_16s1u(coeffMB+i*64, &cBS.mPtr, &cBS.mBitOff, nzCount[i], 0, IPPVC_SCAN_ZIGZAG);
        pm >>= 1;
    }
}

inline void mp4_EncodeMacroBlockIntra_MPEG4(ippBitStream &cBS, Ipp16s *coeffMB, Ipp32s pattern, Ipp32s *nzCount, Ipp32s *predDir, Ipp32s use_intra_dc_vlc, Ipp32s alternate_vertical_scan_flag)
{
    Ipp32s  i, nzc, pm = 32;

    for (i = 0; i < 6; i ++) {
        if (use_intra_dc_vlc)
            ippiEncodeDCIntra_MPEG4_16s1u(coeffMB[i*64], &cBS.mPtr, &cBS.mBitOff, (i < 4) ? IPPVC_BLOCK_LUMA : IPPVC_BLOCK_CHROMA);
        if (pattern & pm) {
            nzc = nzCount[i];
            if (use_intra_dc_vlc && (coeffMB[i*64] != 0))
                nzc --;
            ippiEncodeCoeffsIntra_MPEG4_16s1u(coeffMB+i*64, &cBS.mPtr, &cBS.mBitOff, nzc, 0, use_intra_dc_vlc, alternate_vertical_scan_flag ? IPPVC_SCAN_VERTICAL : predDir[i]);
        }
        pm >>= 1;
    }
}

inline void mp4_EncodeMacroBlockInter_MPEG4(ippBitStream &cBS, Ipp16s *coeffMB, Ipp32s pattern, Ipp32s *nzCount, Ipp32s reversible_vlc, Ipp32s alternate_vertical_scan_flag)
{
    Ipp32s  i, pm = 32;

    for (i = 0; i < 6; i ++) {
        if (pattern & pm)
            ippiEncodeCoeffsInter_MPEG4_16s1u(coeffMB+i*64, &cBS.mPtr, &cBS.mBitOff, nzCount[i], reversible_vlc, alternate_vertical_scan_flag ? IPPVC_SCAN_VERTICAL : IPPVC_SCAN_ZIGZAG);
        pm >>= 1;
    }
}

inline void mp4_EncodeMacroBlockIntra_DC_MPEG4(ippBitStream &cBS, Ipp16s *coeffMB)
{
    Ipp32s  i;

    for (i = 0; i < 6; i ++) {
        ippiEncodeDCIntra_MPEG4_16s1u(coeffMB[i*64], &cBS.mPtr, &cBS.mBitOff, (i < 4) ? IPPVC_BLOCK_LUMA : IPPVC_BLOCK_CHROMA);
    }
}

inline void mp4_EncodeMacroBlockIntra_AC_MPEG4(ippBitStream &cBS, Ipp16s *coeffMB, Ipp32s pattern, Ipp32s *nzCount, Ipp32s *predDir, Ipp32s use_intra_dc_vlc, Ipp32s reversible_vlc)
{
    Ipp32s  i, nzc, pm = 32;

    for (i = 0; i < 6; i ++) {
        if (pattern & pm) {
            nzc = nzCount[i];
            if (use_intra_dc_vlc && (coeffMB[i*64] != 0))
                nzc --;
            ippiEncodeCoeffsIntra_MPEG4_16s1u(coeffMB+i*64, &cBS.mPtr, &cBS.mBitOff, nzc, reversible_vlc, use_intra_dc_vlc, predDir[i]);
        }
        pm >>= 1;

⌨️ 快捷键说明

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