blob: 03e4119b95716378f27ad11857d88fae08da1385 [file] [log] [blame]
/* ------------------------------------------------------------------
* Copyright (C) 1998-2009 PacketVideo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied.
* See the License for the specific language governing permissions
* and limitations under the License.
* -------------------------------------------------------------------
*/
#include "mp4dec_lib.h" /* video decoder function prototypes */
#include "vlc_decode.h"
#include "bitstream.h"
#include "scaling.h"
#include "log/log.h"
/* ====================================================================== /
Function : ConcealTexture_I()
Date : 06/12/2001
Purpose : Conceal texture for I-partition
In/out :
Return :
Modified :
/ ====================================================================== */
void ConcealTexture_I(VideoDecData *video, int32 startFirstPartition, int mb_start, int mb_stop, int slice_counter)
{
int mbnum;
BitstreamDecVideo *stream = video->bitstream;
int16 QP;
int intra_dc_vlc_thr = video->currVop->intraDCVlcThr;
movePointerTo(stream, startFirstPartition);
video->usePrevQP = 0;
for (mbnum = mb_start; mbnum < mb_stop; mbnum++)
{
video->mbnum = mbnum;
video->mbnum_row = PV_GET_ROW(mbnum, video->nMBPerRow);
video->mbnum_col = mbnum - video->mbnum_row * video->nMBPerRow;
video->sliceNo[mbnum] = (uint8) slice_counter;
QP = video->QPMB[mbnum];
PV_VlcDecMCBPC_com_intra(stream);
GetMBheaderDataPart_DQUANT_DC(video, &QP);
if (intra_dc_vlc_thr)
{
if (video->usePrevQP)
QP = video->QPMB[mbnum-1];
if (intra_dc_vlc_thr == 7 || QP >= intra_dc_vlc_thr*2 + 11) /* if switched then conceal from previous frame */
{
ConcealPacket(video, mbnum, mb_stop, slice_counter);
video->mbnum = mb_stop - 1;
video->mbnum_row = PV_GET_ROW(video->mbnum, video->nMBPerRow);
video->mbnum_col = video->mbnum - video->mbnum_row * video->nMBPerRow;
break;
}
}
video->headerInfo.CBP[mbnum] = 0;
video->acPredFlag[mbnum] = 0;
GetMBData_DataPart(video);
video->usePrevQP = 1;
}
return;
}
/* ====================================================================== /
Function : ConcealTexture_P()
Date : 05/16/2000
Purpose : Conceal texture for P-partition
In/out :
Return :
/ ====================================================================== */
void ConcealTexture_P(VideoDecData *video, int mb_start, int mb_stop, int slice_counter)
{
int mbnum;
for (mbnum = mb_start; mbnum < mb_stop; mbnum++)
{
video->mbnum = mbnum;
video->mbnum_row = PV_GET_ROW(mbnum, video->nMBPerRow);
video->mbnum_col = mbnum - video->mbnum_row * video->nMBPerRow;
video->sliceNo[mbnum] = (uint8) slice_counter;
oscl_memset(video->mblock->block, 0, sizeof(typeMBStore));
/* to get rid of dark region caused by INTRA blocks */
/* 05/19/2000 */
if (video->headerInfo.Mode[mbnum] & INTER_MASK)
{
MBMotionComp(video, 0);
}
else
{
video->headerInfo.Mode[mbnum] = MODE_SKIPPED;
SkippedMBMotionComp(video);
}
}
return;
}
/***************************************************************
Function: ConcealPacket
Purpose : Conceal motion and texture of a packet by direct
copying from previous frame.
Returned: void
Modified:
*************************************************************/
void ConcealPacket(VideoDecData *video,
int mb_start,
int mb_stop,
int slice_counter)
{
int i;
for (i = mb_start; i < mb_stop; i++)
{
CopyVopMB(video->currVop, video->concealFrame, i, video->width, video->height);
video->sliceNo[i] = (uint8) slice_counter;
video->headerInfo.Mode[i] = MODE_SKIPPED;
}
return;
}
/****************************************************************************
Function: CopyVopMB
Purpose : Fill a macroblock with previous Vop.
Returned : void
Modified: 6/04/2001 rewrote the function
copies from concealFrame
****************************************************************************/
void CopyVopMB(Vop *curr, uint8 *prevFrame, int mbnum, int width_Y, int height)
{
if (curr == NULL || prevFrame == NULL) {
ALOGE("b/24630158");
return;
}
int width_C = width_Y >> 1;
int row = MB_SIZE;
uint8 *y1, *y2, *u1, *u2, *v1, *v2;
int xpos, ypos, MB_in_width;
int32 lumstart, chrstart, size;
MB_in_width = (width_Y + 15) >> 4;
ypos = PV_GET_ROW(mbnum, MB_in_width);
xpos = mbnum - ypos * MB_in_width;
lumstart = (ypos << 4) * (int32)width_Y + (xpos << 4);
chrstart = (ypos << 3) * (int32)width_C + (xpos << 3);
size = (int32)height * width_Y;
y1 = curr->yChan + lumstart;
u1 = curr->uChan + chrstart;
v1 = curr->vChan + chrstart;
y2 = prevFrame + lumstart;
u2 = prevFrame + size + chrstart;
v2 = prevFrame + size + (size >> 2) + chrstart;
while (row)
{
oscl_memcpy(y1, y2, MB_SIZE);
y1 += width_Y;
y2 += width_Y;
oscl_memcpy(y1, y2, MB_SIZE);
y1 += width_Y;
y2 += width_Y;
oscl_memcpy(y1, y2, MB_SIZE);
y1 += width_Y;
y2 += width_Y;
oscl_memcpy(y1, y2, MB_SIZE);
y1 += width_Y;
y2 += width_Y;
oscl_memcpy(u1, u2, B_SIZE);
u1 += width_C;
u2 += width_C;
oscl_memcpy(u1, u2, B_SIZE);
u1 += width_C;
u2 += width_C;
oscl_memcpy(v1, v2, B_SIZE);
v1 += width_C;
v2 += width_C;
oscl_memcpy(v1, v2, B_SIZE);
v1 += width_C;
v2 += width_C;
row -= 4;
}
return;
} /* CopyVopMB */