Home | History | Annotate | Download | only in src
      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