📄 swdec_processblock.c
字号:
u32 refQP;
u32 col;
ASSERT(pDecContainer);
ASSERT(pData);
ASSERT(mbNum < pDecContainer->VopDesc.totalMbInVop);
ASSERT(blockNum < 6);
ASSERT(scanDir <= SCAN_VER);
ASSERT(pDecContainer->MbDesc[mbNum].QP);
ASSERT(pDecContainer->MbDesc[mbNum].QP < 32);
ASSERT(!(pDecContainer->MbDesc[mbNum].flags & INTER_MB_MASK));
QP = pDecContainer->MbDesc[mbNum].QP;
col = pDecContainer->StrmStorage.col[mbNum];
refQP = pDecContainer->StrmStorage.predictorQP;
/* dc prediction + quantization */
if (blockNum < 4)
{
pData[0] += DIV_W_ROUND(pDecContainer->StrmStorage.predictor,
dcScalerLum[QP]);
pData[0] *= (i32)dcScalerLum[QP];
p1 = pDecContainer->StrmStorage.horLumAcCoeff +
14*col + 7*(blockNum&0x1);
p2 = pDecContainer->StrmStorage.verLumAcCoeff +
7*(blockNum>>1);
}
else
{
pData[0] += DIV_W_ROUND(pDecContainer->StrmStorage.predictor,
dcScalerChr[QP]);
pData[0] *= (i32)dcScalerChr[QP];
p1 = pDecContainer->StrmStorage.horChrAcCoeff +
14*col + 7*(blockNum&0x1);
p2 = pDecContainer->StrmStorage.verChrAcCoeff +
7*(blockNum&0x1);
}
SATURATE(-2048,pData[0],2047);
/* store inverse quantized dc coefficient */
pDecContainer->MbDesc[mbNum].data[blockNum] = (i16)pData[0];
/* ac prediction */
if ( (pDecContainer->MbDesc[mbNum].flags & AC_PRED_FLAG_MASK) &&
!pDecContainer->StrmStorage.isDefaultPredictor )
{
if (scanDir == SCAN_HOR)
{
for (i = 7; i; i--)
{
pData++;
/* add predictor value */
*pData += DIV_W_ROUND((*p1)*(i32)refQP, QP);
SATURATE(-2048,*pData,2047);
p1++;
}
p1-=7;
pData -= 7;
/* set NumIdctRows if block was empty */
if (!pDecContainer->StrmStorage.numIdctRows)
{
pDecContainer->StrmStorage.numIdctRows = 1;
}
}
else /* SCAN_VER */
{
for (i = 1; i < 8; i++)
{
pData += 8;
/* add predictor value */
*pData += DIV_W_ROUND((*p2)*(i32)refQP, QP);
SATURATE(-2048,*pData,2047);
/* increment NumIdctRows if necessary */
if (*pData &&
(i >= pDecContainer->StrmStorage.numIdctRows))
{
pDecContainer->StrmStorage.numIdctRows = i+1;
}
p2++;
}
p2-=7;
pData -= 56;
}
}
/* copy first row and column into storage */
for (i = 7; i; i--)
{
pData++;
*p1++ = *pData;
}
pData -= 7;
for (i = 7; i; i--)
{
pData += 8;
*p2++ = *pData;
}
pData -= 56;
/* dequantize 1. row and 1. column */
for (i = 7; i; i--)
{
pData++;
DEQUANTIZE((*pData), QP);
}
pData -= 7;
for (i = 7; i; i--)
{
pData += 8;
DEQUANTIZE(*pData, QP);
}
}
#endif
/*------------------------------------------------------------------------------
5.12 Function name: SwDec_WriteIntraOutput
Purpose: Write intra block into output picture. Function clips 32-bit
data (already in range [-256,255] after clipping in Idct) into
range [0,255].
Input:
pDecContainer pointer to decContainer_t
data pointer to data to be written
mbNum
blockNum
Output:
------------------------------------------------------------------------------*/
void SwDec_WriteIntraOutput(decContainer_t *pDecContainer, i32 *pData,
u32 mbNum, u32 blockNum)
{
u32 i;
u32 width;
u32 rowOffset,colOffset;
u8 *pOut;
#ifndef MP4DEC_ARM11
const u8* pClipTable = clip+256;
#else
u32 tmp;
#endif
ASSERT(pDecContainer);
ASSERT(pData);
ASSERT(mbNum < pDecContainer->VopDesc.totalMbInVop);
ASSERT(blockNum < 6);
/* luminance */
if (blockNum < 4)
{
width = pDecContainer->VopDesc.vopWidth*16;
rowOffset = pDecContainer->StrmStorage.row[mbNum]*16 +
(blockNum>>1)*8;
colOffset = pDecContainer->StrmStorage.col[mbNum]*16 +
(blockNum&0x1)*8;
pOut = pDecContainer->pOut + rowOffset*width + colOffset;
}
/* chrominance */
else
{
width = pDecContainer->VopDesc.vopWidth*8;
rowOffset = pDecContainer->StrmStorage.row[mbNum]*8;
colOffset = pDecContainer->StrmStorage.col[mbNum]*8;
pOut = pDecContainer->pOut +
(256+(blockNum&0x1)*64)*pDecContainer->VopDesc.vopWidth*
pDecContainer->VopDesc.vopHeight +
rowOffset*width + colOffset;
}
#ifndef MP4DEC_ARM11
/* write whole block into output picture */
for (i = 4; i; i--)
{
pOut[0] = pClipTable[*(pData++)];
pOut[1] = pClipTable[*(pData++)];
pOut[2] = pClipTable[*(pData++)];
pOut[3] = pClipTable[*(pData++)];
pOut[4] = pClipTable[*(pData++)];
pOut[5] = pClipTable[*(pData++)];
pOut[6] = pClipTable[*(pData++)];
pOut[7] = pClipTable[*(pData++)];
pOut += width;
pOut[0] = pClipTable[*(pData++)];
pOut[1] = pClipTable[*(pData++)];
pOut[2] = pClipTable[*(pData++)];
pOut[3] = pClipTable[*(pData++)];
pOut[4] = pClipTable[*(pData++)];
pOut[5] = pClipTable[*(pData++)];
pOut[6] = pClipTable[*(pData++)];
pOut[7] = pClipTable[*(pData++)];
pOut += width;
}
#else
/* clip by using ARM11 SIMD saturation instructions */
__asm
{
MOV i, #8;
loop:
LDR tmp, [pData], #4; /* load byte */
USAT tmp, #8, tmp; /* saturate [0,255] */
STRB tmp, [pOut, #0]; /* store byte (write to output picture) */
LDR tmp, [pData], #4; /* AND SO ON... */
USAT tmp, #8, tmp;
STRB tmp, [pOut, #1];
LDR tmp, [pData], #4;
USAT tmp, #8, tmp;
STRB tmp, [pOut, #2];
LDR tmp, [pData], #4;
USAT tmp, #8, tmp;
STRB tmp, [pOut, #3];
LDR tmp, [pData], #4;
USAT tmp, #8, tmp;
STRB tmp, [pOut, #4];
LDR tmp, [pData], #4;
USAT tmp, #8, tmp;
STRB tmp, [pOut, #5];
LDR tmp, [pData], #4;
USAT tmp, #8, tmp;
STRB tmp, [pOut, #6];
LDR tmp, [pData], #4;
USAT tmp, #8, tmp;
STRB tmp, [pOut, #7];
ADD pOut, pOut, width;
SUBS i, i, #1;
BNE loop
}
#endif
}
/*------------------------------------------------------------------------------
5.13 Function name: SwDec_WriteInterOutput
Purpose: Write inter block into output picture.
Input:
pDecContainer pointer to decContainer_t
pData pointer to data to be written
mbNum
blockNum
Output:
------------------------------------------------------------------------------*/
void SwDec_WriteInterOutput(decContainer_t *pDecContainer, u8 *pData,
u32 mbNum, u32 blockNum)
{
u32 width;
u32 tmp1,tmp2;
u32 rowOffset,colOffset;
u8 *pOut;
u32 *p1,*p2;
ASSERT(pDecContainer);
ASSERT(pData);
ASSERT(mbNum < pDecContainer->VopDesc.totalMbInVop);
ASSERT(blockNum < 6);
/* luminance */
if (blockNum < 4)
{
width = pDecContainer->VopDesc.vopWidth*16;
rowOffset = pDecContainer->StrmStorage.row[mbNum]*16 +
(blockNum>>1)*8;
colOffset = pDecContainer->StrmStorage.col[mbNum]*16 +
(blockNum&0x1)*8;
pOut = pDecContainer->pOut + rowOffset*width + colOffset;
}
/* chrominance */
else
{
width = pDecContainer->VopDesc.vopWidth*8;
rowOffset = pDecContainer->StrmStorage.row[mbNum]*8;
colOffset = pDecContainer->StrmStorage.col[mbNum]*8;
pOut = pDecContainer->pOut +
(256+(blockNum&0x1)*64)*pDecContainer->VopDesc.vopWidth*
pDecContainer->VopDesc.vopHeight +
rowOffset*width + colOffset;
}
/* write whole block into output picture */
p1 = (u32*)pOut;
p2 = (u32*)pData;
tmp1 = *p2++;
tmp2 = *p2++;
p1[0] = tmp1;
p1[1] = tmp2;
p1 += width>>2;
tmp1 = *p2++;
tmp2 = *p2++;
p1[0] = tmp1;
p1[1] = tmp2;
p1 += width>>2;
tmp1 = *p2++;
tmp2 = *p2++;
p1[0] = tmp1;
p1[1] = tmp2;
p1 += width>>2;
tmp1 = *p2++;
tmp2 = *p2++;
p1[0] = tmp1;
p1[1] = tmp2;
p1 += width>>2;
tmp1 = *p2++;
tmp2 = *p2++;
p1[0] = tmp1;
p1[1] = tmp2;
p1 += width>>2;
tmp1 = *p2++;
tmp2 = *p2++;
p1[0] = tmp1;
p1[1] = tmp2;
p1 += width>>2;
tmp1 = *p2++;
tmp2 = *p2++;
p1[0] = tmp1;
p1[1] = tmp2;
p1 += width>>2;
tmp1 = *p2++;
tmp2 = *p2++;
p1[0] = tmp1;
p1[1] = tmp2;
p1 += width>>2;
}
/*------------------------------------------------------------------------------
5.14 Function name: SwDec_CopyOutput
Purpose: Copy whole macroblock from reference picture into output
picture
Input:
pDecContainer pointer to decContainer_t
mbNum
Output:
------------------------------------------------------------------------------*/
void SwDec_CopyOutput(decContainer_t *pDecContainer, u32 mbNum)
{
u32 width;
u32 i;
u32 rowOffset,colOffset;
u8 *pOut;
u8 *pRef;
u32 *p1,*p2;
u32 tmp1,tmp2,tmp3,tmp4,tmp5;
ASSERT(pDecContainer);
ASSERT(mbNum < pDecContainer->VopDesc.totalMbInVop);
width = pDecContainer->VopDesc.vopWidth*16;
rowOffset = pDecContainer->StrmStorage.row[mbNum]*16;
colOffset = pDecContainer->StrmStorage.col[mbNum]*16;
pOut = pDecContainer->pOut + rowOffset*width + colOffset;
pRef = pDecContainer->pRef + rowOffset*width + colOffset;
/* copy luminance blocks, copy as u32s instead of u8s */
p1 = (u32*)pOut;
p2 = (u32*)pRef;
tmp5 = width>>2;
for (i = 8; i; i--)
{
tmp1 = p2[0];
tmp2 = p2[1];
tmp3 = p2[2];
tmp4 = p2[3];
p1[0] = tmp1;
p1[1] = tmp2;
p1[2] = tmp3;
p1[3] = tmp4;
p1 += tmp5;
p2 += tmp5;
tmp1 = p2[0];
tmp2 = p2[1];
tmp3 = p2[2];
tmp4 = p2[3];
p1[0] = tmp1;
p1[1] = tmp2;
p1[2] = tmp3;
p1[3] = tmp4;
p1 += tmp5;
p2 += tmp5;
}
width = pDecContainer->VopDesc.vopWidth*8;
rowOffset = pDecContainer->StrmStorage.row[mbNum]*8;
colOffset = pDecContainer->StrmStorage.col[mbNum]*8;
pOut = pDecContainer->pOut +
256*pDecContainer->VopDesc.vopWidth*
pDecContainer->VopDesc.vopHeight +
rowOffset*width + colOffset;
pRef = pDecContainer->pRef +
256*pDecContainer->VopDesc.vopWidth*
pDecContainer->VopDesc.vopHeight +
rowOffset*width + colOffset;
/* chroma (cb) */
p1 = (u32*)pOut;
p2 = (u32*)pRef;
tmp5 = width>>2;
for (i = 4; i; i--)
{
tmp1 = p2[0];
tmp2 = p2[1];
p1[0] = tmp1;
p1[1] = tmp2;
p1 += tmp5;
p2 += tmp5;
tmp1 = p2[0];
tmp2 = p2[1];
p1[0] = tmp1;
p1[1] = tmp2;
p1 += tmp5;
p2 += tmp5;
}
pOut = pDecContainer->pOut +
320*pDecContainer->VopDesc.vopWidth*
pDecContainer->VopDesc.vopHeight +
rowOffset*width + colOffset;
pRef = pDecContainer->pRef +
320*pDecContainer->VopDesc.vopWidth*
pDecContainer->VopDesc.vopHeight +
rowOffset*width + colOffset;
/* chroma (cr) */
p1 = (u32*)pOut;
p2 = (u32*)pRef;
tmp5 = width>>2;
for (i = 4; i; i--)
{
tmp1 = p2[0];
tmp2 = p2[1];
p1[0] = tmp1;
p1[1] = tmp2;
p1 += tmp5;
p2 += tmp5;
tmp1 = p2[0];
tmp2 = p2[1];
p1[0] = tmp1;
p1[1] = tmp2;
p1 += tmp5;
p2 += tmp5;
}
}
/*lint +e826 +e702 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -