📄 mp4_enc_vop.cpp
字号:
/* ///////////////////////////////////////////////////////////////////////
//
// 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 + -