Initial community commit
This commit is contained in:
parent
537bcbc862
commit
fc06254474
16440 changed files with 4239995 additions and 2 deletions
708
Src/mpeg4dec/mp4dec.h
Normal file
708
Src/mpeg4dec/mp4dec.h
Normal file
|
@ -0,0 +1,708 @@
|
|||
/* ///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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) 2001-2007 Intel Corporation. All Rights Reserved.
|
||||
//
|
||||
// Description: MPEG-4 header.
|
||||
//
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//#ifdef __INTEL_COMPILER
|
||||
//#include <emmintrin.h>
|
||||
//#define USE_INTRINSIC_EMM
|
||||
//#else
|
||||
#undef USE_INTRINSIC_XMM
|
||||
#undef USE_INTRINSIC_EMM
|
||||
//#endif
|
||||
|
||||
#define USE_TABLE_INTRA_DIV
|
||||
|
||||
#define mp4_Div2(a) ((a) >= 0 ? ((a) >> 1) : (((a)+1) >> 1))
|
||||
#define mp4_Div2Round(a) (((a) >> 1) | ((a) & 1))
|
||||
#define mp4_DivRoundInf(a, b) ((((a) + (((a) >= 0) ? ((b) >> 1) : -((b) >> 1))) / (b)))
|
||||
#ifndef USE_TABLE_INTRA_DIV
|
||||
#define mp4_DivIntraDC(a, b) (((a) + ((b) >> 1)) / (b))
|
||||
#define mp4_DivIntraAC(a, b) mp4_DivRoundInf(a, b)
|
||||
#else
|
||||
// tested on (-2047..2047) // (1..46)
|
||||
#define mp4_DivIntraDC(a, b) (((a) * mp4_DivIntraDivisor[b] + (1 << 17)) >> 18)
|
||||
#define mp4_DivIntraAC(a, b) mp4_DivIntraDC(a, b)
|
||||
#endif
|
||||
|
||||
__INLINE int16_t mp4_Median(int16_t a, int16_t b, int16_t c)
|
||||
{
|
||||
if (a > b) {
|
||||
int16_t t = a; a = b; b = t;
|
||||
}
|
||||
return (int16_t)((b <= c) ? b : (c >= a) ? c : a);
|
||||
}
|
||||
|
||||
__INLINE void mp4_ComputeChromaMV(const IppMotionVector *mvLuma, IppMotionVector *mvChroma)
|
||||
{
|
||||
mvChroma->dx = (int16_t)mp4_Div2Round(mvLuma->dx);
|
||||
mvChroma->dy = (int16_t)mp4_Div2Round(mvLuma->dy);
|
||||
}
|
||||
|
||||
__INLINE void mp4_ComputeChromaMVQ(const IppMotionVector *mvLuma, IppMotionVector *mvChroma)
|
||||
{
|
||||
int32_t dx, dy;
|
||||
|
||||
dx = mp4_Div2(mvLuma->dx);
|
||||
dy = mp4_Div2(mvLuma->dy);
|
||||
mvChroma->dx = (int16_t)mp4_Div2Round(dx);
|
||||
mvChroma->dy = (int16_t)mp4_Div2Round(dy);
|
||||
}
|
||||
|
||||
__INLINE void mp4_ComputeChroma4MV(const IppMotionVector mvLuma[4], IppMotionVector *mvChroma)
|
||||
{
|
||||
int32_t dx, dy, cdx, cdy, adx, ady;
|
||||
|
||||
dx = mvLuma[0].dx + mvLuma[1].dx + mvLuma[2].dx + mvLuma[3].dx;
|
||||
dy = mvLuma[0].dy + mvLuma[1].dy + mvLuma[2].dy + mvLuma[3].dy;
|
||||
adx = abs(dx);
|
||||
ady = abs(dy);
|
||||
cdx = mp4_cCbCrMvRound16[adx & 15] + (adx >> 4) * 2;
|
||||
cdy = mp4_cCbCrMvRound16[ady & 15] + (ady >> 4) * 2;
|
||||
mvChroma->dx = (int16_t)((dx >= 0) ? cdx : -cdx);
|
||||
mvChroma->dy = (int16_t)((dy >= 0) ? cdy : -cdy);
|
||||
}
|
||||
|
||||
__INLINE void mp4_ComputeChroma4MVQ(const IppMotionVector mvLuma[4], IppMotionVector *mvChroma)
|
||||
{
|
||||
int32_t dx, dy, cdx, cdy, adx, ady;
|
||||
|
||||
dx = mp4_Div2(mvLuma[0].dx) + mp4_Div2(mvLuma[1].dx) + mp4_Div2(mvLuma[2].dx) + mp4_Div2(mvLuma[3].dx);
|
||||
dy = mp4_Div2(mvLuma[0].dy) + mp4_Div2(mvLuma[1].dy) + mp4_Div2(mvLuma[2].dy) + mp4_Div2(mvLuma[3].dy);
|
||||
adx = abs(dx);
|
||||
ady = abs(dy);
|
||||
cdx = mp4_cCbCrMvRound16[adx & 15] + (adx >> 4) * 2;
|
||||
cdy = mp4_cCbCrMvRound16[ady & 15] + (ady >> 4) * 2;
|
||||
mvChroma->dx = (int16_t)((dx >= 0) ? cdx : -cdx);
|
||||
mvChroma->dy = (int16_t)((dy >= 0) ? cdy : -cdy);
|
||||
}
|
||||
|
||||
#define limitMV(dx, xmin, xmax, mvd) \
|
||||
{ \
|
||||
if ((dx) < (xmin)) \
|
||||
mvd = (int16_t)(xmin); \
|
||||
else if ((dx) >= (xmax)) \
|
||||
mvd = (int16_t)(xmax); \
|
||||
else \
|
||||
mvd = (int16_t)(dx); \
|
||||
}
|
||||
|
||||
__INLINE void mp4_LimitMV(const IppMotionVector *pSrcMV, IppMotionVector *pDstMV, const IppiRect *limitRect, int32_t x, int32_t y, int32_t size)
|
||||
{
|
||||
limitMV(pSrcMV->dx, (limitRect->x - x) << 1, (limitRect->x - x + limitRect->width - size) << 1, pDstMV->dx);
|
||||
limitMV(pSrcMV->dy, (limitRect->y - y) << 1, (limitRect->y - y + limitRect->height - size) << 1, pDstMV->dy);
|
||||
}
|
||||
|
||||
__INLINE void mp4_LimitMVQ(const IppMotionVector *pSrcMV, IppMotionVector *pDstMV, const IppiRect *limitRect, int32_t x, int32_t y, int32_t size)
|
||||
{
|
||||
limitMV(pSrcMV->dx, (limitRect->x - x) << 2, (limitRect->x - x + limitRect->width - size) << 2, pDstMV->dx);
|
||||
limitMV(pSrcMV->dy, (limitRect->y - y) << 2, (limitRect->y - y + limitRect->height - size) << 2, pDstMV->dy);
|
||||
}
|
||||
|
||||
__INLINE void mp4_Limit4MV(const IppMotionVector *pSrcMV, IppMotionVector *pDstMV, const IppiRect *limitRect, int32_t x, int32_t y, int32_t size)
|
||||
{
|
||||
mp4_LimitMV(&pSrcMV[0], &pDstMV[0], limitRect, x , y, size);
|
||||
mp4_LimitMV(&pSrcMV[1], &pDstMV[1], limitRect, x + size, y, size);
|
||||
mp4_LimitMV(&pSrcMV[2], &pDstMV[2], limitRect, x , y + size, size);
|
||||
mp4_LimitMV(&pSrcMV[3], &pDstMV[3], limitRect, x + size, y + size, size);
|
||||
}
|
||||
|
||||
__INLINE void mp4_Limit4MVQ(const IppMotionVector *pSrcMV, IppMotionVector *pDstMV, const IppiRect *limitRect, int32_t x, int32_t y, int32_t size)
|
||||
{
|
||||
mp4_LimitMVQ(&pSrcMV[0], &pDstMV[0], limitRect, x , y, size);
|
||||
mp4_LimitMVQ(&pSrcMV[1], &pDstMV[1], limitRect, x + size, y, size);
|
||||
mp4_LimitMVQ(&pSrcMV[2], &pDstMV[2], limitRect, x , y + size, size);
|
||||
mp4_LimitMVQ(&pSrcMV[3], &pDstMV[3], limitRect, x + size, y + size, size);
|
||||
}
|
||||
|
||||
__INLINE void mp4_LimitFMV(const IppMotionVector *pSrcMV, IppMotionVector *pDstMV, const IppiRect *limitRect, int32_t x, int32_t y, int32_t size)
|
||||
{
|
||||
limitMV(pSrcMV->dx, (limitRect->x - x) << 1, (limitRect->x - x + limitRect->width - size) << 1, pDstMV->dx);
|
||||
limitMV(pSrcMV->dy << 1, (limitRect->y - y) << 1, (limitRect->y - y + limitRect->height - size) << 1, pDstMV->dy);
|
||||
pDstMV->dy >>= 1;
|
||||
}
|
||||
|
||||
__INLINE void mp4_LimitFMVQ(const IppMotionVector *pSrcMV, IppMotionVector *pDstMV, const IppiRect *limitRect, int32_t x, int32_t y, int32_t size)
|
||||
{
|
||||
limitMV(pSrcMV->dx, (limitRect->x - x) << 2, (limitRect->x - x + limitRect->width - size) << 2, pDstMV->dx);
|
||||
limitMV(pSrcMV->dy << 1, (limitRect->y - y) << 2, (limitRect->y - y + limitRect->height - size) << 2, pDstMV->dy);
|
||||
pDstMV->dy >>= 1;
|
||||
}
|
||||
|
||||
#define MP4_MV_OFF_HP(dx, dy, step) \
|
||||
(((dx) >> 1) + (step) * ((dy) >> 1))
|
||||
|
||||
#define MP4_MV_ACC_HP(dx, dy) \
|
||||
((((dy) & 1) << 1) + ((dx) & 1))
|
||||
|
||||
#define MP4_MV_OFF_QP(dx, dy, step) \
|
||||
(((dx) >> 2) + (step) * ((dy) >> 2))
|
||||
|
||||
#define MP4_MV_ACC_QP(dx, dy) \
|
||||
((((dy) & 3) << 2) + ((dx) & 3))
|
||||
|
||||
#define mp4_Copy8x4HP_8u(pSrc, srcStep, pDst, dstStep, mv, rc) \
|
||||
ippiCopy8x4HP_8u_C1R(pSrc + MP4_MV_OFF_HP((mv)->dx, (mv)->dy, srcStep), srcStep, pDst, dstStep, MP4_MV_ACC_HP((mv)->dx, (mv)->dy), rc)
|
||||
|
||||
#define mp4_Copy8x8HP_8u(pSrc, srcStep, pDst, dstStep, mv, rc) \
|
||||
ippiCopy8x8HP_8u_C1R(pSrc + MP4_MV_OFF_HP((mv)->dx, (mv)->dy, srcStep), srcStep, pDst, dstStep, MP4_MV_ACC_HP((mv)->dx, (mv)->dy), rc)
|
||||
|
||||
#define mp4_Copy16x8HP_8u(pSrc, srcStep, pDst, dstStep, mv, rc) \
|
||||
ippiCopy16x8HP_8u_C1R(pSrc + MP4_MV_OFF_HP((mv)->dx, (mv)->dy, srcStep), srcStep, pDst, dstStep, MP4_MV_ACC_HP((mv)->dx, (mv)->dy), rc)
|
||||
|
||||
#define mp4_Copy16x16HP_8u(pSrc, srcStep, pDst, dstStep, mv, rc) \
|
||||
ippiCopy16x16HP_8u_C1R(pSrc + MP4_MV_OFF_HP((mv)->dx, (mv)->dy, srcStep), srcStep, pDst, dstStep, MP4_MV_ACC_HP((mv)->dx, (mv)->dy), rc)
|
||||
|
||||
#define mp4_Copy8x8QP_8u(pSrc, srcStep, pDst, dstStep, mv, rc) \
|
||||
ippiCopy8x8QP_MPEG4_8u_C1R(pSrc + MP4_MV_OFF_QP((mv)->dx, (mv)->dy, srcStep), srcStep, pDst, dstStep, MP4_MV_ACC_QP((mv)->dx, (mv)->dy), rc)
|
||||
|
||||
#define mp4_Copy16x8QP_8u(pSrc, srcStep, pDst, dstStep, mv, rc) \
|
||||
ippiCopy16x8QP_MPEG4_8u_C1R(pSrc + MP4_MV_OFF_QP((mv)->dx, (mv)->dy, srcStep), srcStep, pDst, dstStep, MP4_MV_ACC_QP((mv)->dx, (mv)->dy), rc)
|
||||
|
||||
#define mp4_Copy16x16QP_8u(pSrc, srcStep, pDst, dstStep, mv, rc) \
|
||||
ippiCopy16x16QP_MPEG4_8u_C1R(pSrc + MP4_MV_OFF_QP((mv)->dx, (mv)->dy, srcStep), srcStep, pDst, dstStep, MP4_MV_ACC_QP((mv)->dx, (mv)->dy), rc)
|
||||
|
||||
#define mp4_Add8x8HP_16s8u(pSrc, srcStep, pResid, pDst, dstStep, mv, rc) \
|
||||
ippiAdd8x8HP_16s8u_C1RS(pResid, 16, pSrc + MP4_MV_OFF_HP((mv)->dx, (mv)->dy, srcStep), srcStep, pDst, dstStep, MP4_MV_ACC_HP((mv)->dx, (mv)->dy), rc)
|
||||
|
||||
#define mp4_Add8x8_16s8u(pSrcDst, pResid, srcDstStep) \
|
||||
ippiAdd8x8_16s8u_C1IRS(pResid, 16, pSrcDst, srcDstStep)
|
||||
|
||||
|
||||
#define mp4_UpdateQuant(pInfo, quant) \
|
||||
{ \
|
||||
quant += mp4_dquant[mp4_GetBits9(pInfo, 2)]; \
|
||||
mp4_CLIP(quant, 1, (1 << pInfo->VisualObject.VideoObject.quant_precision) - 1); \
|
||||
}
|
||||
|
||||
#define mp4_UpdateQuant_B(pInfo, quant) \
|
||||
if (mp4_GetBit(pInfo) != 0) { \
|
||||
quant += (mp4_GetBit(pInfo) == 0) ? -2 : 2; \
|
||||
mp4_CLIP(quant, 1, (1 << pInfo->VisualObject.VideoObject.quant_precision) - 1); \
|
||||
}
|
||||
|
||||
__INLINE void mp4_Set8x8_8u(uint8_t *p, int32_t step, uint8_t v)
|
||||
{
|
||||
#if defined(USE_INTRINSIC_XMM) || defined(USE_INTRINSIC_EMM)
|
||||
__m64 _p_v = _mm_set1_pi8(v);
|
||||
*(__m64*)p = _p_v;
|
||||
*(__m64*)(p+step) = _p_v;
|
||||
p += 2 * step;
|
||||
*(__m64*)p = _p_v;
|
||||
*(__m64*)(p+step) = _p_v;
|
||||
p += 2 * step;
|
||||
*(__m64*)p = _p_v;
|
||||
*(__m64*)(p+step) = _p_v;
|
||||
p += 2 * step;
|
||||
*(__m64*)p = _p_v;
|
||||
*(__m64*)(p+step) = _p_v;
|
||||
_mm_empty();
|
||||
#else
|
||||
uint32_t val;
|
||||
|
||||
val = v + (v << 8);
|
||||
val += val << 16;
|
||||
((uint32_t*)p)[0] = val; ((uint32_t*)p)[1] = val; p += step;
|
||||
((uint32_t*)p)[0] = val; ((uint32_t*)p)[1] = val; p += step;
|
||||
((uint32_t*)p)[0] = val; ((uint32_t*)p)[1] = val; p += step;
|
||||
((uint32_t*)p)[0] = val; ((uint32_t*)p)[1] = val; p += step;
|
||||
((uint32_t*)p)[0] = val; ((uint32_t*)p)[1] = val; p += step;
|
||||
((uint32_t*)p)[0] = val; ((uint32_t*)p)[1] = val; p += step;
|
||||
((uint32_t*)p)[0] = val; ((uint32_t*)p)[1] = val; p += step;
|
||||
((uint32_t*)p)[0] = val; ((uint32_t*)p)[1] = val;
|
||||
#endif
|
||||
}
|
||||
|
||||
__INLINE void mp4_Set16x16_8u(uint8_t *p, int32_t step, uint8_t val)
|
||||
{
|
||||
int32_t i, j;
|
||||
|
||||
for (i = 0; i < 16; i ++) {
|
||||
for (j = 0; j < 16; j ++)
|
||||
p[j] = val;
|
||||
p += step;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(USE_INTRINSIC_XMM) || defined(USE_INTRINSIC_EMM)
|
||||
|
||||
#define mp4_Zero4MV(mv) \
|
||||
memset(mv, 0, 4 * sizeof(IppMotionVector));
|
||||
|
||||
#if defined(USE_INTRINSIC_XMM)
|
||||
|
||||
#define mp4_Zero64_16s(pDst) \
|
||||
{ \
|
||||
__m64 _p_zero = _mm_setzero_si64(); \
|
||||
((__m64*)(pDst))[0] = _p_zero; \
|
||||
((__m64*)(pDst))[1] = _p_zero; \
|
||||
((__m64*)(pDst))[2] = _p_zero; \
|
||||
((__m64*)(pDst))[3] = _p_zero; \
|
||||
((__m64*)(pDst))[4] = _p_zero; \
|
||||
((__m64*)(pDst))[5] = _p_zero; \
|
||||
((__m64*)(pDst))[6] = _p_zero; \
|
||||
((__m64*)(pDst))[7] = _p_zero; \
|
||||
((__m64*)(pDst))[8] = _p_zero; \
|
||||
((__m64*)(pDst))[9] = _p_zero; \
|
||||
((__m64*)(pDst))[10] = _p_zero; \
|
||||
((__m64*)(pDst))[11] = _p_zero; \
|
||||
((__m64*)(pDst))[12] = _p_zero; \
|
||||
((__m64*)(pDst))[13] = _p_zero; \
|
||||
((__m64*)(pDst))[14] = _p_zero; \
|
||||
((__m64*)(pDst))[15] = _p_zero; \
|
||||
_m_empty(); \
|
||||
}
|
||||
|
||||
#define mp4_Set64_16s(val, pDst) \
|
||||
{ \
|
||||
__m64 _p_val = _mm_set1_pi16((int16_t)(val)); \
|
||||
((__m64*)(pDst))[0] = _p_val; \
|
||||
((__m64*)(pDst))[1] = _p_val; \
|
||||
((__m64*)(pDst))[2] = _p_val; \
|
||||
((__m64*)(pDst))[3] = _p_val; \
|
||||
((__m64*)(pDst))[4] = _p_val; \
|
||||
((__m64*)(pDst))[5] = _p_val; \
|
||||
((__m64*)(pDst))[6] = _p_val; \
|
||||
((__m64*)(pDst))[7] = _p_val; \
|
||||
((__m64*)(pDst))[8] = _p_val; \
|
||||
((__m64*)(pDst))[9] = _p_val; \
|
||||
((__m64*)(pDst))[10] = _p_val; \
|
||||
((__m64*)(pDst))[11] = _p_val; \
|
||||
((__m64*)(pDst))[12] = _p_val; \
|
||||
((__m64*)(pDst))[13] = _p_val; \
|
||||
((__m64*)(pDst))[14] = _p_val; \
|
||||
((__m64*)(pDst))[15] = _p_val; \
|
||||
_m_empty(); \
|
||||
}
|
||||
|
||||
#elif defined(USE_INTRINSIC_EMM)
|
||||
|
||||
#define mp4_Zero64_16s(pDst) \
|
||||
{ \
|
||||
__m128i _p_val = _mm_setzero_si128(); \
|
||||
((__m128i*)(pDst))[0] = _p_val; \
|
||||
((__m128i*)(pDst))[1] = _p_val; \
|
||||
((__m128i*)(pDst))[2] = _p_val; \
|
||||
((__m128i*)(pDst))[3] = _p_val; \
|
||||
((__m128i*)(pDst))[4] = _p_val; \
|
||||
((__m128i*)(pDst))[5] = _p_val; \
|
||||
((__m128i*)(pDst))[6] = _p_val; \
|
||||
((__m128i*)(pDst))[7] = _p_val; \
|
||||
}
|
||||
|
||||
#define mp4_Set64_16s(val, pDst) \
|
||||
{ \
|
||||
__m128i _p_val = _mm_set1_epi16((int16_t)(val)); \
|
||||
((__m128i*)(pDst))[0] = _p_val; \
|
||||
((__m128i*)(pDst))[1] = _p_val; \
|
||||
((__m128i*)(pDst))[2] = _p_val; \
|
||||
((__m128i*)(pDst))[3] = _p_val; \
|
||||
((__m128i*)(pDst))[4] = _p_val; \
|
||||
((__m128i*)(pDst))[5] = _p_val; \
|
||||
((__m128i*)(pDst))[6] = _p_val; \
|
||||
((__m128i*)(pDst))[7] = _p_val; \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#define mp4_Zero4MV(mv) \
|
||||
(mv)[0].dx = (mv)[0].dy = (mv)[1].dx = (mv)[1].dy = (mv)[2].dx = (mv)[2].dy = (mv)[3].dx = (mv)[3].dy = 0
|
||||
|
||||
#define mp4_Zero64_16s(pDst) \
|
||||
{ \
|
||||
int32_t i; \
|
||||
for (i = 0; i < 32; i += 8) { \
|
||||
((uint32_t*)(pDst))[i] = 0; \
|
||||
((uint32_t*)(pDst))[i+1] = 0; \
|
||||
((uint32_t*)(pDst))[i+2] = 0; \
|
||||
((uint32_t*)(pDst))[i+3] = 0; \
|
||||
((uint32_t*)(pDst))[i+4] = 0; \
|
||||
((uint32_t*)(pDst))[i+5] = 0; \
|
||||
((uint32_t*)(pDst))[i+6] = 0; \
|
||||
((uint32_t*)(pDst))[i+7] = 0; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define mp4_Set64_16s(val, pDst) \
|
||||
{ \
|
||||
int32_t i; \
|
||||
uint32_t v; \
|
||||
v = ((val) << 16) + (Ipp16u)(val); \
|
||||
for (i = 0; i < 32; i += 8) { \
|
||||
((uint32_t*)(pDst))[i] = v; \
|
||||
((uint32_t*)(pDst))[i+1] = v; \
|
||||
((uint32_t*)(pDst))[i+2] = v; \
|
||||
((uint32_t*)(pDst))[i+3] = v; \
|
||||
((uint32_t*)(pDst))[i+4] = v; \
|
||||
((uint32_t*)(pDst))[i+5] = v; \
|
||||
((uint32_t*)(pDst))[i+6] = v; \
|
||||
((uint32_t*)(pDst))[i+7] = v; \
|
||||
} \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#define mp4_MC_HP(pat, pRef, stepRef, pCur, stepCur, coeffMB, mv, rc) \
|
||||
{ \
|
||||
if (pat) { \
|
||||
mp4_Add8x8HP_16s8u(pRef, stepRef, coeffMB, pCur, stepCur, mv, rc); \
|
||||
} else { \
|
||||
mp4_Copy8x8HP_8u(pRef, stepRef, pCur, stepCur, mv, rc); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define mp4_AddResidual(pat, pc, stepc, coeffMB) \
|
||||
{ \
|
||||
if (pat) { \
|
||||
mp4_Add8x8_16s8u(pc, coeffMB, stepc); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define mp4_DCTInvCoeffsIntraMB(coeffMB, lnz, pFc, stepFc) \
|
||||
{ \
|
||||
int32_t i; \
|
||||
for (i = 0; i < 6; i ++) { \
|
||||
if (lnz[i] > 0) \
|
||||
ippiDCT8x8Inv_16s8u_C1R(&coeffMB[i*64], pFc[i], stepFc[i]); \
|
||||
else { \
|
||||
int k = (coeffMB[i*64] + 4) >> 3; \
|
||||
mp4_CLIP(k, 0, 255); \
|
||||
mp4_Set8x8_8u(pFc[i], stepFc[i], (uint8_t)k); \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#define mp4_ReconstructCoeffsIntraMB_SVH(pInfo, coeffMB, lnz, pat, quant, err) \
|
||||
{ \
|
||||
int32_t i, pm = 32; \
|
||||
for (i = 0; i < 6; i ++) { \
|
||||
if (ippiReconstructCoeffsIntra_H263_1u16s(&pInfo->bufptr, &pInfo->bitoff, coeffMB+i*64, &lnz[i], pat & pm, quant, 0, IPPVC_SCAN_ZIGZAG, 0) != ippStsNoErr) { \
|
||||
mp4_Error("Error: decoding coefficients of Intra block"); \
|
||||
goto err; \
|
||||
} \
|
||||
if (pat & pm) { \
|
||||
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTRA_AC); \
|
||||
} else { \
|
||||
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTRA_DC); \
|
||||
} \
|
||||
pm >>= 1; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define mp4_ReconstructCoeffsInterMB_SVH(pInfo, coeffMB, lnz, pat, quant, err) \
|
||||
{ \
|
||||
if (pat) { \
|
||||
int32_t i, pm = 32; \
|
||||
for (i = 0; i < 6; i ++) { \
|
||||
if (pat & pm) { \
|
||||
if (ippiReconstructCoeffsInter_H263_1u16s(&pInfo->bufptr, &pInfo->bitoff, coeffMB+i*64, &lnz[i], quant, 0) != ippStsNoErr) { \
|
||||
mp4_Error("Error: decoding coefficients of Inter block"); \
|
||||
goto err; \
|
||||
} \
|
||||
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTER_C); \
|
||||
} else { \
|
||||
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTER_NC); \
|
||||
} \
|
||||
pm >>= 1; \
|
||||
} \
|
||||
} else { \
|
||||
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTER_NC); \
|
||||
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTER_NC); \
|
||||
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTER_NC); \
|
||||
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTER_NC); \
|
||||
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTER_NC); \
|
||||
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTER_NC); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define mp4_DCTInvCoeffsInterMB_SVH(coeffMB, lastNZ, pat) \
|
||||
if (pat) { \
|
||||
int32_t i, lnz, pm = 32; \
|
||||
int16_t *coeff = coeffMB; \
|
||||
for (i = 0; i < 6; i ++) { \
|
||||
if ((pat) & pm) { \
|
||||
lnz = lastNZ[i]; \
|
||||
if (lnz != 0) { \
|
||||
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 \
|
||||
mp4_Set64_16s((int16_t)((coeff[0] + 4) >> 3), coeff); \
|
||||
} \
|
||||
pm >>= 1; \
|
||||
coeff += 64; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define mp4_DecodeMCInterBlock_SVH(pInfo, quant, pat, pRef, pCur, step, coeffMB, mv, err) \
|
||||
{ \
|
||||
if (pat) { \
|
||||
int32_t lnz; \
|
||||
if (ippiReconstructCoeffsInter_H263_1u16s(&pInfo->bufptr, &pInfo->bitoff, coeffMB, &lnz, quant, 0) != ippStsNoErr) { \
|
||||
mp4_Error("Error: decoding coefficients of Inter block"); \
|
||||
goto err; \
|
||||
} \
|
||||
if (lnz != 0) { \
|
||||
if ((lnz <= 4) && (coeffMB[16] == 0)) \
|
||||
ippiDCT8x8Inv_2x2_16s_C1I(coeffMB); \
|
||||
else if ((lnz <= 13) && (coeffMB[32] == 0)) \
|
||||
ippiDCT8x8Inv_4x4_16s_C1I(coeffMB); \
|
||||
else \
|
||||
ippiDCT8x8Inv_16s_C1I(coeffMB); \
|
||||
} else { \
|
||||
mp4_Set64_16s((int16_t)((coeffMB[0] + 4) >> 3), coeffMB); \
|
||||
} \
|
||||
mp4_Add8x8HP_16s8u(pRef, step, coeffMB, pCur, step, mv, 0); \
|
||||
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTER_C); \
|
||||
} else { \
|
||||
mp4_Copy8x8HP_8u(pRef, step, pCur, step, mv, 0); \
|
||||
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTER_NC); \
|
||||
} \
|
||||
}
|
||||
|
||||
// reset Intra prediction buffer on new Video_packet
|
||||
#define mp4_ResetIntraPredBuffer(pInfo) \
|
||||
{ \
|
||||
mp4_IntraPredBlock *b = pInfo->VisualObject.VideoObject.IntraPredBuff.dcB; \
|
||||
int32_t i; \
|
||||
b[3].dct_dc = b[4].dct_dc = b[5].dct_dc = -1; \
|
||||
b = pInfo->VisualObject.VideoObject.IntraPredBuff.block; \
|
||||
for (i = 0; i <= pInfo->VisualObject.VideoObject.MacroBlockPerRow; i ++) { \
|
||||
b[i*6+0].dct_dc = b[i*6+1].dct_dc = b[i*6+2].dct_dc = b[i*6+3].dct_dc = b[i*6+4].dct_dc = b[i*6+5].dct_dc = -1; \
|
||||
} \
|
||||
}
|
||||
|
||||
// reset B-prediction blocks on new row
|
||||
#define mp4_ResetIntraPredBblock(pInfo) \
|
||||
{ \
|
||||
pInfo->VisualObject.VideoObject.IntraPredBuff.dcB[3].dct_dc = \
|
||||
pInfo->VisualObject.VideoObject.IntraPredBuff.dcB[4].dct_dc = \
|
||||
pInfo->VisualObject.VideoObject.IntraPredBuff.dcB[5].dct_dc = -1; \
|
||||
}
|
||||
|
||||
// mark current MB as invalid for Intra prediction and rotate buffer
|
||||
#define mp4_UpdateIntraPredBuffInvalid(pInfo, colNum) \
|
||||
{ \
|
||||
mp4_IntraPredBlock *b = &pInfo->VisualObject.VideoObject.IntraPredBuff.block[colNum*6+6]; \
|
||||
pInfo->VisualObject.VideoObject.IntraPredBuff.dcB[3].dct_dc = b[3].dct_dc; \
|
||||
pInfo->VisualObject.VideoObject.IntraPredBuff.dcB[4].dct_dc = b[4].dct_dc; \
|
||||
pInfo->VisualObject.VideoObject.IntraPredBuff.dcB[5].dct_dc = b[5].dct_dc; \
|
||||
b[0].dct_dc = b[1].dct_dc = b[2].dct_dc = b[3].dct_dc = b[4].dct_dc = b[5].dct_dc = -1; \
|
||||
/* pInfo->VisualObject.VideoObject.IntraPredBuff.quant[colNum+1] = (uint8_t)quant; */ \
|
||||
}
|
||||
|
||||
|
||||
/* 2x2 and 4x4 DCT decision suitable for Classical Zigzag Scan only */
|
||||
#define mp4_DecodeMCBlockInter_MPEG4(pat, pr, stepr, pc, stepc, mv, rt, err) \
|
||||
{ \
|
||||
if (pat) { \
|
||||
int32_t lnz; \
|
||||
if (ippiReconstructCoeffsInter_MPEG4_1u16s(&pInfo->bufptr, &pInfo->bitoff, coeffMB, &lnz, rvlc, scan, pInfo->VisualObject.VideoObject.QuantInvInterSpec, quant) != ippStsNoErr) { \
|
||||
mp4_Error("Error: decoding coefficients of Inter block"); \
|
||||
goto err; \
|
||||
} \
|
||||
if (pInfo->VisualObject.VideoObject.quant_type == 0 || (coeffMB[63] == 0)) { \
|
||||
if (lnz != 0) { \
|
||||
if ((lnz <= 4) && (coeffMB[16] == 0)) \
|
||||
ippiDCT8x8Inv_2x2_16s_C1I(coeffMB); \
|
||||
else if ((lnz <= 13) && (coeffMB[32] == 0)) \
|
||||
ippiDCT8x8Inv_4x4_16s_C1I(coeffMB); \
|
||||
else \
|
||||
ippiDCT8x8Inv_16s_C1I(coeffMB); \
|
||||
} else { \
|
||||
mp4_Set64_16s((int16_t)((coeffMB[0] + 4) >> 3), coeffMB); \
|
||||
} \
|
||||
} else { \
|
||||
ippiDCT8x8Inv_16s_C1I(coeffMB); \
|
||||
} \
|
||||
mp4_Add8x8HP_16s8u(pr, stepr, coeffMB, pc, stepc, &mv, rt); \
|
||||
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTER_C); \
|
||||
} else { \
|
||||
mp4_Copy8x8HP_8u(pr, stepr, pc, stepc, &mv, rt); \
|
||||
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTER_NC); \
|
||||
} \
|
||||
}
|
||||
|
||||
/* 2x2 and 4x4 DCT decision suitable for Classical Zigzag Scan only */
|
||||
#define mp4_DecodeReconBlockInter_MPEG4(pat, pc, stepc, err) \
|
||||
{ \
|
||||
if (pat) { \
|
||||
int32_t lnz; \
|
||||
if (ippiReconstructCoeffsInter_MPEG4_1u16s(&pInfo->bufptr, &pInfo->bitoff, coeffMB, &lnz, rvlc, scan, pInfo->VisualObject.VideoObject.QuantInvInterSpec, quant) != ippStsNoErr) { \
|
||||
mp4_Error("Error: decoding coefficients of Inter block"); \
|
||||
goto err; \
|
||||
} \
|
||||
if (pInfo->VisualObject.VideoObject.quant_type == 0 || (coeffMB[63] == 0)) { \
|
||||
if (lnz != 0) { \
|
||||
if ((lnz <= 4) && (coeffMB[16] == 0)) \
|
||||
ippiDCT8x8Inv_2x2_16s_C1I(coeffMB); \
|
||||
else if ((lnz <= 13) && (coeffMB[32] == 0)) \
|
||||
ippiDCT8x8Inv_4x4_16s_C1I(coeffMB); \
|
||||
else \
|
||||
ippiDCT8x8Inv_16s_C1I(coeffMB); \
|
||||
} else { \
|
||||
mp4_Set64_16s((int16_t)((coeffMB[0] + 4) >> 3), coeffMB); \
|
||||
} \
|
||||
} else { \
|
||||
ippiDCT8x8Inv_16s_C1I(coeffMB); \
|
||||
} \
|
||||
mp4_Add8x8_16s8u(pc, coeffMB, stepc); \
|
||||
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTER_C); \
|
||||
} else { \
|
||||
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTER_NC); \
|
||||
} \
|
||||
}
|
||||
|
||||
__INLINE int32_t mp4_GetMacroBlockNumberSize(int32_t nmb)
|
||||
{
|
||||
int32_t nb = 0;
|
||||
nmb --;
|
||||
do {
|
||||
nmb >>= 1;
|
||||
nb ++;
|
||||
} while (nmb);
|
||||
return nb;
|
||||
}
|
||||
|
||||
__INLINE int32_t mp4_GetConvRatio(mp4_Info* pInfo)
|
||||
{
|
||||
if (mp4_GetBit(pInfo) == 1)
|
||||
return 0;
|
||||
else
|
||||
return (mp4_GetBit(pInfo) == 0 ? 2 : 4);
|
||||
}
|
||||
|
||||
// decode cbpy for Inter nontransparent MB
|
||||
__INLINE mp4_Status mp4_DecodeCBPY_P(mp4_Info* pInfo, int32_t *yPattern, int32_t mbType)
|
||||
{
|
||||
uint32_t code;
|
||||
|
||||
code = mp4_ShowBits9(pInfo, 6);
|
||||
if (mbType < IPPVC_MBTYPE_INTRA)
|
||||
*yPattern = 15 - mp4_cbpy4[code].code;
|
||||
else
|
||||
*yPattern = mp4_cbpy4[code].code;
|
||||
if (mp4_cbpy4[code].len == 255) {
|
||||
mp4_Error("Error: decoding CBPY");
|
||||
return MP4_STATUS_ERROR;
|
||||
} else {
|
||||
mp4_FlushBits(pInfo, mp4_cbpy4[code].len);
|
||||
return MP4_STATUS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// decode cbpy for Intra nontransparent MB
|
||||
|
||||
__INLINE mp4_Status mp4_DecodeCBPY_I(mp4_Info* pInfo, int32_t *yPattern)
|
||||
{
|
||||
uint32_t code;
|
||||
|
||||
code = mp4_ShowBits9(pInfo, 6);
|
||||
*yPattern = mp4_cbpy4[code].code;
|
||||
if (mp4_cbpy4[code].len == 255) {
|
||||
mp4_Error("Error: decoding CBPY");
|
||||
return MP4_STATUS_ERROR;
|
||||
} else {
|
||||
mp4_FlushBits(pInfo, mp4_cbpy4[code].len);
|
||||
return MP4_STATUS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
extern mp4_Status mp4_DecodeMVD(mp4_Info *pInfo, int32_t *mvdx, int32_t *mvdy, int32_t fcode);
|
||||
extern mp4_Status mp4_DecodeMV(mp4_Info *pInfo, IppMotionVector *mv, int32_t fcode);
|
||||
extern mp4_Status mp4_Decode4MV(mp4_Info *pInfo, IppMotionVector *mv, int32_t fcode);
|
||||
extern mp4_Status mp4_DecodeMV_Direct(mp4_Info *pInfo, IppMotionVector mvC[4], IppMotionVector mvForw[4], IppMotionVector mvBack[4], int32_t TRB, int32_t TRD, int32_t modb, int32_t comb_type);
|
||||
extern mp4_Status mp4_DecodeMV_DirectField(mp4_Info *pInfo, int32_t mb_ftfr, int32_t mb_fbfr, IppMotionVector *mvTop, IppMotionVector *mvBottom, IppMotionVector *mvForwTop, IppMotionVector *mvForwBottom, IppMotionVector *mvBackTop, IppMotionVector *mvBackBottom, int32_t TRB, int32_t TRD, int32_t modb);
|
||||
extern mp4_Status mp4_DecodeIntraMB_SVH(mp4_Info *pInfo, int32_t pat, int32_t quant, uint8_t *pR[], int32_t stepR[]);
|
||||
extern mp4_Status mp4_DecodeIntraMB_DP(mp4_Info *pInfo, int16_t dct_dc[], int32_t x, int32_t pat, int32_t quant, int32_t dcVLC, int32_t ac_pred_flag, uint8_t *pR[], int32_t stepR[]);
|
||||
extern mp4_Status mp4_DecodeIntraMB(mp4_Info *pInfo, int32_t x, int32_t pat, int32_t quant, int32_t dcVLC, int32_t ac_pred_flag, uint8_t *pR[], int32_t stepR[]);
|
||||
extern mp4_Status mp4_DecodeInterMB_SVH(mp4_Info *pInfo, int16_t *coeffMB, int32_t quant, int32_t pat);
|
||||
extern mp4_Status mp4_DecodeInterMB(mp4_Info *pInfo, int16_t *coeffMB, int32_t quant, int32_t pat, int32_t scan);
|
||||
extern mp4_Status mp4_ReconstructCoeffsIntraMB(mp4_Info *pInfo, int32_t x, int32_t pat, int32_t quant, int32_t dcVLC, int32_t ac_pred_flag, int16_t *coeff, int32_t lnz[]);
|
||||
extern mp4_Status mp4_DecodeMCBPC_P(mp4_Info* pInfo, int32_t *mbType, int32_t *mbPattern, int32_t stat);
|
||||
extern mp4_Status mp4_PredictDecode1MV(mp4_Info *pInfo, mp4_MacroBlock *MBcurr, int32_t y, int32_t x);
|
||||
extern mp4_Status mp4_PredictDecode4MV(mp4_Info *pInfo, mp4_MacroBlock *MBcurr, int32_t y, int32_t x);
|
||||
extern mp4_Status mp4_PredictDecodeFMV(mp4_Info *pInfo, mp4_MacroBlock *MBcurr, int32_t y, int32_t x, IppMotionVector *mvT, IppMotionVector *mvB);
|
||||
extern mp4_Status mp4_DecodeVideoObjectPlane(mp4_Info* pInfo);
|
||||
extern mp4_Status mp4_DecodeVOP_I(mp4_Info* pInfo);
|
||||
extern mp4_Status mp4_DecodeVOP_P(mp4_Info* pInfo);
|
||||
extern mp4_Status mp4_DecodeVOP_B(mp4_Info* pInfo);
|
||||
extern mp4_Status mp4_DecodeVOP_S(mp4_Info* pInfo);
|
||||
extern mp4_Status mp4_DecodeVOP_I_MT(mp4_Info* pInfo);
|
||||
extern mp4_Status mp4_DecodeVOP_P_MT(mp4_Info* pInfo);
|
||||
extern mp4_Status mp4_DecodeVOP_B_MT(mp4_Info* pInfo);
|
||||
extern mp4_Status mp4_DecodeVOP_S_MT(mp4_Info* pInfo);
|
||||
extern void mp4_DCTInvCoeffsInterMB(mp4_Info *pInfo, int16_t *coeffMB, int32_t lnz[], int32_t pat, int32_t scan);
|
||||
extern void mp4_PadFrame(mp4_Info* pInfo);
|
||||
extern void mp4_OBMC(mp4_Info *pInfo, mp4_MacroBlock *pMBinfo, IppMotionVector *mvCur, int32_t colNum, int32_t rowNum, IppiRect limitRectL, uint8_t *pYc, int32_t stepYc, uint8_t *pYr, int32_t stepYr, int32_t cbpy, int16_t *coeffMB, int32_t dct_type);
|
||||
extern mp4_Status mp4_CheckDecodeVideoPacket(mp4_Info* pInfo, int32_t *found);
|
||||
extern int32_t mp4_CheckDecodeGOB_SVH(mp4_Info* pInfo);
|
||||
extern void mp4_CopyMacroBlocks(const mp4_Frame *rFrame, mp4_Frame *cFrame, int32_t mbPerRow, int32_t rowNum, int32_t colNum, int32_t n);
|
||||
|
||||
extern mp4_Status mp4_Sprite_Trajectory(mp4_Info* pInfo);
|
||||
extern mp4_Status mp4_PredictDecodeMV(mp4_Info *pInfo, mp4_MacroBlock *MBcurr, int32_t frGOB, int32_t y, int32_t x);
|
||||
extern mp4_Status mp4_DecodeMCBPC_I(mp4_Info* pInfo, int32_t *mbType, int32_t *mbPattern);
|
||||
|
||||
#ifdef FLOAT_POINT_IDCT
|
||||
|
||||
static void fIDCT_16s8u_C1R(int16_t *coeff, uint8_t *pR, int stepR)
|
||||
{
|
||||
__ALIGN16(Ipp32f, c, 64);
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < 64; i ++)
|
||||
c[i] = coeff[i];
|
||||
ippiDCT8x8Inv_32f_C1I(c);
|
||||
for (i = 0; i < 8; i ++)
|
||||
for (j = 0; j < 8; j ++)
|
||||
pR[i*stepR+j] = c[i*8+j] < 0 ? 0 : c[i*8+j] > 255 ? 255 : (int16_t)(c[i*8+j] + 0.5f);
|
||||
}
|
||||
|
||||
static void fIDCT_16s_C1I(int16_t *coeff)
|
||||
{
|
||||
__ALIGN16(Ipp32f, c, 64);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 64; i ++)
|
||||
c[i] = coeff[i];
|
||||
ippiDCT8x8Inv_32f_C1I(c);
|
||||
for (i = 0; i < 64; i ++)
|
||||
coeff[i] = c[i] < 0 ? (int16_t)(c[i] - 0.5f) : (int16_t)(c[i] + 0.5f);
|
||||
}
|
||||
|
||||
#define ippiDCT8x8Inv_16s8u_C1R(coeff, pR, stepR) \
|
||||
fIDCT_16s8u_C1R(coeff, pR, stepR)
|
||||
|
||||
#define ippiDCT8x8Inv_2x2_16s_C1I(coeff) \
|
||||
fIDCT_16s_C1I(coeff)
|
||||
|
||||
#define ippiDCT8x8Inv_4x4_16s_C1I(coeff) \
|
||||
fIDCT_16s_C1I(coeff)
|
||||
|
||||
#define ippiDCT8x8Inv_16s_C1I(coeff) \
|
||||
fIDCT_16s_C1I(coeff)
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
1983
Src/mpeg4dec/mp4decvop.c
Normal file
1983
Src/mpeg4dec/mp4decvop.c
Normal file
File diff suppressed because it is too large
Load diff
831
Src/mpeg4dec/mp4decvopb.c
Normal file
831
Src/mpeg4dec/mp4decvopb.c
Normal file
|
@ -0,0 +1,831 @@
|
|||
/* ///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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) 2001-2007 Intel Corporation. All Rights Reserved.
|
||||
//
|
||||
// Description: Decodes B-VOPs
|
||||
//
|
||||
*/
|
||||
|
||||
|
||||
#include "mp4def.h"
|
||||
#include "mp4dec.h"
|
||||
|
||||
/*
|
||||
// Purpose: decode MPEG-4 BVOP
|
||||
*/
|
||||
mp4_Status mp4_DecodeVOP_B(mp4_Info* pInfo)
|
||||
{
|
||||
__ALIGN16(int16_t, coeffMB, 64*6);
|
||||
__ALIGN16(uint8_t, tmpMB, 64*4);
|
||||
uint32_t code;
|
||||
uint8_t *pYc, *pCbc, *pCrc, *pYp, *pCbp, *pCrp, *pYn, *pCbn, *pCrn, *pc, *pr, *pn;
|
||||
int32_t stepYp, stepYc, stepYn, stepCbp, stepCbc, stepCbn, stepCrp, stepCrc, stepCrn, mbPerRow, mbPerCol;
|
||||
int32_t dx, dy, TRB, TRD, quant, mbCurr, mbInVideoPacket, colNum, rowNum;
|
||||
IppiRect limitRectL, limitRectC;
|
||||
int32_t quarter_sample, modb, mb_type, cbpb, dct_type, field_prediction, rvlc = 0, scan;
|
||||
int32_t mb_ftfr, mb_fbfr, mb_btfr, mb_bbfr, fcode_forward, fcode_backward;
|
||||
mp4_MacroBlock *pMBinfo;
|
||||
mp4_Status sts;
|
||||
|
||||
sts = MP4_STATUS_OK;
|
||||
|
||||
if (!pInfo->VisualObject.cFrame)
|
||||
pInfo->VisualObject.cFrame = CreateFrame(&pInfo->VisualObject);
|
||||
stepYc = pInfo->VisualObject.cFrame->stepY;
|
||||
stepYp = pInfo->VisualObject.rFrame->stepY;
|
||||
stepYn = pInfo->VisualObject.nFrame->stepY;
|
||||
stepCbc = pInfo->VisualObject.cFrame->stepCb;
|
||||
stepCbp = pInfo->VisualObject.rFrame->stepCb;
|
||||
stepCbn = pInfo->VisualObject.nFrame->stepCb;
|
||||
stepCrc = pInfo->VisualObject.cFrame->stepCr;
|
||||
stepCrp = pInfo->VisualObject.rFrame->stepCr;
|
||||
stepCrn = pInfo->VisualObject.nFrame->stepCr;
|
||||
pYc = pInfo->VisualObject.cFrame->pY;
|
||||
pCbc = pInfo->VisualObject.cFrame->pCb;
|
||||
pCrc = pInfo->VisualObject.cFrame->pCr;
|
||||
pYp = pInfo->VisualObject.rFrame->pY;
|
||||
pCbp = pInfo->VisualObject.rFrame->pCb;
|
||||
pCrp = pInfo->VisualObject.rFrame->pCr;
|
||||
pYn = pInfo->VisualObject.nFrame->pY;
|
||||
pCbn = pInfo->VisualObject.nFrame->pCb;
|
||||
pCrn = pInfo->VisualObject.nFrame->pCr;
|
||||
quarter_sample = pInfo->VisualObject.VideoObject.quarter_sample;
|
||||
scan = pInfo->VisualObject.VideoObject.VideoObjectPlane.alternate_vertical_scan_flag ? IPPVC_SCAN_VERTICAL : IPPVC_SCAN_ZIGZAG;
|
||||
fcode_forward = pInfo->VisualObject.VideoObject.VideoObjectPlane.fcode_forward;
|
||||
fcode_backward = pInfo->VisualObject.VideoObject.VideoObjectPlane.fcode_backward;
|
||||
// Bounding rectangles for MV limitation
|
||||
limitRectL.x = - 16 * MP4_NUM_EXT_MB;
|
||||
limitRectL.y = - 16 * MP4_NUM_EXT_MB;
|
||||
limitRectL.width = pInfo->VisualObject.VideoObject.width + 16 * 2 * MP4_NUM_EXT_MB;
|
||||
limitRectL.height = pInfo->VisualObject.VideoObject.height + 16 * 2 * MP4_NUM_EXT_MB;
|
||||
limitRectC.x = -8 * MP4_NUM_EXT_MB;
|
||||
limitRectC.y = -8 * MP4_NUM_EXT_MB;
|
||||
limitRectC.width = (pInfo->VisualObject.VideoObject.width >> 1) + 8 * 2 * MP4_NUM_EXT_MB;
|
||||
limitRectC.height = (pInfo->VisualObject.VideoObject.height >> 1) + 8 * 2 * MP4_NUM_EXT_MB;
|
||||
quant = pInfo->VisualObject.VideoObject.VideoObjectPlane.quant;
|
||||
mbPerRow = pInfo->VisualObject.VideoObject.MacroBlockPerRow;
|
||||
mbPerCol = pInfo->VisualObject.VideoObject.MacroBlockPerCol;
|
||||
mbCurr = colNum = rowNum = 0;
|
||||
TRD = pInfo->VisualObject.VideoObject.TRD;
|
||||
TRB = pInfo->VisualObject.VideoObject.TRB;
|
||||
pMBinfo = pInfo->VisualObject.VideoObject.MBinfo;
|
||||
// decode interlaced B-VOP
|
||||
if (pInfo->VisualObject.VideoObject.interlaced) {
|
||||
IppMotionVector mvCbCrF, mvCbCrB, mvForwT, mvBackT, mvForwB, mvBackB, mvForw[4], mvBack[4], mvCbCrFFT, mvCbCrFFB, mvCbCrBFT, mvCbCrBFB, *mvField = pInfo->VisualObject.VideoObject.FieldMV;
|
||||
|
||||
// warning "variable may be used without having been initialized"
|
||||
mvCbCrF.dx = mvCbCrF.dy = mvCbCrB.dx = mvCbCrB.dy = mvCbCrFFT.dx = mvCbCrFFT.dy = mvCbCrFFB.dx = mvCbCrFFB.dy = mvCbCrBFT.dx = mvCbCrBFT.dy = mvCbCrBFB.dx = mvCbCrBFB.dy = 0;
|
||||
mb_ftfr = mb_fbfr = mb_btfr = mb_bbfr = 0;
|
||||
for (;;) {
|
||||
mbInVideoPacket = 0;
|
||||
// reset MV predictors at new VideoPacket
|
||||
mvForwT.dx = mvForwT.dy = mvBackT.dx = mvBackT.dy = mvForwB.dx = mvForwB.dy = mvBackB.dx = mvBackB.dy = 0;
|
||||
// decode B-VOP macroblocks
|
||||
for (;;) {
|
||||
if (pMBinfo->not_coded) {
|
||||
ippiCopy16x16_8u_C1R(pYp, stepYp, pYc, stepYc);
|
||||
ippiCopy8x8_8u_C1R(pCbp, stepCbp, pCbc, stepCbc);
|
||||
ippiCopy8x8_8u_C1R(pCrp, stepCrp, pCrc, stepCrc);
|
||||
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_NOTCODED);
|
||||
} else {
|
||||
cbpb = 0;
|
||||
if (mp4_GetBit(pInfo)) {
|
||||
modb = 2;
|
||||
mb_type = IPPVC_MBTYPE_DIRECT;
|
||||
} else {
|
||||
modb = mp4_GetBit(pInfo);
|
||||
// decode mb_type
|
||||
code = mp4_ShowBits9(pInfo, 4);
|
||||
if (code != 0) {
|
||||
mb_type = mp4_BVOPmb_type[code].code;
|
||||
mp4_FlushBits(pInfo, mp4_BVOPmb_type[code].len);
|
||||
} else {
|
||||
mp4_Error("Error when decode mb_type of B-VOP macroblock");
|
||||
goto Err_1;
|
||||
}
|
||||
if (modb == 0)
|
||||
cbpb = mp4_GetBits9(pInfo, 6);
|
||||
if (mb_type != IPPVC_MBTYPE_DIRECT && cbpb != 0)
|
||||
mp4_UpdateQuant_B(pInfo, quant);
|
||||
}
|
||||
dct_type = 0;
|
||||
field_prediction = 0;
|
||||
if (cbpb != 0)
|
||||
dct_type = mp4_GetBit(pInfo);
|
||||
if (mb_type != IPPVC_MBTYPE_DIRECT) {
|
||||
field_prediction = mp4_GetBit(pInfo);
|
||||
if (field_prediction) {
|
||||
if (mb_type != IPPVC_MBTYPE_BACKWARD) {
|
||||
mb_ftfr = mp4_GetBit(pInfo);
|
||||
mb_fbfr = mp4_GetBit(pInfo);
|
||||
}
|
||||
if (mb_type != IPPVC_MBTYPE_FORWARD) {
|
||||
mb_btfr = mp4_GetBit(pInfo);
|
||||
mb_bbfr = mp4_GetBit(pInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
// coordinates of current MB for limitation
|
||||
dx = colNum * 16;
|
||||
dy = rowNum * 16;
|
||||
if (mb_type == IPPVC_MBTYPE_FORWARD) {
|
||||
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_FORWARD);
|
||||
if (!field_prediction) {
|
||||
if (mp4_DecodeMV(pInfo, &mvForwT, fcode_forward) != MP4_STATUS_OK)
|
||||
goto Err_1;
|
||||
if (quarter_sample) {
|
||||
mp4_LimitMVQ(&mvForwT, &mvForw[0], &limitRectL, dx, dy, 16);
|
||||
mp4_ComputeChromaMVQ(&mvForw[0], &mvCbCrF);
|
||||
mp4_Copy16x16QP_8u(pYp, stepYp, pYc, stepYc, &mvForw[0], 0);
|
||||
} else {
|
||||
mp4_LimitMV(&mvForwT, &mvForw[0], &limitRectL, dx, dy, 16);
|
||||
mp4_ComputeChromaMV(&mvForw[0], &mvCbCrF);
|
||||
mp4_Copy16x16HP_8u(pYp, stepYp, pYc, stepYc, &mvForw[0], 0);
|
||||
}
|
||||
//mvForw[1] = mvForw[2] = mvForw[3] = mvForw[0];
|
||||
mvForwB = mvForwT;
|
||||
} else {
|
||||
mvForwT.dy = (int16_t)mp4_Div2(mvForwT.dy);
|
||||
if (mp4_DecodeMV(pInfo, &mvForwT, fcode_forward) != MP4_STATUS_OK)
|
||||
goto Err_1;
|
||||
mvForwB.dy = (int16_t)mp4_Div2(mvForwB.dy);
|
||||
if (mp4_DecodeMV(pInfo, &mvForwB, fcode_forward) != MP4_STATUS_OK)
|
||||
goto Err_1;
|
||||
if (quarter_sample) {
|
||||
mp4_LimitFMVQ(&mvForwT, &mvForw[0], &limitRectL, dx, dy, 16);
|
||||
mp4_Copy16x8QP_8u(pYp+(mb_ftfr ? stepYp : 0), stepYp*2, pYc, stepYc*2, &mvForw[0], 0);
|
||||
mvForw[0].dx = (int16_t)mp4_Div2(mvForw[0].dx);
|
||||
mvForw[0].dy = (int16_t)(mp4_Div2(mvForw[0].dy*2) >> 1);
|
||||
mp4_LimitFMVQ(&mvForwB, &mvForw[2], &limitRectL, dx, dy, 16);
|
||||
mp4_Copy16x8QP_8u(pYp+(mb_fbfr ? stepYp : 0), stepYp*2, pYc+stepYc, stepYc*2, &mvForw[2], 0);
|
||||
mvForw[2].dx = (int16_t)mp4_Div2(mvForw[2].dx);
|
||||
mvForw[2].dy = (int16_t)(mp4_Div2(mvForw[2].dy*2) >> 1);
|
||||
} else {
|
||||
mp4_LimitFMV(&mvForwT, &mvForw[0], &limitRectL, dx, dy, 16);
|
||||
mp4_Copy16x8HP_8u(pYp+(mb_ftfr ? stepYp : 0), stepYp*2, pYc, stepYc*2, &mvForw[0], 0);
|
||||
mp4_LimitFMV(&mvForwB, &mvForw[2], &limitRectL, dx, dy, 16);
|
||||
mp4_Copy16x8HP_8u(pYp+(mb_fbfr ? stepYp : 0), stepYp*2, pYc+stepYc, stepYc*2, &mvForw[2], 0);
|
||||
}
|
||||
mvForwT.dy <<= 1;
|
||||
mvForwB.dy <<= 1;
|
||||
//mvForw[1] = mvForw[0];
|
||||
//mvForw[3] = mvForw[2];
|
||||
mp4_ComputeChromaMV(&mvForw[0], &mvCbCrFFT);
|
||||
mp4_ComputeChromaMV(&mvForw[2], &mvCbCrFFB);
|
||||
}
|
||||
if (mp4_DecodeInterMB(pInfo, coeffMB, quant, cbpb, scan) != MP4_STATUS_OK)
|
||||
goto Err_1;
|
||||
if (!dct_type) {
|
||||
mp4_AddResidual(cbpb & 32, pYc, stepYc, coeffMB);
|
||||
mp4_AddResidual(cbpb & 16, pYc+8, stepYc, coeffMB+64);
|
||||
mp4_AddResidual(cbpb & 8, pYc+stepYc*8, stepYc, coeffMB+128);
|
||||
mp4_AddResidual(cbpb & 4, pYc+stepYc*8+8, stepYc, coeffMB+192);
|
||||
} else {
|
||||
mp4_AddResidual(cbpb & 32, pYc, stepYc*2, coeffMB);
|
||||
mp4_AddResidual(cbpb & 16, pYc+8, stepYc*2, coeffMB+64);
|
||||
mp4_AddResidual(cbpb & 8, pYc+stepYc, stepYc*2, coeffMB+128);
|
||||
mp4_AddResidual(cbpb & 4, pYc+stepYc+8, stepYc*2, coeffMB+192);
|
||||
}
|
||||
if (!field_prediction) {
|
||||
mp4_MC_HP(cbpb & 2, pCbp, stepCbp, pCbc, stepCbc, coeffMB+256, &mvCbCrF, 0);
|
||||
mp4_MC_HP(cbpb & 1, pCrp, stepCrp, pCrc, stepCrc, coeffMB+320, &mvCbCrF, 0);
|
||||
} else {
|
||||
mp4_Copy8x4HP_8u(pCbp+(mb_ftfr ? stepCbp : 0), stepCbp*2, pCbc, stepCbc*2, &mvCbCrFFT, 0);
|
||||
mp4_Copy8x4HP_8u(pCrp+(mb_ftfr ? stepCrp : 0), stepCrp*2, pCrc, stepCrc*2, &mvCbCrFFT, 0);
|
||||
mp4_Copy8x4HP_8u(pCbp+(mb_fbfr ? stepCbp : 0), stepCbp*2, pCbc+stepCbc, stepCbc*2, &mvCbCrFFB, 0);
|
||||
mp4_Copy8x4HP_8u(pCrp+(mb_fbfr ? stepCrp : 0), stepCrp*2, pCrc+stepCrc, stepCrc*2, &mvCbCrFFB, 0);
|
||||
mp4_AddResidual(cbpb & 2, pCbc, stepCbc, coeffMB+256);
|
||||
mp4_AddResidual(cbpb & 1, pCrc, stepCrc, coeffMB+320);
|
||||
}
|
||||
} else if (mb_type == IPPVC_MBTYPE_BACKWARD) {
|
||||
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_BACKWARD);
|
||||
if (!field_prediction) {
|
||||
if (mp4_DecodeMV(pInfo, &mvBackT, fcode_backward) != MP4_STATUS_OK)
|
||||
goto Err_1;
|
||||
if (quarter_sample) {
|
||||
mp4_LimitMVQ(&mvBackT, &mvBack[0], &limitRectL, dx, dy, 16);
|
||||
mp4_ComputeChromaMVQ(&mvBack[0], &mvCbCrB);
|
||||
mp4_Copy16x16QP_8u(pYn, stepYn, pYc, stepYc, &mvBack[0], 0);
|
||||
} else {
|
||||
mp4_LimitMV(&mvBackT, &mvBack[0], &limitRectL, dx, dy, 16);
|
||||
mp4_ComputeChromaMV(&mvBack[0], &mvCbCrB);
|
||||
mp4_Copy16x16HP_8u(pYn, stepYn, pYc, stepYc, &mvBack[0], 0);
|
||||
}
|
||||
//mvBack[1] = mvBack[2] = mvBack[3] = mvBack[0];
|
||||
mvBackB = mvBackT;
|
||||
} else {
|
||||
mvBackT.dy = (int16_t)mp4_Div2(mvBackT.dy);
|
||||
if (mp4_DecodeMV(pInfo, &mvBackT, fcode_backward) != MP4_STATUS_OK)
|
||||
goto Err_1;
|
||||
mvBackB.dy = (int16_t)mp4_Div2(mvBackB.dy);
|
||||
if (mp4_DecodeMV(pInfo, &mvBackB, fcode_backward) != MP4_STATUS_OK)
|
||||
goto Err_1;
|
||||
if (quarter_sample) {
|
||||
mp4_LimitFMVQ(&mvBackT, &mvBack[0], &limitRectL, dx, dy, 16);
|
||||
mp4_Copy16x8QP_8u(pYn+(mb_btfr ? stepYn : 0), stepYn*2, pYc, stepYc*2, &mvBack[0], 0);
|
||||
mvBack[0].dx = (int16_t)mp4_Div2(mvBack[0].dx);
|
||||
mvBack[0].dy = (int16_t)(mp4_Div2(mvBack[0].dy*2) >> 1);
|
||||
mp4_LimitFMVQ(&mvBackB, &mvBack[2], &limitRectL, dx, dy, 16);
|
||||
mp4_Copy16x8QP_8u(pYn+(mb_bbfr ? stepYn : 0), stepYn*2, pYc+stepYc, stepYc*2, &mvBack[2], 0);
|
||||
mvBack[2].dx = (int16_t)mp4_Div2(mvBack[2].dx);
|
||||
mvBack[2].dy = (int16_t)(mp4_Div2(mvBack[2].dy*2) >> 1);
|
||||
} else {
|
||||
mp4_LimitFMV(&mvBackT, &mvBack[0], &limitRectL, dx, dy, 16);
|
||||
mp4_Copy16x8HP_8u(pYn+(mb_btfr ? stepYn : 0), stepYn*2, pYc, stepYc*2, &mvBack[0], 0);
|
||||
mp4_LimitFMV(&mvBackB, &mvBack[2], &limitRectL, dx, dy, 16);
|
||||
mp4_Copy16x8HP_8u(pYn+(mb_bbfr ? stepYn : 0), stepYn*2, pYc+stepYc, stepYc*2, &mvBack[2], 0);
|
||||
}
|
||||
mvBackT.dy <<= 1;
|
||||
mvBackB.dy <<= 1;
|
||||
//mvBack[1] = mvBack[0];
|
||||
//mvBack[3] = mvBack[2];
|
||||
mp4_ComputeChromaMV(&mvBack[0], &mvCbCrBFT);
|
||||
mp4_ComputeChromaMV(&mvBack[2], &mvCbCrBFB);
|
||||
}
|
||||
if (mp4_DecodeInterMB(pInfo, coeffMB, quant, cbpb, scan) != MP4_STATUS_OK)
|
||||
goto Err_1;
|
||||
if (!dct_type) {
|
||||
mp4_AddResidual(cbpb & 32, pYc, stepYc, coeffMB);
|
||||
mp4_AddResidual(cbpb & 16, pYc+8, stepYc, coeffMB+64);
|
||||
mp4_AddResidual(cbpb & 8, pYc+stepYc*8, stepYc, coeffMB+128);
|
||||
mp4_AddResidual(cbpb & 4, pYc+stepYc*8+8, stepYc, coeffMB+192);
|
||||
} else {
|
||||
mp4_AddResidual(cbpb & 32, pYc, stepYc*2, coeffMB);
|
||||
mp4_AddResidual(cbpb & 16, pYc+8, stepYc*2, coeffMB+64);
|
||||
mp4_AddResidual(cbpb & 8, pYc+stepYc, stepYc*2, coeffMB+128);
|
||||
mp4_AddResidual(cbpb & 4, pYc+stepYc+8, stepYc*2, coeffMB+192);
|
||||
}
|
||||
if (!field_prediction) {
|
||||
mp4_MC_HP(cbpb & 2, pCbn, stepCbn, pCbc, stepCbc, coeffMB+256, &mvCbCrB, 0);
|
||||
mp4_MC_HP(cbpb & 1, pCrn, stepCrn, pCrc, stepCrc, coeffMB+320, &mvCbCrB, 0);
|
||||
} else {
|
||||
mp4_Copy8x4HP_8u(pCbn+(mb_btfr ? stepCbn : 0), stepCbn*2, pCbc, stepCbc*2, &mvCbCrBFT, 0);
|
||||
mp4_Copy8x4HP_8u(pCrn+(mb_btfr ? stepCrn : 0), stepCrn*2, pCrc, stepCrc*2, &mvCbCrBFT, 0);
|
||||
mp4_Copy8x4HP_8u(pCbn+(mb_bbfr ? stepCbn : 0), stepCbn*2, pCbc+stepCbc, stepCbc*2, &mvCbCrBFB, 0);
|
||||
mp4_Copy8x4HP_8u(pCrn+(mb_bbfr ? stepCrn : 0), stepCrn*2, pCrc+stepCrc, stepCrc*2, &mvCbCrBFB, 0);
|
||||
mp4_AddResidual(cbpb & 2, pCbc, stepCbc, coeffMB+256);
|
||||
mp4_AddResidual(cbpb & 1, pCrc, stepCrc, coeffMB+320);
|
||||
}
|
||||
} else if (mb_type == IPPVC_MBTYPE_INTERPOLATE) {
|
||||
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_INTERPOLATE);
|
||||
if (!field_prediction) {
|
||||
if (mp4_DecodeMV(pInfo, &mvForwT, fcode_forward) != MP4_STATUS_OK)
|
||||
goto Err_1;
|
||||
if (mp4_DecodeMV(pInfo, &mvBackT, fcode_backward) != MP4_STATUS_OK)
|
||||
goto Err_1;
|
||||
if (quarter_sample) {
|
||||
mp4_LimitMVQ(&mvForwT, &mvForw[0], &limitRectL, dx, dy, 16);
|
||||
mp4_ComputeChromaMVQ(&mvForw[0], &mvCbCrF);
|
||||
mp4_Copy16x16QP_8u(pYp, stepYp, pYc, stepYc, &mvForw[0], 0);
|
||||
mp4_LimitMVQ(&mvBackT, &mvBack[0], &limitRectL, dx, dy, 16);
|
||||
mp4_ComputeChromaMVQ(&mvBack[0], &mvCbCrB);
|
||||
mp4_Copy16x16QP_8u(pYn, stepYn, tmpMB, 16, &mvBack[0], 0);
|
||||
} else {
|
||||
mp4_LimitMV(&mvForwT, &mvForw[0], &limitRectL, dx, dy, 16);
|
||||
mp4_ComputeChromaMV(&mvForw[0], &mvCbCrF);
|
||||
mp4_Copy16x16HP_8u(pYp, stepYp, pYc, stepYc, &mvForw[0], 0);
|
||||
mp4_LimitMV(&mvBackT, &mvBack[0], &limitRectL, dx, dy, 16);
|
||||
mp4_ComputeChromaMV(&mvBack[0], &mvCbCrB);
|
||||
mp4_Copy16x16HP_8u(pYn, stepYn, tmpMB, 16, &mvBack[0], 0);
|
||||
}
|
||||
//mvForw[1] = mvForw[2] = mvForw[3] = mvForw[0];
|
||||
mvForwB = mvForwT;
|
||||
//mvBack[1] = mvBack[2] = mvBack[3] = mvBack[0];
|
||||
mvBackB = mvBackT;
|
||||
} else {
|
||||
mvForwT.dy = (int16_t)mp4_Div2(mvForwT.dy);
|
||||
if (mp4_DecodeMV(pInfo, &mvForwT, fcode_forward) != MP4_STATUS_OK)
|
||||
goto Err_1;
|
||||
mvForwB.dy = (int16_t)mp4_Div2(mvForwB.dy);
|
||||
if (mp4_DecodeMV(pInfo, &mvForwB, fcode_forward) != MP4_STATUS_OK)
|
||||
goto Err_1;
|
||||
mvBackT.dy = (int16_t)mp4_Div2(mvBackT.dy);
|
||||
if (mp4_DecodeMV(pInfo, &mvBackT, fcode_backward) != MP4_STATUS_OK)
|
||||
goto Err_1;
|
||||
mvBackB.dy = (int16_t)mp4_Div2(mvBackB.dy);
|
||||
if (mp4_DecodeMV(pInfo, &mvBackB, fcode_backward) != MP4_STATUS_OK)
|
||||
goto Err_1;
|
||||
if (quarter_sample) {
|
||||
mp4_LimitFMVQ(&mvForwT, &mvForw[0], &limitRectL, dx, dy, 16);
|
||||
mp4_Copy16x8QP_8u(pYp+(mb_ftfr ? stepYp : 0), stepYp*2, pYc, stepYc*2, &mvForw[0], 0);
|
||||
mvForw[0].dx = (int16_t)mp4_Div2(mvForw[0].dx);
|
||||
mvForw[0].dy = (int16_t)(mp4_Div2(mvForw[0].dy*2) >> 1);
|
||||
mp4_LimitFMVQ(&mvForwB, &mvForw[2], &limitRectL, dx, dy, 16);
|
||||
mp4_Copy16x8QP_8u(pYp+(mb_fbfr ? stepYp : 0), stepYp*2, pYc+stepYc, stepYc*2, &mvForw[2], 0);
|
||||
mvForw[2].dx = (int16_t)mp4_Div2(mvForw[2].dx);
|
||||
mvForw[2].dy = (int16_t)(mp4_Div2(mvForw[2].dy*2) >> 1);
|
||||
mp4_LimitFMVQ(&mvBackT, &mvBack[0], &limitRectL, dx, dy, 16);
|
||||
mp4_Copy16x8QP_8u(pYn+(mb_btfr ? stepYn : 0), stepYn*2, tmpMB, 32, &mvBack[0], 0);
|
||||
mvBack[0].dx = (int16_t)mp4_Div2(mvBack[0].dx);
|
||||
mvBack[0].dy = (int16_t)(mp4_Div2(mvBack[0].dy*2) >> 1);
|
||||
mp4_LimitFMVQ(&mvBackB, &mvBack[2], &limitRectL, dx, dy, 16);
|
||||
mp4_Copy16x8QP_8u(pYn+(mb_bbfr ? stepYn : 0), stepYn*2, tmpMB+16, 32, &mvBack[2], 0);
|
||||
mvBack[2].dx = (int16_t)mp4_Div2(mvBack[2].dx);
|
||||
mvBack[2].dy = (int16_t)(mp4_Div2(mvBack[2].dy*2) >> 1);
|
||||
} else {
|
||||
mp4_LimitFMV(&mvForwT, &mvForw[0], &limitRectL, dx, dy, 16);
|
||||
mp4_Copy16x8HP_8u(pYp+(mb_ftfr ? stepYp : 0), stepYp*2, pYc, stepYc*2, &mvForw[0], 0);
|
||||
mp4_LimitFMV(&mvForwB, &mvForw[2], &limitRectL, dx, dy, 16);
|
||||
mp4_Copy16x8HP_8u(pYp+(mb_fbfr ? stepYp : 0), stepYp*2, pYc+stepYc, stepYc*2, &mvForw[2], 0);
|
||||
mp4_LimitFMV(&mvBackT, &mvBack[0], &limitRectL, dx, dy, 16);
|
||||
mp4_Copy16x8HP_8u(pYn+(mb_btfr ? stepYn : 0), stepYn*2, tmpMB, 32, &mvBack[0], 0);
|
||||
mp4_LimitFMV(&mvBackB, &mvBack[2], &limitRectL, dx, dy, 16);
|
||||
mp4_Copy16x8HP_8u(pYn+(mb_bbfr ? stepYn : 0), stepYn*2, tmpMB+16, 32, &mvBack[2], 0);
|
||||
}
|
||||
mvForwT.dy <<= 1;
|
||||
mvForwB.dy <<= 1;
|
||||
mvBackT.dy <<= 1;
|
||||
mvBackB.dy <<= 1;
|
||||
//mvForw[1] = mvForw[0];
|
||||
//mvForw[3] = mvForw[2];
|
||||
//mvBack[1] = mvBack[0];
|
||||
//mvBack[3] = mvBack[2];
|
||||
mp4_ComputeChromaMV(&mvForw[0], &mvCbCrFFT);
|
||||
mp4_ComputeChromaMV(&mvForw[2], &mvCbCrFFB);
|
||||
mp4_ComputeChromaMV(&mvBack[0], &mvCbCrBFT);
|
||||
mp4_ComputeChromaMV(&mvBack[2], &mvCbCrBFB);
|
||||
}
|
||||
ippiAverage16x16_8u_C1IR(tmpMB, 16, pYc, stepYc);
|
||||
if (mp4_DecodeInterMB(pInfo, coeffMB, quant, cbpb, scan) != MP4_STATUS_OK)
|
||||
goto Err_1;
|
||||
if (!dct_type) {
|
||||
mp4_AddResidual(cbpb & 32, pYc, stepYc, coeffMB);
|
||||
mp4_AddResidual(cbpb & 16, pYc+8, stepYc, coeffMB+64);
|
||||
mp4_AddResidual(cbpb & 8, pYc+stepYc*8, stepYc, coeffMB+128);
|
||||
mp4_AddResidual(cbpb & 4, pYc+stepYc*8+8, stepYc, coeffMB+192);
|
||||
} else {
|
||||
mp4_AddResidual(cbpb & 32, pYc, stepYc*2, coeffMB);
|
||||
mp4_AddResidual(cbpb & 16, pYc+8, stepYc*2, coeffMB+64);
|
||||
mp4_AddResidual(cbpb & 8, pYc+stepYc, stepYc*2, coeffMB+128);
|
||||
mp4_AddResidual(cbpb & 4, pYc+stepYc+8, stepYc*2, coeffMB+192);
|
||||
}
|
||||
if (!field_prediction) {
|
||||
mp4_Copy8x8HP_8u(pCbp, stepCbp, pCbc, stepCbc, &mvCbCrF, 0);
|
||||
mp4_Copy8x8HP_8u(pCrp, stepCrp, pCrc, stepCrc, &mvCbCrF, 0);
|
||||
mp4_Copy8x8HP_8u(pCbn, stepCbn, tmpMB, 8, &mvCbCrB, 0);
|
||||
mp4_Copy8x8HP_8u(pCrn, stepCrn, tmpMB+64, 8, &mvCbCrB, 0);
|
||||
} else {
|
||||
mp4_Copy8x4HP_8u(pCbp+(mb_ftfr ? stepCbp : 0), stepCbp*2, pCbc, stepCbc*2, &mvCbCrFFT, 0);
|
||||
mp4_Copy8x4HP_8u(pCrp+(mb_ftfr ? stepCrp : 0), stepCrp*2, pCrc, stepCrc*2, &mvCbCrFFT, 0);
|
||||
mp4_Copy8x4HP_8u(pCbp+(mb_fbfr ? stepCbp : 0), stepCbp*2, pCbc+stepCbc, stepCbc*2, &mvCbCrFFB, 0);
|
||||
mp4_Copy8x4HP_8u(pCrp+(mb_fbfr ? stepCrp : 0), stepCrp*2, pCrc+stepCrc, stepCrc*2, &mvCbCrFFB, 0);
|
||||
mp4_Copy8x4HP_8u(pCbn+(mb_btfr ? stepCbn : 0), stepCbn*2, tmpMB, 16, &mvCbCrBFT, 0);
|
||||
mp4_Copy8x4HP_8u(pCrn+(mb_btfr ? stepCrn : 0), stepCrn*2, tmpMB+64, 16, &mvCbCrBFT, 0);
|
||||
mp4_Copy8x4HP_8u(pCbn+(mb_bbfr ? stepCbn : 0), stepCbn*2, tmpMB+8, 16, &mvCbCrBFB, 0);
|
||||
mp4_Copy8x4HP_8u(pCrn+(mb_bbfr ? stepCrn : 0), stepCrn*2, tmpMB+64+8, 16, &mvCbCrBFB, 0);
|
||||
}
|
||||
ippiAverage8x8_8u_C1IR(tmpMB, 8, pCbc, stepCbc);
|
||||
ippiAverage8x8_8u_C1IR(tmpMB+64, 8, pCrc, stepCrc);
|
||||
mp4_AddResidual(cbpb & 2, pCbc, stepCbc, coeffMB+256);
|
||||
mp4_AddResidual(cbpb & 1, pCrc, stepCrc, coeffMB+320);
|
||||
} else { // IPPVC_MBTYPE_DIRECT
|
||||
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_DIRECT);
|
||||
field_prediction = pMBinfo->field_info & 1;
|
||||
if (!field_prediction) {
|
||||
// frame direct mode
|
||||
if (mp4_DecodeMV_Direct(pInfo, pMBinfo->mv, mvForw, mvBack, TRB, TRD, modb, pMBinfo->type) != MP4_STATUS_OK)
|
||||
goto Err_1;
|
||||
if (quarter_sample) {
|
||||
mp4_ComputeChroma4MVQ(mvForw, &mvCbCrF);
|
||||
mp4_Limit4MVQ(mvForw, mvForw, &limitRectL, dx, dy, 8);
|
||||
mp4_ComputeChroma4MVQ(mvBack, &mvCbCrB);
|
||||
mp4_Limit4MVQ(mvBack, mvBack, &limitRectL, dx, dy, 8);
|
||||
pc = pYc;
|
||||
pr = pYp;
|
||||
pn = pYn;
|
||||
mp4_Copy8x8QP_8u(pr, stepYp, pc, stepYc, &mvForw[0], 0);
|
||||
mp4_Copy8x8QP_8u(pn, stepYn, tmpMB, 16, &mvBack[0], 0);
|
||||
mp4_Copy8x8QP_8u(pr+8, stepYp, pc+8, stepYc, &mvForw[1], 0);
|
||||
mp4_Copy8x8QP_8u(pn+8, stepYn, tmpMB+8, 16, &mvBack[1], 0);
|
||||
pc = pYc + stepYc * 8;
|
||||
pr = pYp + stepYp * 8;
|
||||
pn = pYn + stepYn * 8;
|
||||
mp4_Copy8x8QP_8u(pr, stepYp, pc, stepYc, &mvForw[2], 0);
|
||||
mp4_Copy8x8QP_8u(pn, stepYn, tmpMB+128, 16, &mvBack[2], 0);
|
||||
mp4_Copy8x8QP_8u(pr+8, stepYp, pc+8, stepYc, &mvForw[3], 0);
|
||||
mp4_Copy8x8QP_8u(pn+8, stepYn, tmpMB+136, 16, &mvBack[3], 0);
|
||||
} else {
|
||||
mp4_ComputeChroma4MV(mvForw, &mvCbCrF);
|
||||
mp4_Limit4MV(mvForw, mvForw, &limitRectL, dx, dy, 8);
|
||||
mp4_ComputeChroma4MV(mvBack, &mvCbCrB);
|
||||
mp4_Limit4MV(mvBack, mvBack, &limitRectL, dx, dy, 8);
|
||||
pc = pYc;
|
||||
pr = pYp;
|
||||
pn = pYn;
|
||||
mp4_Copy8x8HP_8u(pr, stepYp, pc, stepYc, &mvForw[0], 0);
|
||||
mp4_Copy8x8HP_8u(pn, stepYn, tmpMB, 16, &mvBack[0], 0);
|
||||
mp4_Copy8x8HP_8u(pr+8, stepYp, pc+8, stepYc, &mvForw[1], 0);
|
||||
mp4_Copy8x8HP_8u(pn+8, stepYn, tmpMB+8, 16, &mvBack[1], 0);
|
||||
pc = pYc + stepYc * 8;
|
||||
pr = pYp + stepYp * 8;
|
||||
pn = pYn + stepYn * 8;
|
||||
mp4_Copy8x8HP_8u(pr, stepYp, pc, stepYc, &mvForw[2], 0);
|
||||
mp4_Copy8x8HP_8u(pn, stepYn, tmpMB+128, 16, &mvBack[2], 0);
|
||||
mp4_Copy8x8HP_8u(pr+8, stepYp, pc+8, stepYc, &mvForw[3], 0);
|
||||
mp4_Copy8x8HP_8u(pn+8, stepYn, tmpMB+136, 16, &mvBack[3], 0);
|
||||
}
|
||||
mp4_LimitMV(&mvCbCrF, &mvCbCrF, &limitRectC, dx >> 1, dy >> 1, 8);
|
||||
mp4_LimitMV(&mvCbCrB, &mvCbCrB, &limitRectC, dx >> 1, dy >> 1, 8);
|
||||
} else {
|
||||
mb_ftfr = (pMBinfo->field_info >> 1) & 1;
|
||||
mb_fbfr = (pMBinfo->field_info >> 2) & 1;
|
||||
if (mp4_DecodeMV_DirectField(pInfo, mb_ftfr, mb_fbfr, &mvField[0], &mvField[1], &mvForw[0], &mvForw[2], &mvBack[0], &mvBack[2], TRB, TRD, modb) != MP4_STATUS_OK)
|
||||
goto Err_1;
|
||||
if (quarter_sample) {
|
||||
mp4_LimitFMVQ(&mvForw[0], &mvForw[0], &limitRectL, dx, dy, 16);
|
||||
mp4_LimitFMVQ(&mvForw[2], &mvForw[2], &limitRectL, dx, dy, 16);
|
||||
mp4_LimitFMVQ(&mvBack[0], &mvBack[0], &limitRectL, dx, dy, 16);
|
||||
mp4_LimitFMVQ(&mvBack[2], &mvBack[2], &limitRectL, dx, dy, 16);
|
||||
mp4_Copy16x8QP_8u(pYp+(mb_ftfr ? stepYp : 0), stepYp*2, pYc, stepYc*2, &mvForw[0], 0);
|
||||
mp4_Copy16x8QP_8u(pYp+(mb_fbfr ? stepYp : 0), stepYp*2, pYc+stepYc, stepYc*2, &mvForw[2], 0);
|
||||
mp4_Copy16x8QP_8u(pYn/*+stepYn*mb_btfr*/, stepYn*2, tmpMB, 32, &mvBack[0], 0);
|
||||
mp4_Copy16x8QP_8u(pYn+stepYn/**mb_bbfr*/, stepYn*2, tmpMB+16, 32, &mvBack[2], 0);
|
||||
mvForw[0].dx = (int16_t)mp4_Div2(mvForw[0].dx);
|
||||
mvForw[0].dy = (int16_t)(mp4_Div2(mvForw[0].dy*2) >> 1);
|
||||
mvForw[2].dx = (int16_t)mp4_Div2(mvForw[2].dx);
|
||||
mvForw[2].dy = (int16_t)(mp4_Div2(mvForw[2].dy*2) >> 1);
|
||||
mvBack[0].dx = (int16_t)mp4_Div2(mvBack[0].dx);
|
||||
mvBack[0].dy = (int16_t)(mp4_Div2(mvBack[0].dy*2) >> 1);
|
||||
mvBack[2].dx = (int16_t)mp4_Div2(mvBack[2].dx);
|
||||
mvBack[2].dy = (int16_t)(mp4_Div2(mvBack[2].dy*2) >> 1);
|
||||
} else {
|
||||
mp4_LimitFMV(&mvForw[0], &mvForw[0], &limitRectL, dx, dy, 16);
|
||||
mp4_LimitFMV(&mvForw[2], &mvForw[2], &limitRectL, dx, dy, 16);
|
||||
mp4_LimitFMV(&mvBack[0], &mvBack[0], &limitRectL, dx, dy, 16);
|
||||
mp4_LimitFMV(&mvBack[2], &mvBack[2], &limitRectL, dx, dy, 16);
|
||||
mp4_Copy16x8HP_8u(pYp+(mb_ftfr ? stepYp : 0), stepYp*2, pYc, stepYc*2, &mvForw[0], 0);
|
||||
mp4_Copy16x8HP_8u(pYp+(mb_fbfr ? stepYp : 0), stepYp*2, pYc+stepYc, stepYc*2, &mvForw[2], 0);
|
||||
mp4_Copy16x8HP_8u(pYn/*+stepYn*mb_btfr*/, stepYn*2, tmpMB, 32, &mvBack[0], 0);
|
||||
mp4_Copy16x8HP_8u(pYn+stepYn/**mb_bbfr*/, stepYn*2, tmpMB+16, 32, &mvBack[2], 0);
|
||||
}
|
||||
mp4_ComputeChromaMV(&mvForw[0], &mvCbCrFFT);
|
||||
mp4_ComputeChromaMV(&mvForw[2], &mvCbCrFFB);
|
||||
mp4_ComputeChromaMV(&mvBack[0], &mvCbCrBFT);
|
||||
mp4_ComputeChromaMV(&mvBack[2], &mvCbCrBFB);
|
||||
}
|
||||
ippiAverage16x16_8u_C1IR(tmpMB, 16, pYc, stepYc);
|
||||
if (mp4_DecodeInterMB(pInfo, coeffMB, quant, cbpb, scan) != MP4_STATUS_OK)
|
||||
goto Err_1;
|
||||
if (!dct_type) {
|
||||
mp4_AddResidual(cbpb & 32, pYc, stepYc, coeffMB);
|
||||
mp4_AddResidual(cbpb & 16, pYc+8, stepYc, coeffMB+64);
|
||||
mp4_AddResidual(cbpb & 8, pYc+stepYc*8, stepYc, coeffMB+128);
|
||||
mp4_AddResidual(cbpb & 4, pYc+stepYc*8+8, stepYc, coeffMB+192);
|
||||
} else {
|
||||
mp4_AddResidual(cbpb & 32, pYc, stepYc*2, coeffMB);
|
||||
mp4_AddResidual(cbpb & 16, pYc+8, stepYc*2, coeffMB+64);
|
||||
mp4_AddResidual(cbpb & 8, pYc+stepYc, stepYc*2, coeffMB+128);
|
||||
mp4_AddResidual(cbpb & 4, pYc+stepYc+8, stepYc*2, coeffMB+192);
|
||||
}
|
||||
if (!field_prediction) {
|
||||
mp4_Copy8x8HP_8u(pCbp, stepCbp, pCbc, stepCbc, &mvCbCrF, 0);
|
||||
mp4_Copy8x8HP_8u(pCrp, stepCrp, pCrc, stepCrc, &mvCbCrF, 0);
|
||||
mp4_Copy8x8HP_8u(pCbn, stepCbn, tmpMB, 8, &mvCbCrB, 0);
|
||||
mp4_Copy8x8HP_8u(pCrn, stepCrn, tmpMB+64, 8, &mvCbCrB, 0);
|
||||
} else {
|
||||
mp4_Copy8x4HP_8u(pCbp+(mb_ftfr ? stepCbp : 0), stepCbp*2, pCbc, stepCbc*2, &mvCbCrFFT, 0);
|
||||
mp4_Copy8x4HP_8u(pCrp+(mb_ftfr ? stepCrp : 0), stepCrp*2, pCrc, stepCrc*2, &mvCbCrFFT, 0);
|
||||
mp4_Copy8x4HP_8u(pCbp+(mb_fbfr ? stepCbp : 0), stepCbp*2, pCbc+stepCbc, stepCbc*2, &mvCbCrFFB, 0);
|
||||
mp4_Copy8x4HP_8u(pCrp+(mb_fbfr ? stepCrp : 0), stepCrp*2, pCrc+stepCrc, stepCrc*2, &mvCbCrFFB, 0);
|
||||
mp4_Copy8x4HP_8u(pCbn/*+(mb_btfr ? stepCbn : 0)*/, stepCbn*2, tmpMB, 16, &mvCbCrBFT, 0);
|
||||
mp4_Copy8x4HP_8u(pCrn/*+(mb_btfr ? stepCrn : 0)*/, stepCrn*2, tmpMB+64, 16, &mvCbCrBFT, 0);
|
||||
mp4_Copy8x4HP_8u(pCbn+/*(mb_bbfr ? */stepCbn/* : 0)*/, stepCbn*2, tmpMB+8, 16, &mvCbCrBFB, 0);
|
||||
mp4_Copy8x4HP_8u(pCrn+/*(mb_bbfr ? */stepCrn/* : 0)*/, stepCrn*2, tmpMB+64+8, 16, &mvCbCrBFB, 0);
|
||||
}
|
||||
ippiAverage8x8_8u_C1IR(tmpMB, 8, pCbc, stepCbc);
|
||||
ippiAverage8x8_8u_C1IR(tmpMB+64, 8, pCrc, stepCrc);
|
||||
mp4_AddResidual(cbpb & 2, pCbc, stepCbc, coeffMB+256);
|
||||
mp4_AddResidual(cbpb & 1, pCrc, stepCrc, coeffMB+320);
|
||||
}
|
||||
}
|
||||
//mbCurr ++;
|
||||
mbInVideoPacket ++;
|
||||
colNum ++;
|
||||
pMBinfo ++;
|
||||
mvField += 2;
|
||||
if (colNum == mbPerRow) {
|
||||
colNum = 0;
|
||||
rowNum ++;
|
||||
if (rowNum == mbPerCol)
|
||||
return sts;
|
||||
pYc += (2 * MP4_NUM_EXT_MB + 1) * 16 + (stepYc << 4) - stepYc;
|
||||
pCbc += (2 * MP4_NUM_EXT_MB + 1) * 8 + (stepCbc << 3) - stepCbc;
|
||||
pCrc += (2 * MP4_NUM_EXT_MB + 1) * 8 + (stepCrc << 3) - stepCrc;
|
||||
pYp += (2 * MP4_NUM_EXT_MB + 1) * 16 + (stepYp << 4) - stepYp;
|
||||
pCbp += (2 * MP4_NUM_EXT_MB + 1) * 8 + (stepCbp << 3) - stepCbp;
|
||||
pCrp += (2 * MP4_NUM_EXT_MB + 1) * 8 + (stepCrp << 3) - stepCrp;
|
||||
pYn += (2 * MP4_NUM_EXT_MB + 1) * 16 + (stepYn << 4) - stepYn;
|
||||
pCbn += (2 * MP4_NUM_EXT_MB + 1) * 8 + (stepCbn << 3) - stepCbn;
|
||||
pCrn += (2 * MP4_NUM_EXT_MB + 1) * 8 + (stepCrn << 3) - stepCrn;
|
||||
// reset MV predictors at new row
|
||||
mvForwT.dx = mvForwT.dy = mvBackT.dx = mvBackT.dy = mvForwB.dx = mvForwB.dy = mvBackB.dx = mvBackB.dy = 0;
|
||||
} else {
|
||||
pYc += 16; pCrc += 8; pCbc += 8;
|
||||
pYp += 16; pCrp += 8; pCbp += 8;
|
||||
pYn += 16; pCrn += 8; pCbn += 8;
|
||||
}
|
||||
if (!pInfo->VisualObject.VideoObject.resync_marker_disable) {
|
||||
int32_t found;
|
||||
ErrRet_1:
|
||||
if (mp4_CheckDecodeVideoPacket(pInfo, &found) == MP4_STATUS_OK) {
|
||||
if (found) {
|
||||
quant = pInfo->VisualObject.VideoObject.VideoObjectPlane.quant_scale;
|
||||
mbCurr = pInfo->VisualObject.VideoObject.VideoObjectPlane.macroblock_num;
|
||||
mp4_CopyMacroBlocks(pInfo->VisualObject.rFrame, pInfo->VisualObject.cFrame, mbPerRow, rowNum, colNum, mbCurr - rowNum * mbPerRow - colNum);
|
||||
rowNum = mbCurr / mbPerRow;
|
||||
colNum = mbCurr % mbPerRow;
|
||||
pYc = pInfo->VisualObject.cFrame->pY + (rowNum * stepYc + colNum) * 16; pCbc = pInfo->VisualObject.cFrame->pCb + (rowNum * stepCbc + colNum) * 8; pCrc = pInfo->VisualObject.cFrame->pCr + (rowNum * stepCrc + colNum) * 8;
|
||||
pYp = pInfo->VisualObject.rFrame->pY + (rowNum * stepYp + colNum) * 16; pCbp = pInfo->VisualObject.rFrame->pCb + (rowNum * stepCbp + colNum) * 8; pCrp = pInfo->VisualObject.rFrame->pCr + (rowNum * stepCrp + colNum) * 8;
|
||||
pYn = pInfo->VisualObject.nFrame->pY + (rowNum * stepYn + colNum) * 16; pCbn = pInfo->VisualObject.nFrame->pCb + (rowNum * stepCbn + colNum) * 8; pCrn = pInfo->VisualObject.nFrame->pCr + (rowNum * stepCrn + colNum) * 8;
|
||||
pMBinfo = pInfo->VisualObject.VideoObject.MBinfo + mbCurr;
|
||||
break;
|
||||
}
|
||||
} else
|
||||
goto Err_1;
|
||||
}
|
||||
}
|
||||
}
|
||||
Err_1:
|
||||
sts = MP4_STATUS_ERROR;
|
||||
if (pInfo->stopOnErr)
|
||||
return sts;
|
||||
if (pInfo->VisualObject.VideoObject.resync_marker_disable || !mp4_SeekResyncMarker(pInfo))
|
||||
{
|
||||
mp4_CopyMacroBlocks(pInfo->VisualObject.rFrame, pInfo->VisualObject.cFrame, mbPerRow, rowNum, colNum, pInfo->VisualObject.VideoObject.MacroBlockPerVOP - rowNum * mbPerRow - colNum);
|
||||
return sts;
|
||||
}
|
||||
goto ErrRet_1;
|
||||
}
|
||||
// decode usual B-VOP
|
||||
for (;;) {
|
||||
IppMotionVector mvCbCrF, mvCbCrB, mvForw, mvBack, mvForwLim, mvBackLim;
|
||||
|
||||
mbInVideoPacket = 0;
|
||||
// reset MV predictors at new VideoPacket
|
||||
mvForw.dx = mvForw.dy = mvBack.dx = mvBack.dy = 0;
|
||||
// decode B-VOP macroblocks
|
||||
for (;;) {
|
||||
if (pMBinfo->not_coded) {
|
||||
ippiCopy16x16_8u_C1R(pYp, stepYp, pYc, stepYc);
|
||||
ippiCopy8x8_8u_C1R(pCbp, stepCbp, pCbc, stepCbc);
|
||||
ippiCopy8x8_8u_C1R(pCrp, stepCrp, pCrc, stepCrc);
|
||||
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_NOTCODED);
|
||||
} else {
|
||||
cbpb = 0;
|
||||
if (mp4_GetBit(pInfo)) {
|
||||
modb = 2;
|
||||
mb_type = IPPVC_MBTYPE_DIRECT;
|
||||
} else {
|
||||
modb = mp4_GetBit(pInfo);
|
||||
// decode mb_type
|
||||
code = mp4_ShowBits9(pInfo, 4);
|
||||
if (code != 0) {
|
||||
mb_type = mp4_BVOPmb_type[code].code;
|
||||
mp4_FlushBits(pInfo, mp4_BVOPmb_type[code].len);
|
||||
} else {
|
||||
mp4_Error("Error when decode mb_type of B-VOP macroblock");
|
||||
goto Err_2;
|
||||
}
|
||||
if (modb == 0)
|
||||
cbpb = mp4_GetBits9(pInfo, 6);
|
||||
if (mb_type != IPPVC_MBTYPE_DIRECT && cbpb != 0)
|
||||
mp4_UpdateQuant_B(pInfo, quant);
|
||||
}
|
||||
// coordinates of current MB for limitation
|
||||
dx = colNum * 16;
|
||||
dy = rowNum * 16;
|
||||
if (mb_type == IPPVC_MBTYPE_FORWARD) {
|
||||
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_FORWARD);
|
||||
if (mp4_DecodeMV(pInfo, &mvForw, fcode_forward) != MP4_STATUS_OK)
|
||||
goto Err_2;
|
||||
if (quarter_sample) {
|
||||
mp4_LimitMVQ(&mvForw, &mvForwLim, &limitRectL, dx, dy, 16);
|
||||
mp4_ComputeChromaMVQ(&mvForwLim, &mvCbCrF);
|
||||
mp4_Copy16x16QP_8u(pYp, stepYp, pYc, stepYc, &mvForwLim, 0);
|
||||
mp4_DecodeReconBlockInter_MPEG4(cbpb & 32, pYc, stepYc, Err_2);
|
||||
mp4_DecodeReconBlockInter_MPEG4(cbpb & 16, pYc+8, stepYc, Err_2);
|
||||
mp4_DecodeReconBlockInter_MPEG4(cbpb & 8, pYc+8*stepYc, stepYc, Err_2);
|
||||
mp4_DecodeReconBlockInter_MPEG4(cbpb & 4, pYc+8*stepYc+8, stepYc, Err_2);
|
||||
} else {
|
||||
mp4_LimitMV(&mvForw, &mvForwLim, &limitRectL, dx, dy, 16);
|
||||
mp4_ComputeChromaMV(&mvForwLim, &mvCbCrF);
|
||||
if (cbpb & 60) {
|
||||
mp4_DecodeMCBlockInter_MPEG4(cbpb & 32, pYp, stepYp, pYc, stepYc, mvForwLim, 0, Err_2);
|
||||
mp4_DecodeMCBlockInter_MPEG4(cbpb & 16, pYp+8, stepYp, pYc+8, stepYc, mvForwLim, 0, Err_2);
|
||||
mp4_DecodeMCBlockInter_MPEG4(cbpb & 8, pYp+8*stepYp, stepYp, pYc+8*stepYc, stepYc, mvForwLim, 0, Err_2);
|
||||
mp4_DecodeMCBlockInter_MPEG4(cbpb & 4, pYp+8*stepYp+8, stepYp, pYc+8*stepYc+8, stepYc, mvForwLim, 0, Err_2);
|
||||
} else {
|
||||
mp4_Copy16x16HP_8u(pYp, stepYp, pYc, stepYc, &mvForwLim, 0);
|
||||
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTER_NC);
|
||||
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTER_NC);
|
||||
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTER_NC);
|
||||
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTER_NC);
|
||||
}
|
||||
}
|
||||
mp4_DecodeMCBlockInter_MPEG4(cbpb & 2, pCbp, stepCbp, pCbc, stepCbc, mvCbCrF, 0, Err_2);
|
||||
mp4_DecodeMCBlockInter_MPEG4(cbpb & 1, pCrp, stepCrp, pCrc, stepCrc, mvCbCrF, 0, Err_2);
|
||||
} else if (mb_type == IPPVC_MBTYPE_BACKWARD) {
|
||||
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_BACKWARD);
|
||||
if (mp4_DecodeMV(pInfo, &mvBack, fcode_backward) != MP4_STATUS_OK)
|
||||
goto Err_2;
|
||||
if (quarter_sample) {
|
||||
mp4_LimitMVQ(&mvBack, &mvBackLim, &limitRectL, dx, dy, 16);
|
||||
mp4_ComputeChromaMVQ(&mvBackLim, &mvCbCrB);
|
||||
mp4_Copy16x16QP_8u(pYn, stepYn, pYc, stepYc, &mvBackLim, 0);
|
||||
mp4_DecodeReconBlockInter_MPEG4(cbpb & 32, pYc, stepYc, Err_2);
|
||||
mp4_DecodeReconBlockInter_MPEG4(cbpb & 16, pYc+8, stepYc, Err_2);
|
||||
mp4_DecodeReconBlockInter_MPEG4(cbpb & 8, pYc+8*stepYc, stepYc, Err_2);
|
||||
mp4_DecodeReconBlockInter_MPEG4(cbpb & 4, pYc+8*stepYc+8, stepYc, Err_2);
|
||||
} else {
|
||||
mp4_LimitMV(&mvBack, &mvBackLim, &limitRectL, dx, dy, 16);
|
||||
mp4_ComputeChromaMV(&mvBackLim, &mvCbCrB);
|
||||
if (cbpb & 60) {
|
||||
mp4_DecodeMCBlockInter_MPEG4(cbpb & 32, pYn, stepYn, pYc, stepYc, mvBackLim, 0, Err_2);
|
||||
mp4_DecodeMCBlockInter_MPEG4(cbpb & 16, pYn+8, stepYn, pYc+8, stepYc, mvBackLim, 0, Err_2);
|
||||
mp4_DecodeMCBlockInter_MPEG4(cbpb & 8, pYn+8*stepYn, stepYp, pYc+8*stepYc, stepYc, mvBackLim, 0, Err_2);
|
||||
mp4_DecodeMCBlockInter_MPEG4(cbpb & 4, pYn+8*stepYn+8, stepYp, pYc+8*stepYc+8, stepYc, mvBackLim, 0, Err_2);
|
||||
} else {
|
||||
mp4_Copy16x16HP_8u(pYn, stepYn, pYc, stepYc, &mvBackLim, 0);
|
||||
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTER_NC);
|
||||
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTER_NC);
|
||||
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTER_NC);
|
||||
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nB_INTER_NC);
|
||||
}
|
||||
}
|
||||
mp4_DecodeMCBlockInter_MPEG4(cbpb & 2, pCbn, stepCbn, pCbc, stepCbc, mvCbCrB, 0, Err_2);
|
||||
mp4_DecodeMCBlockInter_MPEG4(cbpb & 1, pCrn, stepCrn, pCrc, stepCrc, mvCbCrB, 0, Err_2);
|
||||
}
|
||||
else if (mb_type == IPPVC_MBTYPE_INTERPOLATE)
|
||||
{
|
||||
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_INTERPOLATE);
|
||||
if (mp4_DecodeMV(pInfo, &mvForw, fcode_forward) != MP4_STATUS_OK)
|
||||
goto Err_2;
|
||||
if (mp4_DecodeMV(pInfo, &mvBack, fcode_backward) != MP4_STATUS_OK)
|
||||
goto Err_2;
|
||||
if (quarter_sample)
|
||||
{
|
||||
mp4_LimitMVQ(&mvForw, &mvForwLim, &limitRectL, dx, dy, 16);
|
||||
mp4_ComputeChromaMVQ(&mvForwLim, &mvCbCrF);
|
||||
mp4_Copy16x16QP_8u(pYp, stepYp, pYc, stepYc, &mvForwLim, 0);
|
||||
mp4_LimitMVQ(&mvBack, &mvBackLim, &limitRectL, dx, dy, 16);
|
||||
mp4_ComputeChromaMVQ(&mvBackLim, &mvCbCrB);
|
||||
mp4_Copy16x16QP_8u(pYn, stepYn, tmpMB, 16, &mvBackLim, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
mp4_LimitMV(&mvForw, &mvForwLim, &limitRectL, dx, dy, 16);
|
||||
mp4_ComputeChromaMV(&mvForwLim, &mvCbCrF);
|
||||
mp4_Copy16x16HP_8u(pYp, stepYp, pYc, stepYc, &mvForwLim, 0);
|
||||
mp4_LimitMV(&mvBack, &mvBackLim, &limitRectL, dx, dy, 16);
|
||||
mp4_ComputeChromaMV(&mvBackLim, &mvCbCrB);
|
||||
mp4_Copy16x16HP_8u(pYn, stepYn, tmpMB, 16, &mvBackLim, 0);
|
||||
}
|
||||
ippiAverage16x16_8u_C1IR(tmpMB, 16, pYc, stepYc);
|
||||
mp4_DecodeReconBlockInter_MPEG4(cbpb & 32, pYc, stepYc, Err_2);
|
||||
mp4_DecodeReconBlockInter_MPEG4(cbpb & 16, pYc+8, stepYc, Err_2);
|
||||
mp4_DecodeReconBlockInter_MPEG4(cbpb & 8, pYc+8*stepYc, stepYc, Err_2);
|
||||
mp4_DecodeReconBlockInter_MPEG4(cbpb & 4, pYc+8*stepYc+8, stepYc, Err_2);
|
||||
mp4_Copy8x8HP_8u(pCbp, stepCbp, pCbc, stepCbc, &mvCbCrF, 0);
|
||||
mp4_Copy8x8HP_8u(pCbn, stepCbn, tmpMB, 8, &mvCbCrB, 0);
|
||||
ippiAverage8x8_8u_C1IR(tmpMB, 8, pCbc, stepCbc);
|
||||
mp4_DecodeReconBlockInter_MPEG4(cbpb & 2, pCbc, stepCbc, Err_2);
|
||||
mp4_Copy8x8HP_8u(pCrp, stepCrp, pCrc, stepCrc, &mvCbCrF, 0);
|
||||
mp4_Copy8x8HP_8u(pCrn, stepCrn, tmpMB, 8, &mvCbCrB, 0);
|
||||
ippiAverage8x8_8u_C1IR(tmpMB, 8, pCrc, stepCrc);
|
||||
mp4_DecodeReconBlockInter_MPEG4(cbpb & 1, pCrc, stepCrc, Err_2);
|
||||
}
|
||||
else
|
||||
{ // IPPVC_MBTYPE_DIRECT
|
||||
IppMotionVector mvForw[4], mvBack[4], mvForwLim[4], mvBackLim[4];
|
||||
|
||||
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_DIRECT);
|
||||
//f MVs of collocated block of recently decoded I or P frame used in Direct mode
|
||||
if (mp4_DecodeMV_Direct(pInfo, pMBinfo->mv, mvForw, mvBack, TRB, TRD, modb, pMBinfo->type) != MP4_STATUS_OK)
|
||||
goto Err_2;
|
||||
if (quarter_sample)
|
||||
{
|
||||
mp4_Limit4MVQ(mvForw, mvForwLim, &limitRectL, dx, dy, 8);
|
||||
mp4_ComputeChroma4MVQ(mvForw, &mvCbCrF);
|
||||
mp4_Limit4MVQ(mvBack, mvBackLim, &limitRectL, dx, dy, 8);
|
||||
mp4_ComputeChroma4MVQ(mvBack, &mvCbCrB);
|
||||
mp4_Copy8x8QP_8u(pYp, stepYp, pYc, stepYc, &mvForwLim[0], 0);
|
||||
mp4_Copy8x8QP_8u(pYn, stepYn, tmpMB, 16, &mvBackLim[0], 0);
|
||||
mp4_Copy8x8QP_8u(pYp+8, stepYp, pYc+8, stepYc, &mvForwLim[1], 0);
|
||||
mp4_Copy8x8QP_8u(pYn+8, stepYn, tmpMB+8, 16, &mvBackLim[1], 0);
|
||||
mp4_Copy8x8QP_8u(pYp+8*stepYp, stepYp, pYc+8*stepYc, stepYc, &mvForwLim[2], 0);
|
||||
mp4_Copy8x8QP_8u(pYn+8*stepYn, stepYn, tmpMB+8*16, 16, &mvBackLim[2], 0);
|
||||
mp4_Copy8x8QP_8u(pYp+8*stepYp+8, stepYp, pYc+8*stepYc+8, stepYc, &mvForwLim[3], 0);
|
||||
mp4_Copy8x8QP_8u(pYn+8*stepYn+8, stepYn, tmpMB+8*16+8, 16, &mvBackLim[3], 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pMBinfo->type == IPPVC_MBTYPE_INTER4V) {
|
||||
mp4_Limit4MV(mvForw, mvForwLim, &limitRectL, dx, dy, 8);
|
||||
mp4_ComputeChroma4MV(mvForw, &mvCbCrF);
|
||||
mp4_Limit4MV(mvBack, mvBackLim, &limitRectL, dx, dy, 8);
|
||||
mp4_ComputeChroma4MV(mvBack, &mvCbCrB);
|
||||
mp4_Copy8x8HP_8u(pYp, stepYp, pYc, stepYc, &mvForwLim[0], 0);
|
||||
mp4_Copy8x8HP_8u(pYn, stepYn, tmpMB, 16, &mvBackLim[0], 0);
|
||||
mp4_Copy8x8HP_8u(pYp+8, stepYp, pYc+8, stepYc, &mvForwLim[1], 0);
|
||||
mp4_Copy8x8HP_8u(pYn+8, stepYn, tmpMB+8, 16, &mvBackLim[1], 0);
|
||||
mp4_Copy8x8HP_8u(pYp+8*stepYp, stepYp, pYc+8*stepYc, stepYc, &mvForwLim[2], 0);
|
||||
mp4_Copy8x8HP_8u(pYn+8*stepYn, stepYn, tmpMB+8*16, 16, &mvBackLim[2], 0);
|
||||
mp4_Copy8x8HP_8u(pYp+8*stepYp+8, stepYp, pYc+8*stepYc+8, stepYc, &mvForwLim[3], 0);
|
||||
mp4_Copy8x8HP_8u(pYn+8*stepYn+8, stepYn, tmpMB+8*16+8, 16, &mvBackLim[3], 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
mp4_LimitMV(mvForw, mvForwLim, &limitRectL, dx, dy, 16);
|
||||
mp4_ComputeChromaMV(mvForwLim, &mvCbCrF);
|
||||
mp4_LimitMV(mvBack, mvBackLim, &limitRectL, dx, dy, 16);
|
||||
mp4_ComputeChromaMV(mvBackLim, &mvCbCrB);
|
||||
mp4_Copy16x16HP_8u(pYp, stepYp, pYc, stepYc, &mvForwLim[0], 0);
|
||||
mp4_Copy16x16HP_8u(pYn, stepYn, tmpMB, 16, &mvBackLim[0], 0);
|
||||
}
|
||||
}
|
||||
ippiAverage16x16_8u_C1IR(tmpMB, 16, pYc, stepYc);
|
||||
mp4_DecodeReconBlockInter_MPEG4(cbpb & 32, pYc, stepYc, Err_2);
|
||||
mp4_DecodeReconBlockInter_MPEG4(cbpb & 16, pYc+8, stepYc, Err_2);
|
||||
mp4_DecodeReconBlockInter_MPEG4(cbpb & 8, pYc+8*stepYc, stepYc, Err_2);
|
||||
mp4_DecodeReconBlockInter_MPEG4(cbpb & 4, pYc+8*stepYc+8, stepYc, Err_2);
|
||||
mp4_LimitMV(&mvCbCrF, &mvCbCrF, &limitRectC, dx >> 1, dy >> 1, 8);
|
||||
mp4_LimitMV(&mvCbCrB, &mvCbCrB, &limitRectC, dx >> 1, dy >> 1, 8);
|
||||
mp4_Copy8x8HP_8u(pCbp, stepCbp, pCbc, stepCbc, &mvCbCrF, 0);
|
||||
mp4_Copy8x8HP_8u(pCbn, stepCbn, tmpMB, 8, &mvCbCrB, 0);
|
||||
ippiAverage8x8_8u_C1IR(tmpMB, 8, pCbc, stepCbc);
|
||||
mp4_DecodeReconBlockInter_MPEG4(cbpb & 2, pCbc, stepCbc, Err_2);
|
||||
mp4_Copy8x8HP_8u(pCrp, stepCrp, pCrc, stepCrc, &mvCbCrF, 0);
|
||||
mp4_Copy8x8HP_8u(pCrn, stepCrn, tmpMB, 8, &mvCbCrB, 0);
|
||||
ippiAverage8x8_8u_C1IR(tmpMB, 8, pCrc, stepCrc);
|
||||
mp4_DecodeReconBlockInter_MPEG4(cbpb & 1, pCrc, stepCrc, Err_2);
|
||||
}
|
||||
}
|
||||
//mbCurr ++;
|
||||
mbInVideoPacket ++;
|
||||
colNum ++;
|
||||
pMBinfo ++;
|
||||
if (colNum == mbPerRow)
|
||||
{
|
||||
colNum = 0;
|
||||
rowNum ++;
|
||||
if (rowNum == mbPerCol)
|
||||
return sts;
|
||||
pYc += (2 * MP4_NUM_EXT_MB + 1) * 16 + (stepYc << 4) - stepYc;
|
||||
pCbc += (2 * MP4_NUM_EXT_MB + 1) * 8 + (stepCbc << 3) - stepCbc;
|
||||
pCrc += (2 * MP4_NUM_EXT_MB + 1) * 8 + (stepCrc << 3) - stepCrc;
|
||||
pYp += (2 * MP4_NUM_EXT_MB + 1) * 16 + (stepYp << 4) - stepYp;
|
||||
pCbp += (2 * MP4_NUM_EXT_MB + 1) * 8 + (stepCbp << 3) - stepCbp;
|
||||
pCrp += (2 * MP4_NUM_EXT_MB + 1) * 8 + (stepCrp << 3) - stepCrp;
|
||||
pYn += (2 * MP4_NUM_EXT_MB + 1) * 16 + (stepYn << 4) - stepYn;
|
||||
pCbn += (2 * MP4_NUM_EXT_MB + 1) * 8 + (stepCbn << 3) - stepCbn;
|
||||
pCrn += (2 * MP4_NUM_EXT_MB + 1) * 8 + (stepCrn << 3) - stepCrn;
|
||||
// reset MV predictors at new row
|
||||
mvForw.dx = mvForw.dy = mvBack.dx = mvBack.dy = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
pYc += 16; pCrc += 8; pCbc += 8;
|
||||
pYp += 16; pCrp += 8; pCbp += 8;
|
||||
pYn += 16; pCrn += 8; pCbn += 8;
|
||||
}
|
||||
if (!pInfo->VisualObject.VideoObject.resync_marker_disable)
|
||||
{
|
||||
int32_t found;
|
||||
ErrRet_2:
|
||||
if (mp4_CheckDecodeVideoPacket(pInfo, &found) == MP4_STATUS_OK)
|
||||
{
|
||||
if (found)
|
||||
{
|
||||
quant = pInfo->VisualObject.VideoObject.VideoObjectPlane.quant_scale;
|
||||
mbCurr = pInfo->VisualObject.VideoObject.VideoObjectPlane.macroblock_num;
|
||||
mp4_CopyMacroBlocks(pInfo->VisualObject.rFrame, pInfo->VisualObject.cFrame, mbPerRow, rowNum, colNum, mbCurr - rowNum * mbPerRow - colNum);
|
||||
rowNum = mbCurr / mbPerRow;
|
||||
colNum = mbCurr % mbPerRow;
|
||||
pYc = pInfo->VisualObject.cFrame->pY + (rowNum * stepYc + colNum) * 16; pCbc = pInfo->VisualObject.cFrame->pCb + (rowNum * stepCbc + colNum) * 8; pCrc = pInfo->VisualObject.cFrame->pCr + (rowNum * stepCrc + colNum) * 8;
|
||||
pYp = pInfo->VisualObject.rFrame->pY + (rowNum * stepYp + colNum) * 16; pCbp = pInfo->VisualObject.rFrame->pCb + (rowNum * stepCbp + colNum) * 8; pCrp = pInfo->VisualObject.rFrame->pCr + (rowNum * stepCrp + colNum) * 8;
|
||||
pYn = pInfo->VisualObject.nFrame->pY + (rowNum * stepYn + colNum) * 16; pCbn = pInfo->VisualObject.nFrame->pCb + (rowNum * stepCbn + colNum) * 8; pCrn = pInfo->VisualObject.nFrame->pCr + (rowNum * stepCrn + colNum) * 8;
|
||||
pMBinfo = pInfo->VisualObject.VideoObject.MBinfo + mbCurr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
goto Err_2;
|
||||
}
|
||||
}
|
||||
}
|
||||
Err_2:
|
||||
sts = MP4_STATUS_ERROR;
|
||||
if (pInfo->stopOnErr)
|
||||
return sts;
|
||||
if (pInfo->VisualObject.VideoObject.resync_marker_disable || !mp4_SeekResyncMarker(pInfo))
|
||||
{
|
||||
mp4_CopyMacroBlocks(pInfo->VisualObject.rFrame, pInfo->VisualObject.cFrame, mbPerRow, rowNum, colNum, pInfo->VisualObject.VideoObject.MacroBlockPerVOP - rowNum * mbPerRow - colNum);
|
||||
return sts;
|
||||
}
|
||||
goto ErrRet_2;
|
||||
}
|
||||
|
408
Src/mpeg4dec/mp4decvopi.c
Normal file
408
Src/mpeg4dec/mp4decvopi.c
Normal file
|
@ -0,0 +1,408 @@
|
|||
/* ///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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) 2001-2007 Intel Corporation. All Rights Reserved.
|
||||
//
|
||||
// Description: Decodes I-VOPs
|
||||
//
|
||||
*/
|
||||
|
||||
#include "mp4def.h"
|
||||
#include "mp4dec.h"
|
||||
|
||||
/*
|
||||
// decode mcbpc and set MBtype and ChromaPattern
|
||||
*/
|
||||
/*static*/ mp4_Status mp4_DecodeMCBPC_I(mp4_Info* pInfo, int32_t *mbType, int32_t *mbPattern)
|
||||
{
|
||||
uint32_t code;
|
||||
int32_t type, pattern, fb;
|
||||
|
||||
code = mp4_ShowBits9(pInfo, 9);
|
||||
if (code == 1) {
|
||||
type = IPPVC_MB_STUFFING;
|
||||
pattern = 0;
|
||||
fb = 9;
|
||||
} else if (code >= 64) {
|
||||
type = IPPVC_MBTYPE_INTRA;
|
||||
pattern = code >> 6;
|
||||
if (pattern >= 4) {
|
||||
pattern = 0;
|
||||
fb = 1;
|
||||
} else
|
||||
fb = 3;
|
||||
} else {
|
||||
type = IPPVC_MBTYPE_INTRA_Q;
|
||||
pattern = code >> 3;
|
||||
if (pattern >= 4) {
|
||||
pattern = 0;
|
||||
fb = 4;
|
||||
} else if (code >= 8) {
|
||||
fb = 6;
|
||||
} else {
|
||||
mp4_Error("Error: decoding MCBPC");
|
||||
return MP4_STATUS_ERROR;
|
||||
}
|
||||
}
|
||||
mp4_FlushBits(pInfo, fb);
|
||||
*mbType = type;
|
||||
*mbPattern = pattern;
|
||||
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);
|
||||
return MP4_STATUS_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
// decode IVOP
|
||||
*/
|
||||
mp4_Status mp4_DecodeVOP_I(mp4_Info* pInfo)
|
||||
{
|
||||
int32_t quant, quantPred, dcVLC, mb_type, cbpc, cbpy, ac_pred_flag;
|
||||
int32_t i, j, nmb, nmbgob, stepYc, stepCbc, stepCrc, stepFc[6], mbCurr, mbInVideoPacket, colNum, rowNum, mbPerRow, mbPerCol;
|
||||
uint8_t *pFc[6];
|
||||
mp4_Status sts;
|
||||
|
||||
if (pInfo->VisualObject.cFrame)
|
||||
{
|
||||
DebugBreak();
|
||||
}
|
||||
pInfo->VisualObject.cFrame = CreateFrame(&pInfo->VisualObject);
|
||||
stepYc = pInfo->VisualObject.cFrame->stepY;
|
||||
stepCbc = pInfo->VisualObject.cFrame->stepCb;
|
||||
stepCrc = pInfo->VisualObject.cFrame->stepCr;
|
||||
mbPerRow = pInfo->VisualObject.VideoObject.MacroBlockPerRow;
|
||||
mbPerCol = pInfo->VisualObject.VideoObject.MacroBlockPerCol;
|
||||
stepFc[0] = stepFc[1] = stepFc[2] = stepFc[3] = stepYc; stepFc[4] = stepCbc; stepFc[5] = stepCrc;
|
||||
pFc[0] = pInfo->VisualObject.cFrame->pY; pFc[1] = pInfo->VisualObject.cFrame->pY + 8;
|
||||
pFc[2] = pInfo->VisualObject.cFrame->pY + 8 * stepYc; pFc[3] = pInfo->VisualObject.cFrame->pY + 8 * stepYc + 8;
|
||||
pFc[4] = pInfo->VisualObject.cFrame->pCb; pFc[5] = pInfo->VisualObject.cFrame->pCr;
|
||||
nmb = pInfo->VisualObject.VideoObject.MacroBlockPerVOP;
|
||||
mbCurr = colNum = rowNum = 0;
|
||||
sts = MP4_STATUS_OK;
|
||||
// decode short_video_header I-VOP
|
||||
if (pInfo->VisualObject.VideoObject.short_video_header)
|
||||
{
|
||||
quant = pInfo->VisualObject.VideoObject.VideoObjectPlaneH263.vop_quant;
|
||||
nmbgob = 0;
|
||||
pInfo->VisualObject.VideoObject.VideoObjectPlaneH263.gob_number = 0;
|
||||
for (;;)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (mp4_DecodeMCBPC_I(pInfo, &mb_type, &cbpc) != MP4_STATUS_OK)
|
||||
goto Err_1;
|
||||
} while (mb_type == IPPVC_MB_STUFFING);
|
||||
if (mp4_DecodeCBPY_I(pInfo, &cbpy) != MP4_STATUS_OK)
|
||||
goto Err_1;
|
||||
if (mb_type == IPPVC_MBTYPE_INTRA_Q)
|
||||
mp4_UpdateQuant(pInfo, quant);
|
||||
if (mp4_DecodeIntraMB_SVH(pInfo, (cbpy << 2) + cbpc, quant, pFc, stepFc) != MP4_STATUS_OK)
|
||||
goto Err_1;
|
||||
colNum ++;
|
||||
if (colNum == mbPerRow) {
|
||||
colNum = 0;
|
||||
rowNum ++;
|
||||
if (rowNum == mbPerCol)
|
||||
break;
|
||||
pFc[0] += (2 * MP4_NUM_EXT_MB + 1) * 16 + (stepYc << 4) - stepYc;
|
||||
pFc[1] += (2 * MP4_NUM_EXT_MB + 1) * 16 + (stepYc << 4) - stepYc;
|
||||
pFc[2] += (2 * MP4_NUM_EXT_MB + 1) * 16 + (stepYc << 4) - stepYc;
|
||||
pFc[3] += (2 * MP4_NUM_EXT_MB + 1) * 16 + (stepYc << 4) - stepYc;
|
||||
pFc[4] += (2 * MP4_NUM_EXT_MB + 1) * 8 + (stepCbc << 3) - stepCbc;
|
||||
pFc[5] += (2 * MP4_NUM_EXT_MB + 1) * 8 + (stepCrc << 3) - stepCrc;
|
||||
}
|
||||
else
|
||||
{
|
||||
pFc[0] += 16; pFc[1] += 16; pFc[2] += 16; pFc[3] += 16; pFc[4] += 8; pFc[5] += 8;
|
||||
}
|
||||
nmbgob ++;
|
||||
if (nmbgob == pInfo->VisualObject.VideoObject.VideoObjectPlaneH263.num_macroblocks_in_gob && pInfo->VisualObject.VideoObject.VideoObjectPlaneH263.gob_number < (pInfo->VisualObject.VideoObject.VideoObjectPlaneH263.num_gobs_in_vop - 1)) {
|
||||
ErrRet_1:
|
||||
if (mp4_CheckDecodeGOB_SVH(pInfo) != MP4_STATUS_OK)
|
||||
goto Err_1;
|
||||
if (!pInfo->VisualObject.VideoObject.VideoObjectPlaneH263.gob_header_empty)
|
||||
{
|
||||
quant = pInfo->VisualObject.VideoObject.VideoObjectPlaneH263.quant_scale;
|
||||
i = pInfo->VisualObject.VideoObject.VideoObjectPlaneH263.gob_number * pInfo->VisualObject.VideoObject.VideoObjectPlaneH263.num_rows_in_gob;
|
||||
mp4_CopyMacroBlocks(pInfo->VisualObject.rFrame, pInfo->VisualObject.cFrame, mbPerRow, rowNum, colNum, (i - rowNum) * mbPerRow - colNum);
|
||||
rowNum = i;
|
||||
colNum = 0;
|
||||
pFc[0] = pInfo->VisualObject.cFrame->pY + i * stepYc * 16; pFc[1] = pFc[0] + 8; pFc[2] = pFc[0] + 8 * stepYc; pFc[3] = pFc[2] + 8;
|
||||
pFc[4] = pInfo->VisualObject.cFrame->pCb + i * stepCbc * 8; pFc[5] = pInfo->VisualObject.cFrame->pCr + i * stepCrc * 8;
|
||||
}
|
||||
nmbgob = 0;
|
||||
}
|
||||
}
|
||||
mp4_AlignBits(pInfo);
|
||||
return sts;
|
||||
Err_1:
|
||||
sts = MP4_STATUS_ERROR;
|
||||
if (pInfo->stopOnErr)
|
||||
return sts;
|
||||
if (!mp4_SeekGOBMarker(pInfo))
|
||||
{
|
||||
mp4_CopyMacroBlocks(pInfo->VisualObject.rFrame, pInfo->VisualObject.cFrame, mbPerRow, rowNum, colNum, pInfo->VisualObject.VideoObject.MacroBlockPerVOP - rowNum * mbPerRow - colNum);
|
||||
return sts;
|
||||
}
|
||||
goto ErrRet_1;
|
||||
}
|
||||
quant = pInfo->VisualObject.VideoObject.VideoObjectPlane.quant;
|
||||
if (pInfo->VisualObject.VideoObject.sprite_enable != MP4_SPRITE_STATIC)
|
||||
ippsZero_8u((uint8_t*)pInfo->VisualObject.VideoObject.MBinfo, nmb * sizeof(mp4_MacroBlock));
|
||||
// decode data_partitioned I-VOP
|
||||
if (pInfo->VisualObject.VideoObject.data_partitioned)
|
||||
{
|
||||
mp4_DataPartMacroBlock *pMBdp;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
// reset Intra prediction buffer on new Video_packet
|
||||
mp4_ResetIntraPredBuffer(pInfo);
|
||||
mbInVideoPacket = 0;
|
||||
pMBdp = &pInfo->VisualObject.VideoObject.DataPartBuff[mbCurr];
|
||||
// decode mb_type/cbpc/dquant/DC part
|
||||
for (;;)
|
||||
{
|
||||
if (mp4_DecodeMCBPC_I(pInfo, &mb_type, &cbpc) != MP4_STATUS_OK)
|
||||
goto Err_2;
|
||||
if (mb_type != IPPVC_MB_STUFFING)
|
||||
{
|
||||
if (mbInVideoPacket == nmb - mbCurr)
|
||||
{
|
||||
mp4_Error("DC Marker missed");
|
||||
goto Err_2;
|
||||
}
|
||||
quantPred = quant;
|
||||
if (mb_type == IPPVC_MBTYPE_INTRA_Q)
|
||||
mp4_UpdateQuant(pInfo, quant);
|
||||
if (mbInVideoPacket == 0)
|
||||
quantPred = quant;
|
||||
dcVLC = (quantPred < mp4_DC_vlc_Threshold[pInfo->VisualObject.VideoObject.VideoObjectPlane.intra_dc_vlc_thr]) ? 1 : 0;
|
||||
if (dcVLC) {
|
||||
for (i = 0; i < 6; i ++) {
|
||||
if (ippiDecodeDCIntra_MPEG4_1u16s(&pInfo->bufptr, &pInfo->bitoff, &pMBdp->dct_dc[i], (i < 4) ? IPPVC_BLOCK_LUMA : IPPVC_BLOCK_CHROMA) != ippStsNoErr)
|
||||
goto Err_2;
|
||||
}
|
||||
}
|
||||
pMBdp->quant = (uint8_t)quant;
|
||||
pMBdp->type = (uint8_t)mb_type;
|
||||
pMBdp->pat = (uint8_t)cbpc;
|
||||
pMBdp ++;
|
||||
mbInVideoPacket ++;
|
||||
}
|
||||
if (mp4_ShowBits(pInfo, 19) == MP4_DC_MARKER)
|
||||
{
|
||||
mp4_GetBits(pInfo, 19);
|
||||
break;
|
||||
}
|
||||
}
|
||||
pMBdp = &pInfo->VisualObject.VideoObject.DataPartBuff[mbCurr];
|
||||
// decode ac_pred_flag/cbpy part
|
||||
for (i = 0; i < mbInVideoPacket; i ++)
|
||||
{
|
||||
pMBdp[i].ac_pred_flag = (uint8_t)mp4_GetBit(pInfo);
|
||||
if (mp4_DecodeCBPY_I(pInfo, &cbpy) != MP4_STATUS_OK)
|
||||
{
|
||||
if (pInfo->stopOnErr)
|
||||
goto Err_2;
|
||||
for (j = i + 1; j < mbInVideoPacket; j ++)
|
||||
pMBdp[j].ac_pred_flag = 1;
|
||||
break;
|
||||
}
|
||||
pMBdp[i].pat = (uint8_t)((cbpy << 2) + pMBdp[i].pat);
|
||||
}
|
||||
// decode AC part and reconstruct macroblocks
|
||||
for (i = 0; i < mbInVideoPacket; i ++) {
|
||||
if (colNum == 0) {
|
||||
// reset B-prediction blocks on new row
|
||||
mp4_ResetIntraPredBblock(pInfo);
|
||||
}
|
||||
quant = pMBdp[i].quant;
|
||||
quantPred = (i == 0) ? quant : pMBdp[i-1].quant;
|
||||
dcVLC = (quantPred < mp4_DC_vlc_Threshold[pInfo->VisualObject.VideoObject.VideoObjectPlane.intra_dc_vlc_thr]) ? 1 : 0;
|
||||
ac_pred_flag = pMBdp[i].ac_pred_flag;
|
||||
if (mp4_DecodeIntraMB_DP(pInfo, pMBdp[i].dct_dc, colNum, pMBdp[i].pat, quant, dcVLC, ac_pred_flag, pFc, stepFc) != MP4_STATUS_OK)
|
||||
//if (!pInfo->VisualObject.VideoObject.reversible_vlc)
|
||||
goto Err_2;
|
||||
//else
|
||||
// goto Err_RVLC;
|
||||
colNum ++;
|
||||
if (colNum == mbPerRow)
|
||||
{
|
||||
colNum = 0;
|
||||
rowNum ++;
|
||||
if (rowNum == mbPerCol)
|
||||
return sts;
|
||||
pFc[0] += (2 * MP4_NUM_EXT_MB + 1) * 16 + (stepYc << 4) - stepYc;
|
||||
pFc[1] += (2 * MP4_NUM_EXT_MB + 1) * 16 + (stepYc << 4) - stepYc;
|
||||
pFc[2] += (2 * MP4_NUM_EXT_MB + 1) * 16 + (stepYc << 4) - stepYc;
|
||||
pFc[3] += (2 * MP4_NUM_EXT_MB + 1) * 16 + (stepYc << 4) - stepYc;
|
||||
pFc[4] += (2 * MP4_NUM_EXT_MB + 1) * 8 + (stepCbc << 3) - stepCbc;
|
||||
pFc[5] += (2 * MP4_NUM_EXT_MB + 1) * 8 + (stepCrc << 3) - stepCrc;
|
||||
}
|
||||
else
|
||||
{
|
||||
pFc[0] += 16; pFc[1] += 16; pFc[2] += 16; pFc[3] += 16; pFc[4] += 8; pFc[5] += 8;
|
||||
}
|
||||
}
|
||||
mbCurr += mbInVideoPacket;
|
||||
if (!pInfo->VisualObject.VideoObject.resync_marker_disable)
|
||||
{
|
||||
int32_t found;
|
||||
ErrRet_2:
|
||||
if (mp4_CheckDecodeVideoPacket(pInfo, &found) == MP4_STATUS_OK)
|
||||
{
|
||||
if (found)
|
||||
{
|
||||
quant = pInfo->VisualObject.VideoObject.VideoObjectPlane.quant_scale;
|
||||
mbCurr = pInfo->VisualObject.VideoObject.VideoObjectPlane.macroblock_num;
|
||||
mp4_CopyMacroBlocks(pInfo->VisualObject.rFrame, pInfo->VisualObject.cFrame, mbPerRow, rowNum, colNum, mbCurr - rowNum * mbPerRow - colNum);
|
||||
rowNum = mbCurr / mbPerRow;
|
||||
colNum = mbCurr % mbPerRow;
|
||||
pFc[0] = pInfo->VisualObject.cFrame->pY + (rowNum * stepYc + colNum) * 16; pFc[1] = pFc[0] + 8; pFc[2] = pFc[0] + stepYc * 8; pFc[3] = pFc[2] + 8;
|
||||
pFc[4] = pInfo->VisualObject.cFrame->pCb + (rowNum * stepCbc + colNum) * 8; pFc[5] = pInfo->VisualObject.cFrame->pCr + (rowNum * stepCrc + colNum) * 8;
|
||||
}
|
||||
else
|
||||
goto Err_2;
|
||||
}
|
||||
else
|
||||
goto Err_2;
|
||||
}
|
||||
}
|
||||
Err_2:
|
||||
sts = MP4_STATUS_ERROR;
|
||||
if (pInfo->stopOnErr)
|
||||
return sts;
|
||||
if (pInfo->VisualObject.VideoObject.resync_marker_disable || !mp4_SeekResyncMarker(pInfo))
|
||||
{
|
||||
mp4_CopyMacroBlocks(pInfo->VisualObject.rFrame, pInfo->VisualObject.cFrame, mbPerRow, rowNum, colNum, pInfo->VisualObject.VideoObject.MacroBlockPerVOP - rowNum * mbPerRow - colNum);
|
||||
return sts;
|
||||
}
|
||||
goto ErrRet_2;
|
||||
#if 0
|
||||
Err_RVLC:
|
||||
{
|
||||
uint8_t *sBufptr = pInfo->bufptr;
|
||||
int32_t sBitoff = pInfo->bitoff;
|
||||
|
||||
pInfo->bitoff --;
|
||||
if (pInfo->bitoff == -1) {
|
||||
pInfo->bitoff = 7;
|
||||
pInfo->bufptr --;
|
||||
}
|
||||
// decode AC part and reconstruct macroblocks
|
||||
for (j = mbInVideoPacket - 1; j >= i; j --) {
|
||||
int32_t lnz, quantPred, dcVLC;
|
||||
|
||||
quantPred = ((j == 0) ? pMBdp[j].quant : pMBdp[j-1].quant);
|
||||
dcVLC = (quantPred < mp4_DC_vlc_Threshold[pInfo->VisualObject.VideoObject.VideoObjectPlane.intra_dc_vlc_thr]) ? 1 : 0;
|
||||
if (ippiDecodeCoeffsIntraRVLCBack_MPEG4_1u16s(&pInfo->bufptr, &pInfo->bitoff, pDCTdp[j*64*6], &lnz, dcVLC) != ippStsNoErr)
|
||||
break;
|
||||
}
|
||||
pInfo->bufptr = sBufptr;
|
||||
pInfo->bitoff = sBitoff;
|
||||
}
|
||||
goto ErrRet_2;
|
||||
#endif
|
||||
}
|
||||
// decode not data partitioned I-VOP
|
||||
else {
|
||||
int32_t stepY = stepYc, dct_type = 0, pYoff23 = 8 * stepYc;
|
||||
for (;;) {
|
||||
// reset Intra prediction buffer on new Video_packet
|
||||
mp4_ResetIntraPredBuffer(pInfo);
|
||||
mbInVideoPacket = 0;
|
||||
// decode blocks
|
||||
for (;;) {
|
||||
if (colNum == 0) {
|
||||
// reset B-prediction blocks on new row
|
||||
mp4_ResetIntraPredBblock(pInfo);
|
||||
}
|
||||
if (mp4_DecodeMCBPC_I(pInfo, &mb_type, &cbpc) != MP4_STATUS_OK)
|
||||
goto Err_3;
|
||||
if (mb_type != IPPVC_MB_STUFFING) {
|
||||
ac_pred_flag = mp4_GetBit(pInfo);
|
||||
if (mp4_DecodeCBPY_I(pInfo, &cbpy) != MP4_STATUS_OK)
|
||||
goto Err_3;
|
||||
quantPred = quant;
|
||||
if (mb_type == IPPVC_MBTYPE_INTRA_Q)
|
||||
mp4_UpdateQuant(pInfo, quant);
|
||||
if (mbInVideoPacket == 0)
|
||||
quantPred = quant;
|
||||
dcVLC = (quantPred < mp4_DC_vlc_Threshold[pInfo->VisualObject.VideoObject.VideoObjectPlane.intra_dc_vlc_thr]) ? 1 : 0;
|
||||
if (pInfo->VisualObject.VideoObject.interlaced) {
|
||||
dct_type = mp4_GetBit(pInfo);
|
||||
if (dct_type) {
|
||||
stepY = stepYc * 2;
|
||||
pYoff23 = stepYc;
|
||||
} else {
|
||||
stepY = stepYc;
|
||||
pYoff23 = 8 * stepYc;
|
||||
}
|
||||
stepFc[0] = stepFc[1] = stepFc[2] = stepFc[3] = stepY;
|
||||
}
|
||||
pFc[2] = pFc[0] + pYoff23; pFc[3] = pFc[1] + pYoff23;
|
||||
if (mp4_DecodeIntraMB(pInfo, colNum, (cbpy << 2) + cbpc, quant, dcVLC, ac_pred_flag, pFc, stepFc) != MP4_STATUS_OK)
|
||||
goto Err_3;
|
||||
mbInVideoPacket ++;
|
||||
colNum ++;
|
||||
if (colNum == mbPerRow) {
|
||||
colNum = 0;
|
||||
rowNum ++;
|
||||
if (rowNum == mbPerCol) {
|
||||
// skip stuffing
|
||||
while (mp4_ShowBits9(pInfo, 9) == 1)
|
||||
mp4_FlushBits(pInfo, 9);
|
||||
return sts;
|
||||
}
|
||||
pFc[0] += (2 * MP4_NUM_EXT_MB + 1) * 16 + (stepYc << 4) - stepYc;
|
||||
pFc[1] += (2 * MP4_NUM_EXT_MB + 1) * 16 + (stepYc << 4) - stepYc;
|
||||
pFc[4] += (2 * MP4_NUM_EXT_MB + 1) * 8 + (stepCbc << 3) - stepCbc;
|
||||
pFc[5] += (2 * MP4_NUM_EXT_MB + 1) * 8 + (stepCrc << 3) - stepCrc;
|
||||
} else {
|
||||
pFc[0] += 16; pFc[1] += 16; pFc[4] += 8; pFc[5] += 8;
|
||||
}
|
||||
}
|
||||
if (!pInfo->VisualObject.VideoObject.resync_marker_disable)
|
||||
{
|
||||
int32_t found;
|
||||
ErrRet_3:
|
||||
if (mp4_CheckDecodeVideoPacket(pInfo, &found) == MP4_STATUS_OK)
|
||||
{
|
||||
if (found)
|
||||
{
|
||||
quant = pInfo->VisualObject.VideoObject.VideoObjectPlane.quant_scale;
|
||||
mbCurr = pInfo->VisualObject.VideoObject.VideoObjectPlane.macroblock_num;
|
||||
mp4_CopyMacroBlocks(pInfo->VisualObject.rFrame, pInfo->VisualObject.cFrame, mbPerRow, rowNum, colNum, mbCurr - rowNum * mbPerRow - colNum);
|
||||
rowNum = mbCurr / mbPerRow;
|
||||
colNum = mbCurr % mbPerRow;
|
||||
pFc[0] = pInfo->VisualObject.cFrame->pY + (rowNum * stepYc + colNum) * 16; pFc[1] = pFc[0] + 8;
|
||||
pFc[4] = pInfo->VisualObject.cFrame->pCb + (rowNum * stepCbc + colNum) * 8; pFc[5] = pInfo->VisualObject.cFrame->pCr + (rowNum * stepCrc + colNum) * 8;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
goto Err_3;
|
||||
}
|
||||
}
|
||||
}
|
||||
Err_3:
|
||||
sts = MP4_STATUS_ERROR;
|
||||
if (pInfo->stopOnErr)
|
||||
return sts;
|
||||
if (pInfo->VisualObject.VideoObject.resync_marker_disable || !mp4_SeekResyncMarker(pInfo))
|
||||
{
|
||||
mp4_CopyMacroBlocks(pInfo->VisualObject.rFrame, pInfo->VisualObject.cFrame, mbPerRow, rowNum, colNum, pInfo->VisualObject.VideoObject.MacroBlockPerVOP - rowNum * mbPerRow - colNum);
|
||||
return sts;
|
||||
}
|
||||
goto ErrRet_3;
|
||||
}
|
||||
}
|
||||
|
||||
|
1079
Src/mpeg4dec/mp4decvopp.c
Normal file
1079
Src/mpeg4dec/mp4decvopp.c
Normal file
File diff suppressed because it is too large
Load diff
655
Src/mpeg4dec/mp4decvops.c
Normal file
655
Src/mpeg4dec/mp4decvops.c
Normal file
|
@ -0,0 +1,655 @@
|
|||
/* ///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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) 2001-2007 Intel Corporation. All Rights Reserved.
|
||||
//
|
||||
// Description: Decodes S-VOPs
|
||||
//
|
||||
*/
|
||||
|
||||
#include "mp4def.h"
|
||||
#include "mp4dec.h"
|
||||
|
||||
/*
|
||||
// decode MPEG-4 SVOP
|
||||
*/
|
||||
mp4_Status mp4_DecodeVOP_S(mp4_Info* pInfo)
|
||||
{
|
||||
__ALIGN16(int16_t, coeffMB, 64*6);
|
||||
int32_t quant, quantPred, i, j, dcVLC, nmb, dx, dy, pat;
|
||||
int32_t stepYr, stepYc, stepCbr, stepCbc, stepCrr, stepCrc, mbPerRow, mbPerCol;
|
||||
int32_t mbCurr, mbInVideoPacket, colNum, rowNum, stepF[6];
|
||||
uint8_t *pYc, *pCbc, *pCrc, *pYr, *pCbr, *pCrr, *pF[6];
|
||||
int32_t mb_not_coded, mb_type, cbpc, cbpy, ac_pred_flag, cbpyPrev, mcsel;
|
||||
int32_t scan, obmc_disable, rt, quarter_sample, interlaced, fcode_forward;
|
||||
IppiRect limitRectL, limitRectC;
|
||||
IppMotionVector mvCur[4], mvPrev[4], mvTmp[4], mvCbCr;
|
||||
mp4_MacroBlock *pMBinfo;
|
||||
IppiRect spriteRect, vopRect;
|
||||
mp4_Status sts;
|
||||
|
||||
if (!pInfo->VisualObject.cFrame)
|
||||
pInfo->VisualObject.cFrame = CreateFrame(&pInfo->VisualObject);
|
||||
|
||||
mbPerRow = pInfo->VisualObject.VideoObject.MacroBlockPerRow;
|
||||
mbPerCol = pInfo->VisualObject.VideoObject.MacroBlockPerCol;
|
||||
stepYc = pInfo->VisualObject.cFrame->stepY;
|
||||
stepYr = pInfo->VisualObject.rFrame->stepY;
|
||||
stepCbc = pInfo->VisualObject.cFrame->stepCb;
|
||||
stepCbr = pInfo->VisualObject.rFrame->stepCb;
|
||||
stepCrc = pInfo->VisualObject.cFrame->stepCr;
|
||||
stepCrr = pInfo->VisualObject.rFrame->stepCr;
|
||||
pYc = pInfo->VisualObject.cFrame->pY;
|
||||
pCbc = pInfo->VisualObject.cFrame->pCb;
|
||||
pCrc = pInfo->VisualObject.cFrame->pCr;
|
||||
pYr = pInfo->VisualObject.rFrame->pY;
|
||||
pCbr = pInfo->VisualObject.rFrame->pCb;
|
||||
pCrr = pInfo->VisualObject.rFrame->pCr;
|
||||
stepF[0] = stepF[1] = stepF[2] = stepF[3] = stepYc; stepF[4] = stepCbc; stepF[5] = stepCrc;
|
||||
// Bounding rectangle for MV limitation
|
||||
limitRectL.x = - 16 * MP4_NUM_EXT_MB;
|
||||
limitRectL.y = - 16 * MP4_NUM_EXT_MB;
|
||||
limitRectL.width = pInfo->VisualObject.VideoObject.width + 16 * 2 * MP4_NUM_EXT_MB;
|
||||
limitRectL.height = pInfo->VisualObject.VideoObject.height + 16 * 2 * MP4_NUM_EXT_MB;
|
||||
limitRectC.x = -8 * MP4_NUM_EXT_MB;
|
||||
limitRectC.y = -8 * MP4_NUM_EXT_MB;
|
||||
limitRectC.width = (pInfo->VisualObject.VideoObject.width >> 1) + 8 * 2 * MP4_NUM_EXT_MB;
|
||||
limitRectC.height = (pInfo->VisualObject.VideoObject.height >> 1) + 8 * 2 * MP4_NUM_EXT_MB;
|
||||
pMBinfo = pInfo->VisualObject.VideoObject.MBinfo;
|
||||
rt = pInfo->VisualObject.VideoObject.VideoObjectPlane.rounding_type;
|
||||
quarter_sample = pInfo->VisualObject.VideoObject.quarter_sample;
|
||||
obmc_disable = pInfo->VisualObject.VideoObject.obmc_disable;
|
||||
interlaced = pInfo->VisualObject.VideoObject.interlaced;
|
||||
scan = pInfo->VisualObject.VideoObject.VideoObjectPlane.alternate_vertical_scan_flag ? IPPVC_SCAN_VERTICAL : IPPVC_SCAN_ZIGZAG;
|
||||
nmb = pInfo->VisualObject.VideoObject.MacroBlockPerVOP;
|
||||
quant = quantPred = pInfo->VisualObject.VideoObject.VideoObjectPlane.quant;
|
||||
mbCurr = colNum = rowNum = 0;
|
||||
cbpc = 0;
|
||||
// init WarpSpec for Sprites or GMC
|
||||
vopRect.x = 0;
|
||||
vopRect.y = 0;
|
||||
vopRect.width = pInfo->VisualObject.VideoObject.width;
|
||||
vopRect.height = pInfo->VisualObject.VideoObject.height;
|
||||
if (pInfo->VisualObject.VideoObject.sprite_enable == MP4_SPRITE_STATIC) {
|
||||
spriteRect.x = pInfo->VisualObject.VideoObject.sprite_left_coordinate;
|
||||
spriteRect.y = pInfo->VisualObject.VideoObject.sprite_top_coordinate;
|
||||
spriteRect.width = pInfo->VisualObject.VideoObject.sprite_width;
|
||||
spriteRect.height = pInfo->VisualObject.VideoObject.sprite_height;
|
||||
fcode_forward = 1;
|
||||
} else {
|
||||
spriteRect = vopRect; // for shapes they may be different !!!!!!
|
||||
fcode_forward = pInfo->VisualObject.VideoObject.VideoObjectPlane.fcode_forward;
|
||||
}
|
||||
ippiWarpInit_MPEG4(pInfo->VisualObject.VideoObject.WarpSpec,
|
||||
pInfo->VisualObject.VideoObject.VideoObjectPlane.warping_mv_code_du,
|
||||
pInfo->VisualObject.VideoObject.VideoObjectPlane.warping_mv_code_dv,
|
||||
pInfo->VisualObject.VideoObject.sprite_warping_points,
|
||||
pInfo->VisualObject.VideoObject.sprite_enable,
|
||||
pInfo->VisualObject.VideoObject.sprite_warping_accuracy,
|
||||
rt, quarter_sample, fcode_forward,
|
||||
&spriteRect, &vopRect);
|
||||
// decode basic sprites
|
||||
if (pInfo->VisualObject.VideoObject.sprite_enable == MP4_SPRITE_STATIC)
|
||||
{
|
||||
//if (pInfo->VisualObject.VideoObject.shape != MP4_SHAPE_TYPE_RECTANGULAR) {
|
||||
// if (mp4_InitVOPShape(pInfo) != MP4_STATUS_OK)
|
||||
// return MP4_STATUS_ERROR;
|
||||
//}
|
||||
ippiWarpLuma_MPEG4_8u_C1R(pInfo->VisualObject.sFrame->pY, pInfo->VisualObject.sFrame->stepY,
|
||||
pYc, stepYc, &vopRect, pInfo->VisualObject.VideoObject.WarpSpec);
|
||||
if (pInfo->VisualObject.VideoObject.sprite_brightness_change)
|
||||
ippiChangeSpriteBrightness_MPEG4_8u_C1IR(pYc, stepYc, vopRect.width, vopRect.height, pInfo->VisualObject.VideoObject.VideoObjectPlane.brightness_change_factor);
|
||||
vopRect.width >>= 1; vopRect.height >>= 1;
|
||||
ippiWarpChroma_MPEG4_8u_P2R(pInfo->VisualObject.sFrame->pCb, pInfo->VisualObject.sFrame->stepCb,
|
||||
pInfo->VisualObject.sFrame->pCr, pInfo->VisualObject.sFrame->stepCr,
|
||||
pCbc, stepCbc, pCrc, stepCrc, &vopRect, pInfo->VisualObject.VideoObject.WarpSpec);
|
||||
return MP4_STATUS_OK;
|
||||
}
|
||||
sts = MP4_STATUS_OK;
|
||||
// decode data_partitioned S(GMC)-VOP
|
||||
if (pInfo->VisualObject.VideoObject.data_partitioned) {
|
||||
for (;;) {
|
||||
mp4_DataPartMacroBlock *pMBdp;
|
||||
int32_t x, y;
|
||||
|
||||
x = colNum;
|
||||
y = rowNum;
|
||||
// reset Intra prediction buffer on new Video_packet
|
||||
mp4_ResetIntraPredBuffer(pInfo);
|
||||
pMBdp = &pInfo->VisualObject.VideoObject.DataPartBuff[mbCurr];
|
||||
pMBinfo = &pInfo->VisualObject.VideoObject.MBinfo[mbCurr];
|
||||
mbInVideoPacket = 0;
|
||||
// decode not_coded/mcsel/mb_type/cbpc/MV part
|
||||
for (;;) {
|
||||
mb_not_coded = mp4_GetBit(pInfo);
|
||||
if (mb_not_coded) {
|
||||
mb_type = IPPVC_MBTYPE_INTER;
|
||||
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_NOTCODED);
|
||||
} else {
|
||||
if (mp4_DecodeMCBPC_P(pInfo, &mb_type, &cbpc, 1) != MP4_STATUS_OK)
|
||||
goto Err_2;
|
||||
}
|
||||
if (mb_type != IPPVC_MB_STUFFING) {
|
||||
if (mbInVideoPacket == nmb - mbCurr) {
|
||||
mp4_Error("DC Marker missed");
|
||||
goto Err_2;
|
||||
}
|
||||
pMBinfo->validPred = 1;
|
||||
if (mb_type < IPPVC_MBTYPE_INTER4V && !mb_not_coded)
|
||||
mcsel = mp4_GetBit(pInfo);
|
||||
else
|
||||
mcsel = mb_not_coded;
|
||||
if (!mcsel) {
|
||||
if (mb_type <= IPPVC_MBTYPE_INTER4V) {
|
||||
if (mb_type != IPPVC_MBTYPE_INTER4V) {
|
||||
if (mp4_PredictDecode1MV(pInfo, pMBinfo, y, x) != MP4_STATUS_OK)
|
||||
goto Err_2;
|
||||
pMBinfo->mv[1] = pMBinfo->mv[2] = pMBinfo->mv[3] = pMBinfo->mv[0];
|
||||
} else {
|
||||
if (mp4_PredictDecode4MV(pInfo, pMBinfo, y, x) != MP4_STATUS_OK)
|
||||
goto Err_2;
|
||||
}
|
||||
} else {
|
||||
mp4_Zero4MV(pMBinfo->mv);
|
||||
}
|
||||
} else {
|
||||
ippiCalcGlobalMV_MPEG4(x << 4, y << 4, pMBinfo->mv, pInfo->VisualObject.VideoObject.WarpSpec);
|
||||
pMBinfo->mv[1] = pMBinfo->mv[2] = pMBinfo->mv[3] = pMBinfo->mv[0];
|
||||
}
|
||||
pMBinfo->not_coded = (uint8_t)mb_not_coded;
|
||||
pMBinfo->type = (uint8_t)mb_type;
|
||||
pMBinfo ++;
|
||||
pMBdp->pat = (uint8_t)cbpc;
|
||||
pMBdp->mcsel = (uint8_t)mcsel;
|
||||
pMBdp ++;
|
||||
mbInVideoPacket ++;
|
||||
x ++;
|
||||
if (x == mbPerRow) {
|
||||
x = 0;
|
||||
y ++;
|
||||
}
|
||||
}
|
||||
if (mp4_ShowBits(pInfo, 17) == MP4_MV_MARKER) {
|
||||
mp4_GetBits(pInfo, 17);
|
||||
break;
|
||||
}
|
||||
}
|
||||
pMBdp = &pInfo->VisualObject.VideoObject.DataPartBuff[mbCurr];
|
||||
pMBinfo = &pInfo->VisualObject.VideoObject.MBinfo[mbCurr];
|
||||
// decode ac_pred_flag/cbpy/dquant/IntraDC part
|
||||
for (i = 0; i < mbInVideoPacket; i ++) {
|
||||
if (!pMBinfo->not_coded) {
|
||||
mb_type = pMBinfo->type;
|
||||
if (mb_type >= IPPVC_MBTYPE_INTRA)
|
||||
pMBdp->ac_pred_flag = (uint8_t)mp4_GetBit(pInfo);
|
||||
if (mp4_DecodeCBPY_P(pInfo, &cbpy, mb_type) != MP4_STATUS_OK)
|
||||
goto Err_2;
|
||||
pMBdp->pat = (uint8_t)((cbpy << 2) + pMBdp->pat);
|
||||
quantPred = quant;
|
||||
if (mb_type == IPPVC_MBTYPE_INTER_Q || mb_type == IPPVC_MBTYPE_INTRA_Q)
|
||||
mp4_UpdateQuant(pInfo, quant);
|
||||
pMBdp->quant = (uint8_t)quant;
|
||||
if (i == 0)
|
||||
quantPred = quant;
|
||||
// decode DC coefficient of Intra blocks
|
||||
dcVLC = (quantPred < mp4_DC_vlc_Threshold[pInfo->VisualObject.VideoObject.VideoObjectPlane.intra_dc_vlc_thr]) ? 1 : 0;
|
||||
if ((mb_type >= IPPVC_MBTYPE_INTRA) && dcVLC) {
|
||||
for (j = 0; j < 6; j ++) {
|
||||
if (ippiDecodeDCIntra_MPEG4_1u16s(&pInfo->bufptr, &pInfo->bitoff, &pMBdp->dct_dc[j], j < 4 ? IPPVC_BLOCK_LUMA : IPPVC_BLOCK_CHROMA) != ippStsNoErr)
|
||||
goto Err_2;
|
||||
}
|
||||
}
|
||||
} else
|
||||
pMBdp->pat = 0;
|
||||
pMBinfo->not_coded = 0; // for B-VOP all MB have MVs
|
||||
if (pMBdp->mcsel)
|
||||
pMBinfo->type = IPPVC_MBTYPE_INTRA; // for OBMC MVs
|
||||
pMBdp ++;
|
||||
pMBinfo ++;
|
||||
}
|
||||
if (mbCurr + mbInVideoPacket < nmb)
|
||||
pMBinfo->type = IPPVC_MBTYPE_INTRA; // for OBMC set first MB of the next videopacket as invalid for right MV
|
||||
pMBdp = &pInfo->VisualObject.VideoObject.DataPartBuff[mbCurr];
|
||||
pMBinfo = &pInfo->VisualObject.VideoObject.MBinfo[mbCurr];
|
||||
// decode coeffs and reconstruct macroblocks
|
||||
for (i = 0; i < mbInVideoPacket; i ++) {
|
||||
if (colNum == 0) {
|
||||
// reset B-prediction blocks on new row
|
||||
mp4_ResetIntraPredBblock(pInfo);
|
||||
}
|
||||
quant = pMBdp->quant;
|
||||
mb_type = pMBinfo->type;
|
||||
mcsel = pMBdp->mcsel;
|
||||
if (!mcsel && (mb_type >= IPPVC_MBTYPE_INTRA)) {
|
||||
quantPred = (i == 0) ? quant : pMBdp[-1].quant;
|
||||
dcVLC = (quantPred < mp4_DC_vlc_Threshold[pInfo->VisualObject.VideoObject.VideoObjectPlane.intra_dc_vlc_thr]) ? 1 : 0;
|
||||
pF[0] = pYc; pF[1] = pYc + 8; pF[2] = pYc + 8 * stepYc; pF[3] = pYc + 8 * stepYc + 8; pF[4] = pCbc; pF[5] = pCrc;
|
||||
if (mp4_DecodeIntraMB_DP(pInfo, pMBdp->dct_dc, colNum, pMBdp->pat, quant, dcVLC, pMBdp->ac_pred_flag, pF, stepF) != MP4_STATUS_OK)
|
||||
goto Err_2;
|
||||
} else {
|
||||
mp4_UpdateIntraPredBuffInvalid(pInfo, colNum);
|
||||
dx = colNum * 16;
|
||||
dy = rowNum * 16;
|
||||
pat = pMBdp->pat;
|
||||
cbpy = pat >> 2;
|
||||
cbpc = pat & 3;
|
||||
if (pat)
|
||||
if (mp4_DecodeInterMB(pInfo, coeffMB, quant, pat, scan) != MP4_STATUS_OK)
|
||||
goto Err_2;
|
||||
if (!mcsel) {
|
||||
if (mb_type == IPPVC_MBTYPE_INTER4V) {
|
||||
if (quarter_sample) {
|
||||
mp4_Limit4MVQ(pMBinfo->mv, mvCur, &limitRectL, dx, dy, 8);
|
||||
mp4_ComputeChroma4MVQ(pMBinfo->mv, &mvCbCr);
|
||||
} else {
|
||||
mp4_Limit4MV(pMBinfo->mv, mvCur, &limitRectL, dx, dy, 8);
|
||||
mp4_ComputeChroma4MV(pMBinfo->mv, &mvCbCr);
|
||||
}
|
||||
mp4_LimitMV(&mvCbCr, &mvCbCr, &limitRectC, dx >> 1, dy >> 1, 8);
|
||||
} else {
|
||||
if (quarter_sample) {
|
||||
mp4_LimitMVQ(pMBinfo->mv, mvCur, &limitRectL, dx, dy, 16);
|
||||
mp4_ComputeChromaMVQ(mvCur, &mvCbCr);
|
||||
} else {
|
||||
mp4_LimitMV(pMBinfo->mv, mvCur, &limitRectL, dx, dy, 16);
|
||||
mp4_ComputeChromaMV(mvCur, &mvCbCr);
|
||||
}
|
||||
mvCur[1] = mvCur[2] = mvCur[3] = mvCur[0];
|
||||
}
|
||||
if (obmc_disable) {
|
||||
if (quarter_sample) {
|
||||
if (mb_type == IPPVC_MBTYPE_INTER4V) {
|
||||
mp4_Copy8x8QP_8u(pYr, stepYr, pYc, stepYc, &mvCur[0], rt);
|
||||
mp4_Copy8x8QP_8u(pYr+8, stepYr, pYc+8, stepYc, &mvCur[1], rt);
|
||||
mp4_Copy8x8QP_8u(pYr+8*stepYr, stepYr, pYc+8*stepYc, stepYc, &mvCur[2], rt);
|
||||
mp4_Copy8x8QP_8u(pYr+8*stepYr+8, stepYr, pYc+8*stepYc+8, stepYc, &mvCur[3], rt);
|
||||
} else
|
||||
mp4_Copy16x16QP_8u(pYr, stepYr, pYc, stepYc, &mvCur[0], rt);
|
||||
} else {
|
||||
if (mb_type == IPPVC_MBTYPE_INTER4V) {
|
||||
mp4_Copy8x8HP_8u(pYr, stepYr, pYc, stepYc, &mvCur[0], rt);
|
||||
mp4_Copy8x8HP_8u(pYr+8, stepYr, pYc+8, stepYc, &mvCur[1], rt);
|
||||
mp4_Copy8x8HP_8u(pYr+8*stepYr, stepYr, pYc+8*stepYc, stepYc, &mvCur[2], rt);
|
||||
mp4_Copy8x8HP_8u(pYr+8*stepYr+8, stepYr, pYc+8*stepYc+8, stepYc, &mvCur[3], rt);
|
||||
} else
|
||||
mp4_Copy16x16HP_8u(pYr, stepYr, pYc, stepYc, &mvCur[0], rt);
|
||||
}
|
||||
mp4_AddResidual(cbpy & 8, pYc, stepYc, coeffMB);
|
||||
mp4_AddResidual(cbpy & 4, pYc+8, stepYc, coeffMB+64);
|
||||
mp4_AddResidual(cbpy & 2, pYc+stepYc*8, stepYc, coeffMB+128);
|
||||
mp4_AddResidual(cbpy & 1, pYc+stepYc*8+8, stepYc, coeffMB+192);
|
||||
} else {
|
||||
mp4_OBMC(pInfo, pMBinfo, mvCur, colNum, rowNum, limitRectL, pYc, stepYc, pYr, stepYr, cbpy, coeffMB, 0);
|
||||
}
|
||||
mp4_MC_HP(cbpc & 2, pCbr, stepCbr, pCbc, stepCbc, coeffMB+256, &mvCbCr, rt);
|
||||
mp4_MC_HP(cbpc & 1, pCrr, stepCrr, pCrc, stepCrc, coeffMB+320, &mvCbCr, rt);
|
||||
} else {
|
||||
IppiRect mbRect;
|
||||
|
||||
mbRect.x = dx; mbRect.y = dy; mbRect.width = mbRect.height = 16;
|
||||
ippiWarpLuma_MPEG4_8u_C1R(pInfo->VisualObject.rFrame->pY, stepYr, pYc, stepYc, &mbRect, pInfo->VisualObject.VideoObject.WarpSpec);
|
||||
mbRect.x >>= 1; mbRect.y >>= 1; mbRect.width = mbRect.height = 8;
|
||||
ippiWarpChroma_MPEG4_8u_P2R(pInfo->VisualObject.rFrame->pCb, stepCbr, pInfo->VisualObject.rFrame->pCr, stepCrr, pCbc, stepCbc, pCrc, stepCrc, &mbRect, pInfo->VisualObject.VideoObject.WarpSpec);
|
||||
if (pat) {
|
||||
mp4_AddResidual(cbpy & 8, pYc, stepYc, coeffMB);
|
||||
mp4_AddResidual(cbpy & 4, pYc+8, stepYc, coeffMB+64);
|
||||
mp4_AddResidual(cbpy & 2, pYc+stepYc*8, stepYc, coeffMB+128);
|
||||
mp4_AddResidual(cbpy & 1, pYc+stepYc*8+8, stepYc, coeffMB+192);
|
||||
mp4_AddResidual(cbpc & 2, pCbc, stepCbc, coeffMB+256);
|
||||
mp4_AddResidual(cbpc & 1, pCrc, stepCrc, coeffMB+320);
|
||||
}
|
||||
}
|
||||
}
|
||||
pMBinfo ++;
|
||||
pMBdp ++;
|
||||
colNum ++;
|
||||
if (colNum == mbPerRow) {
|
||||
colNum = 0;
|
||||
rowNum ++;
|
||||
if (rowNum == mbPerCol)
|
||||
return sts;
|
||||
pYc += (2 * MP4_NUM_EXT_MB + 1) * 16 + (stepYc << 4) - stepYc;
|
||||
pCbc += (2 * MP4_NUM_EXT_MB + 1) * 8 + (stepCbc << 3) - stepCbc;
|
||||
pCrc += (2 * MP4_NUM_EXT_MB + 1) * 8 + (stepCrc << 3) - stepCrc;
|
||||
pYr += (2 * MP4_NUM_EXT_MB + 1) * 16 + (stepYr << 4) - stepYr;
|
||||
pCbr += (2 * MP4_NUM_EXT_MB + 1) * 8 + (stepCbr << 3) - stepCbr;
|
||||
pCrr += (2 * MP4_NUM_EXT_MB + 1) * 8 + (stepCrr << 3) - stepCrr;
|
||||
}
|
||||
else
|
||||
{
|
||||
pYc += 16; pCrc += 8; pCbc += 8;
|
||||
pYr += 16; pCrr += 8; pCbr += 8;
|
||||
}
|
||||
}
|
||||
//mbCurr += mbInVideoPacket;
|
||||
if (!pInfo->VisualObject.VideoObject.resync_marker_disable)
|
||||
{
|
||||
int32_t found;
|
||||
ErrRet_2:
|
||||
if (mp4_CheckDecodeVideoPacket(pInfo, &found) == MP4_STATUS_OK)
|
||||
{
|
||||
if (found)
|
||||
{
|
||||
quant = pInfo->VisualObject.VideoObject.VideoObjectPlane.quant_scale;
|
||||
mbInVideoPacket = pInfo->VisualObject.VideoObject.VideoObjectPlane.macroblock_num - mbCurr;
|
||||
mbCurr = pInfo->VisualObject.VideoObject.VideoObjectPlane.macroblock_num;
|
||||
mp4_CopyMacroBlocks(pInfo->VisualObject.rFrame, pInfo->VisualObject.cFrame, mbPerRow, rowNum, colNum, mbCurr - rowNum * mbPerRow - colNum);
|
||||
rowNum = mbCurr / mbPerRow;
|
||||
colNum = mbCurr % mbPerRow;
|
||||
pYc = pInfo->VisualObject.cFrame->pY + (rowNum * stepYc + colNum) * 16; pCbc = pInfo->VisualObject.cFrame->pCb + (rowNum * stepCbc + colNum) * 8; pCrc = pInfo->VisualObject.cFrame->pCr + (rowNum * stepCrc + colNum) * 8;
|
||||
pYr = pInfo->VisualObject.rFrame->pY + (rowNum * stepYr + colNum) * 16; pCbr = pInfo->VisualObject.rFrame->pCb + (rowNum * stepCbr + colNum) * 8; pCrr = pInfo->VisualObject.rFrame->pCr + (rowNum * stepCrr + colNum) * 8;
|
||||
pMBinfo = pInfo->VisualObject.VideoObject.MBinfo + mbCurr;
|
||||
} else
|
||||
goto Err_2;
|
||||
} else
|
||||
goto Err_2;
|
||||
}
|
||||
// mark MBs the previous videopacket as invalid for prediction
|
||||
for (i = 1; i <= IPP_MIN(mbInVideoPacket, mbPerRow + 1); i ++)
|
||||
pMBinfo[-i].validPred = 0;
|
||||
}
|
||||
Err_2:
|
||||
sts = MP4_STATUS_ERROR;
|
||||
if (pInfo->stopOnErr)
|
||||
return sts;
|
||||
if (pInfo->VisualObject.VideoObject.resync_marker_disable || !mp4_SeekResyncMarker(pInfo))
|
||||
{
|
||||
mp4_CopyMacroBlocks(pInfo->VisualObject.rFrame, pInfo->VisualObject.cFrame, mbPerRow, rowNum, colNum, pInfo->VisualObject.VideoObject.MacroBlockPerVOP - rowNum * mbPerRow - colNum);
|
||||
return sts;
|
||||
}
|
||||
goto ErrRet_2;
|
||||
}
|
||||
// decode not data_partitioned S-VOP
|
||||
{
|
||||
int32_t stepY, pYoff23, field_prediction, dct_type, dct_typePrev, mb_ftfr, mb_fbfr;
|
||||
IppMotionVector mvCbCrT, mvCbCrB, *mvField = pInfo->VisualObject.VideoObject.FieldMV;
|
||||
|
||||
// warning "variable may be used without having been initialized"
|
||||
dx = dy = ac_pred_flag = cbpy = cbpyPrev = field_prediction = dct_type = dct_typePrev = mb_ftfr = mb_fbfr = 0;
|
||||
mvCbCr.dx = mvCbCr.dy = mvCbCrT.dx = mvCbCrT.dy = mvCbCrB.dx = mvCbCrB.dy = 0;
|
||||
for (;;) {
|
||||
// reset Intra prediction buffer on new Video_packet
|
||||
mp4_ResetIntraPredBuffer(pInfo);
|
||||
mbInVideoPacket = 0;
|
||||
// decode blocks
|
||||
for (;;) {
|
||||
if (colNum == 0) {
|
||||
// reset B-prediction blocks on new row
|
||||
mp4_ResetIntraPredBblock(pInfo);
|
||||
}
|
||||
mb_not_coded = mp4_GetBit(pInfo);
|
||||
mb_type = IPPVC_MBTYPE_INTER;
|
||||
if (!mb_not_coded) {
|
||||
if (mp4_DecodeMCBPC_P(pInfo, &mb_type, &cbpc, 1) != MP4_STATUS_OK)
|
||||
goto Err_3;
|
||||
}
|
||||
if (mb_type != IPPVC_MB_STUFFING) {
|
||||
if (!mb_not_coded) {
|
||||
mcsel = (mb_type < IPPVC_MBTYPE_INTER4V) ? mp4_GetBit(pInfo) : 0;
|
||||
if (mb_type >= IPPVC_MBTYPE_INTRA)
|
||||
ac_pred_flag = mp4_GetBit(pInfo);
|
||||
if (mp4_DecodeCBPY_P(pInfo, &cbpy, mb_type) != MP4_STATUS_OK)
|
||||
goto Err_3;
|
||||
quantPred = quant;
|
||||
if (mb_type == IPPVC_MBTYPE_INTER_Q || mb_type == IPPVC_MBTYPE_INTRA_Q)
|
||||
mp4_UpdateQuant(pInfo, quant);
|
||||
if (interlaced) {
|
||||
dct_type = 0;
|
||||
field_prediction = 0;
|
||||
if (mb_type >= IPPVC_MBTYPE_INTRA || (cbpy + cbpc) != 0)
|
||||
dct_type = mp4_GetBit(pInfo);
|
||||
if ((mb_type == IPPVC_MBTYPE_INTER || mb_type == IPPVC_MBTYPE_INTER_Q) && !mcsel) {
|
||||
field_prediction = mp4_GetBit(pInfo);
|
||||
if (field_prediction) {
|
||||
mb_ftfr = mp4_GetBit(pInfo);
|
||||
mb_fbfr = mp4_GetBit(pInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mp4_StatisticInc_(&pInfo->VisualObject.Statistic.nMB_NOTCODED);
|
||||
mcsel = 1;
|
||||
field_prediction = 0;
|
||||
}
|
||||
pMBinfo->validPred = 1;
|
||||
pMBinfo->not_coded = 0; // for B-VOP all MB have MVs
|
||||
pMBinfo->type = (uint8_t)(mcsel ? IPPVC_MBTYPE_INTRA : mb_type); // for OBMC MVs
|
||||
pMBinfo->field_info = (uint8_t)(field_prediction + (mb_ftfr << 1) + (mb_fbfr << 2));
|
||||
if (mb_type >= IPPVC_MBTYPE_INTRA) {
|
||||
if (mbInVideoPacket == 0)
|
||||
quantPred = quant;
|
||||
dcVLC = (quantPred < mp4_DC_vlc_Threshold[pInfo->VisualObject.VideoObject.VideoObjectPlane.intra_dc_vlc_thr]) ? 1 : 0;
|
||||
if (dct_type) {
|
||||
stepY = stepYc * 2;
|
||||
pYoff23 = stepYc;
|
||||
} else {
|
||||
stepY = stepYc;
|
||||
pYoff23 = 8 * stepYc;
|
||||
}
|
||||
stepF[0] = stepF[1] = stepF[2] = stepF[3] = stepY;
|
||||
pF[0] = pYc; pF[1] = pYc + 8; pF[2] = pYc + pYoff23; pF[3] = pYc + pYoff23 + 8; pF[4] = pCbc; pF[5] = pCrc;
|
||||
if (mp4_DecodeIntraMB(pInfo, colNum, (cbpy << 2) + cbpc, quant, dcVLC, ac_pred_flag, pF, stepF) != MP4_STATUS_OK)
|
||||
goto Err_3;
|
||||
mp4_Zero4MV(pMBinfo->mv);
|
||||
} else {
|
||||
mp4_UpdateIntraPredBuffInvalid(pInfo, colNum);
|
||||
dx = colNum * 16;
|
||||
dy = rowNum * 16;
|
||||
if (!mcsel) {
|
||||
if (!field_prediction) {
|
||||
if (mb_type != IPPVC_MBTYPE_INTER4V) {
|
||||
if (mp4_PredictDecode1MV(pInfo, pMBinfo, rowNum, colNum) != MP4_STATUS_OK)
|
||||
goto Err_3;
|
||||
pMBinfo->mv[1] = pMBinfo->mv[2] = pMBinfo->mv[3] = pMBinfo->mv[0];
|
||||
if (quarter_sample) {
|
||||
mp4_LimitMVQ(pMBinfo->mv, mvCur, &limitRectL, dx, dy, 16);
|
||||
mp4_ComputeChromaMVQ(mvCur, &mvCbCr);
|
||||
} else {
|
||||
mp4_LimitMV(pMBinfo->mv, mvCur, &limitRectL, dx, dy, 16);
|
||||
mp4_ComputeChromaMV(mvCur, &mvCbCr);
|
||||
}
|
||||
mvCur[1] = mvCur[2] = mvCur[3] = mvCur[0];
|
||||
} else {
|
||||
if (mp4_PredictDecode4MV(pInfo, pMBinfo, rowNum, colNum) != MP4_STATUS_OK)
|
||||
goto Err_3;
|
||||
if (quarter_sample) {
|
||||
mp4_Limit4MVQ(pMBinfo->mv, mvCur, &limitRectL, dx, dy, 8);
|
||||
mp4_ComputeChroma4MVQ(pMBinfo->mv, &mvCbCr);
|
||||
} else {
|
||||
mp4_Limit4MV(pMBinfo->mv, mvCur, &limitRectL, dx, dy, 8);
|
||||
mp4_ComputeChroma4MV(pMBinfo->mv, &mvCbCr);
|
||||
}
|
||||
mp4_LimitMV(&mvCbCr, &mvCbCr, &limitRectC, dx >> 1, dy >> 1, 8);
|
||||
}
|
||||
} else {
|
||||
IppMotionVector mvFT, mvFB;
|
||||
if (mp4_PredictDecodeFMV(pInfo, pMBinfo, rowNum, colNum, &mvFT, &mvFB) != MP4_STATUS_OK)
|
||||
goto Err_3;
|
||||
mvField[0] = mvFT; mvField[1] = mvFB;
|
||||
if (quarter_sample) {
|
||||
mp4_LimitFMVQ(&mvFT, &mvCur[0], &limitRectL, dx, dy, 16);
|
||||
mp4_LimitFMVQ(&mvFB, &mvCur[2], &limitRectL, dx, dy, 16);
|
||||
mvTmp[0].dx = (int16_t)mp4_Div2(mvCur[0].dx);
|
||||
mvTmp[0].dy = (int16_t)(mp4_Div2(mvCur[0].dy << 1) >> 1);
|
||||
mvTmp[2].dx = (int16_t)mp4_Div2(mvCur[2].dx);
|
||||
mvTmp[2].dy = (int16_t)(mp4_Div2(mvCur[2].dy << 1) >> 1);
|
||||
mp4_ComputeChromaMV(&mvTmp[0], &mvCbCrT);
|
||||
mp4_ComputeChromaMV(&mvTmp[2], &mvCbCrB);
|
||||
} else {
|
||||
mp4_LimitFMV(&mvFT, &mvCur[0], &limitRectL, dx, dy, 16);
|
||||
mp4_LimitFMV(&mvFB, &mvCur[2], &limitRectL, dx, dy, 16);
|
||||
mp4_ComputeChromaMV(&mvCur[0], &mvCbCrT);
|
||||
mp4_ComputeChromaMV(&mvCur[2], &mvCbCrB);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ippiCalcGlobalMV_MPEG4(dx, dy, pMBinfo->mv, pInfo->VisualObject.VideoObject.WarpSpec);
|
||||
pMBinfo->mv[1] = pMBinfo->mv[2] = pMBinfo->mv[3] = pMBinfo->mv[0];
|
||||
}
|
||||
}
|
||||
if (!obmc_disable) {
|
||||
// OBMC for previous MB
|
||||
if (colNum > 0)
|
||||
if (pMBinfo[-1].type < IPPVC_MBTYPE_INTRA && !(pMBinfo[-1].field_info & 1)) // previous is marked as INTRA if it was mcsel
|
||||
mp4_OBMC(pInfo, pMBinfo - 1, mvPrev, colNum - 1, rowNum, limitRectL, pYc - 16, stepYc, pYr - 16, stepYr, cbpyPrev, coeffMB, dct_typePrev);
|
||||
if (mb_type < IPPVC_MBTYPE_INTRA && !field_prediction && !mcsel) {
|
||||
cbpyPrev = cbpy;
|
||||
dct_typePrev = dct_type;
|
||||
mvPrev[0] = mvCur[0]; mvPrev[1] = mvCur[1]; mvPrev[2] = mvCur[2]; mvPrev[3] = mvCur[3];
|
||||
if (mp4_DecodeInterMB(pInfo, coeffMB, quant, (cbpy << 2) + cbpc, scan) != MP4_STATUS_OK)
|
||||
goto Err_3;
|
||||
mp4_MC_HP(cbpc & 2, pCbr, stepCbr, pCbc, stepCbc, coeffMB+256, &mvCbCr, rt);
|
||||
mp4_MC_HP(cbpc & 1, pCrr, stepCrr, pCrc, stepCrc, coeffMB+320, &mvCbCr, rt);
|
||||
// OBMC current MB if it is the last in the row
|
||||
if (colNum == mbPerRow - 1)
|
||||
mp4_OBMC(pInfo, pMBinfo, mvPrev, colNum, rowNum, limitRectL, pYc, stepYc, pYr, stepYr, cbpyPrev, coeffMB, dct_typePrev);
|
||||
}
|
||||
}
|
||||
if (mb_type < IPPVC_MBTYPE_INTRA && (obmc_disable || field_prediction || mcsel)) {
|
||||
pat = mb_not_coded ? 0 : ((cbpy << 2) + cbpc);
|
||||
if (pat)
|
||||
if (mp4_DecodeInterMB(pInfo, coeffMB, quant, pat, scan) != MP4_STATUS_OK)
|
||||
goto Err_3;
|
||||
if (!mcsel) {
|
||||
if (quarter_sample) {
|
||||
if (!field_prediction) {
|
||||
if (mb_type == IPPVC_MBTYPE_INTER4V) {
|
||||
mp4_Copy8x8QP_8u(pYr, stepYr, pYc, stepYc, &mvCur[0], rt);
|
||||
mp4_Copy8x8QP_8u(pYr+8, stepYr, pYc+8, stepYc, &mvCur[1], rt);
|
||||
mp4_Copy8x8QP_8u(pYr+stepYr*8, stepYr, pYc+stepYc*8, stepYc, &mvCur[2], rt);
|
||||
mp4_Copy8x8QP_8u(pYr+8+stepYr*8, stepYr, pYc+8+stepYc*8, stepYc, &mvCur[3], rt);
|
||||
} else {
|
||||
mp4_Copy16x16QP_8u(pYr, stepYr, pYc, stepYc, &mvCur[0], rt);
|
||||
}
|
||||
} else {
|
||||
mp4_Copy16x8QP_8u(pYr+stepYr*mb_ftfr, stepYr*2, pYc, stepYc*2, &mvCur[0], rt);
|
||||
mp4_Copy16x8QP_8u(pYr+stepYr*mb_fbfr, stepYr*2, pYc+stepYc, stepYc*2, &mvCur[2], rt);
|
||||
}
|
||||
} else {
|
||||
if (!field_prediction) {
|
||||
if (mb_type == IPPVC_MBTYPE_INTER4V) {
|
||||
mp4_Copy8x8HP_8u(pYr, stepYr, pYc, stepYc, &mvCur[0], rt);
|
||||
mp4_Copy8x8HP_8u(pYr+8, stepYr, pYc+8, stepYc, &mvCur[1], rt);
|
||||
mp4_Copy8x8HP_8u(pYr+stepYr*8, stepYr, pYc+stepYc*8, stepYc, &mvCur[2], rt);
|
||||
mp4_Copy8x8HP_8u(pYr+8+stepYr*8, stepYr, pYc+8+stepYc*8, stepYc, &mvCur[3], rt);
|
||||
} else {
|
||||
mp4_Copy16x16HP_8u(pYr, stepYr, pYc, stepYc, &mvCur[0], rt);
|
||||
}
|
||||
} else {
|
||||
mp4_Copy16x8HP_8u(pYr+stepYr*mb_ftfr, stepYr*2, pYc, stepYc*2, &mvCur[0], rt);
|
||||
mp4_Copy16x8HP_8u(pYr+stepYr*mb_fbfr, stepYr*2, pYc+stepYc, stepYc*2, &mvCur[2], rt);
|
||||
}
|
||||
}
|
||||
if (!dct_type) {
|
||||
mp4_AddResidual(cbpy & 8, pYc, stepYc, coeffMB);
|
||||
mp4_AddResidual(cbpy & 4, pYc+8, stepYc, coeffMB+64);
|
||||
mp4_AddResidual(cbpy & 2, pYc+stepYc*8, stepYc, coeffMB+128);
|
||||
mp4_AddResidual(cbpy & 1, pYc+stepYc*8+8, stepYc, coeffMB+192);
|
||||
} else {
|
||||
mp4_AddResidual(cbpy & 8, pYc, stepYc*2, coeffMB);
|
||||
mp4_AddResidual(cbpy & 4, pYc+8, stepYc*2, coeffMB+64);
|
||||
mp4_AddResidual(cbpy & 2, pYc+stepYc, stepYc*2, coeffMB+128);
|
||||
mp4_AddResidual(cbpy & 1, pYc+stepYc+8, stepYc*2, coeffMB+192);
|
||||
}
|
||||
if (!field_prediction) {
|
||||
mp4_MC_HP(cbpc & 2, pCbr, stepCbr, pCbc, stepCbc, coeffMB+256, &mvCbCr, rt);
|
||||
mp4_MC_HP(cbpc & 1, pCrr, stepCrr, pCrc, stepCrc, coeffMB+320, &mvCbCr, rt);
|
||||
} else {
|
||||
mp4_Copy8x4HP_8u(pCbr+(mb_ftfr ? stepCbr : 0), stepCbr*2, pCbc, stepCbc*2, &mvCbCrT, rt);
|
||||
mp4_Copy8x4HP_8u(pCrr+(mb_ftfr ? stepCrr : 0), stepCrr*2, pCrc, stepCrc*2, &mvCbCrT, rt);
|
||||
mp4_Copy8x4HP_8u(pCbr+(mb_fbfr ? stepCbr : 0), stepCbr*2, pCbc+stepCbc, stepCbc*2, &mvCbCrB, rt);
|
||||
mp4_Copy8x4HP_8u(pCrr+(mb_fbfr ? stepCrr : 0), stepCrr*2, pCrc+stepCrc, stepCrc*2, &mvCbCrB, rt);
|
||||
mp4_AddResidual(cbpc & 2, pCbc, stepCbc, coeffMB+256);
|
||||
mp4_AddResidual(cbpc & 1, pCrc, stepCrc, coeffMB+320);
|
||||
}
|
||||
} else {
|
||||
IppiRect mbRect;
|
||||
|
||||
mbRect.x = dx; mbRect.y = dy; mbRect.width = mbRect.height = 16;
|
||||
ippiWarpLuma_MPEG4_8u_C1R(pInfo->VisualObject.rFrame->pY, stepYr, pYc, stepYc, &mbRect, pInfo->VisualObject.VideoObject.WarpSpec);
|
||||
mbRect.x >>= 1; mbRect.y >>= 1; mbRect.width = mbRect.height = 8;
|
||||
ippiWarpChroma_MPEG4_8u_P2R(pInfo->VisualObject.rFrame->pCb, stepCbr, pInfo->VisualObject.rFrame->pCr, stepCrr, pCbc, stepCbc, pCrc, stepCrc, &mbRect, pInfo->VisualObject.VideoObject.WarpSpec);
|
||||
if (pat) {
|
||||
if (!dct_type) {
|
||||
mp4_AddResidual(cbpy & 8, pYc, stepYc, coeffMB);
|
||||
mp4_AddResidual(cbpy & 4, pYc+8, stepYc, coeffMB+64);
|
||||
mp4_AddResidual(cbpy & 2, pYc+stepYc*8, stepYc, coeffMB+128);
|
||||
mp4_AddResidual(cbpy & 1, pYc+stepYc*8+8, stepYc, coeffMB+192);
|
||||
} else {
|
||||
mp4_AddResidual(cbpy & 8, pYc, stepYc*2, coeffMB);
|
||||
mp4_AddResidual(cbpy & 4, pYc+8, stepYc*2, coeffMB+64);
|
||||
mp4_AddResidual(cbpy & 2, pYc+stepYc, stepYc*2, coeffMB+128);
|
||||
mp4_AddResidual(cbpy & 1, pYc+stepYc+8, stepYc*2, coeffMB+192);
|
||||
}
|
||||
mp4_AddResidual(cbpc & 2, pCbc, stepCbc, coeffMB+256);
|
||||
mp4_AddResidual(cbpc & 1, pCrc, stepCrc, coeffMB+320);
|
||||
}
|
||||
}
|
||||
}
|
||||
pMBinfo ++;
|
||||
mvField += 2;
|
||||
mbInVideoPacket ++;
|
||||
colNum ++;
|
||||
if (colNum == mbPerRow) {
|
||||
colNum = 0;
|
||||
rowNum ++;
|
||||
if (rowNum == mbPerCol) {
|
||||
// skip stuffing
|
||||
while (mp4_ShowBits(pInfo, 10) == 1)
|
||||
mp4_FlushBits(pInfo, 10);
|
||||
return sts;
|
||||
}
|
||||
pYc += (2 * MP4_NUM_EXT_MB + 1) * 16 + (stepYc << 4) - stepYc;
|
||||
pCbc += (2 * MP4_NUM_EXT_MB + 1) * 8 + (stepCbc << 3) - stepCbc;
|
||||
pCrc += (2 * MP4_NUM_EXT_MB + 1) * 8 + (stepCrc << 3) - stepCrc;
|
||||
pYr += (2 * MP4_NUM_EXT_MB + 1) * 16 + (stepYr << 4) - stepYr;
|
||||
pCbr += (2 * MP4_NUM_EXT_MB + 1) * 8 + (stepCbr << 3) - stepCbr;
|
||||
pCrr += (2 * MP4_NUM_EXT_MB + 1) * 8 + (stepCrr << 3) - stepCrr;
|
||||
} else {
|
||||
pYc += 16; pCrc += 8; pCbc += 8;
|
||||
pYr += 16; pCrr += 8; pCbr += 8;
|
||||
}
|
||||
}
|
||||
if (!pInfo->VisualObject.VideoObject.resync_marker_disable) {
|
||||
int32_t found;
|
||||
ErrRet_3:
|
||||
if (mp4_CheckDecodeVideoPacket(pInfo, &found) == MP4_STATUS_OK) {
|
||||
if (found) {
|
||||
mbInVideoPacket = pInfo->VisualObject.VideoObject.VideoObjectPlane.macroblock_num - mbCurr;
|
||||
quant = pInfo->VisualObject.VideoObject.VideoObjectPlane.quant_scale;
|
||||
mbCurr = pInfo->VisualObject.VideoObject.VideoObjectPlane.macroblock_num;
|
||||
mp4_CopyMacroBlocks(pInfo->VisualObject.rFrame, pInfo->VisualObject.cFrame, mbPerRow, rowNum, colNum, mbCurr - rowNum * mbPerRow - colNum);
|
||||
rowNum = mbCurr / mbPerRow;
|
||||
colNum = mbCurr % mbPerRow;
|
||||
pYc = pInfo->VisualObject.cFrame->pY + (rowNum * stepYc + colNum) * 16; pCbc = pInfo->VisualObject.cFrame->pCb + (rowNum * stepCbc + colNum) * 8; pCrc = pInfo->VisualObject.cFrame->pCr + (rowNum * stepCrc + colNum) * 8;
|
||||
pYr = pInfo->VisualObject.rFrame->pY + (rowNum * stepYr + colNum) * 16; pCbr = pInfo->VisualObject.rFrame->pCb + (rowNum * stepCbr + colNum) * 8; pCrr = pInfo->VisualObject.rFrame->pCr + (rowNum * stepCrr + colNum) * 8;
|
||||
pMBinfo = pInfo->VisualObject.VideoObject.MBinfo + mbCurr;
|
||||
mvField = pInfo->VisualObject.VideoObject.FieldMV + 2 * mbCurr;
|
||||
break;
|
||||
}
|
||||
} else
|
||||
goto Err_3;
|
||||
}
|
||||
}
|
||||
// mark MBs the previous videopacket as invalid for prediction
|
||||
for (i = 1; i <= IPP_MIN(mbInVideoPacket, mbPerRow + 1); i ++) {
|
||||
pMBinfo[-i].validPred = 0;
|
||||
}
|
||||
}
|
||||
Err_3:
|
||||
sts = MP4_STATUS_ERROR;
|
||||
if (pInfo->stopOnErr)
|
||||
return sts;
|
||||
if (pInfo->VisualObject.VideoObject.resync_marker_disable || !mp4_SeekResyncMarker(pInfo)) {
|
||||
mp4_CopyMacroBlocks(pInfo->VisualObject.rFrame, pInfo->VisualObject.cFrame, mbPerRow, rowNum, colNum, pInfo->VisualObject.VideoObject.MacroBlockPerVOP - rowNum * mbPerRow - colNum);
|
||||
return sts;
|
||||
}
|
||||
goto ErrRet_3;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
975
Src/mpeg4dec/mp4def.h
Normal file
975
Src/mpeg4dec/mp4def.h
Normal file
|
@ -0,0 +1,975 @@
|
|||
/* ///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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) 2001-2008 Intel Corporation. All Rights Reserved.
|
||||
//
|
||||
// Description: MPEG-4 header.
|
||||
//
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <bfc/platform/types.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "../tools/staticlib/ipp_px.h"
|
||||
#include "ippdefs.h"
|
||||
#include "ippcore.h"
|
||||
#include "ipps.h"
|
||||
#include "ippi.h"
|
||||
#include "ippvc.h"
|
||||
//#include "vm_debug.h"
|
||||
//#include "vm_thread.h"
|
||||
|
||||
#pragma warning(disable : 4710) // function not inlined
|
||||
#pragma warning(disable : 4514) // unreferenced inline function has been removed CL
|
||||
#pragma warning(disable : 4100) // unreferenced formal parameter CL
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//#define USE_INLINE_BITS_FUNC
|
||||
#define USE_NOTCODED_STATE
|
||||
|
||||
#if defined(__INTEL_COMPILER) || defined(_MSC_VER)
|
||||
#define __INLINE static __inline
|
||||
#elif defined( __GNUC__ )
|
||||
#define __INLINE static __inline__
|
||||
#else
|
||||
#define __INLINE static
|
||||
#endif
|
||||
|
||||
#if defined(__INTEL_COMPILER) && !defined(_WIN32_WCE)
|
||||
#define __ALIGN16(type, name, size) \
|
||||
__declspec (align(16)) type name[size]
|
||||
#else
|
||||
#if defined(_WIN64) || defined(WIN64) || defined(LINUX64)
|
||||
#define __ALIGN16(type, name, size) \
|
||||
uint8_t _a16_##name[(size)*sizeof(type)+15]; type *name = (type*)(((int64_t)(_a16_##name) + 15) & ~15)
|
||||
#else
|
||||
#define __ALIGN16(type, name, size) \
|
||||
uint8_t _a16_##name[(size)*sizeof(type)+15]; type *name = (type*)(((int32_t)(_a16_##name) + 15) & ~15)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define mp4_CLIP(x, min, max) if ((x) < (min)) (x) = (min); else if ((x) > (max)) (x) = (max)
|
||||
#define mp4_CLIPR(x, max) if ((x) > (max)) (x) = (max)
|
||||
#define mp4_SWAP(type, x, y) {mp4_Frame *t = (x); (x) = (y); (y) = t;}
|
||||
#define mp4_ABS(a) ((a) >= 0 ? (a) : -(a))
|
||||
|
||||
/* Timer Info */
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(WIN32) || defined(WIN64)
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
typedef struct _mp4_Timer {
|
||||
LARGE_INTEGER count;
|
||||
LARGE_INTEGER start;
|
||||
LARGE_INTEGER stop;
|
||||
int32_t calls;
|
||||
} mp4_Timer;
|
||||
|
||||
__INLINE void mp4_TimerStart(mp4_Timer *t)
|
||||
{
|
||||
QueryPerformanceCounter(&t->start);
|
||||
}
|
||||
|
||||
__INLINE void mp4_TimerStop(mp4_Timer *t)
|
||||
{
|
||||
QueryPerformanceCounter(&t->stop);
|
||||
t->count.QuadPart += t->stop.QuadPart - t->start.QuadPart;
|
||||
t->calls ++;
|
||||
}
|
||||
|
||||
#define TIMER_FREQ_TYPE LARGE_INTEGER
|
||||
|
||||
__INLINE void mp4_GetTimerFreq(TIMER_FREQ_TYPE *f)
|
||||
{
|
||||
QueryPerformanceFrequency(f);
|
||||
}
|
||||
|
||||
__INLINE double mp4_GetTimerSec(mp4_Timer *t, TIMER_FREQ_TYPE f)
|
||||
{
|
||||
return (double)t->count.QuadPart / (double)f.QuadPart;
|
||||
}
|
||||
|
||||
#else // LINUX
|
||||
|
||||
#include <time.h>
|
||||
|
||||
typedef struct _mp4_Timer {
|
||||
clock_t count;
|
||||
clock_t start;
|
||||
clock_t stop;
|
||||
int32_t calls;
|
||||
} mp4_Timer;
|
||||
|
||||
__INLINE void mp4_TimerStart(mp4_Timer *t)
|
||||
{
|
||||
t->start = clock();
|
||||
}
|
||||
|
||||
__INLINE void mp4_TimerStop(mp4_Timer *t)
|
||||
{
|
||||
t->stop = clock();
|
||||
t->count += t->stop - t->start;
|
||||
t->calls ++;
|
||||
}
|
||||
|
||||
#define TIMER_FREQ_TYPE int32_t
|
||||
|
||||
__INLINE void mp4_GetTimerFreq(TIMER_FREQ_TYPE *f)
|
||||
{
|
||||
*f = CLOCKS_PER_SEC;
|
||||
}
|
||||
|
||||
__INLINE double mp4_GetTimerSec(mp4_Timer *t, TIMER_FREQ_TYPE f)
|
||||
{
|
||||
return (double)t->count / (double)f;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* number of exterior MB */
|
||||
#define MP4_NUM_EXT_MB 1
|
||||
|
||||
/* Statistic Info */
|
||||
typedef struct _mp4_Statistic {
|
||||
// VideoObjectLayer Info
|
||||
int32_t nVOP;
|
||||
int32_t nVOP_I;
|
||||
int32_t nVOP_P;
|
||||
int32_t nVOP_B;
|
||||
int32_t nVOP_S;
|
||||
int32_t nMB;
|
||||
int32_t nMB_INTER;
|
||||
int32_t nMB_INTER_Q;
|
||||
int32_t nMB_INTRA;
|
||||
int32_t nMB_INTRA_Q;
|
||||
int32_t nMB_INTER4V;
|
||||
int32_t nMB_DIRECT;
|
||||
int32_t nMB_INTERPOLATE;
|
||||
int32_t nMB_BACKWARD;
|
||||
int32_t nMB_FORWARD;
|
||||
int32_t nMB_NOTCODED;
|
||||
int32_t nB_INTRA_DC;
|
||||
int32_t nB_INTRA_AC;
|
||||
int32_t nB_INTER_C;
|
||||
int32_t nB_INTER_NC;
|
||||
// app Timing Info
|
||||
mp4_Timer time_DecodeShow; // decode + draw + file reading
|
||||
mp4_Timer time_Decode; // decode + file reading
|
||||
mp4_Timer time_DecodeOnly; // decode only
|
||||
} mp4_Statistic;
|
||||
|
||||
__INLINE void mp4_StatisticInc(int32_t *s)
|
||||
{
|
||||
*s = (*s) + 1;
|
||||
}
|
||||
|
||||
// when using Full Statistic, FPS is less
|
||||
#ifdef MP4_FULL_STAT
|
||||
#define mp4_StatisticInc_(s) mp4_StatisticInc(s)
|
||||
#define mp4_TimerStart_(t) mp4_TimerStart(t)
|
||||
#define mp4_TimerStop_(t) mp4_TimerStop(t)
|
||||
#else
|
||||
#define mp4_StatisticInc_(s)
|
||||
#define mp4_TimerStart_(t)
|
||||
#define mp4_TimerStop_(t)
|
||||
#endif
|
||||
|
||||
/* status codes */
|
||||
typedef enum {
|
||||
MP4_STATUS_OK = 0, // no error
|
||||
MP4_STATUS_NO_MEM = -1, // out of memory
|
||||
MP4_STATUS_FILE_ERROR = -2, // file error
|
||||
MP4_STATUS_NOTSUPPORT = -3, // not supported mode
|
||||
MP4_STATUS_PARSE_ERROR = -4, // fail in parse MPEG-4 stream
|
||||
MP4_STATUS_ERROR = -5 // unknown/unspecified error
|
||||
} mp4_Status;
|
||||
|
||||
/* MPEG-4 start code values */
|
||||
// ISO/IEC 14496-2: table 6-3
|
||||
enum {
|
||||
MP4_VIDEO_OBJECT_MIN_SC = 0x00,
|
||||
MP4_VIDEO_OBJECT_MAX_SC = 0x1F,
|
||||
MP4_VIDEO_OBJECT_LAYER_MIN_SC = 0x20,
|
||||
MP4_VIDEO_OBJECT_LAYER_MAX_SC = 0x2F,
|
||||
MP4_FGS_BP_MIN_SC = 0x40,
|
||||
MP4_FGS_BP_MAX_SC = 0x5F,
|
||||
MP4_VISUAL_OBJECT_SEQUENCE_SC = 0xB0,
|
||||
MP4_VISUAL_OBJECT_SEQUENCE_EC = 0xB1,
|
||||
MP4_USER_DATA_SC = 0xB2,
|
||||
MP4_GROUP_OF_VOP_SC = 0xB3,
|
||||
MP4_VIDEO_SESSION_ERROR_SC = 0xB4,
|
||||
MP4_VISUAL_OBJECT_SC = 0xB5,
|
||||
MP4_VIDEO_OBJECT_PLANE_SC = 0xB6,
|
||||
MP4_SLICE_SC = 0xB7,
|
||||
MP4_EXTENSION_SC = 0xB8,
|
||||
MP4_FGS_VOP_SC = 0xB9,
|
||||
MP4_FBA_OBJECT_SC = 0xBA,
|
||||
MP4_FBA_OBJECT_PLANE_SC = 0xBB,
|
||||
MP4_MESH_OBJECT_SC = 0xBC,
|
||||
MP4_MESH_OBJECT_PLANE_SC = 0xBD,
|
||||
MP4_STILL_TEXTURE_OBJECT_SC = 0xBE,
|
||||
MP4_TEXTURE_SPATIAL_LAYER_SC = 0xBF,
|
||||
MP4_TEXTURE_SNR_LAYER_SC = 0xC0,
|
||||
MP4_TEXTURE_TILE_SC = 0xC1,
|
||||
MP4_TEXTURE_SHAPE_LAYER_SC = 0xC2,
|
||||
MP4_STUFFING_SC = 0xC3
|
||||
};
|
||||
|
||||
/* MPEG-4 code values */
|
||||
// ISO/IEC 14496-2:2004 table 6-6
|
||||
enum {
|
||||
MP4_VISUAL_OBJECT_TYPE_VIDEO = 1,
|
||||
MP4_VISUAL_OBJECT_TYPE_TEXTURE = 2,
|
||||
MP4_VISUAL_OBJECT_TYPE_MESH = 3,
|
||||
MP4_VISUAL_OBJECT_TYPE_FBA = 4,
|
||||
MP4_VISUAL_OBJECT_TYPE_3DMESH = 5
|
||||
};
|
||||
|
||||
// ISO/IEC 14496-2:2004 table 6-7
|
||||
enum {
|
||||
MP4_VIDEO_FORMAT_COMPONENT = 0,
|
||||
MP4_VIDEO_FORMAT_PAL = 1,
|
||||
MP4_VIDEO_FORMAT_NTSC = 2,
|
||||
MP4_VIDEO_FORMAT_SECAM = 3,
|
||||
MP4_VIDEO_FORMAT_MAC = 4,
|
||||
MP4_VIDEO_FORMAT_UNSPECIFIED = 5
|
||||
};
|
||||
|
||||
// ISO/IEC 14496-2:2004 table 6-8..10
|
||||
enum {
|
||||
MP4_VIDEO_COLORS_FORBIDDEN = 0,
|
||||
MP4_VIDEO_COLORS_ITU_R_BT_709 = 1,
|
||||
MP4_VIDEO_COLORS_UNSPECIFIED = 2,
|
||||
MP4_VIDEO_COLORS_RESERVED = 3,
|
||||
MP4_VIDEO_COLORS_ITU_R_BT_470_2_M = 4,
|
||||
MP4_VIDEO_COLORS_ITU_R_BT_470_2_BG = 5,
|
||||
MP4_VIDEO_COLORS_SMPTE_170M = 6,
|
||||
MP4_VIDEO_COLORS_SMPTE_240M = 7,
|
||||
MP4_VIDEO_COLORS_GENERIC_FILM = 8
|
||||
};
|
||||
|
||||
// ISO/IEC 14496-2:2004 table 6-11
|
||||
enum {
|
||||
MP4_VIDEO_OBJECT_TYPE_SIMPLE = 1,
|
||||
MP4_VIDEO_OBJECT_TYPE_SIMPLE_SCALABLE = 2,
|
||||
MP4_VIDEO_OBJECT_TYPE_CORE = 3,
|
||||
MP4_VIDEO_OBJECT_TYPE_MAIN = 4,
|
||||
MP4_VIDEO_OBJECT_TYPE_NBIT = 5,
|
||||
MP4_VIDEO_OBJECT_TYPE_2DTEXTURE = 6,
|
||||
MP4_VIDEO_OBJECT_TYPE_2DMESH = 7,
|
||||
MP4_VIDEO_OBJECT_TYPE_SIMPLE_FACE = 8,
|
||||
MP4_VIDEO_OBJECT_TYPE_STILL_SCALABLE_TEXTURE = 9,
|
||||
MP4_VIDEO_OBJECT_TYPE_ADVANCED_REAL_TIME_SIMPLE = 10,
|
||||
MP4_VIDEO_OBJECT_TYPE_CORE_SCALABLE = 11,
|
||||
MP4_VIDEO_OBJECT_TYPE_ADVANCED_CODING_EFFICIENCY = 12,
|
||||
MP4_VIDEO_OBJECT_TYPE_ADVANCED_SCALABLE_TEXTURE = 13,
|
||||
MP4_VIDEO_OBJECT_TYPE_SIMPLE_FBA = 14,
|
||||
MP4_VIDEO_OBJECT_TYPE_SIMPLE_STUDIO = 15,
|
||||
MP4_VIDEO_OBJECT_TYPE_CORE_STUDIO = 16,
|
||||
MP4_VIDEO_OBJECT_TYPE_ADVANCED_SIMPLE = 17,
|
||||
MP4_VIDEO_OBJECT_TYPE_FINE_GRANULARITY_SCALABLE = 18
|
||||
};
|
||||
|
||||
// ISO/IEC 14496-2:2004 table 6.17 (maximum defined video_object_layer_shape_extension)
|
||||
#define MP4_SHAPE_EXT_NUM 13
|
||||
// ISO/IEC 14496-2:2004 table 6-14
|
||||
enum {
|
||||
MP4_ASPECT_RATIO_FORBIDDEN = 0,
|
||||
MP4_ASPECT_RATIO_1_1 = 1,
|
||||
MP4_ASPECT_RATIO_12_11 = 2,
|
||||
MP4_ASPECT_RATIO_10_11 = 3,
|
||||
MP4_ASPECT_RATIO_16_11 = 4,
|
||||
MP4_ASPECT_RATIO_40_33 = 5,
|
||||
MP4_ASPECT_RATIO_EXTPAR = 15
|
||||
};
|
||||
|
||||
// ISO/IEC 14496-2:2004 table 6-15
|
||||
#define MP4_CHROMA_FORMAT_420 1
|
||||
// ISO/IEC 14496-2:2004 table 6-16
|
||||
enum {
|
||||
MP4_SHAPE_TYPE_RECTANGULAR = 0,
|
||||
MP4_SHAPE_TYPE_BINARY = 1,
|
||||
MP4_SHAPE_TYPE_BINARYONLY = 2,
|
||||
MP4_SHAPE_TYPE_GRAYSCALE = 3
|
||||
};
|
||||
|
||||
// ISO/IEC 14496-2:2004 table 6-19
|
||||
#define MP4_SPRITE_STATIC 1
|
||||
#define MP4_SPRITE_GMC 2
|
||||
// ISO/IEC 14496-2:2004 table 6-24
|
||||
enum {
|
||||
MP4_VOP_TYPE_I = 0,
|
||||
MP4_VOP_TYPE_P = 1,
|
||||
MP4_VOP_TYPE_B = 2,
|
||||
MP4_VOP_TYPE_S = 3
|
||||
};
|
||||
|
||||
// ISO/IEC 14496-2:2004 table 6-26
|
||||
enum {
|
||||
MP4_SPRITE_TRANSMIT_MODE_STOP = 0,
|
||||
MP4_SPRITE_TRANSMIT_MODE_PIECE = 1,
|
||||
MP4_SPRITE_TRANSMIT_MODE_UPDATE = 2,
|
||||
MP4_SPRITE_TRANSMIT_MODE_PAUSE = 3
|
||||
};
|
||||
|
||||
// ISO/IEC 14496-2:2004 table 7-3
|
||||
enum {
|
||||
MP4_BAB_TYPE_MVDSZ_NOUPDATE = 0,
|
||||
MP4_BAB_TYPE_MVDSNZ_NOUPDATE = 1,
|
||||
MP4_BAB_TYPE_TRANSPARENT = 2,
|
||||
MP4_BAB_TYPE_OPAQUE = 3,
|
||||
MP4_BAB_TYPE_INTRACAE = 4,
|
||||
MP4_BAB_TYPE_MVDSZ_INTERCAE = 5,
|
||||
MP4_BAB_TYPE_MVDSNZ_INTERCAE = 6
|
||||
};
|
||||
|
||||
#define MP4_DC_MARKER 0x6B001 // 110 1011 0000 0000 0001
|
||||
#define MP4_MV_MARKER 0x1F001 // 1 1111 0000 0000 0001
|
||||
|
||||
// ISO/IEC 14496-2:2004 table G.1
|
||||
enum {
|
||||
MP4_SIMPLE_PROFILE_LEVEL_1 = 0x01,
|
||||
MP4_SIMPLE_PROFILE_LEVEL_2 = 0x02,
|
||||
MP4_SIMPLE_PROFILE_LEVEL_3 = 0x03,
|
||||
MP4_SIMPLE_PROFILE_LEVEL_0 = 0x08,
|
||||
MP4_SIMPLE_SCALABLE_PROFILE_LEVEL_0 = 0x10,
|
||||
MP4_SIMPLE_SCALABLE_PROFILE_LEVEL_1 = 0x11,
|
||||
MP4_SIMPLE_SCALABLE_PROFILE_LEVEL_2 = 0x12,
|
||||
MP4_CORE_PROFILE_LEVEL_1 = 0x21,
|
||||
MP4_CORE_PROFILE_LEVEL_2 = 0x22,
|
||||
MP4_MAIN_PROFILE_LEVEL_2 = 0x32,
|
||||
MP4_MAIN_PROFILE_LEVEL_3 = 0x33,
|
||||
MP4_MAIN_PROFILE_LEVEL_4 = 0x34,
|
||||
MP4_NBIT_PROFILE_LEVEL_2 = 0x42,
|
||||
MP4_SCALABLE_TEXTURE_PROFILE_LEVEL_1 = 0x51,
|
||||
MP4_SIMPLE_FACE_ANIMATION_PROFILE_LEVEL_1 = 0x61,
|
||||
MP4_SIMPLE_FACE_ANIMATION_PROFILE_LEVEL_2 = 0x62,
|
||||
MP4_SIMPLE_FBA_PROFILE_LEVEL_1 = 0x63,
|
||||
MP4_SIMPLE_FBA_PROFILE_LEVEL_2 = 0x64,
|
||||
MP4_BASIC_ANIMATED_TEXTURE_PROFILE_LEVEL_1 = 0x71,
|
||||
MP4_BASIC_ANIMATED_TEXTURE_PROFILE_LEVEL_2 = 0x72,
|
||||
MP4_HYBRID_PROFILE_LEVEL_1 = 0x81,
|
||||
MP4_HYBRID_PROFILE_LEVEL_2 = 0x82,
|
||||
MP4_ADVANCED_REAL_TIME_SIMPLE_PROFILE_LEVEL_1 = 0x91,
|
||||
MP4_ADVANCED_REAL_TIME_SIMPLE_PROFILE_LEVEL_2 = 0x92,
|
||||
MP4_ADVANCED_REAL_TIME_SIMPLE_PROFILE_LEVEL_3 = 0x93,
|
||||
MP4_ADVANCED_REAL_TIME_SIMPLE_PROFILE_LEVEL_4 = 0x94,
|
||||
MP4_CORE_SCALABLE_PROFILE_LEVEL_1 = 0xA1,
|
||||
MP4_CORE_SCALABLE_PROFILE_LEVEL_2 = 0xA2,
|
||||
MP4_CORE_SCALABLE_PROFILE_LEVEL_3 = 0xA3,
|
||||
MP4_ADVANCED_CODING_EFFICIENCY_PROFILE_LEVEL_1 = 0xB1,
|
||||
MP4_ADVANCED_CODING_EFFICIENCY_PROFILE_LEVEL_2 = 0xB2,
|
||||
MP4_ADVANCED_CODING_EFFICIENCY_PROFILE_LEVEL_3 = 0xB3,
|
||||
MP4_ADVANCED_CODING_EFFICIENCY_PROFILE_LEVEL_4 = 0xB4,
|
||||
MP4_ADVANCED_CORE_PROFILE_LEVEL_1 = 0xC1,
|
||||
MP4_ADVANCED_CORE_PROFILE_LEVEL_2 = 0xC2,
|
||||
MP4_ADVANCED_SCALABLE_TEXTURE_PROFILE_LEVEL_1 = 0xD1,
|
||||
MP4_ADVANCED_SCALABLE_TEXTURE_PROFILE_LEVEL_2 = 0xD2,
|
||||
MP4_ADVANCED_SCALABLE_TEXTURE_PROFILE_LEVEL_3 = 0xD3,
|
||||
MP4_SIMPLE_STUDIO_PROFILE_LEVEL_1 = 0xE1,
|
||||
MP4_SIMPLE_STUDIO_PROFILE_LEVEL_2 = 0xE2,
|
||||
MP4_SIMPLE_STUDIO_PROFILE_LEVEL_3 = 0xE3,
|
||||
MP4_SIMPLE_STUDIO_PROFILE_LEVEL_4 = 0xE4,
|
||||
MP4_CORE_STUDIO_PROFILE_LEVEL_1 = 0xE5,
|
||||
MP4_CORE_STUDIO_PROFILE_LEVEL_2 = 0xE6,
|
||||
MP4_CORE_STUDIO_PROFILE_LEVEL_3 = 0xE7,
|
||||
MP4_CORE_STUDIO_PROFILE_LEVEL_4 = 0xE8,
|
||||
MP4_ADVANCED_SIMPLE_PROFILE_LEVEL_0 = 0xF0,
|
||||
MP4_ADVANCED_SIMPLE_PROFILE_LEVEL_1 = 0xF1,
|
||||
MP4_ADVANCED_SIMPLE_PROFILE_LEVEL_2 = 0xF2,
|
||||
MP4_ADVANCED_SIMPLE_PROFILE_LEVEL_3 = 0xF3,
|
||||
MP4_ADVANCED_SIMPLE_PROFILE_LEVEL_4 = 0xF4,
|
||||
MP4_ADVANCED_SIMPLE_PROFILE_LEVEL_5 = 0xF5,
|
||||
MP4_ADVANCED_SIMPLE_PROFILE_LEVEL_3B = 0xF7,
|
||||
MP4_FGS_PROFILE_LEVEL_0 = 0xF8,
|
||||
MP4_FGS_PROFILE_LEVEL_1 = 0xF9,
|
||||
MP4_FGS_PROFILE_LEVEL_2 = 0xFA,
|
||||
MP4_FGS_PROFILE_LEVEL_3 = 0xFB,
|
||||
MP4_FGS_PROFILE_LEVEL_4 = 0xFC,
|
||||
MP4_FGS_PROFILE_LEVEL_5 = 0xFD
|
||||
};
|
||||
|
||||
/* Frame Info */
|
||||
typedef struct _mp4_Frame {
|
||||
uint8_t* apY; // allocated with border
|
||||
uint8_t* apCb; // allocated with border
|
||||
uint8_t* apCr; // allocated with border
|
||||
int32_t stepY;
|
||||
int32_t stepCr;
|
||||
int32_t stepCb;
|
||||
uint8_t* pY; // real pointer
|
||||
uint8_t* pCb; // real pointer
|
||||
uint8_t* pCr; // real pointer
|
||||
int32_t type;
|
||||
int64_t time;
|
||||
int32_t mbPerRow; // info for realloc VOP with Shape
|
||||
int32_t mbPerCol;
|
||||
uint8_t* apB; // for binary mask
|
||||
uint8_t* pB;
|
||||
uint8_t* apA[3]; // for aux components
|
||||
uint8_t* pA[3];
|
||||
uint8_t* mid;
|
||||
uint64_t timestamp; // user-provided timestamp
|
||||
int QP;
|
||||
unsigned int reference_count;
|
||||
int outputted; // for debugging purposes
|
||||
int sprite; // 0 - frame, 1 - sprite
|
||||
struct _mp4_Frame *next; // benski> for linked list of display & free frames
|
||||
} mp4_Frame;
|
||||
|
||||
/* Block Info for Intra Prediction */
|
||||
typedef struct _mp4_IntraPredBlock {
|
||||
struct _mp4_IntraPredBlock *predA;
|
||||
struct _mp4_IntraPredBlock *predB;
|
||||
struct _mp4_IntraPredBlock *predC;
|
||||
int16_t dct_acA[8];
|
||||
int16_t dct_acC[8];
|
||||
int16_t dct_dc;
|
||||
} mp4_IntraPredBlock;
|
||||
|
||||
/* Buffer for Intra Prediction */
|
||||
typedef struct _mp4_IntraPredBuff {
|
||||
uint8_t *quant; // quant buffer;
|
||||
mp4_IntraPredBlock dcB[6]; // blocks for Left-Top DC only
|
||||
mp4_IntraPredBlock *block;
|
||||
} mp4_IntraPredBuff;
|
||||
|
||||
/* MacroBlock Info Data Partitioned mode */
|
||||
typedef struct _mp4_DataPartMacroBlock {
|
||||
int16_t dct_dc[6];
|
||||
uint8_t type;
|
||||
uint8_t not_coded;
|
||||
uint8_t mcsel;
|
||||
uint8_t ac_pred_flag;
|
||||
uint8_t pat;
|
||||
uint8_t quant;
|
||||
} mp4_DataPartMacroBlock;
|
||||
|
||||
/* MacroBlock Info for Motion */
|
||||
typedef struct _mp4_MacroBlock {
|
||||
IppMotionVector mv[4];
|
||||
uint8_t validPred; // for MV pred, OBMC
|
||||
uint8_t type; // for OBMC, BVOP
|
||||
uint8_t not_coded; // for OBMC, BVOP
|
||||
uint8_t field_info; // for Interlaced BVOP Direct mode
|
||||
} mp4_MacroBlock;
|
||||
|
||||
/* Group Of Video Object Plane Info */
|
||||
typedef struct _mp4_GroupOfVideoObjectPlane {
|
||||
int64_t time_code;
|
||||
int32_t closed_gov;
|
||||
int32_t broken_link;
|
||||
} mp4_GroupOfVideoObjectPlane;
|
||||
|
||||
/* Video Object Plane Info */
|
||||
typedef struct _mp4_VideoObjectPlane {
|
||||
int32_t coding_type;
|
||||
int32_t modulo_time_base;
|
||||
int32_t time_increment;
|
||||
int32_t coded;
|
||||
int32_t id; // verid != 1 (newpred)
|
||||
int32_t id_for_prediction_indication; // verid != 1 (newpred)
|
||||
int32_t id_for_prediction; // verid != 1 (newpred)
|
||||
int32_t rounding_type;
|
||||
int32_t reduced_resolution; // verid != 1
|
||||
int32_t vop_width;
|
||||
int32_t vop_height;
|
||||
int32_t vop_horizontal_mc_spatial_ref;
|
||||
int32_t vop_vertical_mc_spatial_ref;
|
||||
int32_t background_composition;
|
||||
int32_t change_conv_ratio_disable;
|
||||
int32_t vop_constant_alpha;
|
||||
int32_t vop_constant_alpha_value;
|
||||
int32_t intra_dc_vlc_thr;
|
||||
int32_t top_field_first;
|
||||
int32_t alternate_vertical_scan_flag;
|
||||
int32_t sprite_transmit_mode;
|
||||
int32_t warping_mv_code_du[4];
|
||||
int32_t warping_mv_code_dv[4];
|
||||
int32_t brightness_change_factor;
|
||||
int32_t quant;
|
||||
int32_t alpha_quant[3];
|
||||
int32_t fcode_forward;
|
||||
int32_t fcode_backward;
|
||||
int32_t shape_coding_type;
|
||||
int32_t load_backward_shape;
|
||||
int32_t ref_select_code;
|
||||
int32_t dx;
|
||||
int32_t dy;
|
||||
int32_t quant_scale;
|
||||
int32_t macroblock_num;
|
||||
int32_t vop_id;
|
||||
int32_t vop_id_for_prediction_indication;
|
||||
int32_t vop_id_for_prediction;
|
||||
} mp4_VideoObjectPlane;
|
||||
|
||||
/* mp4_ComplexityEstimation Info */
|
||||
typedef struct _mp4_ComplexityEstimation {
|
||||
int32_t estimation_method;
|
||||
int32_t shape_complexity_estimation_disable;
|
||||
int32_t opaque;
|
||||
int32_t transparent;
|
||||
int32_t intra_cae;
|
||||
int32_t inter_cae;
|
||||
int32_t no_update;
|
||||
int32_t upsampling;
|
||||
int32_t texture_complexity_estimation_set_1_disable;
|
||||
int32_t intra_blocks;
|
||||
int32_t inter_blocks;
|
||||
int32_t inter4v_blocks;
|
||||
int32_t not_coded_blocks;
|
||||
int32_t texture_complexity_estimation_set_2_disable;
|
||||
int32_t dct_coefs;
|
||||
int32_t dct_lines;
|
||||
int32_t vlc_symbols;
|
||||
int32_t vlc_bits;
|
||||
int32_t motion_compensation_complexity_disable;
|
||||
int32_t apm;
|
||||
int32_t npm;
|
||||
int32_t interpolate_mc_q;
|
||||
int32_t forw_back_mc_q;
|
||||
int32_t halfpel2;
|
||||
int32_t halfpel4;
|
||||
int32_t version2_complexity_estimation_disable; // verid != 1
|
||||
int32_t sadct; // verid != 1
|
||||
int32_t quarterpel; // verid != 1
|
||||
int32_t dcecs_opaque;
|
||||
int32_t dcecs_transparent;
|
||||
int32_t dcecs_intra_cae;
|
||||
int32_t dcecs_inter_cae;
|
||||
int32_t dcecs_no_update;
|
||||
int32_t dcecs_upsampling;
|
||||
int32_t dcecs_intra_blocks;
|
||||
int32_t dcecs_inter_blocks;
|
||||
int32_t dcecs_inter4v_blocks;
|
||||
int32_t dcecs_not_coded_blocks;
|
||||
int32_t dcecs_dct_coefs;
|
||||
int32_t dcecs_dct_lines;
|
||||
int32_t dcecs_vlc_symbols;
|
||||
int32_t dcecs_vlc_bits;
|
||||
int32_t dcecs_apm;
|
||||
int32_t dcecs_npm;
|
||||
int32_t dcecs_interpolate_mc_q;
|
||||
int32_t dcecs_forw_back_mc_q;
|
||||
int32_t dcecs_halfpel2;
|
||||
int32_t dcecs_halfpel4;
|
||||
int32_t dcecs_sadct; // verid != 1
|
||||
int32_t dcecs_quarterpel; // verid != 1
|
||||
} mp4_ComplexityEstimation;
|
||||
|
||||
/* mp4_Scalability Info */
|
||||
typedef struct _mp4_ScalabilityParameters {
|
||||
int32_t dummy;
|
||||
} mp4_ScalabilityParameters;
|
||||
|
||||
/* VOLControlParameters Info */
|
||||
typedef struct _mp4_VOLControlParameters {
|
||||
int32_t chroma_format;
|
||||
int32_t low_delay;
|
||||
int32_t vbv_parameters;
|
||||
int32_t bit_rate;
|
||||
int32_t vbv_buffer_size;
|
||||
int32_t vbv_occupancy;
|
||||
} mp4_VOLControlParameters;
|
||||
|
||||
/* Video Object Plane with int16_t header Info */
|
||||
typedef struct _mp4_VideoObjectPlaneH263 {
|
||||
int32_t temporal_reference;
|
||||
int32_t split_screen_indicator;
|
||||
int32_t document_camera_indicator;
|
||||
int32_t full_picture_freeze_release;
|
||||
int32_t source_format;
|
||||
int32_t picture_coding_type;
|
||||
int32_t vop_quant;
|
||||
int32_t gob_number;
|
||||
int32_t num_gobs_in_vop;
|
||||
int32_t num_macroblocks_in_gob;
|
||||
int32_t gob_header_empty;
|
||||
int32_t gob_frame_id;
|
||||
int32_t quant_scale;
|
||||
int32_t num_rows_in_gob;
|
||||
} mp4_VideoObjectPlaneH263;
|
||||
|
||||
/* Video Object Info */
|
||||
typedef struct _mp4_VideoObject {
|
||||
// iso part
|
||||
int32_t id;
|
||||
int32_t short_video_header;
|
||||
int32_t random_accessible_vol;
|
||||
int32_t type_indication;
|
||||
int32_t is_identifier;
|
||||
int32_t verid;
|
||||
int32_t priority;
|
||||
int32_t aspect_ratio_info;
|
||||
int32_t aspect_ratio_info_par_width;
|
||||
int32_t aspect_ratio_info_par_height;
|
||||
int32_t is_vol_control_parameters;
|
||||
mp4_VOLControlParameters VOLControlParameters;
|
||||
int32_t shape;
|
||||
int32_t shape_extension; // verid != 1
|
||||
int32_t vop_time_increment_resolution;
|
||||
int32_t vop_time_increment_resolution_bits;
|
||||
int32_t fixed_vop_rate;
|
||||
int32_t fixed_vop_time_increment;
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
int32_t interlaced;
|
||||
int32_t obmc_disable;
|
||||
int32_t sprite_enable; // if verid != 1 (2 bit GMC is added)
|
||||
int32_t sprite_width;
|
||||
int32_t sprite_height;
|
||||
int32_t sprite_left_coordinate;
|
||||
int32_t sprite_top_coordinate;
|
||||
int32_t sprite_warping_points;
|
||||
int32_t sprite_warping_accuracy;
|
||||
int32_t sprite_brightness_change;
|
||||
int32_t low_latency_sprite_enable;
|
||||
int32_t sadct_disable; // verid != 1
|
||||
int32_t not_8_bit;
|
||||
int32_t quant_precision;
|
||||
int32_t bits_per_pixel;
|
||||
int32_t no_gray_quant_update;
|
||||
int32_t composition_method;
|
||||
int32_t linear_composition;
|
||||
int32_t quant_type;
|
||||
int32_t load_intra_quant_mat;
|
||||
uint8_t intra_quant_mat[64];
|
||||
int32_t load_nonintra_quant_mat;
|
||||
uint8_t nonintra_quant_mat[64];
|
||||
int32_t load_intra_quant_mat_grayscale[3];
|
||||
uint8_t intra_quant_mat_grayscale[3][64];
|
||||
int32_t load_nonintra_quant_mat_grayscale[3];
|
||||
uint8_t nonintra_quant_mat_grayscale[3][64];
|
||||
int32_t quarter_sample; // verid != 1
|
||||
int32_t complexity_estimation_disable;
|
||||
mp4_ComplexityEstimation ComplexityEstimation;
|
||||
int32_t resync_marker_disable;
|
||||
int32_t data_partitioned;
|
||||
int32_t reversible_vlc;
|
||||
int32_t newpred_enable; // verid != 1
|
||||
int32_t requested_upstream_message_type;// verid != 1
|
||||
int32_t newpred_segment_type; // verid != 1
|
||||
int32_t reduced_resolution_vop_enable; // verid != 1
|
||||
int32_t scalability;
|
||||
mp4_ScalabilityParameters ScalabilityParameters;
|
||||
mp4_GroupOfVideoObjectPlane GroupOfVideoObjectPlane;
|
||||
mp4_VideoObjectPlane VideoObjectPlane;
|
||||
mp4_VideoObjectPlaneH263 VideoObjectPlaneH263;
|
||||
// app part
|
||||
int32_t VOPindex;
|
||||
int32_t MacroBlockPerRow;
|
||||
int32_t MacroBlockPerCol;
|
||||
int32_t MacroBlockPerVOP;
|
||||
int32_t mbns; // num bits for MacroBlockPerVOP
|
||||
mp4_MacroBlock* MBinfo;
|
||||
mp4_IntraPredBuff IntraPredBuff;
|
||||
mp4_DataPartMacroBlock* DataPartBuff;
|
||||
IppiQuantInvIntraSpec_MPEG4* QuantInvIntraSpec;
|
||||
IppiQuantInvInterSpec_MPEG4* QuantInvInterSpec;
|
||||
IppiWarpSpec_MPEG4* WarpSpec;
|
||||
// for B-VOP
|
||||
int32_t prevPlaneIsB;
|
||||
// for interlaced B-VOP direct mode
|
||||
int32_t Tframe;
|
||||
IppMotionVector* FieldMV;
|
||||
// for B-VOP direct mode
|
||||
int32_t TRB, TRD;
|
||||
// time increment of past and future VOP for B-VOP
|
||||
int64_t rTime, nTime;
|
||||
// VOP global time
|
||||
int64_t vop_sync_time, vop_sync_time_b;
|
||||
#ifdef USE_NOTCODED_STATE
|
||||
// not_coded MB state
|
||||
uint8_t* ncState;
|
||||
int32_t ncStateCleared;
|
||||
#endif
|
||||
} mp4_VideoObject;
|
||||
|
||||
/* StillTexture Object Info */
|
||||
typedef struct _mp4_StillTextureObject {
|
||||
int32_t dummy;
|
||||
} mp4_StillTextureObject;
|
||||
|
||||
/* Mesh Object Info */
|
||||
typedef struct _mp4_MeshObject {
|
||||
int32_t dummy;
|
||||
} mp4_MeshObject;
|
||||
|
||||
/* Face Object Info */
|
||||
typedef struct _mp4_FaceObject {
|
||||
int32_t dummy;
|
||||
} mp4_FaceObject;
|
||||
|
||||
/* video_signal_type Info */
|
||||
typedef struct _mp4_VideoSignalType {
|
||||
int32_t is_video_signal_type;
|
||||
int32_t video_format;
|
||||
int32_t video_range;
|
||||
int32_t is_colour_description;
|
||||
int32_t colour_primaries;
|
||||
int32_t transfer_characteristics;
|
||||
int32_t matrix_coefficients;
|
||||
} mp4_VideoSignalType;
|
||||
|
||||
/* Visual Object Info */
|
||||
typedef struct _mp4_VisualObject {
|
||||
int32_t is_identifier;
|
||||
int32_t verid;
|
||||
int32_t priority;
|
||||
int32_t type;
|
||||
mp4_VideoSignalType VideoSignalType;
|
||||
mp4_VideoObject VideoObject;
|
||||
mp4_StillTextureObject StillTextureObject;
|
||||
mp4_MeshObject MeshObject;
|
||||
mp4_FaceObject FaceObject;
|
||||
mp4_Frame *sFrame; // static sprite
|
||||
mp4_Frame *cFrame; // current TODO make pointer
|
||||
mp4_Frame *rFrame; // reference in past TODO make pointer
|
||||
mp4_Frame *nFrame; // reference in future TODO make pointer
|
||||
int32_t frameCount;
|
||||
int32_t frameInterval;
|
||||
int32_t frameScale;
|
||||
mp4_Statistic Statistic;
|
||||
mp4_Frame *frame_cache; // linked list of available frames (malloc cache)
|
||||
mp4_Frame *sprite_cache; // linked list of available sprite (malloc cache)
|
||||
mp4_Frame *display_frames; // linked list of display frames
|
||||
} mp4_VisualObject;
|
||||
|
||||
/* Full Info */
|
||||
typedef struct _mp4_Info {
|
||||
int32_t ftype; // 0 - raw, 1 - mp4, 2 - avi
|
||||
int32_t ftype_f; // ftype == 1 (0 - QuickTime(tm)), ftype == 2 (0 - DivX(tm) v. < 5, XVID, 1 - DivX(tm) v. >= 5)
|
||||
uint8_t* buffer; /* buffer header for saving MPEG-4 stream */
|
||||
size_t buflen; /* total buffer length */
|
||||
size_t len; /* valid data in buffer */
|
||||
uint8_t* bufptr; /* current frame, point to header or data */
|
||||
int32_t bitoff; /* mostly point to next frame header or PSC */
|
||||
int32_t profile_and_level_indication;
|
||||
mp4_VisualObject VisualObject;
|
||||
int32_t stopOnErr;
|
||||
int strictSyntaxCheck;
|
||||
int noPVOPs;
|
||||
int noBVOPs;
|
||||
} mp4_Info;
|
||||
|
||||
/* bitstream functions */
|
||||
extern uint8_t* mp4_FindStartCodePtr(mp4_Info* pInfo);
|
||||
extern uint8_t* mp4_FindStartCodeOrShortPtr(mp4_Info* pInfo);
|
||||
extern int32_t mp4_SeekStartCodePtr(mp4_Info* pInfo);
|
||||
extern int32_t mp4_SeekStartCodeOrShortPtr(mp4_Info* pInfo);
|
||||
extern int32_t mp4_SeekStartCodeValue(mp4_Info* pInfo, uint8_t code);
|
||||
extern uint8_t* mp4_FindShortVideoStartMarkerPtr(mp4_Info* pInfo);
|
||||
extern int32_t mp4_SeekShortVideoStartMarker(mp4_Info* pInfo);
|
||||
extern int32_t mp4_SeekGOBMarker(mp4_Info* pInfo);
|
||||
extern int32_t mp4_SeekResyncMarker(mp4_Info* pInfo);
|
||||
extern int32_t mp4_FindResyncMarker(mp4_Info* pInfo);
|
||||
extern int mp4_IsStartCodeOrShort(mp4_Info* pInfo);
|
||||
extern int mp4_IsStartCodeValue(mp4_Info* pInfo, int min, int max);
|
||||
extern int mp4_IsShortCode(mp4_Info* pInfo);
|
||||
|
||||
/* tables */
|
||||
typedef struct _mp4_VLC1 {
|
||||
uint8_t code;
|
||||
uint8_t len;
|
||||
} mp4_VLC1;
|
||||
|
||||
extern const uint8_t mp4_DefaultIntraQuantMatrix[];
|
||||
extern const uint8_t mp4_DefaultNonIntraQuantMatrix[];
|
||||
extern const uint8_t mp4_ClassicalZigzag[];
|
||||
extern const uint8_t mp4_DCScalerLuma[];
|
||||
extern const uint8_t mp4_DCScalerChroma[];
|
||||
extern const uint8_t mp4_cCbCrMvRound16[];
|
||||
extern const uint8_t mp4_cCbCrMvRound12[];
|
||||
extern const uint8_t mp4_cCbCrMvRound8[];
|
||||
extern const uint8_t mp4_cCbCrMvRound4[];
|
||||
extern const Ipp8s mp4_dquant[];
|
||||
extern const mp4_VLC1 mp4_cbpy1[];
|
||||
extern const mp4_VLC1 mp4_cbpy2[];
|
||||
extern const mp4_VLC1 mp4_cbpy3[];
|
||||
extern const mp4_VLC1 mp4_cbpy4[];
|
||||
extern const mp4_VLC1* mp4_cbpy_t[];
|
||||
extern const uint8_t mp4_cbpy_b[];
|
||||
extern const int32_t mp4_DC_vlc_Threshold[];
|
||||
extern const uint8_t mp4_PVOPmb_type[];
|
||||
extern const uint8_t mp4_PVOPmb_cbpc[];
|
||||
extern const uint8_t mp4_PVOPmb_bits[];
|
||||
extern const mp4_VLC1 mp4_BVOPmb_type[];
|
||||
extern const mp4_VLC1 mp4_MVD_B12_1[];
|
||||
extern const mp4_VLC1 mp4_MVD_B12_2[];
|
||||
extern const int32_t mp4_H263_width[];
|
||||
extern const int32_t mp4_H263_height[];
|
||||
extern const int32_t mp4_H263_mbgob[];
|
||||
extern const int32_t mp4_H263_gobvop[];
|
||||
extern const int32_t mp4_H263_rowgob[];
|
||||
extern const uint8_t mp4_aux_comp_count[];
|
||||
extern const uint8_t mp4_aux_comp_is_alpha[];
|
||||
extern const uint8_t mp4_BABtypeIntra[][3];
|
||||
extern const int32_t mp4_DivIntraDivisor[];
|
||||
|
||||
// project functions
|
||||
extern void mp4_Error(const char *str);
|
||||
//#define mp4_Error(str) puts(str)
|
||||
extern mp4_Status mp4_InitVOL(mp4_Info *pInfo);
|
||||
extern mp4_Status mp4_FreeVOL(mp4_Info *pInfo);
|
||||
extern void mp4_ResetVOL(mp4_Info *pInfo);
|
||||
//extern void mp4_ShowFrame(mp4_Frame *frame);
|
||||
#define mp4_ShowFrame(frame)
|
||||
extern mp4_Status mp4_Parse_VisualObjectSequence(mp4_Info* pInfo);
|
||||
extern mp4_Status mp4_Parse_VisualObject(mp4_Info* pInfo);
|
||||
extern mp4_Status mp4_Parse_VideoObject(mp4_Info* pInfo);
|
||||
extern mp4_Status mp4_Parse_GroupOfVideoObjectPlane(mp4_Info* pInfo);
|
||||
extern mp4_Status mp4_Parse_VideoObjectPlane(mp4_Info* pInfo);
|
||||
extern mp4_Status mp4_DecodeVideoObjectPlane(mp4_Info* pInfo);
|
||||
|
||||
#ifndef USE_INLINE_BITS_FUNC
|
||||
extern uint32_t mp4_ShowBits(mp4_Info* pInfo, int32_t n);
|
||||
extern uint32_t mp4_ShowBit(mp4_Info* pInfo);
|
||||
extern uint32_t mp4_ShowBits9(mp4_Info* pInfo, int32_t n);
|
||||
extern void mp4_FlushBits(mp4_Info* pInfo, int32_t n);
|
||||
extern uint32_t mp4_GetBits(mp4_Info* pInfo, int32_t n);
|
||||
//extern uint32_t mp4_GetBit(mp4_Info* pInfo);
|
||||
extern uint32_t mp4_GetBits9(mp4_Info* pInfo, int32_t n);
|
||||
extern void mp4_AlignBits(mp4_Info* pInfo);
|
||||
extern void mp4_AlignBits7F(mp4_Info* pInfo);
|
||||
extern uint32_t mp4_ShowBitsAlign(mp4_Info* pInfo, int32_t n);
|
||||
extern uint32_t mp4_ShowBitsAlign7F(mp4_Info* pInfo, int32_t n);
|
||||
#else
|
||||
__INLINE uint32_t mp4_ShowBits(mp4_Info* pInfo, int32_t n)
|
||||
{
|
||||
uint8_t* ptr = pInfo->bufptr;
|
||||
uint32_t tmp = (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | (ptr[3]);
|
||||
tmp <<= pInfo->bitoff;
|
||||
tmp >>= 32 - n;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
__INLINE uint32_t mp4_ShowBit(mp4_Info* pInfo)
|
||||
{
|
||||
uint32_t tmp = pInfo->bufptr[0];
|
||||
tmp >>= 7 - pInfo->bitoff;
|
||||
return (tmp & 1);
|
||||
}
|
||||
|
||||
__INLINE uint32_t mp4_ShowBits9(mp4_Info* pInfo, int32_t n)
|
||||
{
|
||||
uint8_t* ptr = pInfo->bufptr;
|
||||
uint32_t tmp = (ptr[0] << 8) | ptr[1];
|
||||
tmp <<= (pInfo->bitoff + 16);
|
||||
tmp >>= 32 - n;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
__INLINE void mp4_FlushBits(mp4_Info* pInfo, int32_t n)
|
||||
{
|
||||
n = n + pInfo->bitoff;
|
||||
pInfo->bufptr += n >> 3;
|
||||
pInfo->bitoff = n & 7;
|
||||
}
|
||||
|
||||
__INLINE uint32_t mp4_GetBits(mp4_Info* pInfo, int32_t n)
|
||||
{
|
||||
uint8_t* ptr = pInfo->bufptr;
|
||||
uint32_t tmp = (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | (ptr[3]);
|
||||
tmp <<= pInfo->bitoff;
|
||||
tmp >>= 32 - n;
|
||||
n = n + pInfo->bitoff;
|
||||
pInfo->bufptr += n >> 3;
|
||||
pInfo->bitoff = n & 7;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
__INLINE uint32_t mp4_GetBits9(mp4_Info* pInfo, int32_t n)
|
||||
{
|
||||
uint8_t* ptr = pInfo->bufptr;
|
||||
uint32_t tmp = (ptr[0] << 8) | ptr[1];
|
||||
tmp <<= (pInfo->bitoff + 16);
|
||||
tmp >>= 32 - n;
|
||||
n = n + pInfo->bitoff;
|
||||
pInfo->bufptr += n >> 3;
|
||||
pInfo->bitoff = n & 7;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
__INLINE void mp4_AlignBits(mp4_Info* pInfo)
|
||||
{
|
||||
if (pInfo->bitoff > 0) {
|
||||
pInfo->bitoff = 0;
|
||||
(pInfo->bufptr)++;
|
||||
}
|
||||
}
|
||||
|
||||
__INLINE void mp4_AlignBits7F(mp4_Info* pInfo)
|
||||
{
|
||||
if (pInfo->bitoff > 0) {
|
||||
pInfo->bitoff = 0;
|
||||
(pInfo->bufptr)++;
|
||||
} else {
|
||||
if (*pInfo->bufptr == 0x7F)
|
||||
(pInfo->bufptr)++;
|
||||
}
|
||||
}
|
||||
|
||||
__INLINE uint32_t mp4_ShowBitsAlign(mp4_Info* pInfo, int32_t n)
|
||||
{
|
||||
uint8_t* ptr = pInfo->bitoff ? (pInfo->bufptr + 1) : pInfo->bufptr;
|
||||
uint32_t tmp = (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | (ptr[3]);
|
||||
tmp >>= 32 - n;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
__INLINE uint32_t mp4_ShowBitsAlign7F(mp4_Info* pInfo, int32_t n)
|
||||
{
|
||||
uint8_t* ptr = pInfo->bitoff ? (pInfo->bufptr + 1) : pInfo->bufptr;
|
||||
uint32_t tmp;
|
||||
if (!pInfo->bitoff) {
|
||||
if (*ptr == 0x7F)
|
||||
ptr ++;
|
||||
}
|
||||
tmp = (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | (ptr[3]);
|
||||
tmp >>= 32 - n;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
#endif // USE_INLINE_BITS_FUNC
|
||||
|
||||
__INLINE uint32_t mp4_GetBit(mp4_Info* pInfo)
|
||||
{
|
||||
uint32_t tmp = pInfo->bufptr[0];
|
||||
if (pInfo->bitoff != 7) {
|
||||
tmp >>= 7 - pInfo->bitoff;
|
||||
pInfo->bitoff ++;
|
||||
} else {
|
||||
pInfo->bitoff = 0;
|
||||
pInfo->bufptr ++;
|
||||
}
|
||||
return (tmp & 1);
|
||||
}
|
||||
|
||||
__INLINE int32_t mp4_GetMarkerBit(mp4_Info* pInfo) {
|
||||
if (!mp4_GetBit(pInfo)) {
|
||||
mp4_Error("Error: wrong marker bit");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
// added by benski
|
||||
extern mp4_Frame *CreateFrame(mp4_VisualObject *object);
|
||||
extern void ReleaseFrame(mp4_VisualObject *object, mp4_Frame *frame);
|
||||
extern mp4_Frame *GetDisplayFrame(mp4_VisualObject *object);
|
||||
extern void DisplayFrame(mp4_VisualObject *object, mp4_Frame *frame);
|
||||
extern void FreeCache(mp4_VisualObject *object);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
1109
Src/mpeg4dec/mp4parse.c
Normal file
1109
Src/mpeg4dec/mp4parse.c
Normal file
File diff suppressed because it is too large
Load diff
326
Src/mpeg4dec/mp4stream.c
Normal file
326
Src/mpeg4dec/mp4stream.c
Normal file
|
@ -0,0 +1,326 @@
|
|||
/* ///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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) 2001-2008 Intel Corporation. All Rights Reserved.
|
||||
//
|
||||
// Description: Decodes MPEG-4 bitstream.
|
||||
//
|
||||
*/
|
||||
|
||||
|
||||
#include "mp4def.h"
|
||||
|
||||
#ifndef USE_INLINE_BITS_FUNC
|
||||
|
||||
uint32_t mp4_ShowBits(mp4_Info* pInfo, int32_t n)
|
||||
{
|
||||
uint8_t* ptr = pInfo->bufptr;
|
||||
uint32_t tmp = (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | (ptr[3]);
|
||||
tmp <<= pInfo->bitoff;
|
||||
tmp >>= 32 - n;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
uint32_t mp4_ShowBit(mp4_Info* pInfo)
|
||||
{
|
||||
uint32_t tmp = pInfo->bufptr[0];
|
||||
tmp >>= 7 - pInfo->bitoff;
|
||||
return (tmp & 1);
|
||||
}
|
||||
|
||||
uint32_t mp4_ShowBits9(mp4_Info* pInfo, int32_t n)
|
||||
{
|
||||
uint8_t* ptr = pInfo->bufptr;
|
||||
uint32_t tmp = (ptr[0] << 8) | ptr[1];
|
||||
tmp <<= (pInfo->bitoff + 16);
|
||||
tmp >>= 32 - n;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void mp4_FlushBits(mp4_Info* pInfo, int32_t n)
|
||||
{
|
||||
n = n + pInfo->bitoff;
|
||||
pInfo->bufptr += n >> 3;
|
||||
pInfo->bitoff = n & 7;
|
||||
}
|
||||
|
||||
uint32_t mp4_GetBits(mp4_Info* pInfo, int32_t n)
|
||||
{
|
||||
uint8_t* ptr = pInfo->bufptr;
|
||||
uint32_t tmp = (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | (ptr[3]);
|
||||
tmp <<= pInfo->bitoff;
|
||||
tmp >>= 32 - n;
|
||||
n = n + pInfo->bitoff;
|
||||
pInfo->bufptr += n >> 3;
|
||||
pInfo->bitoff = n & 7;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
uint32_t mp4_GetBits9(mp4_Info* pInfo, int32_t n)
|
||||
{
|
||||
uint8_t* ptr = pInfo->bufptr;
|
||||
uint32_t tmp = (ptr[0] << 8) | ptr[1];
|
||||
tmp <<= (pInfo->bitoff + 16);
|
||||
tmp >>= 32 - n;
|
||||
n = n + pInfo->bitoff;
|
||||
pInfo->bufptr += n >> 3;
|
||||
pInfo->bitoff = n & 7;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
void mp4_AlignBits(mp4_Info* pInfo)
|
||||
{
|
||||
if (pInfo->bitoff > 0) {
|
||||
pInfo->bitoff = 0;
|
||||
(pInfo->bufptr)++;
|
||||
}
|
||||
}
|
||||
|
||||
void mp4_AlignBits7F(mp4_Info* pInfo)
|
||||
{
|
||||
if (pInfo->bitoff > 0) {
|
||||
pInfo->bitoff = 0;
|
||||
(pInfo->bufptr)++;
|
||||
} else {
|
||||
if (*pInfo->bufptr == 0x7F)
|
||||
(pInfo->bufptr)++;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t mp4_ShowBitsAlign(mp4_Info* pInfo, int32_t n)
|
||||
{
|
||||
uint8_t* ptr = pInfo->bitoff ? (pInfo->bufptr + 1) : pInfo->bufptr;
|
||||
uint32_t tmp = (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | (ptr[3]);
|
||||
tmp >>= 32 - n;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
uint32_t mp4_ShowBitsAlign7F(mp4_Info* pInfo, int32_t n)
|
||||
{
|
||||
uint8_t* ptr = pInfo->bitoff ? (pInfo->bufptr + 1) : pInfo->bufptr;
|
||||
uint32_t tmp;
|
||||
if (!pInfo->bitoff) {
|
||||
if (*ptr == 0x7F)
|
||||
ptr ++;
|
||||
}
|
||||
tmp = (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | (ptr[3]);
|
||||
tmp >>= 32 - n;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
uint8_t* mp4_FindStartCodePtr(mp4_Info* pInfo)
|
||||
{
|
||||
int32_t i, len = pInfo->buflen - (pInfo->bufptr - pInfo->buffer);
|
||||
uint8_t* ptr = pInfo->bufptr;
|
||||
for (i = 0; i < len - 3; i++) {
|
||||
if (ptr[i] == 0 && ptr[i + 1] == 0 && ptr[i + 2] == 1) {
|
||||
return ptr + i + 3;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint8_t* mp4_FindStartCodeOrShortPtr(mp4_Info* pInfo)
|
||||
{
|
||||
int32_t i, len = pInfo->buflen - (pInfo->bufptr - pInfo->buffer);
|
||||
uint8_t* ptr = pInfo->bufptr;
|
||||
for (i = 0; i < len - 3; i++) {
|
||||
if (ptr[i] == 0 && ptr[i + 1] == 0 && ptr[i + 2] == 1) {
|
||||
return ptr + i + 3;
|
||||
}
|
||||
// short_video_header
|
||||
if (ptr[i] == 0 && ptr[i + 1] == 0 && (ptr[i + 2] & 0xFC) == 0x80) {
|
||||
return ptr + i;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int32_t mp4_SeekStartCodePtr(mp4_Info* pInfo)
|
||||
{
|
||||
uint8_t* ptr;
|
||||
|
||||
if (pInfo->bitoff) {
|
||||
pInfo->bufptr ++;
|
||||
pInfo->bitoff = 0;
|
||||
}
|
||||
ptr = mp4_FindStartCodePtr(pInfo);
|
||||
if (ptr) {
|
||||
pInfo->bufptr = ptr;
|
||||
return 1;
|
||||
} else {
|
||||
pInfo->bufptr = pInfo->buffer + (pInfo->buflen > 3 ? pInfo->buflen - 3 : 0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t mp4_SeekStartCodeOrShortPtr(mp4_Info* pInfo)
|
||||
{
|
||||
uint8_t* ptr;
|
||||
|
||||
if (pInfo->bitoff) {
|
||||
pInfo->bufptr ++;
|
||||
pInfo->bitoff = 0;
|
||||
}
|
||||
ptr = mp4_FindStartCodeOrShortPtr(pInfo);
|
||||
if (ptr) {
|
||||
pInfo->bufptr = ptr;
|
||||
return 1;
|
||||
} else {
|
||||
pInfo->bufptr = pInfo->buffer + (pInfo->buflen > 3 ? pInfo->buflen - 3 : 0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t mp4_SeekStartCodeValue(mp4_Info* pInfo, uint8_t code)
|
||||
{
|
||||
while (mp4_SeekStartCodePtr(pInfo)) {
|
||||
if (*(pInfo->bufptr) == code) {
|
||||
(pInfo->bufptr) ++;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t* mp4_FindShortVideoStartMarkerPtr(mp4_Info* pInfo)
|
||||
{
|
||||
int32_t i, len = pInfo->buflen - (pInfo->bufptr - pInfo->buffer);
|
||||
uint8_t* ptr = pInfo->bufptr;
|
||||
for (i = 0; i < len - 3; i++) {
|
||||
if (ptr[i] == 0 && ptr[i + 1] == 0 && (ptr[i + 2] & (~3)) == 0x80) {
|
||||
return ptr + i + 2;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int32_t mp4_SeekShortVideoStartMarker(mp4_Info* pInfo)
|
||||
{
|
||||
uint8_t* ptr;
|
||||
|
||||
if (pInfo->bitoff) {
|
||||
pInfo->bufptr ++;
|
||||
pInfo->bitoff = 0;
|
||||
}
|
||||
ptr = mp4_FindShortVideoStartMarkerPtr(pInfo);
|
||||
if (ptr) {
|
||||
pInfo->bufptr = ptr;
|
||||
return 1;
|
||||
} else {
|
||||
pInfo->bufptr = pInfo->buffer + (pInfo->buflen > 3 ? pInfo->buflen - 3 : 0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//changed pInfo->len on pInfo->buflen!!!
|
||||
int32_t mp4_SeekGOBMarker(mp4_Info* pInfo)
|
||||
{
|
||||
for (; pInfo->bufptr < pInfo->buffer + pInfo->buflen - 2; pInfo->bufptr ++) {
|
||||
if (pInfo->bufptr[0] == 0) {
|
||||
pInfo->bitoff = 0;
|
||||
if (pInfo->bufptr[0] == 0 && pInfo->bufptr[1] == 0 && (pInfo->bufptr[2] & (~3)) == 0x80)
|
||||
return 0;
|
||||
pInfo->bufptr --;
|
||||
for (pInfo->bitoff = 1; pInfo->bitoff <= 7; pInfo->bitoff ++) {
|
||||
if (mp4_ShowBits(pInfo, 17) == 1)
|
||||
return 1;
|
||||
}
|
||||
pInfo->bufptr ++;
|
||||
for (pInfo->bitoff = 0; pInfo->bitoff <= 7; pInfo->bitoff ++) {
|
||||
if (mp4_ShowBits(pInfo, 17) == 1)
|
||||
return 1;
|
||||
}
|
||||
pInfo->bufptr ++;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t mp4_SeekResyncMarker(mp4_Info* pInfo)
|
||||
{
|
||||
int32_t rml;
|
||||
|
||||
if (pInfo->VisualObject.VideoObject.VideoObjectPlane.coding_type == MP4_VOP_TYPE_I)
|
||||
rml = 17;
|
||||
else if (pInfo->VisualObject.VideoObject.VideoObjectPlane.coding_type == MP4_VOP_TYPE_B)
|
||||
rml = 16 + IPP_MAX(pInfo->VisualObject.VideoObject.VideoObjectPlane.fcode_forward, pInfo->VisualObject.VideoObject.VideoObjectPlane.fcode_backward);
|
||||
else
|
||||
rml = 16 + pInfo->VisualObject.VideoObject.VideoObjectPlane.fcode_forward;
|
||||
pInfo->bitoff = 0;
|
||||
for (; pInfo->bufptr < pInfo->buffer + pInfo->buflen - 2; pInfo->bufptr ++) {
|
||||
if (pInfo->bufptr[0] == 0) {
|
||||
if (pInfo->bufptr[0] == 0 && pInfo->bufptr[1] == 0 && pInfo->bufptr[2] == 1)
|
||||
return 0;
|
||||
if (mp4_ShowBits(pInfo, rml) == 1) {
|
||||
// check stuffing bits
|
||||
pInfo->bufptr --;
|
||||
pInfo->bitoff = 7;
|
||||
while (pInfo->bitoff > 0 && mp4_ShowBit(pInfo))
|
||||
pInfo->bitoff --;
|
||||
if (pInfo->bitoff == 0 && mp4_ShowBit(pInfo)) {
|
||||
// stuffing bits are invalid
|
||||
pInfo->bufptr[0] = 0x7f;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
pInfo->bufptr += 2;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t mp4_FindResyncMarker(mp4_Info* pInfo)
|
||||
{
|
||||
int32_t rml;
|
||||
|
||||
if (pInfo->VisualObject.VideoObject.VideoObjectPlane.coding_type == MP4_VOP_TYPE_I)
|
||||
rml = 17;
|
||||
else if (pInfo->VisualObject.VideoObject.VideoObjectPlane.coding_type == MP4_VOP_TYPE_B)
|
||||
rml = 16 + IPP_MAX(pInfo->VisualObject.VideoObject.VideoObjectPlane.fcode_forward, pInfo->VisualObject.VideoObject.VideoObjectPlane.fcode_backward);
|
||||
else
|
||||
rml = 16 + pInfo->VisualObject.VideoObject.VideoObjectPlane.fcode_forward;
|
||||
pInfo->bitoff = 0;
|
||||
for (; pInfo->bufptr < pInfo->buffer + pInfo->buflen - 2; pInfo->bufptr ++) {
|
||||
if (pInfo->bufptr[0] == 0)
|
||||
{
|
||||
if (pInfo->bufptr[0] == 0 && pInfo->bufptr[1] == 0 && pInfo->bufptr[2] == 1)
|
||||
return 0;
|
||||
if (mp4_ShowBits(pInfo, rml) == 1)
|
||||
{
|
||||
return rml;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mp4_IsStartCodeOrShort(mp4_Info* pInfo)
|
||||
{
|
||||
if (pInfo->bufptr[0] == 0 && pInfo->bufptr[1] == 0 && (pInfo->bufptr[2] == 1 || ((pInfo->bufptr[2] & 0xFC) == 0x80)))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int mp4_IsStartCodeValue(mp4_Info* pInfo, int min, int max)
|
||||
{
|
||||
if (pInfo->bufptr[0-3] == 0 && pInfo->bufptr[1-3] == 0 && pInfo->bufptr[2-3] == 1)
|
||||
if (pInfo->bufptr[3-3] >= min && pInfo->bufptr[3-3] <= max)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int mp4_IsShortCode(mp4_Info* pInfo)
|
||||
{
|
||||
if (pInfo->bufptr[0] == 0 && pInfo->bufptr[1] == 0 && ((pInfo->bufptr[2] & 0xFC) == 0x80))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
153
Src/mpeg4dec/mp4tbl.c
Normal file
153
Src/mpeg4dec/mp4tbl.c
Normal file
|
@ -0,0 +1,153 @@
|
|||
/* ///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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) 2001-2007 Intel Corporation. All Rights Reserved.
|
||||
//
|
||||
// Description: MPEG-4 related tables.
|
||||
//
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "mp4def.h"
|
||||
|
||||
#define DI(b) ((1 << 18) + b) / b
|
||||
|
||||
const int32_t mp4_DivIntraDivisor[47] = {
|
||||
DI( 1), DI( 1), DI( 2), DI( 3), DI( 4), DI( 5), DI( 6), DI( 7), DI( 8), DI( 9),
|
||||
DI(10), DI(11), DI(12), DI(13), DI(14), DI(15), DI(16), DI(17), DI(18), DI(19),
|
||||
DI(20), DI(21), DI(22), DI(23), DI(24), DI(25), DI(26), DI(27), DI(28), DI(29),
|
||||
DI(30), DI(31), DI(32), DI(33), DI(34), DI(35), DI(36), DI(37), DI(38), DI(39),
|
||||
DI(40), DI(41), DI(42), DI(43), DI(44), DI(45), DI(46)
|
||||
};
|
||||
|
||||
#define DCSL(q) (q <= 4) ? 8 : (q <= 8) ? (q << 1) : (q <= 24) ? (q + 8) : ((q << 1) - 16)
|
||||
|
||||
const uint8_t mp4_DCScalerLuma[32] = {
|
||||
DCSL( 0), DCSL( 1), DCSL( 2), DCSL( 3), DCSL( 4), DCSL( 5), DCSL( 6), DCSL( 7),
|
||||
DCSL( 8), DCSL( 9), DCSL(10), DCSL(11), DCSL(12), DCSL(13), DCSL(14), DCSL(15),
|
||||
DCSL(16), DCSL(17), DCSL(18), DCSL(19), DCSL(20), DCSL(21), DCSL(22), DCSL(23),
|
||||
DCSL(24), DCSL(25), DCSL(26), DCSL(27), DCSL(28), DCSL(29), DCSL(30), DCSL(31)
|
||||
};
|
||||
|
||||
#define DCSC(q) (q <= 4) ? 8 : (q <= 24) ? ((q + 13) >> 1) : (q - 6)
|
||||
|
||||
const uint8_t mp4_DCScalerChroma[32] = {
|
||||
DCSC( 0), DCSC( 1), DCSC( 2), DCSC( 3), DCSC( 4), DCSC( 5), DCSC( 6), DCSC( 7),
|
||||
DCSC( 8), DCSC( 9), DCSC(10), DCSC(11), DCSC(12), DCSC(13), DCSC(14), DCSC(15),
|
||||
DCSC(16), DCSC(17), DCSC(18), DCSC(19), DCSC(20), DCSC(21), DCSC(22), DCSC(23),
|
||||
DCSC(24), DCSC(25), DCSC(26), DCSC(27), DCSC(28), DCSC(29), DCSC(30), DCSC(31)
|
||||
};
|
||||
|
||||
const uint8_t mp4_DefaultIntraQuantMatrix[64] = {
|
||||
8, 17, 18, 19, 21, 23, 25, 27, 17, 18, 19, 21, 23, 25, 27, 28,
|
||||
20, 21, 22, 23, 24, 26, 28, 30, 21, 22, 23, 24, 26, 28, 30, 32,
|
||||
22, 23, 24, 26, 28, 30, 32, 35, 23, 24, 26, 28, 30, 32, 35, 38,
|
||||
25, 26, 28, 30, 32, 35, 38, 41, 27, 28, 30, 32, 35, 38, 41, 45
|
||||
};
|
||||
|
||||
const uint8_t mp4_DefaultNonIntraQuantMatrix[64] = {
|
||||
16, 17, 18, 19, 20, 21, 22, 23, 17, 18, 19, 20, 21, 22, 23, 24,
|
||||
18, 19, 20, 21, 22, 23, 24, 25, 19, 20, 21, 22, 23, 24, 26, 27,
|
||||
20, 21, 22, 23, 25, 26, 27, 28, 21, 22, 23, 24, 26, 27, 28, 30,
|
||||
22, 23, 24, 26, 27, 28, 30, 31, 23, 24, 25, 27, 28, 30, 31, 33
|
||||
};
|
||||
|
||||
const uint8_t mp4_ClassicalZigzag[64] = {
|
||||
0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5,
|
||||
12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28,
|
||||
35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51,
|
||||
58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63
|
||||
};
|
||||
|
||||
const uint8_t mp4_cCbCrMvRound16[16] = {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2};
|
||||
const uint8_t mp4_cCbCrMvRound12[12] = {0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2};
|
||||
const uint8_t mp4_cCbCrMvRound8[8] = {0, 0, 1, 1, 1, 1, 1, 2};
|
||||
const uint8_t mp4_cCbCrMvRound4[4] = {0, 1, 1, 1};
|
||||
|
||||
const Ipp8s mp4_dquant[4] = {-1, -2, 1, 2};
|
||||
|
||||
const mp4_VLC1 mp4_cbpy1[4] = {{0,255},{0,2},{1,1},{1,1}};
|
||||
const mp4_VLC1 mp4_cbpy2[16] = {{0,255},{0,4},{1,3},{1,3},{2,2},{2,2},{2,2},{2,2},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1},{3,1}};
|
||||
const mp4_VLC1 mp4_cbpy3[64] = {{1,255},{1,6},{2,5},{2,5},{4,5},{4,5},{5,5},{5,5},{6,3},{6,3},{6,3},{6,3},{6,3},{6,3},{6,3},{6,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{3,3},{0,3},{0,3},{0,3},{0,3},{0,3},{0,3},{0,3},{0,3},{7,1},{7,1},{7,1},{7,1},{7,1},{7,1},{7,1},{7,1},{7,1},{7,1},{7,1},{7,1},{7,1},{7,1},{7,1},{7,1},{7,1},{7,1},{7,1},{7,1},{7,1},{7,1},{7,1},{7,1},{7,1},{7,1},{7,1},{7,1},{7,1},{7,1},{7,1},{7,1}};
|
||||
const mp4_VLC1 mp4_cbpy4[64] = {{16,255},{16,255},{6,6},{9,6},{8,5},{8,5},{4,5},{4,5},{2,5},{2,5},{1,5},{1,5},{0,4},{0,4},{0,4},{0,4},{12,4},{12,4},{12,4},{12,4},{10,4},{10,4},{10,4},{10,4},{14,4},{14,4},{14,4},{14,4},{5,4},{5,4},{5,4},{5,4},{13,4},{13,4},{13,4},{13,4},{3,4},{3,4},{3,4},{3,4},{11,4},{11,4},{11,4},{11,4},{7,4},{7,4},{7,4},{7,4},{15,2},{15,2},{15,2},{15,2},{15,2},{15,2},{15,2},{15,2},{15,2},{15,2},{15,2},{15,2},{15,2},{15,2},{15,2},{15,2}};
|
||||
const mp4_VLC1* mp4_cbpy_t[4] = {mp4_cbpy1, mp4_cbpy2, mp4_cbpy3, mp4_cbpy4};
|
||||
const uint8_t mp4_cbpy_b[4] = {2, 4, 6, 6};
|
||||
|
||||
const int32_t mp4_DC_vlc_Threshold[8] = {512, 13, 15, 17, 19, 21, 23, 0};
|
||||
|
||||
const uint8_t mp4_PVOPmb_type[256] = {255,255,4,4,4,1,3,3,3,3,2,2,3,3,3,3,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
|
||||
const uint8_t mp4_PVOPmb_cbpc[256] = {0,0,3,2,1,3,2,2,1,1,3,3,3,3,3,3,2,2,2,2,1,1,1,1,2,2,2,2,1,1,1,1,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
|
||||
const uint8_t mp4_PVOPmb_bits[256] = {9,9,9,9,9,9,8,8,8,8,8,8,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3};
|
||||
|
||||
const mp4_VLC1 mp4_BVOPmb_type[16] = {
|
||||
{255, 255}, {IPPVC_MBTYPE_FORWARD, 4}, {IPPVC_MBTYPE_BACKWARD, 3}, {IPPVC_MBTYPE_BACKWARD, 3},
|
||||
{IPPVC_MBTYPE_INTERPOLATE, 2}, {IPPVC_MBTYPE_INTERPOLATE, 2}, {IPPVC_MBTYPE_INTERPOLATE, 2}, {IPPVC_MBTYPE_INTERPOLATE, 2},
|
||||
{IPPVC_MBTYPE_DIRECT, 1}, {IPPVC_MBTYPE_DIRECT, 1}, {IPPVC_MBTYPE_DIRECT, 1}, {IPPVC_MBTYPE_DIRECT, 1},
|
||||
{IPPVC_MBTYPE_DIRECT, 1}, {IPPVC_MBTYPE_DIRECT, 1}, {IPPVC_MBTYPE_DIRECT, 1}, {IPPVC_MBTYPE_DIRECT, 1}
|
||||
};
|
||||
|
||||
const mp4_VLC1 mp4_MVD_B12_1[] = {
|
||||
{32,12},{31,12},
|
||||
{30,11},{30,11},{29,11},{29,11},{28,11},{28,11},
|
||||
{27,11},{27,11},{26,11},{26,11},{25,11},{25,11},
|
||||
{24,10},{24,10},{24,10},{24,10},{23,10},{23,10},{23,10},{23,10},
|
||||
{22,10},{22,10},{22,10},{22,10},{21,10},{21,10},{21,10},{21,10},
|
||||
{20,10},{20,10},{20,10},{20,10},{19,10},{19,10},{19,10},{19,10},
|
||||
{18,10},{18,10},{18,10},{18,10},{17,10},{17,10},{17,10},{17,10},
|
||||
{16,10},{16,10},{16,10},{16,10},{15,10},{15,10},{15,10},{15,10},
|
||||
{14,10},{14,10},{14,10},{14,10},{13,10},{13,10},{13,10},{13,10},
|
||||
{12,10},{12,10},{12,10},{12,10},{11,10},{11,10},{11,10},{11,10},
|
||||
{10, 9},{10, 9},{10, 9},{10, 9},{10, 9},{10, 9},{10, 9},{10, 9},
|
||||
{ 9, 9},{ 9, 9},{ 9, 9},{ 9, 9},{ 9, 9},{ 9, 9},{ 9, 9},{ 9, 9},
|
||||
{ 8, 9},{ 8, 9},{ 8, 9},{ 8, 9},{ 8, 9},{ 8, 9},{ 8, 9},{ 8, 9},
|
||||
{0x7, 7},{ 7, 7},{ 7, 7},{ 7, 7},{ 7, 7},{ 7, 7},{ 7, 7},{ 7, 7},
|
||||
{0x7, 7},{ 7, 7},{ 7, 7},{ 7, 7},{ 7, 7},{ 7, 7},{ 7, 7},{ 7, 7},
|
||||
{0x7, 7},{ 7, 7},{ 7, 7},{ 7, 7},{ 7, 7},{ 7, 7},{ 7, 7},{ 7, 7},
|
||||
{0x7, 7},{ 7, 7},{ 7, 7},{ 7, 7},{ 7, 7},{ 7, 7},{ 7, 7},{ 7, 7},
|
||||
};
|
||||
|
||||
const mp4_VLC1 mp4_MVD_B12_2[] = {
|
||||
{ 6, 7},{ 5, 7},{ 4, 6},{ 4, 6},
|
||||
{ 3, 4},{ 3, 4},{ 3, 4},{ 3, 4},{ 3, 4},{ 3, 4},{ 3, 4},{ 3, 4},
|
||||
{ 2, 3},{ 2, 3},{ 2, 3},{ 2, 3},{ 2, 3},{ 2, 3},{ 2, 3},{ 2, 3},
|
||||
{ 2, 3},{ 2, 3},{ 2, 3},{ 2, 3},{ 2, 3},{ 2, 3},{ 2, 3},{ 2, 3},
|
||||
{ 1, 2},{ 1, 2},{ 1, 2},{ 1, 2},{ 1, 2},{ 1, 2},{ 1, 2},{ 1, 2},
|
||||
{ 1, 2},{ 1, 2},{ 1, 2},{ 1, 2},{ 1, 2},{ 1, 2},{ 1, 2},{ 1, 2},
|
||||
{ 1, 2},{ 1, 2},{ 1, 2},{ 1, 2},{ 1, 2},{ 1, 2},{ 1, 2},{ 1, 2},
|
||||
{ 1, 2},{ 1, 2},{ 1, 2},{ 1, 2},{ 1, 2},{ 1, 2},{ 1, 2},{ 1, 2},
|
||||
{ 0, 1},{ 0, 1},{ 0, 1},{ 0, 1},{ 0, 1},{ 0, 1},{ 0, 1},{ 0, 1},
|
||||
{ 0, 1},{ 0, 1},{ 0, 1},{ 0, 1},{ 0, 1},{ 0, 1},{ 0, 1},{ 0, 1},
|
||||
{ 0, 1},{ 0, 1},{ 0, 1},{ 0, 1},{ 0, 1},{ 0, 1},{ 0, 1},{ 0, 1},
|
||||
{ 0, 1},{ 0, 1},{ 0, 1},{ 0, 1},{ 0, 1},{ 0, 1},{ 0, 1},{ 0, 1},
|
||||
{ 0, 1},{ 0, 1},{ 0, 1},{ 0, 1},{ 0, 1},{ 0, 1},{ 0, 1},{ 0, 1},
|
||||
{ 0, 1},{ 0, 1},{ 0, 1},{ 0, 1},{ 0, 1},{ 0, 1},{ 0, 1},{ 0, 1},
|
||||
{ 0, 1},{ 0, 1},{ 0, 1},{ 0, 1},{ 0, 1},{ 0, 1},{ 0, 1},{ 0, 1},
|
||||
{ 0, 1},{ 0, 1},{ 0, 1},{ 0, 1},{ 0, 1},{ 0, 1},{ 0, 1},{ 0, 1},
|
||||
};
|
||||
|
||||
const int32_t mp4_H263_width[5] = {128, 176, 352, 704, 1408};
|
||||
const int32_t mp4_H263_height[5] = {96, 144, 288, 576, 1152};
|
||||
const int32_t mp4_H263_mbgob[5] = {8, 11, 22, 88, 352};
|
||||
const int32_t mp4_H263_gobvop[5] = {6, 9, 18, 18, 18};
|
||||
const int32_t mp4_H263_rowgob[5] = {1, 1, 1, 2, 4};
|
||||
|
||||
const uint8_t mp4_aux_comp_count[MP4_SHAPE_EXT_NUM+1] = {1, 1, 2, 2, 3, 1, 2, 1, 1, 2, 3, 2, 3, 0};
|
||||
const uint8_t mp4_aux_comp_is_alpha[MP4_SHAPE_EXT_NUM+1] = {1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0};
|
||||
const uint8_t mp4_BABtypeIntra[81][3] = {
|
||||
2, 4, 3, 4, 3, 2, 4, 2, 3, 2, 4, 3, 2, 3, 4, 2, 3, 4, 2, 4, 3, 2, 3, 4,
|
||||
4, 2, 3, 4, 3, 2, 2, 3, 4, 2, 3, 4, 4, 3, 2, 2, 3, 4, 3, 2, 4, 4, 3, 2,
|
||||
2, 3, 4, 2, 3, 4, 4, 2, 3, 2, 3, 4, 4, 3, 2, 4, 2, 3, 2, 3, 4, 4, 3, 2,
|
||||
4, 2, 3, 4, 3, 2, 4, 3, 2, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4,
|
||||
2, 3, 4, 2, 3, 4, 2, 3, 4, 4, 3, 2, 2, 3, 4, 4, 3, 2, 4, 3, 2, 2, 3, 4,
|
||||
3, 4, 2, 4, 3, 2, 2, 3, 4, 3, 4, 2, 4, 3, 2, 2, 3, 4, 4, 3, 2, 4, 2, 3,
|
||||
2, 3, 4, 4, 3, 2, 4, 2, 3, 2, 4, 3, 3, 4, 2, 4, 2, 3, 2, 4, 3, 4, 2, 3,
|
||||
4, 2, 3, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 2, 3, 4, 4, 2, 3, 2, 3, 4,
|
||||
4, 3, 2, 4, 3, 2, 4, 2, 3, 3, 4, 2, 3, 4, 2, 4, 2, 3, 3, 4, 2, 4, 3, 2,
|
||||
2, 4, 3, 4, 3, 2, 4, 2, 3, 4, 2, 3, 3, 4, 2, 4, 3, 2, 2, 4, 3, 3, 4, 2,
|
||||
4, 3, 2
|
||||
};
|
||||
|
20
Src/mpeg4dec/mpeg4dec.sln
Normal file
20
Src/mpeg4dec/mpeg4dec.sln
Normal file
|
@ -0,0 +1,20 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||
# Visual Studio 2008
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mpeg4dec", "mpeg4dec.vcproj", "{F082AB20-F012-4CB0-AA60-A8F7177AEBC1}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{F082AB20-F012-4CB0-AA60-A8F7177AEBC1}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{F082AB20-F012-4CB0-AA60-A8F7177AEBC1}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{F082AB20-F012-4CB0-AA60-A8F7177AEBC1}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{F082AB20-F012-4CB0-AA60-A8F7177AEBC1}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
214
Src/mpeg4dec/mpeg4dec.vcproj
Normal file
214
Src/mpeg4dec/mpeg4dec.vcproj
Normal file
|
@ -0,0 +1,214 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="mpeg4dec"
|
||||
ProjectGUID="{F082AB20-F012-4CB0-AA60-A8F7177AEBC1}"
|
||||
RootNamespace="mpeg4dec"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="196613"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="4"
|
||||
CharacterSet="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../Wasabi;"$(ProgramFiles)\Intel\IPP\6.1.1.035\ia32\include""
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="4"
|
||||
CharacterSet="1"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="3"
|
||||
InlineFunctionExpansion="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
FavorSizeOrSpeed="1"
|
||||
AdditionalIncludeDirectories="../Wasabi;"$(ProgramFiles)\Intel\IPP\6.1.1.035\ia32\include""
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="2"
|
||||
BufferSecurityCheck="false"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\mp4decvop.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\mp4decvopb.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\mp4decvopi.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\mp4decvopp.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\mp4decvops.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\mp4parse.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\mp4stream.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\mp4tbl.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\mpeg4vid_api.c"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\mp4dec.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\mp4def.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\mpeg4vid_api.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
661
Src/mpeg4dec/mpeg4vid_api.c
Normal file
661
Src/mpeg4dec/mpeg4vid_api.c
Normal file
|
@ -0,0 +1,661 @@
|
|||
#include "mpeg4vid_api.h"
|
||||
#include "mp4def.h"
|
||||
#include "mp4dec.h"
|
||||
|
||||
/* TODO: we havn't implemented "end of stream" yet, but when we do
|
||||
we need to flush out the buffered frames
|
||||
m_decInfo->VisualObject.vFrame = m_decInfo->VisualObject.VideoObject.prevPlaneIsB ?
|
||||
&m_decInfo->VisualObject.nFrame : &m_decInfo->VisualObject.cFrame;
|
||||
*/
|
||||
|
||||
// disable post processing for now, doesn't seem to be working out too well
|
||||
//#define MP4V_DO_POST_PROCESS
|
||||
|
||||
#define MAX_CODED_FRAME 8000000 // TODO: benski> verify
|
||||
typedef struct
|
||||
{
|
||||
mp4_Info dec;
|
||||
int initted;
|
||||
int resetting;
|
||||
int skip_b_frames;
|
||||
#ifdef MP4V_DO_POST_PROCESS
|
||||
mp4_Frame ppFrame0, ppFrame1;
|
||||
#endif
|
||||
__declspec(align(32)) uint8_t buffer[MAX_CODED_FRAME];
|
||||
} MPEG4VideoDecoder;
|
||||
|
||||
static int FreeBuffers(MPEG4VideoDecoder *decoder);
|
||||
|
||||
void mp4_Error(const char *str)
|
||||
{
|
||||
puts(str);
|
||||
}
|
||||
|
||||
mpeg4vid_decoder_t MPEG4Video_CreateDecoder(int filetype, int codec)
|
||||
{
|
||||
MPEG4VideoDecoder *decoder = (MPEG4VideoDecoder *)malloc(sizeof(MPEG4VideoDecoder));
|
||||
memset(decoder, 0, sizeof(MPEG4VideoDecoder));
|
||||
|
||||
// set configuration stuff
|
||||
decoder->dec.stopOnErr = 0;
|
||||
decoder->dec.strictSyntaxCheck = 0;
|
||||
decoder->dec.VisualObject.verid = 1;
|
||||
decoder->dec.ftype = filetype;
|
||||
decoder->dec.ftype_f = codec;
|
||||
|
||||
return decoder;
|
||||
}
|
||||
|
||||
void MPEG4Video_DestroyDecoder(mpeg4vid_decoder_t d)
|
||||
{
|
||||
MPEG4VideoDecoder *decoder = (MPEG4VideoDecoder *)d;
|
||||
if (decoder)
|
||||
{
|
||||
#ifdef MP4V_DO_POST_PROCESS
|
||||
free(decoder->ppFrame0.mid);
|
||||
free(decoder->ppFrame1.mid);
|
||||
#endif
|
||||
FreeBuffers(decoder);
|
||||
free(decoder);
|
||||
}
|
||||
}
|
||||
|
||||
void MPEG4Video_Flush(mpeg4vid_decoder_t d)
|
||||
{
|
||||
MPEG4VideoDecoder *decoder = (MPEG4VideoDecoder *)d;
|
||||
if (decoder && decoder->initted)
|
||||
{
|
||||
mp4_ResetVOL(&decoder->dec);
|
||||
decoder->resetting = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static int AllocateInitFrame(mp4_Frame* pFrame)
|
||||
{
|
||||
int32_t w, h;
|
||||
|
||||
w = (pFrame->mbPerRow + 2 * MP4_NUM_EXT_MB) << 4;
|
||||
h = (pFrame->mbPerCol + 2 * MP4_NUM_EXT_MB) << 4;
|
||||
pFrame->mid = malloc(w * h + (w * h >> 1));
|
||||
if (!pFrame->mid)
|
||||
return 1; // out of memory
|
||||
|
||||
ippsSet_8u(0, pFrame->mid, w * h);
|
||||
ippsSet_8u(128, pFrame->mid + w * h, w * h >> 1);
|
||||
|
||||
pFrame->stepY = w;
|
||||
pFrame->stepCb = w >> 1;
|
||||
pFrame->stepCr = w >> 1;
|
||||
|
||||
/* benski> stuff from LockFrame... */
|
||||
pFrame->apY = pFrame->mid;
|
||||
pFrame->pY = pFrame->apY + w * 16 + 16;
|
||||
pFrame->apCb = pFrame->apY + w * h;
|
||||
w >>= 1;
|
||||
h >>= 1;
|
||||
pFrame->pCb = pFrame->apCb + w * 8 + 8;
|
||||
pFrame->apCr = pFrame->apCb + w * h;
|
||||
pFrame->pCr = pFrame->apCr + w * 8 + 8;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int AllocateBuffers(MPEG4VideoDecoder *decoder)
|
||||
{
|
||||
if (mp4_InitVOL(&decoder->dec) != MP4_STATUS_OK)
|
||||
{
|
||||
mp4_Error("Error: No memory to allocate internal buffers\n");
|
||||
return 1;//UMC_ERR_ALLOC;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int InsideInit(MPEG4VideoDecoder *decoder)
|
||||
{
|
||||
int status;
|
||||
uint32_t code;
|
||||
int h_vo_found = 0, h_vos_found = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (!mp4_SeekStartCodeOrShortPtr(&decoder->dec))
|
||||
{
|
||||
mp4_Error("Error: Can't find Visual Object or Video Object start codes or short_video_start_marker\n");
|
||||
return 1;//UMC_ERR_SYNC;
|
||||
}
|
||||
// check short_video_start_marker
|
||||
if (mp4_IsShortCode(&decoder->dec))
|
||||
{
|
||||
if ((mp4_Parse_VideoObject(&decoder->dec)) != MP4_STATUS_OK)
|
||||
return 1;//UMC_ERR_INVALID_STREAM;
|
||||
break;
|
||||
}
|
||||
code = mp4_GetBits(&decoder->dec, 8);
|
||||
if (!h_vos_found && code == MP4_VISUAL_OBJECT_SEQUENCE_SC)
|
||||
{
|
||||
h_vos_found = 1;
|
||||
if ((mp4_Parse_VisualObjectSequence(&decoder->dec)) != MP4_STATUS_OK)
|
||||
return 1;//UMC_ERR_INVALID_STREAM;
|
||||
}
|
||||
|
||||
if (!h_vo_found && code == MP4_VISUAL_OBJECT_SC)
|
||||
{
|
||||
h_vo_found = 1;
|
||||
if ((mp4_Parse_VisualObject(&decoder->dec)) != MP4_STATUS_OK)
|
||||
return 1;//UMC_ERR_INVALID_STREAM;
|
||||
}
|
||||
// some streams can start with video_object_layer
|
||||
if ((int32_t)code >= MP4_VIDEO_OBJECT_LAYER_MIN_SC && code <= MP4_VIDEO_OBJECT_LAYER_MAX_SC) {
|
||||
decoder->dec.bufptr -= 4;
|
||||
if ((mp4_Parse_VideoObject(&decoder->dec)) != MP4_STATUS_OK)
|
||||
return 1;//UMC_ERR_INVALID_STREAM;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
status = AllocateBuffers(decoder);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
|
||||
#if 0 // don't really care about this, but might be useful code for later?
|
||||
// set profile/level info
|
||||
decoder->profile = decoder->dec.profile_and_level_indication >> 4;
|
||||
decoder->level = decoder->dec.profile_and_level_indication & 15;
|
||||
if (decoder->profile == MPEG4_PROFILE_SIMPLE)
|
||||
if (decoder->level == 8)
|
||||
decoder->level = MPEG4_LEVEL_0;
|
||||
if (decoder->profile == MPEG4_PROFILE_ADVANCED_SIMPLE) {
|
||||
if (decoder->level == 7)
|
||||
decoder->level = MPEG4_LEVEL_3B;
|
||||
if (decoder->level > 7) {
|
||||
decoder->profile = MPEG4_PROFILE_FGS;
|
||||
decoder->level -= 8;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
decoder->initted = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int FreeBuffers(MPEG4VideoDecoder *decoder)
|
||||
{
|
||||
int status = 0;
|
||||
|
||||
ReleaseFrame(&decoder->dec.VisualObject, decoder->dec.VisualObject.cFrame);
|
||||
decoder->dec.VisualObject.cFrame=0;
|
||||
ReleaseFrame(&decoder->dec.VisualObject, decoder->dec.VisualObject.rFrame);
|
||||
decoder->dec.VisualObject.rFrame=0;
|
||||
ReleaseFrame(&decoder->dec.VisualObject, decoder->dec.VisualObject.nFrame);
|
||||
decoder->dec.VisualObject.nFrame=0;
|
||||
ReleaseFrame(&decoder->dec.VisualObject, decoder->dec.VisualObject.sFrame);
|
||||
decoder->dec.VisualObject.sFrame=0;
|
||||
FreeCache(&decoder->dec.VisualObject);
|
||||
|
||||
mp4_FreeVOL(&decoder->dec);
|
||||
return status;
|
||||
}
|
||||
|
||||
static int PostProcess(MPEG4VideoDecoder *decoder, mp4_Frame *inout)
|
||||
{
|
||||
#ifdef MP4V_DO_POST_PROCESS
|
||||
int w, h, i, j, k, QP, width, height;
|
||||
IppiSize size;
|
||||
Ipp8u *pSrc[3], *pDst[3];
|
||||
int srcPitch[3], dstPitch[3], threshold[6];
|
||||
int m_DeblockingProcPlane[3] = {1,1,1}; // TODO: configurable
|
||||
int m_DeringingProcPlane[3] = {1,1,1}; // TODO: configurable
|
||||
int32_t m_DeblockingTHR1 = 2; // TODO
|
||||
int32_t m_DeblockingTHR2 = 6; // TODO
|
||||
QP = inout->QP;
|
||||
width = (decoder->dec.VisualObject.VideoObject.width + 7) & (~7);
|
||||
height = (decoder->dec.VisualObject.VideoObject.height + 7) & (~7);
|
||||
if (m_DeblockingProcPlane[0] || m_DeblockingProcPlane[1] || m_DeblockingProcPlane[2]) {
|
||||
pSrc[0] = inout->pY;
|
||||
srcPitch[0] = inout->stepY;
|
||||
pDst[0] = decoder->ppFrame0.pY;
|
||||
dstPitch[0] = decoder->ppFrame0.stepY;
|
||||
pSrc[1] = inout->pCb;
|
||||
srcPitch[1] = inout->stepCb;
|
||||
pDst[1] = decoder->ppFrame0.pCb;
|
||||
dstPitch[1] = decoder->ppFrame0.stepCb;
|
||||
pSrc[2] = inout->pCr;
|
||||
srcPitch[2] = inout->stepCr;
|
||||
pDst[2] = decoder->ppFrame0.pCr;
|
||||
dstPitch[2] = decoder->ppFrame0.stepCr;
|
||||
for (k = 0; k < 3; k ++) {
|
||||
if (m_DeblockingProcPlane[k]) {
|
||||
size.height = 8;
|
||||
if (k == 0) {
|
||||
size.width = width;
|
||||
h = height >> 3;
|
||||
w = width >> 3;
|
||||
} else {
|
||||
size.width = width >> 1;
|
||||
h = height >> 4;
|
||||
w = width >> 4;
|
||||
}
|
||||
for (i = 0; i < h; i ++) {
|
||||
ippiCopy_8u_C1R(pSrc[k], srcPitch[k], pDst[k], dstPitch[k], size);
|
||||
if (i > 0) {
|
||||
for (j = 0; j < w; j ++)
|
||||
ippiFilterDeblocking8x8HorEdge_MPEG4_8u_C1IR(pDst[k] + 8 * j, dstPitch[k], QP, m_DeblockingTHR1, m_DeblockingTHR2);
|
||||
for (j = 1; j < w; j ++)
|
||||
ippiFilterDeblocking8x8VerEdge_MPEG4_8u_C1IR(pDst[k] - 8 * dstPitch[k] + 8 * j, dstPitch[k], QP, m_DeblockingTHR1, m_DeblockingTHR2);
|
||||
}
|
||||
if (i == h - 1) {
|
||||
for (j = 1; j < w; j ++)
|
||||
ippiFilterDeblocking8x8VerEdge_MPEG4_8u_C1IR(pDst[k] + 8 * j, dstPitch[k], QP, m_DeblockingTHR1, m_DeblockingTHR2);
|
||||
}
|
||||
pSrc[k] += srcPitch[k] * 8;
|
||||
pDst[k] += dstPitch[k] * 8;
|
||||
}
|
||||
} else {
|
||||
if (k == 0) {
|
||||
size.width = width;
|
||||
size.height = height;
|
||||
} else {
|
||||
size.width = width >> 1;
|
||||
size.height = height >> 1;
|
||||
}
|
||||
ippiCopy_8u_C1R(pSrc[k], srcPitch[k], pDst[k], dstPitch[k], size);
|
||||
}
|
||||
}
|
||||
*inout = decoder->ppFrame0;
|
||||
}
|
||||
if (m_DeringingProcPlane[0] || m_DeringingProcPlane[1] || m_DeringingProcPlane[2]) {
|
||||
pSrc[0] = inout->pY;
|
||||
srcPitch[0] = inout->stepY;
|
||||
pDst[0] = decoder->ppFrame1.pY;
|
||||
dstPitch[0] = decoder->ppFrame1.stepY;
|
||||
if (!m_DeringingProcPlane[0]) {
|
||||
size.width = width;
|
||||
size.height = height;
|
||||
ippiCopy_8u_C1R(pSrc[0], srcPitch[0], pDst[0], dstPitch[0], size);
|
||||
}
|
||||
pSrc[1] = inout->pCb;
|
||||
srcPitch[1] = inout->stepCb;
|
||||
pDst[1] = decoder->ppFrame1.pCb;
|
||||
dstPitch[1] = decoder->ppFrame1.stepCb;
|
||||
if (!m_DeringingProcPlane[1]) {
|
||||
size.width = width >> 1;
|
||||
size.height = height >> 1;
|
||||
ippiCopy_8u_C1R(pSrc[1], srcPitch[1], pDst[1], dstPitch[1], size);
|
||||
}
|
||||
pSrc[2] = inout->pCr;
|
||||
srcPitch[2] = inout->stepCr;
|
||||
pDst[2] = decoder->ppFrame1.pCr;
|
||||
dstPitch[2] = decoder->ppFrame1.stepCr;
|
||||
if (!m_DeringingProcPlane[2]) {
|
||||
size.width = width >> 1;
|
||||
size.height = height >> 1;
|
||||
ippiCopy_8u_C1R(pSrc[2], srcPitch[2], pDst[2], dstPitch[2], size);
|
||||
}
|
||||
h = inout->mbPerCol;
|
||||
w = inout->mbPerRow;
|
||||
for (i = 0; i < h; i ++) {
|
||||
for (j = 0; j < w; j ++) {
|
||||
ippiFilterDeringingThreshold_MPEG4_8u_P3R(pSrc[0]+ 16 * j, srcPitch[0], pSrc[1] + 8 * j, srcPitch[1], pSrc[2] + 8 * j, srcPitch[2], threshold);
|
||||
// copy border macroblocks
|
||||
if (i == 0 || i == h - 1 || j == 0 || j == w - 1) {
|
||||
if (m_DeringingProcPlane[0])
|
||||
ippiCopy16x16_8u_C1R(pSrc[0] + 16 * j, srcPitch[0], pDst[0] + 16 * j, dstPitch[0]);
|
||||
if (m_DeringingProcPlane[1])
|
||||
ippiCopy8x8_8u_C1R(pSrc[1] + 8 * j, srcPitch[1], pDst[1] + 8 * j, dstPitch[1]);
|
||||
if (m_DeringingProcPlane[2])
|
||||
ippiCopy8x8_8u_C1R(pSrc[2] + 8 * j, srcPitch[2], pDst[2] + 8 * j, dstPitch[2]);
|
||||
}
|
||||
if (m_DeringingProcPlane[0]) {
|
||||
if (i != 0 && j != 0)
|
||||
ippiFilterDeringingSmooth8x8_MPEG4_8u_C1R(pSrc[0] + 16 * j, srcPitch[0], pDst[0] + 16 * j, dstPitch[0], QP, threshold[0]);
|
||||
if (i != 0 && j != w - 1)
|
||||
ippiFilterDeringingSmooth8x8_MPEG4_8u_C1R(pSrc[0] + 16 * j + 8, srcPitch[0], pDst[0] + 16 * j + 8, dstPitch[0], QP, threshold[1]);
|
||||
if (i != h - 1 && j != 0)
|
||||
ippiFilterDeringingSmooth8x8_MPEG4_8u_C1R(pSrc[0] + 16 * j + 8 * srcPitch[0], srcPitch[0], pDst[0] + 16 * j + 8 * dstPitch[0], dstPitch[0], QP, threshold[2]);
|
||||
if (i != h - 1 && j != w - 1)
|
||||
ippiFilterDeringingSmooth8x8_MPEG4_8u_C1R(pSrc[0] + 16 * j + 8 * srcPitch[0] + 8, srcPitch[0], pDst[0] + 16 * j + 8 * dstPitch[0] + 8, dstPitch[0], QP, threshold[3]);
|
||||
}
|
||||
if (i != 0 && j != 0 && i != h - 1 && j != w - 1) {
|
||||
if (m_DeringingProcPlane[1])
|
||||
ippiFilterDeringingSmooth8x8_MPEG4_8u_C1R(pSrc[1] + 8 * j, srcPitch[1], pDst[1] + 8 * j, dstPitch[1], QP, threshold[4]);
|
||||
if (m_DeringingProcPlane[2])
|
||||
ippiFilterDeringingSmooth8x8_MPEG4_8u_C1R(pSrc[2] + 8 * j, srcPitch[2], pDst[2] + 8 * j, dstPitch[2], QP, threshold[5]);
|
||||
}
|
||||
}
|
||||
pSrc[0] += srcPitch[0] * 16;
|
||||
pDst[0] += dstPitch[0] * 16;
|
||||
pSrc[1] += srcPitch[1] * 8;
|
||||
pDst[1] += dstPitch[1] * 8;
|
||||
pSrc[2] += srcPitch[2] * 8;
|
||||
pDst[2] += dstPitch[2] * 8;
|
||||
}
|
||||
*inout = decoder->ppFrame1;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MPEG4Video_DecodeFrame(mpeg4vid_decoder_t d, const void *buffer, size_t bufferlen, uint64_t time_code)
|
||||
{
|
||||
int status=0;
|
||||
int code;
|
||||
MPEG4VideoDecoder *decoder = (MPEG4VideoDecoder *)d;
|
||||
|
||||
if (bufferlen > (MAX_CODED_FRAME-32))
|
||||
return;
|
||||
|
||||
if (buffer)
|
||||
{
|
||||
memcpy(decoder->buffer, buffer, bufferlen);
|
||||
memset(decoder->buffer+bufferlen, 0, 32);
|
||||
decoder->dec.bitoff = 0;
|
||||
decoder->dec.bufptr = decoder->dec.buffer = (uint8_t *)decoder->buffer;
|
||||
decoder->dec.buflen = bufferlen;
|
||||
}
|
||||
|
||||
if (!decoder->initted) // initialize off the first packet
|
||||
{
|
||||
status = InsideInit(decoder);
|
||||
if (status)
|
||||
return;
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
// Seeking the VOP start_code, and then begin the vop decoding
|
||||
if (decoder->dec.VisualObject.VideoObject.short_video_header)
|
||||
{
|
||||
if (!mp4_SeekShortVideoStartMarker(&decoder->dec))
|
||||
{
|
||||
mp4_Error("Error: Failed seeking short_video_start_marker\n");
|
||||
status = 1;//UMC_ERR_SYNC;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
if (!mp4_SeekStartCodePtr(&decoder->dec)) {
|
||||
mp4_Error("Error: Failed seeking GOV or VOP Start Code");
|
||||
status = 1;//UMC_ERR_SYNC;
|
||||
break;
|
||||
}
|
||||
code = decoder->dec.bufptr[0];
|
||||
decoder->dec.bufptr++;
|
||||
// parse repeated VOS, VO and VOL headers because stream may be glued from different streams
|
||||
if (code == MP4_VISUAL_OBJECT_SEQUENCE_SC)
|
||||
{
|
||||
if (mp4_Parse_VisualObjectSequence(&decoder->dec) != MP4_STATUS_OK)
|
||||
{
|
||||
status = 1;//UMC_ERR_INVALID_STREAM;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (code == MP4_VISUAL_OBJECT_SC)
|
||||
{
|
||||
if (mp4_Parse_VisualObject(&decoder->dec) != MP4_STATUS_OK)
|
||||
{
|
||||
status = 1;//UMC_ERR_INVALID_STREAM;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (code >= MP4_VIDEO_OBJECT_LAYER_MIN_SC && code <= MP4_VIDEO_OBJECT_LAYER_MAX_SC)
|
||||
{
|
||||
// save parameters which can affect on reinit
|
||||
Ipp32s interlaced = decoder->dec.VisualObject.VideoObject.interlaced;
|
||||
Ipp32s data_partitioned = decoder->dec.VisualObject.VideoObject.data_partitioned;
|
||||
Ipp32s sprite_enable = decoder->dec.VisualObject.VideoObject.sprite_enable;
|
||||
Ipp32s width = decoder->dec.VisualObject.VideoObject.width;
|
||||
Ipp32s height = decoder->dec.VisualObject.VideoObject.height;
|
||||
|
||||
// in repeated headers check only VOL header
|
||||
decoder->dec.bufptr -= 4;
|
||||
|
||||
if (mp4_Parse_VideoObject(&decoder->dec) != MP4_STATUS_OK) {
|
||||
status = 1;//UMC_ERR_INVALID_STREAM;
|
||||
break;
|
||||
}
|
||||
// realloc if something was changed
|
||||
if (interlaced != decoder->dec.VisualObject.VideoObject.interlaced ||
|
||||
data_partitioned != decoder->dec.VisualObject.VideoObject.data_partitioned ||
|
||||
sprite_enable != decoder->dec.VisualObject.VideoObject.sprite_enable ||
|
||||
width != decoder->dec.VisualObject.VideoObject.width ||
|
||||
height != decoder->dec.VisualObject.VideoObject.height)
|
||||
{
|
||||
// TODO: return a code so we can return MP4_VIDEO_OUTPUT_FORMAT_CHANGED
|
||||
if (decoder->dec.strictSyntaxCheck)
|
||||
{
|
||||
mp4_Error("Error: Repeated VOL header is different from previous");
|
||||
status = 1;//UMC_ERR_INVALID_STREAM;
|
||||
break;
|
||||
}
|
||||
|
||||
// UnlockBuffers();
|
||||
status = FreeBuffers(decoder);
|
||||
if (status)
|
||||
break;
|
||||
|
||||
status = AllocateBuffers(decoder);
|
||||
if (status)
|
||||
break;
|
||||
|
||||
// free buffers for MPEG-4 post-processing
|
||||
#ifdef MP4V_DO_POST_PROCESS
|
||||
free(decoder->ppFrame0.mid);
|
||||
decoder->ppFrame0.mid = 0;
|
||||
|
||||
free(decoder->ppFrame1.mid);
|
||||
decoder->ppFrame1.mid = 0;
|
||||
#endif
|
||||
|
||||
// TODO: clear cache and display frames
|
||||
}
|
||||
// reinit quant matrix
|
||||
ippiQuantInvIntraInit_MPEG4(decoder->dec.VisualObject.VideoObject.quant_type ? decoder->dec.VisualObject.VideoObject.intra_quant_mat : NULL, decoder->dec.VisualObject.VideoObject.QuantInvIntraSpec, 8);
|
||||
ippiQuantInvInterInit_MPEG4(decoder->dec.VisualObject.VideoObject.quant_type ? decoder->dec.VisualObject.VideoObject.nonintra_quant_mat : NULL, decoder->dec.VisualObject.VideoObject.QuantInvInterSpec, 8);
|
||||
}
|
||||
else if (code == MP4_GROUP_OF_VOP_SC)
|
||||
{
|
||||
if (mp4_Parse_GroupOfVideoObjectPlane(&decoder->dec) != MP4_STATUS_OK)
|
||||
{
|
||||
status = 1;//UMC_ERR_INVALID_STREAM;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (decoder->dec.bufptr[-1] == MP4_VIDEO_OBJECT_PLANE_SC)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (status)
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
// parse VOP header
|
||||
if ((mp4_Parse_VideoObjectPlane(&decoder->dec)) != MP4_STATUS_OK)
|
||||
{
|
||||
//status = UMC_WRN_INVALID_STREAM;
|
||||
status = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (decoder->resetting && decoder->dec.VisualObject.VideoObject.VideoObjectPlane.coding_type != MP4_VOP_TYPE_I)
|
||||
{
|
||||
//UnlockBuffers();
|
||||
//return UMC_ERR_NOT_ENOUGH_DATA;
|
||||
// decoder->dec.VisualObject.vFrame = NULL;
|
||||
status = 1;//UMC_ERR_NOT_ENOUGH_DATA;
|
||||
break;
|
||||
}
|
||||
if (decoder->dec.VisualObject.VideoObject.VideoObjectPlane.coding_type == MP4_VOP_TYPE_B)
|
||||
{
|
||||
if (decoder->skip_b_frames)
|
||||
{
|
||||
decoder->dec.bufptr = decoder->dec.buffer+ decoder->dec.buflen;
|
||||
status = 1;//UMC_ERR_NOT_ENOUGH_DATA;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// decode VOP
|
||||
if ((mp4_DecodeVideoObjectPlane(&decoder->dec)) != MP4_STATUS_OK)
|
||||
{
|
||||
status = 1;//UMC_WRN_INVALID_STREAM;
|
||||
}
|
||||
if (decoder->dec.VisualObject.cFrame)
|
||||
{
|
||||
decoder->dec.VisualObject.cFrame->timestamp = time_code;
|
||||
decoder->dec.VisualObject.cFrame->QP = decoder->dec.VisualObject.VideoObject.short_video_header ? decoder->dec.VisualObject.VideoObject.VideoObjectPlaneH263.vop_quant : decoder->dec.VisualObject.VideoObject.VideoObjectPlane.quant;
|
||||
}
|
||||
|
||||
// after reset it is need to skip first B-frames
|
||||
if (decoder->dec.VisualObject.VideoObject.VOPindex < 2 && decoder->dec.VisualObject.VideoObject.VideoObjectPlane.coding_type == MP4_VOP_TYPE_B)
|
||||
{
|
||||
status = 1;//UMC_ERR_NOT_ENOUGH_DATA;
|
||||
break;
|
||||
}
|
||||
|
||||
// do not count not_coded P frames with same vop_time as reference (in AVI)
|
||||
|
||||
if (decoder->dec.VisualObject.VideoObject.VideoObjectPlane.coded ||
|
||||
(
|
||||
decoder->dec.VisualObject.cFrame &&
|
||||
(!decoder->dec.VisualObject.rFrame || (decoder->dec.VisualObject.rFrame->time != decoder->dec.VisualObject.cFrame->time)) &&
|
||||
(!decoder->dec.VisualObject.nFrame || (decoder->dec.VisualObject.nFrame->time != decoder->dec.VisualObject.cFrame->time))
|
||||
)
|
||||
)
|
||||
{
|
||||
decoder->dec.VisualObject.VideoObject.VOPindex++;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = 1;//UMC_ERR_NOT_ENOUGH_DATA;
|
||||
break;
|
||||
}
|
||||
if (decoder->resetting && decoder->dec.VisualObject.VideoObject.VideoObjectPlane.coding_type == MP4_VOP_TYPE_I)
|
||||
{
|
||||
// TODO: ???m_time_reset = (Ipp32s)decoder->dec.VisualObject.cFrame.time;
|
||||
//decoder->dec.VisualObject.vFrame = NULL;
|
||||
decoder->resetting = 0;
|
||||
}
|
||||
|
||||
}
|
||||
// return status;
|
||||
}
|
||||
|
||||
void MPEG4Video_GetPicture(mpeg4vid_decoder_t d, mp4_Frame **frame)
|
||||
{
|
||||
int status = 0;
|
||||
MPEG4VideoDecoder *decoder = (MPEG4VideoDecoder *)d;
|
||||
|
||||
mp4_Frame *rendFrame = GetDisplayFrame(&decoder->dec.VisualObject);
|
||||
if (rendFrame)
|
||||
{
|
||||
uint64_t timestamp = rendFrame->timestamp;
|
||||
#ifdef MP4V_DO_POST_PROCESS
|
||||
if (1 /* TODO: disable deblocking and deringing on request*/)
|
||||
{
|
||||
if (!decoder->ppFrame0.mid)
|
||||
{
|
||||
decoder->ppFrame0.mbPerRow = decoder->dec.VisualObject.vFrame->mbPerRow;
|
||||
decoder->ppFrame0.mbPerCol = decoder->dec.VisualObject.vFrame->mbPerCol;
|
||||
status = AllocateInitFrame(&decoder->ppFrame0);
|
||||
if (status)
|
||||
return ;
|
||||
}
|
||||
if (!decoder->ppFrame1.mid)
|
||||
{
|
||||
decoder->ppFrame1.mbPerRow = decoder->dec.VisualObject.vFrame->mbPerRow;
|
||||
decoder->ppFrame1.mbPerCol = decoder->dec.VisualObject.vFrame->mbPerCol;
|
||||
status = AllocateInitFrame(&decoder->ppFrame1);
|
||||
if (status)
|
||||
return ;
|
||||
}
|
||||
|
||||
PostProcess(decoder, rendFrame);
|
||||
}
|
||||
#endif
|
||||
//if (m_LastDecodedFrame.GetColorFormat() != YUV420) {
|
||||
// m_LastDecodedFrame.Init(decoder->dec.VisualObject.VideoObject.width, decoder->dec.VisualObject.VideoObject.height, YUV420);
|
||||
//}
|
||||
|
||||
// TODO ??? m_LastDecodedFrame.SetTime(pts);
|
||||
*frame = rendFrame;
|
||||
rendFrame->timestamp = timestamp;
|
||||
}
|
||||
else
|
||||
*frame = 0;
|
||||
}
|
||||
|
||||
void MPEG4Video_ReleaseFrame(mpeg4vid_decoder_t d, mp4_Frame *frame)
|
||||
{
|
||||
MPEG4VideoDecoder *decoder = (MPEG4VideoDecoder *)d;
|
||||
ReleaseFrame(&decoder->dec.VisualObject, frame);
|
||||
}
|
||||
|
||||
static double GetAspectRatio(mp4_VideoObject *video_object)
|
||||
{
|
||||
int aspect_ratio_width=1, aspect_ratio_height=1;
|
||||
switch (video_object->aspect_ratio_info)
|
||||
{
|
||||
case MP4_ASPECT_RATIO_FORBIDDEN:
|
||||
case MP4_ASPECT_RATIO_1_1:
|
||||
aspect_ratio_width = 1;
|
||||
aspect_ratio_height = 1;
|
||||
break;
|
||||
case MP4_ASPECT_RATIO_12_11:
|
||||
aspect_ratio_width = 12;
|
||||
aspect_ratio_height = 11;
|
||||
break;
|
||||
case MP4_ASPECT_RATIO_10_11:
|
||||
aspect_ratio_width = 10;
|
||||
aspect_ratio_height = 11;
|
||||
break;
|
||||
case MP4_ASPECT_RATIO_16_11:
|
||||
aspect_ratio_width = 16;
|
||||
aspect_ratio_height = 11;
|
||||
break;
|
||||
case MP4_ASPECT_RATIO_40_33:
|
||||
aspect_ratio_width = 40;
|
||||
aspect_ratio_height = 33;
|
||||
break;
|
||||
default:
|
||||
aspect_ratio_width = video_object->aspect_ratio_info_par_width;
|
||||
aspect_ratio_height = video_object->aspect_ratio_info_par_height;
|
||||
break;
|
||||
}
|
||||
return (double)aspect_ratio_width / (double)aspect_ratio_height;
|
||||
}
|
||||
|
||||
int MPEG4Video_GetOutputFormat(mpeg4vid_decoder_t d, int *width, int *height, double *aspect_ratio)
|
||||
{
|
||||
MPEG4VideoDecoder *decoder = (MPEG4VideoDecoder *)d;
|
||||
if (decoder && decoder->initted)
|
||||
{
|
||||
*width = decoder->dec.VisualObject.VideoObject.width;
|
||||
*height = decoder->dec.VisualObject.VideoObject.height;
|
||||
*aspect_ratio = GetAspectRatio(&decoder->dec.VisualObject.VideoObject);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void MPEG4Video_HurryUp(mpeg4vid_decoder_t d, int state)
|
||||
{
|
||||
MPEG4VideoDecoder *decoder = (MPEG4VideoDecoder *)d;
|
||||
if (decoder)
|
||||
{
|
||||
decoder->skip_b_frames = state;
|
||||
}
|
||||
}
|
||||
void MPEG4Video_EndOfStream(mpeg4vid_decoder_t d)
|
||||
{
|
||||
MPEG4VideoDecoder *decoder = (MPEG4VideoDecoder *)d;
|
||||
if (decoder)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
}
|
54
Src/mpeg4dec/mpeg4vid_api.h
Normal file
54
Src/mpeg4dec/mpeg4vid_api.h
Normal file
|
@ -0,0 +1,54 @@
|
|||
#pragma once
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
#include <bfc/platform/types.h>
|
||||
#include "mp4def.h"
|
||||
typedef void *mpeg4vid_decoder_t;
|
||||
|
||||
mpeg4vid_decoder_t MPEG4Video_CreateDecoder(int filetype, int codec);
|
||||
void MPEG4Video_DestroyDecoder(mpeg4vid_decoder_t decoder);
|
||||
void MPEG4Video_DecodeFrame(mpeg4vid_decoder_t decoder, const void *buffer, size_t bufferlen, uint64_t time_code);
|
||||
void MPEG4Video_GetPicture(mpeg4vid_decoder_t decoder, mp4_Frame **frame);
|
||||
int MPEG4Video_GetOutputFormat(mpeg4vid_decoder_t decoder, int *width, int *height, double *aspect_ratio);
|
||||
void MPEG4Video_Flush(mpeg4vid_decoder_t decoder);
|
||||
void MPEG4Video_HurryUp(mpeg4vid_decoder_t decoder, int state);
|
||||
void MPEG4Video_EndOfStream(mpeg4vid_decoder_t decoder);
|
||||
void MPEG4Video_ReleaseFrame(mpeg4vid_decoder_t d, mp4_Frame *frame);
|
||||
#define MPEG4_PROFILE_SIMPLE 0
|
||||
#define MPEG4_PROFILE_SIMPLE_SCALABLE 1
|
||||
#define MPEG4_PROFILE_CORE 2
|
||||
#define MPEG4_PROFILE_MAIN 3
|
||||
#define MPEG4_PROFILE_NBIT 4
|
||||
#define MPEG4_PROFILE_SCALABLE_TEXTURE 5
|
||||
#define MPEG4_PROFILE_SIMPLE_FACE 6
|
||||
#define MPEG4_PROFILE_BASIC_ANIMATED_TEXTURE 7
|
||||
#define MPEG4_PROFILE_HYBRID 8
|
||||
#define MPEG4_PROFILE_ADVANCED_REAL_TIME_SIMPLE 9
|
||||
#define MPEG4_PROFILE_CORE_SCALABLE 10
|
||||
#define MPEG4_PROFILE_ADVANCED_CODE_EFFICIENCY 11
|
||||
#define MPEG4_PROFILE_ADVANCED_CORE 12
|
||||
#define MPEG4_PROFILE_ADVANCED_SCALABLE_TEXTURE 13
|
||||
#define MPEG4_PROFILE_STUDIO 14
|
||||
#define MPEG4_PROFILE_ADVANCED_SIMPLE 15
|
||||
#define MPEG4_PROFILE_FGS 16
|
||||
|
||||
#define MPEG4_LEVEL_0 0
|
||||
#define MPEG4_LEVEL_1 1
|
||||
#define MPEG4_LEVEL_2 2
|
||||
#define MPEG4_LEVEL_3 3
|
||||
#define MPEG4_LEVEL_4 4
|
||||
#define MPEG4_LEVEL_5 5
|
||||
#define MPEG4_LEVEL_3B 13
|
||||
|
||||
#define MPEG4_FILETYPE_RAW 0
|
||||
#define MPEG4_FILETYPE_MP4 1
|
||||
#define MPEG4_FILETYPE_AVI 2
|
||||
|
||||
#define MPEG4_CODEC_DEFAULT 0
|
||||
#define MPEG4_CODEC_DIVX5 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
Loading…
Add table
Add a link
Reference in a new issue