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********/
28PV_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********/
144PV_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
194PV_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