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********/
PV_ReadVideoPacketHeader(VideoDecData * video,int * next_MB)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********/
PV_GobHeader(VideoDecData * video)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
PV_H263SliceHeader(VideoDecData * video,int * next_MB)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