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 #include "mp4dec_lib.h" /* video decoder function prototypes */ 19 #include "vlc_decode.h" 20 #include "bitstream.h" 21 #include "scaling.h" 22 23 /* ====================================================================== / 24 Function : ConcealTexture_I() 25 Date : 06/12/2001 26 Purpose : Conceal texture for I-partition 27 In/out : 28 Return : 29 Modified : 30 / ====================================================================== */ 31 void ConcealTexture_I(VideoDecData *video, int32 startFirstPartition, int mb_start, int mb_stop, int slice_counter) 32 { 33 int mbnum; 34 BitstreamDecVideo *stream = video->bitstream; 35 int16 QP; 36 int intra_dc_vlc_thr = video->currVop->intraDCVlcThr; 37 38 movePointerTo(stream, startFirstPartition); 39 40 video->usePrevQP = 0; 41 for (mbnum = mb_start; mbnum < mb_stop; mbnum++) 42 { 43 video->mbnum = mbnum; 44 video->mbnum_row = PV_GET_ROW(mbnum, video->nMBPerRow); 45 video->mbnum_col = mbnum - video->mbnum_row * video->nMBPerRow; 46 video->sliceNo[mbnum] = (uint8) slice_counter; 47 QP = video->QPMB[mbnum]; 48 PV_VlcDecMCBPC_com_intra(stream); 49 GetMBheaderDataPart_DQUANT_DC(video, &QP); 50 51 if (intra_dc_vlc_thr) 52 { 53 if (video->usePrevQP) 54 QP = video->QPMB[mbnum-1]; 55 if (intra_dc_vlc_thr == 7 || QP >= intra_dc_vlc_thr*2 + 11) /* if switched then conceal from previous frame */ 56 { 57 ConcealPacket(video, mbnum, mb_stop, slice_counter); 58 video->mbnum = mb_stop - 1; 59 video->mbnum_row = PV_GET_ROW(video->mbnum, video->nMBPerRow); 60 video->mbnum_col = video->mbnum - video->mbnum_row * video->nMBPerRow; 61 break; 62 } 63 } 64 65 video->headerInfo.CBP[mbnum] = 0; 66 video->acPredFlag[mbnum] = 0; 67 GetMBData_DataPart(video); 68 video->usePrevQP = 1; 69 } 70 return; 71 } 72 73 /* ====================================================================== / 74 Function : ConcealTexture_P() 75 Date : 05/16/2000 76 Purpose : Conceal texture for P-partition 77 In/out : 78 Return : 79 / ====================================================================== */ 80 81 void ConcealTexture_P(VideoDecData *video, int mb_start, int mb_stop, int slice_counter) 82 { 83 int mbnum; 84 85 for (mbnum = mb_start; mbnum < mb_stop; mbnum++) 86 { 87 video->mbnum = mbnum; 88 video->mbnum_row = PV_GET_ROW(mbnum, video->nMBPerRow); 89 video->mbnum_col = mbnum - video->mbnum_row * video->nMBPerRow; 90 video->sliceNo[mbnum] = (uint8) slice_counter; 91 oscl_memset(video->mblock->block, 0, sizeof(typeMBStore)); 92 /* to get rid of dark region caused by INTRA blocks */ 93 /* 05/19/2000 */ 94 if (video->headerInfo.Mode[mbnum] & INTER_MASK) 95 { 96 MBMotionComp(video, 0); 97 } 98 else 99 { 100 video->headerInfo.Mode[mbnum] = MODE_SKIPPED; 101 SkippedMBMotionComp(video); 102 } 103 } 104 105 return; 106 } 107 108 /*************************************************************** 109 Function: ConcealPacket 110 Purpose : Conceal motion and texture of a packet by direct 111 copying from previous frame. 112 Returned: void 113 Modified: 114 *************************************************************/ 115 void ConcealPacket(VideoDecData *video, 116 int mb_start, 117 int mb_stop, 118 int slice_counter) 119 { 120 int i; 121 for (i = mb_start; i < mb_stop; i++) 122 { 123 CopyVopMB(video->currVop, video->concealFrame, i, video->width, video->height); 124 video->sliceNo[i] = (uint8) slice_counter; 125 video->headerInfo.Mode[i] = MODE_SKIPPED; 126 } 127 128 return; 129 } 130 131 /**************************************************************************** 132 Function: CopyVopMB 133 Purpose : Fill a macroblock with previous Vop. 134 Returned : void 135 Modified: 6/04/2001 rewrote the function 136 copies from concealFrame 137 ****************************************************************************/ 138 void CopyVopMB(Vop *curr, uint8 *prevFrame, int mbnum, int width_Y, int height) 139 { 140 int width_C = width_Y >> 1; 141 int row = MB_SIZE; 142 uint8 *y1, *y2, *u1, *u2, *v1, *v2; 143 int xpos, ypos, MB_in_width; 144 int32 lumstart, chrstart, size; 145 146 MB_in_width = (width_Y + 15) >> 4; 147 ypos = PV_GET_ROW(mbnum, MB_in_width); 148 xpos = mbnum - ypos * MB_in_width; 149 lumstart = (ypos << 4) * (int32)width_Y + (xpos << 4); 150 chrstart = (ypos << 3) * (int32)width_C + (xpos << 3); 151 152 size = (int32)height * width_Y; 153 154 y1 = curr->yChan + lumstart; 155 u1 = curr->uChan + chrstart; 156 v1 = curr->vChan + chrstart; 157 y2 = prevFrame + lumstart; 158 u2 = prevFrame + size + chrstart; 159 v2 = prevFrame + size + (size >> 2) + chrstart; 160 while (row) 161 { 162 oscl_memcpy(y1, y2, MB_SIZE); 163 y1 += width_Y; 164 y2 += width_Y; 165 oscl_memcpy(y1, y2, MB_SIZE); 166 y1 += width_Y; 167 y2 += width_Y; 168 oscl_memcpy(y1, y2, MB_SIZE); 169 y1 += width_Y; 170 y2 += width_Y; 171 oscl_memcpy(y1, y2, MB_SIZE); 172 y1 += width_Y; 173 y2 += width_Y; 174 175 oscl_memcpy(u1, u2, B_SIZE); 176 u1 += width_C; 177 u2 += width_C; 178 oscl_memcpy(u1, u2, B_SIZE); 179 u1 += width_C; 180 u2 += width_C; 181 182 oscl_memcpy(v1, v2, B_SIZE); 183 v1 += width_C; 184 v2 += width_C; 185 oscl_memcpy(v1, v2, B_SIZE); 186 v1 += width_C; 187 v2 += width_C; 188 189 row -= 4; 190 } 191 return; 192 } /* CopyVopMB */ 193 194