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" 19 #include "vlc_decode.h" 20 #include "bitstream.h" 21 22 23 /***********************************************************CommentBegin****** 24 * 04/13/2000 : initial modification to the new PV-Decoder 25 * Lib format. 26 * 04/16/2001 : Removed PV_END_OF_BUFFER case, error resilience 27 ***********************************************************CommentEnd********/ 28 PV_STATUS PV_ReadVideoPacketHeader(VideoDecData *video, int *next_MB) 29 { 30 PV_STATUS status; 31 Vol *currVol = video->vol[video->currLayer]; 32 Vop *currVop = video->currVop; 33 BitstreamDecVideo *stream = video->bitstream; 34 int fcode_forward; 35 int resync_marker_length; 36 int nbits = video->nBitsForMBID; 37 uint32 tmpvar32; 38 uint tmpvar16; 39 int16 quantizer; 40 int nTotalMB = video->nTotalMB; 41 42 fcode_forward = currVop->fcodeForward; 43 resync_marker_length = 17; 44 45 if (currVop->predictionType != I_VOP) resync_marker_length = 16 + fcode_forward; 46 47 status = PV_BitstreamShowBitsByteAlign(stream, resync_marker_length, &tmpvar32); 48 /* if (status != PV_SUCCESS && status != PV_END_OF_BUFFER) return status; */ 49 if (tmpvar32 == RESYNC_MARKER) 50 { 51 // DecNextStartCode(stream); 52 PV_BitstreamByteAlign(stream); 53 BitstreamReadBits32(stream, resync_marker_length); 54 55 int mbnum = (int) BitstreamReadBits16(stream, nbits); 56 if (mbnum < 0) { 57 return PV_FAIL; 58 } 59 *next_MB = mbnum; 60 // if (*next_MB <= video->mbnum) /* needs more investigation */ 61 // *next_MB = video->mbnum+1; 62 63 if (*next_MB >= nTotalMB) /* fix 04/05/01 */ 64 { 65 *next_MB = video->mbnum + 1; 66 if (*next_MB >= nTotalMB) /* this check is needed */ 67 *next_MB = nTotalMB - 1; 68 } 69 quantizer = (int16) BitstreamReadBits16(stream, currVol->quantPrecision); 70 if (quantizer == 0) return PV_FAIL; /* 04/03/01 */ 71 72 currVop->quantizer = quantizer; 73 74 /* if we have HEC, read some redundant VOP header information */ 75 /* this part needs improvement 04/05/01 */ 76 if (BitstreamRead1Bits(stream)) 77 { 78 int time_base = -1; 79 80 /* modulo_time_base (? bits) */ 81 do 82 { 83 time_base++; 84 tmpvar16 = BitstreamRead1Bits(stream); 85 } 86 while (tmpvar16 == 1); 87 88 /* marker bit */ 89 BitstreamRead1Bits(stream); 90 91 /* vop_time_increment (1-15 bits) */ 92 BitstreamReadBits16(stream, currVol->nbitsTimeIncRes); 93 94 /* marker bit */ 95 BitstreamRead1Bits(stream); 96 97 /* vop_prediction_type (2 bits) */ 98 BitstreamReadBits16(stream, 2); 99 100 /* Added intra_dc_vlc_thr reading */ 101 BitstreamReadBits16(stream, 3); 102 103 /* fcodes */ 104 if (currVop->predictionType != I_VOP) 105 { 106 fcode_forward = (int) BitstreamReadBits16(stream, 3); 107 108 if (currVop->predictionType == B_VOP) 109 { 110 BitstreamReadBits16(stream, 3); 111 } 112 } 113 114 } 115 } 116 else 117 { 118 PV_BitstreamByteAlign(stream); /* */ 119 status = BitstreamCheckEndBuffer(stream); /* return end_of_VOP 03/30/01 */ 120 if (status != PV_SUCCESS) 121 { 122 return status; 123 } 124 status = BitstreamShowBits32HC(stream, &tmpvar32); /* 07/07/01 */ 125 /* -16 = 0xFFFFFFF0*/ 126 if ((tmpvar32 & 0xFFFFFFF0) == VISUAL_OBJECT_SEQUENCE_START_CODE) /* start code mask 00 00 01 */ 127 128 { 129 /* we don't have to check for legl stuffing here. 05/08/2000 */ 130 return PV_END_OF_VOP; 131 } 132 else 133 { 134 return PV_FAIL; 135 } 136 } 137 138 return PV_SUCCESS; 139 } 140 141 142 143 /***********************************************************CommentBegin****** 144 * 3/10/00 : initial modification to the 145 * new PV-Decoder Lib format. 146 * 04/17/01 : remove PV_END_OF_BUFFER, error checking 147 ***********************************************************CommentEnd********/ 148 PV_STATUS PV_GobHeader(VideoDecData *video) 149 { 150 uint32 tmpvar; 151 Vop *currVop = video->currVop; 152 BitstreamDecVideo *stream = video->bitstream; 153 int quantPrecision = 5; 154 int16 quantizer; 155 156 BitstreamShowBits32(stream, GOB_RESYNC_MARKER_LENGTH, &tmpvar); 157 158 if (tmpvar != GOB_RESYNC_MARKER) 159 { 160 PV_BitstreamShowBitsByteAlign(stream, GOB_RESYNC_MARKER_LENGTH, &tmpvar); 161 162 if (tmpvar != GOB_RESYNC_MARKER) 163 { 164 return PV_FAIL; 165 } 166 else 167 PV_BitstreamByteAlign(stream); /* if bytealigned GOBHEADER search is performed */ 168 /* then no more noforcestuffing */ 169 } 170 171 /* we've got a GOB header info here */ 172 BitstreamShowBits32(stream, GOB_RESYNC_MARKER_LENGTH + 5, &tmpvar); 173 tmpvar &= 0x1F; 174 175 if (tmpvar == 0) 176 { 177 return PV_END_OF_VOP; 178 } 179 180 if (tmpvar == 31) 181 { 182 PV_BitstreamFlushBits(stream, GOB_RESYNC_MARKER_LENGTH + 5); 183 BitstreamByteAlignNoForceStuffing(stream); 184 return PV_END_OF_VOP; 185 } 186 187 PV_BitstreamFlushBits(stream, GOB_RESYNC_MARKER_LENGTH + 5); 188 currVop->gobNumber = (int) tmpvar; 189 if (currVop->gobNumber >= video->nGOBinVop) return PV_FAIL; 190 currVop->gobFrameID = (int) BitstreamReadBits16(stream, 2); 191 quantizer = (int16) BitstreamReadBits16(stream, quantPrecision); 192 if (quantizer == 0) return PV_FAIL; /* 04/03/01 */ 193 194 currVop->quantizer = quantizer; 195 return PV_SUCCESS; 196 } 197 #ifdef PV_ANNEX_IJKT_SUPPORT 198 PV_STATUS PV_H263SliceHeader(VideoDecData *video, int *next_MB) 199 { 200 PV_STATUS status; 201 uint32 tmpvar; 202 Vop *currVop = video->currVop; 203 BitstreamDecVideo *stream = video->bitstream; 204 int nTotalMB = video->nTotalMB; 205 int16 quantizer; 206 207 PV_BitstreamShowBitsByteAlignNoForceStuffing(stream, 17, &tmpvar); 208 if (tmpvar == RESYNC_MARKER) 209 { 210 BitstreamByteAlignNoForceStuffing(stream); 211 PV_BitstreamFlushBits(stream, 17); 212 if (!BitstreamRead1Bits(stream)) 213 { 214 return PV_FAIL; 215 } 216 *next_MB = BitstreamReadBits16(stream, video->nBitsForMBID); 217 if (*next_MB >= nTotalMB) /* fix 04/05/01 */ 218 { 219 *next_MB = video->mbnum + 1; 220 if (*next_MB >= nTotalMB) /* this check is needed */ 221 *next_MB = nTotalMB - 1; 222 } 223 /* we will not parse sebp2 for large pictures 3GPP */ 224 quantizer = (int16) BitstreamReadBits16(stream, 5); 225 if (quantizer == 0) return PV_FAIL; 226 227 currVop->quantizer = quantizer; 228 if (!BitstreamRead1Bits(stream)) 229 { 230 return PV_FAIL; 231 } 232 currVop->gobFrameID = (int) BitstreamReadBits16(stream, 2); 233 } 234 else 235 { 236 status = BitstreamCheckEndBuffer(stream); /* return end_of_VOP 03/30/01 */ 237 if (status != PV_SUCCESS) 238 { 239 return status; 240 } 241 PV_BitstreamShowBitsByteAlign(stream, SHORT_VIDEO_START_MARKER_LENGTH, &tmpvar); 242 243 if (tmpvar == SHORT_VIDEO_START_MARKER) 244 { 245 /* we don't have to check for legal stuffing here. 05/08/2000 */ 246 return PV_END_OF_VOP; 247 } 248 else 249 { 250 return PV_FAIL; 251 } 252 } 253 return PV_SUCCESS; 254 } 255 #endif 256 257