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