1 /* ------------------------------------------------------------------ 2 * Copyright (C) 1998-2009 PacketVideo 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 13 * express or implied. 14 * See the License for the specific language governing permissions 15 * and limitations under the License. 16 * ------------------------------------------------------------------- 17 */ 18 19 #define LOG_TAG "conceal" 20 21 #include "log/log.h" 22 23 #include "mp4dec_lib.h" /* video decoder function prototypes */ 24 #include "vlc_decode.h" 25 #include "bitstream.h" 26 #include "scaling.h" 27 28 /* ====================================================================== / 29 Function : ConcealTexture_I() 30 Date : 06/12/2001 31 Purpose : Conceal texture for I-partition 32 In/out : 33 Return : 34 Modified : 35 / ====================================================================== */ 36 void ConcealTexture_I(VideoDecData *video, int32 startFirstPartition, int mb_start, int mb_stop, int slice_counter) 37 { 38 int mbnum; 39 BitstreamDecVideo *stream = video->bitstream; 40 int16 QP; 41 int intra_dc_vlc_thr = video->currVop->intraDCVlcThr; 42 43 movePointerTo(stream, startFirstPartition); 44 45 video->usePrevQP = 0; 46 for (mbnum = mb_start; mbnum < mb_stop; mbnum++) 47 { 48 video->mbnum = mbnum; 49 video->mbnum_row = PV_GET_ROW(mbnum, video->nMBPerRow); 50 video->mbnum_col = mbnum - video->mbnum_row * video->nMBPerRow; 51 video->sliceNo[mbnum] = (uint8) slice_counter; 52 QP = video->QPMB[mbnum]; 53 PV_VlcDecMCBPC_com_intra(stream); 54 GetMBheaderDataPart_DQUANT_DC(video, &QP); 55 56 if (intra_dc_vlc_thr) 57 { 58 if (video->usePrevQP) 59 QP = video->QPMB[mbnum-1]; 60 if (intra_dc_vlc_thr == 7 || QP >= intra_dc_vlc_thr*2 + 11) /* if switched then conceal from previous frame */ 61 { 62 ConcealPacket(video, mbnum, mb_stop, slice_counter); 63 video->mbnum = mb_stop - 1; 64 video->mbnum_row = PV_GET_ROW(video->mbnum, video->nMBPerRow); 65 video->mbnum_col = video->mbnum - video->mbnum_row * video->nMBPerRow; 66 break; 67 } 68 } 69 70 video->headerInfo.CBP[mbnum] = 0; 71 video->acPredFlag[mbnum] = 0; 72 GetMBData_DataPart(video); 73 video->usePrevQP = 1; 74 } 75 return; 76 } 77 78 /* ====================================================================== / 79 Function : ConcealTexture_P() 80 Date : 05/16/2000 81 Purpose : Conceal texture for P-partition 82 In/out : 83 Return : 84 / ====================================================================== */ 85 86 void ConcealTexture_P(VideoDecData *video, int mb_start, int mb_stop, int slice_counter) 87 { 88 int mbnum; 89 90 for (mbnum = mb_start; mbnum < mb_stop; mbnum++) 91 { 92 video->mbnum = mbnum; 93 video->mbnum_row = PV_GET_ROW(mbnum, video->nMBPerRow); 94 video->mbnum_col = mbnum - video->mbnum_row * video->nMBPerRow; 95 video->sliceNo[mbnum] = (uint8) slice_counter; 96 oscl_memset(video->mblock->block, 0, sizeof(typeMBStore)); 97 /* to get rid of dark region caused by INTRA blocks */ 98 /* 05/19/2000 */ 99 if (video->headerInfo.Mode[mbnum] & INTER_MASK) 100 { 101 MBMotionComp(video, 0); 102 } 103 else 104 { 105 video->headerInfo.Mode[mbnum] = MODE_SKIPPED; 106 SkippedMBMotionComp(video); 107 } 108 } 109 110 return; 111 } 112 113 /*************************************************************** 114 Function: ConcealPacket 115 Purpose : Conceal motion and texture of a packet by direct 116 copying from previous frame. 117 Returned: void 118 Modified: 119 *************************************************************/ 120 void ConcealPacket(VideoDecData *video, 121 int mb_start, 122 int mb_stop, 123 int slice_counter) 124 { 125 int i; 126 for (i = mb_start; i < mb_stop; i++) 127 { 128 CopyVopMB(video->currVop, video->concealFrame, i, video->width, video->height); 129 video->sliceNo[i] = (uint8) slice_counter; 130 video->headerInfo.Mode[i] = MODE_SKIPPED; 131 } 132 133 return; 134 } 135 136 /**************************************************************************** 137 Function: CopyVopMB 138 Purpose : Fill a macroblock with previous Vop. 139 Returned : void 140 Modified: 6/04/2001 rewrote the function 141 copies from concealFrame 142 ****************************************************************************/ 143 void CopyVopMB(Vop *curr, uint8 *prevFrame, int mbnum, int width_Y, int height) 144 { 145 if (curr == NULL || prevFrame == NULL) { 146 ALOGE("b/24630158"); 147 return; 148 } 149 int width_C = width_Y >> 1; 150 int row = MB_SIZE; 151 uint8 *y1, *y2, *u1, *u2, *v1, *v2; 152 int xpos, ypos, MB_in_width; 153 int32 lumstart, chrstart, size; 154 155 MB_in_width = (width_Y + 15) >> 4; 156 ypos = PV_GET_ROW(mbnum, MB_in_width); 157 xpos = mbnum - ypos * MB_in_width; 158 lumstart = (ypos << 4) * (int32)width_Y + (xpos << 4); 159 chrstart = (ypos << 3) * (int32)width_C + (xpos << 3); 160 161 size = (int32)height * width_Y; 162 163 y1 = curr->yChan + lumstart; 164 u1 = curr->uChan + chrstart; 165 v1 = curr->vChan + chrstart; 166 y2 = prevFrame + lumstart; 167 u2 = prevFrame + size + chrstart; 168 v2 = prevFrame + size + (size >> 2) + chrstart; 169 while (row) 170 { 171 oscl_memcpy(y1, y2, MB_SIZE); 172 y1 += width_Y; 173 y2 += width_Y; 174 oscl_memcpy(y1, y2, MB_SIZE); 175 y1 += width_Y; 176 y2 += width_Y; 177 oscl_memcpy(y1, y2, MB_SIZE); 178 y1 += width_Y; 179 y2 += width_Y; 180 oscl_memcpy(y1, y2, MB_SIZE); 181 y1 += width_Y; 182 y2 += width_Y; 183 184 oscl_memcpy(u1, u2, B_SIZE); 185 u1 += width_C; 186 u2 += width_C; 187 oscl_memcpy(u1, u2, B_SIZE); 188 u1 += width_C; 189 u2 += width_C; 190 191 oscl_memcpy(v1, v2, B_SIZE); 192 v1 += width_C; 193 v2 += width_C; 194 oscl_memcpy(v1, v2, B_SIZE); 195 v1 += width_C; 196 v2 += width_C; 197 198 row -= 4; 199 } 200 return; 201 } /* CopyVopMB */ 202 203