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