/media/libstagefright/codecs/m4v_h263/dec/src/vop.cpp
C++ | 1643 lines | 1160 code | 196 blank | 287 comment | 369 complexity | 49ebd2c85a47c4f2a64f087595ad92c4 MD5 | raw file
Large files files are truncated, but you can click here to view the full file
- /* ------------------------------------------------------------------
- * Copyright (C) 1998-2009 PacketVideo
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- * -------------------------------------------------------------------
- */
- #include "mp4dec_lib.h"
- #include "bitstream.h"
- #include "vlc_decode.h"
- #include "zigzag.h"
- #define OSCL_DISABLE_WARNING_CONV_POSSIBLE_LOSS_OF_DATA
- #ifdef PV_SUPPORT_MAIN_PROFILE
- /* INTRA */
- const static int mpeg_iqmat_def[NCOEFF_BLOCK] =
- {
- 8, 17, 18, 19, 21, 23, 25, 27,
- 17, 18, 19, 21, 23, 25, 27, 28,
- 20, 21, 22, 23, 24, 26, 28, 30,
- 21, 22, 23, 24, 26, 28, 30, 32,
- 22, 23, 24, 26, 28, 30, 32, 35,
- 23, 24, 26, 28, 30, 32, 35, 38,
- 25, 26, 28, 30, 32, 35, 38, 41,
- 27, 28, 30, 32, 35, 38, 41, 45
- };
- /* INTER */
- const static int mpeg_nqmat_def[64] =
- {
- 16, 17, 18, 19, 20, 21, 22, 23,
- 17, 18, 19, 20, 21, 22, 23, 24,
- 18, 19, 20, 21, 22, 23, 24, 25,
- 19, 20, 21, 22, 23, 24, 26, 27,
- 20, 21, 22, 23, 25, 26, 27, 28,
- 21, 22, 23, 24, 26, 27, 28, 30,
- 22, 23, 24, 26, 27, 28, 30, 31,
- 23, 24, 25, 27, 28, 30, 31, 33
- };
- #endif
- /* ======================================================================== */
- /* Function : CalcNumBits() */
- /* Purpose : */
- /* In/out : */
- /* Return : Calculate the minimum number of bits required to */
- /* represent x. */
- /* Note : This is an equivalent implementation of */
- /* (long)ceil(log((double)x)/log(2.0)) */
- /* Modified : */
- /* ======================================================================== */
- int CalcNumBits(uint x)
- {
- int i = 1;
- while (x >>= 1) i++;
- return i;
- }
- /***********************************************************CommentBegin******
- *
- * -- DecodeVolHeader -- Decode the header of a VOL
- *
- * 04/10/2000 : initial modification to the new PV-Decoder Lib format.
- * 10/12/2001 : reject non compliant bitstreams
- *
- ***********************************************************CommentEnd********/
- PV_STATUS DecodeVOLHeader(VideoDecData *video, int layer)
- {
- PV_STATUS status;
- Vol *currVol;
- BitstreamDecVideo *stream;
- uint32 tmpvar, vol_shape;
- uint32 startCode;
- #ifdef PV_SUPPORT_MAIN_PROFILE
- int *qmat, i, j;
- #endif
- int version_id = 1;
- #ifdef PV_TOLERATE_VOL_ERRORS
- uint32 profile = 0x01;
- #endif
- /* There's a "currLayer" variable inside videoDecData. */
- /* However, we don't maintain it until we decode frame data. 04/05/2000 */
- currVol = video->vol[layer];
- stream = currVol->bitstream;
- currVol->moduloTimeBase = 0;
- /* Determine which start code for the decoder to begin with */
- status = BitstreamShowBits32HC(stream, &startCode);
- if (startCode == VISUAL_OBJECT_SEQUENCE_START_CODE)
- { /* Bitstream Exhchange Fix 9/99 */
- /* Bitstream Exchange requires we allow start with Video Object Sequence */
- /* visual_object_sequence_start_code */
- (void) BitstreamReadBits32HC(stream);
- tmpvar = (uint32) BitstreamReadBits16(stream, 8); /* profile */
- #ifndef PV_TOLERATE_VOL_ERRORS
- if (layer) /* */
- {
- /* support SSPL0-2 */
- if (tmpvar != 0x10 && tmpvar != 0x11 && tmpvar != 0x12 &&
- tmpvar != 0xA1 && tmpvar != 0xA2 && tmpvar != 0xA3/* Core SP@L1-L3 */)
- return PV_FAIL;
- }
- else
- {
- /* support SPL0-3 & SSPL0-2 */
- if (tmpvar != 0x01 && tmpvar != 0x02 && tmpvar != 0x03 && tmpvar != 0x08 &&
- tmpvar != 0x10 && tmpvar != 0x11 && tmpvar != 0x12 &&
- tmpvar != 0x21 && tmpvar != 0x22 && /* Core Profile Levels */
- tmpvar != 0xA1 && tmpvar != 0xA2 && tmpvar != 0xA3 &&
- tmpvar != 0xF0 && tmpvar != 0xF1 && /* Advanced Simple Profile Levels*/
- tmpvar != 0xF2 && tmpvar != 0xF3 &&
- tmpvar != 0xF4 && tmpvar != 0xF5)
- return PV_FAIL;
- }
- #else
- profile = tmpvar;
- #endif
- // save the profile and level for the query
- currVol->profile_level_id = (uint)tmpvar; // 6/10/04
- status = BitstreamShowBits32HC(stream, &tmpvar);
- if (tmpvar == USER_DATA_START_CODE)
- {
- /* Something has to be done with user data 11/11/99 */
- status = DecodeUserData(stream);
- if (status != PV_SUCCESS) return PV_FAIL;
- }
- /* visual_object_start_code */
- BitstreamShowBits32HC(stream, &tmpvar);
- if (tmpvar != VISUAL_OBJECT_START_CODE)
- {
- do
- {
- /* Search for VOL_HEADER */
- status = PVSearchNextM4VFrame(stream); /* search 0x00 0x00 0x01 */
- if (status != PV_SUCCESS) return PV_FAIL; /* breaks the loop */
- BitstreamShowBits32(stream, VOL_START_CODE_LENGTH, &tmpvar);
- PV_BitstreamFlushBits(stream, 8);
- }
- while (tmpvar != VOL_START_CODE);
- goto decode_vol;
- }
- else
- {
- BitstreamReadBits32HC(stream);
- }
- /* is_visual_object_identifier */
- tmpvar = (uint32) BitstreamRead1Bits(stream);
- if (tmpvar)
- {
- /* visual_object_verid */
- tmpvar = (uint32) BitstreamReadBits16(stream, 4);
- /* visual_object_priority */
- tmpvar = (uint32) BitstreamReadBits16(stream, 3);
- }
- /* visual_object_type */
- BitstreamShowBits32(stream, 4, &tmpvar);
- if (tmpvar == 1)
- { /* video_signal_type */
- PV_BitstreamFlushBits(stream, 4);
- tmpvar = (uint32) BitstreamRead1Bits(stream);
- if (tmpvar == 1)
- {
- /* video_format */
- tmpvar = (uint32) BitstreamReadBits16(stream, 3);
- /* video_range */
- tmpvar = (uint32) BitstreamRead1Bits(stream);
- /* color_description */
- tmpvar = (uint32) BitstreamRead1Bits(stream);
- if (tmpvar == 1)
- {
- /* color_primaries */
- tmpvar = (uint32) BitstreamReadBits16(stream, 8);
- /* transfer_characteristics */
- tmpvar = (uint32) BitstreamReadBits16(stream, 8);
- /* matrix_coefficients */
- tmpvar = (uint32) BitstreamReadBits16(stream, 8);
- }
- }
- }
- else
- {
- do
- {
- /* Search for VOL_HEADER */
- status = PVSearchNextM4VFrame(stream); /* search 0x00 0x00 0x01 */
- if (status != PV_SUCCESS) return PV_FAIL; /* breaks the loop */
- BitstreamShowBits32(stream, VOL_START_CODE_LENGTH, &tmpvar);
- PV_BitstreamFlushBits(stream, 8);
- }
- while (tmpvar != VOL_START_CODE);
- goto decode_vol;
- }
- /* next_start_code() */
- status = PV_BitstreamByteAlign(stream); /* 10/12/01 */
- status = BitstreamShowBits32HC(stream, &tmpvar);
- if (tmpvar == USER_DATA_START_CODE)
- {
- /* Something has to be done to deal with user data (parse it) 11/11/99 */
- status = DecodeUserData(stream);
- if (status != PV_SUCCESS) return PV_FAIL;
- }
- status = BitstreamShowBits32(stream, 27, &tmpvar); /* 10/12/01 */
- }
- else
- {
- /* tmpvar = 0; */ /* 10/12/01 */
- status = BitstreamShowBits32(stream, 27, &tmpvar); /* uncomment this line if you want
- to start decoding with a
- video_object_start_code */
- }
- if (tmpvar == VO_START_CODE)
- {
- /*****
- *
- * Read the VOL header entries from the bitstream
- *
- *****/
- /* video_object_start_code */
- tmpvar = BitstreamReadBits32(stream, 27);
- tmpvar = (uint32) BitstreamReadBits16(stream, 5);
- /* video_object_layer_start_code */
- BitstreamShowBits32(stream, VOL_START_CODE_LENGTH, &tmpvar);
- if (tmpvar != VOL_START_CODE)
- {
- status = BitstreamCheckEndBuffer(stream);
- if (status == PV_END_OF_VOP)
- {
- video->shortVideoHeader = TRUE;
- return PV_SUCCESS;
- }
- else
- {
- do
- {
- /* Search for VOL_HEADER */
- status = PVSearchNextM4VFrame(stream);/* search 0x00 0x00 0x01 */
- if (status != PV_SUCCESS) return PV_FAIL; /* breaks the loop */
- BitstreamShowBits32(stream, VOL_START_CODE_LENGTH, &tmpvar);
- PV_BitstreamFlushBits(stream, 8); /* advance the byte ptr */
- }
- while (tmpvar != VOL_START_CODE);
- }
- }
- else
- {
- PV_BitstreamFlushBits(stream, 8);
- }
- decode_vol:
- PV_BitstreamFlushBits(stream, VOL_START_CODE_LENGTH - 8);
- video->shortVideoHeader = 0;
- /* vol_id (4 bits) */
- currVol->volID = (int) BitstreamReadBits16(stream, 4);
- /* RandomAccessible flag */
- tmpvar = (uint32) BitstreamRead1Bits(stream);
- /* object type */
- tmpvar = (uint32) BitstreamReadBits16(stream, 8); /* */
- #ifdef PV_TOLERATE_VOL_ERRORS
- if (tmpvar == 0)
- {
- if (layer) /* */
- {
- /* support SSPL0-2 */
- if (profile != 0x10 && profile != 0x11 && profile != 0x12)
- return PV_FAIL;
- tmpvar = 0x02;
- }
- else
- {
- /* support SPL0-3 & SSPL0-2 */
- if (profile != 0x01 && profile != 0x02 && profile != 0x03 && profile != 0x08 &&
- profile != 0x10 && profile != 0x11 && profile != 0x12)
- return PV_FAIL;
- tmpvar = 0x01;
- }
- profile |= 0x0100;
- }
- #endif
- if (layer)
- {
- if (tmpvar != 0x02) return PV_FAIL;
- }
- else
- {
- if (tmpvar != 0x01) return PV_FAIL;
- }
- /* version id specified? */
- tmpvar = (uint32) BitstreamRead1Bits(stream);
- if (tmpvar == 1)
- {
- /* version ID */
- version_id = (uint32) BitstreamReadBits16(stream, 4);
- /* priority */
- tmpvar = (uint32) BitstreamReadBits16(stream, 3);
- }
- /* aspect ratio info */
- tmpvar = (uint32) BitstreamReadBits16(stream, 4);
- if (tmpvar == 0) return PV_FAIL;
- if (tmpvar == 0xf /* extended_par */)
- {
- /* width */
- tmpvar = (uint32) BitstreamReadBits16(stream, 8);
- /* height */
- tmpvar = (uint32) BitstreamReadBits16(stream, 8);
- }
- /* control parameters present? */
- tmpvar = (uint32) BitstreamRead1Bits(stream);
- /* Get the parameters (skipped) */
- /* 03/10/99 */
- if (tmpvar)
- {
- /* chroma_format */
- tmpvar = BitstreamReadBits16(stream, 2);
- if (tmpvar != 1) return PV_FAIL;
- /* low_delay */
- tmpvar = BitstreamRead1Bits(stream);
- /* vbv_parameters present? */
- tmpvar = (uint32) BitstreamRead1Bits(stream);
- if (tmpvar)
- {
- /* first_half_bit_rate */
- BitstreamReadBits16(stream, 15);
- if (!BitstreamRead1Bits(stream)) return PV_FAIL;
- /* latter_half_bit_rate */
- BitstreamReadBits16(stream, 15);
- if (!BitstreamRead1Bits(stream)) return PV_FAIL;
- /* first_half_vbv_buffer_size */
- BitstreamReadBits16(stream, 15);
- if (!BitstreamRead1Bits(stream)) return PV_FAIL;
- /* latter_half_vbv_buffer_size */
- BitstreamReadBits16(stream, 3);
- /* first_half_vbv_occupancy */
- BitstreamReadBits16(stream, 11);
- if (!BitstreamRead1Bits(stream)) return PV_FAIL;
- /* latter_half_vbv_occupancy */
- BitstreamReadBits16(stream, 15);
- if (!BitstreamRead1Bits(stream)) return PV_FAIL;
- }
- }
- /* video_object_layer_shape (2 bits), only 00 (rect) is supported for now */
- vol_shape = (uint32) BitstreamReadBits16(stream, 2);
- if (vol_shape) return PV_FAIL;
- /* marker bit, 03/10/99 */
- if (!BitstreamRead1Bits(stream)) return PV_FAIL;
- /* vop_time_increment_resolution */
- currVol->timeIncrementResolution = BitstreamReadBits16(stream, 16);
- if (currVol->timeIncrementResolution == 0) return PV_FAIL;
- /* . since nbitsTimeIncRes will be used over and over again, */
- /* we should put it in Vol structure. 04/12/2000. */
- currVol->nbitsTimeIncRes = CalcNumBits((uint)currVol->timeIncrementResolution - 1);
- if (!BitstreamRead1Bits(stream)) return PV_FAIL;
- /* fixed_vop_rate */
- currVol->fixedVopRate = (int) BitstreamRead1Bits(stream);
- if (currVol->fixedVopRate)
- {
- /* fixed_vop_time_increment */
- tmpvar = BitstreamReadBits16(stream, currVol->nbitsTimeIncRes);
- }
- /* marker bit */
- if (!BitstreamRead1Bits(stream)) return PV_FAIL;
- /* video_object_layer_width (13 bits) */
- video->displayWidth = video->width = (int) BitstreamReadBits16(stream, 13);
- /* round up to a multiple of MB_SIZE. 08/09/2000 */
- video->width = (video->width + 15) & -16;
- // video->displayWidth += (video->displayWidth & 0x1); /* displayed image should be even size */
- /* marker bit */
- if (!BitstreamRead1Bits(stream)) return PV_FAIL;
- /* video_object_layer_height (13 bits) */
- video->displayHeight = video->height = (int) BitstreamReadBits16(stream, 13);
- /* round up to a multiple of MB_SIZE. 08/09/2000 */
- video->height = (video->height + 15) & -16;
- // video->displayHeight += (video->displayHeight & 0x1); /* displayed image should be even size */
- if (!BitstreamRead1Bits(stream)) return PV_FAIL;
- /* 03/10/99 */
- /* interlaced */
- tmpvar = (uint32) BitstreamRead1Bits(stream);
- if (tmpvar != 0)
- {
- mp4dec_log("DecodeVOLHeader(): Interlaced video is not supported.\n");
- return PV_FAIL;
- }
- /* obmc_disable */
- tmpvar = (uint32) BitstreamRead1Bits(stream);
- if (tmpvar == 0) return PV_FAIL;
- if (version_id == 1)
- {
- /* sprite_enable (1 bits) */
- tmpvar = (uint32) BitstreamRead1Bits(stream);
- if (tmpvar)
- {
- mp4dec_log("DecodeVOLHeader(): Sprite is not supported.\n");
- return PV_FAIL;
- }
- }
- else
- {
- /* For version 2, vol_sprite_usage has two bits. */
- /* sprite_enable */
- tmpvar = (uint32) BitstreamReadBits16(stream, 2);
- if (tmpvar)
- {
- mp4dec_log("DecodeVOLHeader(): Sprite is not supported.\n");
- return PV_FAIL;
- }
- }
- /* not_8_bit */
- if (BitstreamRead1Bits(stream))
- {
- /* quant_precision */
- currVol->quantPrecision = BitstreamReadBits16(stream, 4);
- /* bits_per_pixel */
- currVol->bitsPerPixel = BitstreamReadBits16(stream, 4);
- mp4dec_log("DecodeVOLHeader(): not an 8-bit stream.\n"); // For the time being we do not support != 8 bits
- return PV_FAIL;
- }
- else
- {
- currVol->quantPrecision = 5;
- currVol->bitsPerPixel = 8;
- }
- /* quant_type (1 bit) */
- currVol->quantType = BitstreamRead1Bits(stream);
- if (currVol->quantType)
- {
- #ifdef PV_SUPPORT_MAIN_PROFILE
- /* load quantization matrices. 5/22/2000 */
- /* load_intra_quant_mat (1 bit) */
- qmat = currVol->iqmat;
- currVol->loadIntraQuantMat = BitstreamRead1Bits(stream);
- if (currVol->loadIntraQuantMat)
- {
- /* intra_quant_mat (8*64 bits) */
- i = 0;
- do
- {
- qmat[*(zigzag_inv+i)] = (int) BitstreamReadBits16(stream, 8);
- }
- while ((qmat[*(zigzag_inv+i)] != 0) && (++i < 64));
- for (j = i; j < 64; j++)
- qmat[*(zigzag_inv+j)] = qmat[*(zigzag_inv+i-1)];
- }
- else
- {
- oscl_memcpy(qmat, mpeg_iqmat_def, 64*sizeof(int));
- }
- qmat[0] = 0; /* necessary for switched && MPEG quant 07/09/01 */
- /* load_nonintra_quant_mat (1 bit) */
- qmat = currVol->niqmat;
- currVol->loadNonIntraQuantMat = BitstreamRead1Bits(stream);
- if (currVol->loadNonIntraQuantMat)
- {
- /* nonintra_quant_mat (8*64 bits) */
- i = 0;
- do
- {
- qmat[*(zigzag_inv+i)] = (int) BitstreamReadBits16(stream, 8);
- }
- while ((qmat[*(zigzag_inv+i)] != 0) && (++i < 64));
- for (j = i; j < 64; j++)
- qmat[*(zigzag_inv+j)] = qmat[*(zigzag_inv+i-1)];
- }
- else
- {
- oscl_memcpy(qmat, mpeg_nqmat_def, 64*sizeof(int));
- }
- #else
- return PV_FAIL;
- #endif
- }
- if (version_id != 1)
- {
- /* quarter_sample enabled */
- tmpvar = BitstreamRead1Bits(stream);
- if (tmpvar) return PV_FAIL;
- }
- /* complexity_estimation_disable */
- currVol->complexity_estDisable = BitstreamRead1Bits(stream);
- if (currVol->complexity_estDisable == 0)
- {
- currVol->complexity_estMethod = BitstreamReadBits16(stream, 2);
- if (currVol->complexity_estMethod < 2)
- {
- /* shape_complexity_estimation_disable */
- tmpvar = BitstreamRead1Bits(stream);
- if (tmpvar == 0)
- {
- mp4dec_log("DecodeVOLHeader(): Shape Complexity estimation is not supported.\n");
- return PV_FAIL;
- }
- /* texture_complexity_estimation_set_1_disable */
- tmpvar = BitstreamRead1Bits(stream);
- if (tmpvar == 0)
- {
- currVol->complexity.text_1 = BitstreamReadBits16(stream, 4);
- }
- /* marker bit */
- if (!BitstreamRead1Bits(stream)) return PV_FAIL;
- /* texture_complexity_estimation_set_2_disable */
- tmpvar = BitstreamRead1Bits(stream);
- if (tmpvar == 0)
- {
- currVol->complexity.text_2 = BitstreamReadBits16(stream, 4);
- }
- /* motion_compensation_complexity_disable */
- tmpvar = BitstreamRead1Bits(stream);
- if (tmpvar == 0)
- {
- currVol->complexity.mc = BitstreamReadBits16(stream, 6);
- }
- /* marker bit */
- if (!BitstreamRead1Bits(stream)) return PV_FAIL;
- if (currVol->complexity_estMethod == 1)
- { /* version2_complexity_estimation_disable */
- tmpvar = BitstreamRead1Bits(stream);
- if (tmpvar == 0)
- {
- mp4dec_log("DecodeVOLHeader(): sadct, quarter pel not supported.\n");
- return PV_FAIL;
- }
- }
- }
- }
- /* 03/10/99 */
- /* resync_marker_disable */
- currVol->errorResDisable = (int) BitstreamRead1Bits(stream);
- /* data_partititioned */
- currVol->dataPartitioning = (int) BitstreamRead1Bits(stream);
- video->vlcDecCoeffIntra = &VlcDecTCOEFIntra;
- video->vlcDecCoeffInter = &VlcDecTCOEFInter;
- if (currVol->dataPartitioning)
- {
- if (layer) return PV_FAIL; /* */
- /* reversible_vlc */
- currVol->useReverseVLC = (int)BitstreamRead1Bits(stream);
- if (currVol->useReverseVLC)
- {
- video->vlcDecCoeffIntra = &RvlcDecTCOEFIntra;
- video->vlcDecCoeffInter = &RvlcDecTCOEFInter;
- }
- currVol->errorResDisable = 0;
- }
- else
- {
- currVol->useReverseVLC = 0;
- }
- if (version_id != 1)
- {
- /* newpred_enable */
- tmpvar = BitstreamRead1Bits(stream);
- if (tmpvar) return PV_FAIL;
- /* reduced_resolution_vop */
- tmpvar = BitstreamRead1Bits(stream);
- if (tmpvar) return PV_FAIL;
- }
- /* Intra AC/DC prediction is always true */
- video->intra_acdcPredDisable = 0;
- /* scalability */
- currVol->scalability = (int) BitstreamRead1Bits(stream);
- if (currVol->scalability)
- {
- if (layer == 0) return PV_FAIL; /* */
- /* hierarchy_type: 1 : temporal, 0 : spatial */
- /* 03/10/99 */
- currVol->scalType = (int) BitstreamRead1Bits(stream); /* */
- if (!currVol->scalType) return PV_FAIL;
- /* ref_layer_id (4 bits) */
- currVol->refVolID = (int) BitstreamReadBits16(stream, 4);
- if (layer) /* */
- {
- if (currVol->refVolID != video->vol[0]->volID) return PV_FAIL;
- }
- /* ref_layer_sampling_direc (1 bits) */
- /* 1 : ref. layer has higher resolution */
- /* 0 : ref. layer has equal or lower resolution */
- currVol->refSampDir = (int) BitstreamRead1Bits(stream);
- if (currVol->refSampDir) return PV_FAIL;
- /* hor_sampling_factor_n (5 bits) */
- currVol->horSamp_n = (int) BitstreamReadBits16(stream, 5);
- /* hor_sampling_factor_m (5 bits) */
- currVol->horSamp_m = (int) BitstreamReadBits16(stream, 5);
- if (currVol->horSamp_m == 0) return PV_FAIL;
- if (currVol->horSamp_n != currVol->horSamp_m) return PV_FAIL;
- /* ver_sampling_factor_n (5 bits) */
- currVol->verSamp_n = (int) BitstreamReadBits16(stream, 5);
- /* ver_sampling_factor_m (5 bits) */
- currVol->verSamp_m = (int) BitstreamReadBits16(stream, 5);
- if (currVol->verSamp_m == 0) return PV_FAIL;
- if (currVol->verSamp_n != currVol->verSamp_m) return PV_FAIL;
- /* enhancement_type: 1 : partial region, 0 : full region */
- /* 04/10/2000: we only support full region enhancement layer. */
- if (BitstreamRead1Bits(stream)) return PV_FAIL;
- }
- PV_BitstreamByteAlign(stream);
- status = BitstreamShowBits32HC(stream, &tmpvar);
- /* if we hit the end of buffer, tmpvar == 0. 08/30/2000 */
- if (tmpvar == USER_DATA_START_CODE)
- {
- status = DecodeUserData(stream);
- /* you should not check for status here 03/19/2002 */
- status = PV_SUCCESS;
- }
- /* Compute some convenience variables: 04/13/2000 */
- video->nMBPerRow = video->width / MB_SIZE;
- video->nMBPerCol = video->height / MB_SIZE;
- video->nTotalMB = video->nMBPerRow * video->nMBPerCol;
- video->nBitsForMBID = CalcNumBits((uint)video->nTotalMB - 1);
- #ifdef PV_ANNEX_IJKT_SUPPORT
- video->modified_quant = 0;
- video->advanced_INTRA = 0;
- video->deblocking = 0;
- video->slice_structure = 0;
- #endif
- }
- else
- {
- /* SHORT_HEADER */
- status = BitstreamShowBits32(stream, SHORT_VIDEO_START_MARKER_LENGTH, &tmpvar);
- if (tmpvar == SHORT_VIDEO_START_MARKER)
- {
- video->shortVideoHeader = TRUE;
- }
- else
- {
- do
- {
- /* Search for VOL_HEADER */
- status = PVSearchNextM4VFrame(stream); /* search 0x00 0x00 0x01 */
- if (status != PV_SUCCESS) return PV_FAIL; /* breaks the loop */
- BitstreamShowBits32(stream, VOL_START_CODE_LENGTH, &tmpvar);
- PV_BitstreamFlushBits(stream, 8);
- }
- while (tmpvar != VOL_START_CODE);
- goto decode_vol;
- }
- }
- #ifdef PV_TOLERATE_VOL_ERRORS
- if (profile > 0xFF || profile == 0)
- {
- return PV_BAD_VOLHEADER;
- }
- #endif
- return status;
- }
- /***********************************************************CommentBegin******
- *
- * -- DecodeGOV -- Decodes the Group of VOPs from bitstream
- *
- * 04/20/2000 initial modification to the new PV-Decoder Lib format.
- *
- ***********************************************************CommentEnd********/
- PV_STATUS DecodeGOVHeader(BitstreamDecVideo *stream, uint32 *time_base)
- {
- uint32 tmpvar, time_s;
- int closed_gov, broken_link;
- /* group_start_code (32 bits) */
- // tmpvar = BitstreamReadBits32(stream, 32);
- /* hours */
- tmpvar = (uint32) BitstreamReadBits16(stream, 5);
- time_s = tmpvar * 3600;
- /* minutes */
- tmpvar = (uint32) BitstreamReadBits16(stream, 6);
- time_s += tmpvar * 60;
- /* marker bit */
- tmpvar = (uint32) BitstreamRead1Bits(stream);
- /* seconds */
- tmpvar = (uint32) BitstreamReadBits16(stream, 6);
- time_s += tmpvar;
- /* We have to check the timestamp here. If the sync timestamp is */
- /* earlier than the previous timestamp or longer than 60 sec. */
- /* after the previous timestamp, assume the GOV header is */
- /* corrupted. 05/12/2000 */
- *time_base = time_s; /* 02/27/2002 */
- // *time_base = *time_base/1000;
- // tmpvar = time_s - *time_base;
- // if (tmpvar <= 60) *time_base = time_s;
- // else return PV_FAIL;
- tmpvar = (uint32) BitstreamRead1Bits(stream);
- closed_gov = tmpvar;
- tmpvar = (uint32) BitstreamRead1Bits(stream);
- broken_link = tmpvar;
- if ((closed_gov == 0) && (broken_link == 1))
- {
- return PV_SUCCESS; /* 03/15/2002 you can also return PV_FAIL */
- }
- PV_BitstreamByteAlign(stream);
- BitstreamShowBits32HC(stream, &tmpvar);
- while (tmpvar == USER_DATA_START_CODE) /* 03/15/2002 */
- {
- DecodeUserData(stream);
- BitstreamShowBits32HC(stream, &tmpvar);
- }
- return PV_SUCCESS;
- }
- /***********************************************************CommentBegin******
- *
- * -- DecodeVopHeader -- Decodes the VOPheader information from the bitstream
- *
- * 04/12/2000 Initial port to the new PV decoder library format.
- * 05/10/2000 Error resilient decoding of vop header.
- *
- ***********************************************************CommentEnd********/
- PV_STATUS DecodeVOPHeader(VideoDecData *video, Vop *currVop, Bool use_ext_timestamp)
- {
- PV_STATUS status = PV_SUCCESS;
- Vol *currVol = video->vol[video->currLayer];
- BitstreamDecVideo *stream = currVol->bitstream;
- uint32 tmpvar;
- int time_base;
- /*****
- * Read the VOP header from the bitstream (No shortVideoHeader Mode here!)
- *****/
- BitstreamShowBits32HC(stream, &tmpvar);
- /* check if we have a GOV header here. 08/30/2000 */
- if (tmpvar == GROUP_START_CODE)
- {
- tmpvar = BitstreamReadBits32HC(stream);
- // rewindBitstream(stream, START_CODE_LENGTH); /* for backward compatibility */
- status = DecodeGOVHeader(stream, &tmpvar);
- if (status != PV_SUCCESS)
- {
- return status;
- }
- // use_ext_timestamp = TRUE; /* 02/08/2002 */
- /* We should have a VOP header following the GOV header. 03/15/2001 */
- BitstreamShowBits32HC(stream, &tmpvar);
- }
- #ifdef PV_SUPPORT_TEMPORAL_SCALABILITY
- currVop->timeStamp = -1;
- #endif
- if (tmpvar == VOP_START_CODE)
- {
- tmpvar = BitstreamReadBits32HC(stream);
- }
- else
- {
- PV_BitstreamFlushBits(stream, 8); // advance by a byte
- status = PV_FAIL;
- goto return_point;
- }
- /* vop_prediction_type (2 bits) */
- currVop->predictionType = (int) BitstreamReadBits16(stream, 2);
- /* modulo_time_base (? bits) */
- time_base = -1;
- do
- {
- time_base++;
- tmpvar = (uint32) BitstreamRead1Bits(stream);
- }
- while (tmpvar == 1);
- if (!use_ext_timestamp)
- {
- currVol->moduloTimeBase += 1000 * time_base; /* milliseconds based MTB 11/12/01 */
- }
- /* marker_bit (1 bit) */
- if (!BitstreamRead1Bits(stream))
- {
- status = PV_FAIL;
- goto return_point;
- }
- /* vop_time_increment (1-15 bits) in Nov_Compliant (1-16 bits) */
- /* we always assumes fixed vop rate here */
- currVop->timeInc = BitstreamReadBits16(stream, currVol->nbitsTimeIncRes);
- /* marker_bit (1 bit) */
- if (!BitstreamRead1Bits(stream))
- {
- status = PV_FAIL;
- goto return_point;
- }
- /* vop_coded */
- currVop->vopCoded = (int) BitstreamRead1Bits(stream);
- if (currVop->vopCoded == 0)
- {
- status = PV_SUCCESS;
- goto return_point;
- }
- /* read vop_rounding_type */
- if (currVop->predictionType == P_VOP)
- {
- currVop->roundingType = (int) BitstreamRead1Bits(stream);
- }
- else
- {
- currVop->roundingType = 0;
- }
- if (currVol->complexity_estDisable == 0)
- {
- if (currVol->complexity_estMethod < 2) /* OCT 2002 */
- {
- if ((currVol->complexity.text_1 >> 3) & 0x1) /* intra */
- BitstreamReadBits16(stream, 8);
- if (currVol->complexity.text_1 & 0x1) /* not_coded */
- BitstreamReadBits16(stream, 8);
- if ((currVol->complexity.text_2 >> 3) & 0x1) /* dct_coefs */
- BitstreamReadBits16(stream, 8);
- if ((currVol->complexity.text_2 >> 2) & 0x1) /* dct_lines */
- BitstreamReadBits16(stream, 8);
- if ((currVol->complexity.text_2 >> 1) & 0x1) /* vlc_symbols */
- BitstreamReadBits16(stream, 8);
- if (currVol->complexity.text_2 & 0x1) /* vlc_bits */
- BitstreamReadBits16(stream, 4);
- if (currVop->predictionType != I_VOP)
- {
- if ((currVol->complexity.text_1 >> 2) & 0x1) /* inter */
- BitstreamReadBits16(stream, 8);
- if ((currVol->complexity.text_1 >> 1) & 0x1) /* inter_4v */
- BitstreamReadBits16(stream, 8);
- if ((currVol->complexity.mc >> 5) & 0x1) /* apm */
- BitstreamReadBits16(stream, 8);
- if ((currVol->complexity.mc >> 4) & 0x1) /* npm */
- BitstreamReadBits16(stream, 8);
- /* interpolate_mc_q */
- if ((currVol->complexity.mc >> 2) & 0x1) /* forw_back_mc_q */
- BitstreamReadBits16(stream, 8);
- if ((currVol->complexity.mc >> 1) & 0x1) /* halfpel2 */
- BitstreamReadBits16(stream, 8);
- if (currVol->complexity.mc & 0x1) /* halfpel4 */
- BitstreamReadBits16(stream, 8);
- }
- if (currVop->predictionType == B_VOP)
- {
- if ((currVol->complexity.mc >> 3) & 0x1) /* interpolate_mc_q */
- BitstreamReadBits16(stream, 8);
- }
- }
- }
- /* read intra_dc_vlc_thr */
- currVop->intraDCVlcThr = (int) BitstreamReadBits16(stream, 3);
- /* read vop_quant (currVol->quantPrecision bits) */
- currVop->quantizer = (int16) BitstreamReadBits16(stream, currVol->quantPrecision);
- if (currVop->quantizer == 0)
- {
- currVop->quantizer = video->prevVop->quantizer;
- status = PV_FAIL;
- goto return_point;
- }
- /* read vop_fcode_forward */
- if (currVop->predictionType != I_VOP)
- {
- tmpvar = (uint32) BitstreamReadBits16(stream, 3);
- if (tmpvar < 1)
- {
- currVop->fcodeForward = 1;
- status = PV_FAIL;
- goto return_point;
- }
- currVop->fcodeForward = tmpvar;
- }
- else
- {
- currVop->fcodeForward = 0;
- }
- /* read vop_fcode_backward */
- if (currVop->predictionType == B_VOP)
- {
- tmpvar = (uint32) BitstreamReadBits16(stream, 3);
- if (tmpvar < 1)
- {
- currVop->fcodeBackward = 1;
- status = PV_FAIL;
- goto return_point;
- }
- currVop->fcodeBackward = tmpvar;
- }
- else
- {
- currVop->fcodeBackward = 0;
- }
- if (currVol->scalability)
- {
- currVop->refSelectCode = (int) BitstreamReadBits16(stream, 2);
- }
- return_point:
- return status;
- }
- /***********************************************************CommentBegin******
- *
- * -- VideoPlaneWithShortHeader -- Decodes the short_video_header information from the bitstream
- * Modified :
- 04/23/2001. Remove the codes related to the
- "first pass" decoding. We use a different function
- to set up the decoder now.
- ***********************************************************CommentEnd********/
- PV_STATUS DecodeShortHeader(VideoDecData *video, Vop *currVop)
- {
- PV_STATUS status = PV_SUCCESS;
- Vol *currVol = video->vol[0];
- BitstreamDecVideo *stream = currVol->bitstream;
- uint32 tmpvar;
- int32 size;
- int extended_PTYPE = FALSE;
- int UFEP = 0, custom_PFMT = 0, custom_PCF = 0;
- status = BitstreamShowBits32(stream, SHORT_VIDEO_START_MARKER_LENGTH, &tmpvar);
- if (tmpvar != SHORT_VIDEO_START_MARKER)
- {
- status = PV_FAIL;
- goto return_point;
- }
- PV_BitstreamFlushBits(stream, SHORT_VIDEO_START_MARKER_LENGTH);
- /* Temporal reference. Using vop_time_increment_resolution = 30000 */
- tmpvar = (uint32) BitstreamReadBits16(stream, 8);
- currVop->temporalRef = (int) tmpvar;
- currVop->timeInc = 0xff & (256 + currVop->temporalRef - video->prevVop->temporalRef);
- currVol->moduloTimeBase += currVop->timeInc; /* mseconds 11/12/01 */
- /* Marker Bit */
- if (!BitstreamRead1Bits(stream))
- {
- mp4dec_log("DecodeShortHeader(): Marker bit wrong.\n");
- status = PV_FAIL;
- goto return_point;
- }
- /* Zero Bit */
- if (BitstreamRead1Bits(stream))
- {
- mp4dec_log("DecodeShortHeader(): Zero bit wrong.\n");
- status = PV_FAIL;
- goto return_point;
- }
- /*split_screen_indicator*/
- if (BitstreamRead1Bits(stream))
- {
- mp4dec_log("DecodeShortHeader(): Split Screen not supported.\n");
- VideoDecoderErrorDetected(video);
- }
- /*document_freeze_camera*/
- if (BitstreamRead1Bits(stream))
- {
- mp4dec_log("DecodeShortHeader(): Freeze Camera not supported.\n");
- VideoDecoderErrorDetected(video);
- }
- /*freeze_picture_release*/
- if (BitstreamRead1Bits(stream))
- {
- mp4dec_log("DecodeShortHeader(): Freeze Release not supported.\n");
- VideoDecoderErrorDetected(video);
- }
- /* source format */
- switch (BitstreamReadBits16(stream, 3))
- {
- case 1:
- if (video->size < 128*96)
- {
- status = PV_FAIL;
- goto return_point;
- }
- video->displayWidth = video->width = 128;
- video->displayHeight = video->height = 96;
- break;
- case 2:
- if (video->size < 176*144)
- {
- status = PV_FAIL;
- goto return_point;
- }
- video->displayWidth = video->width = 176;
- video->displayHeight = video->height = 144;
- break;
- case 3:
- if (video->size < 352*288)
- {
- status = PV_FAIL;
- goto return_point;
- }
- video->displayWidth = video->width = 352;
- video->displayHeight = video->height = 288;
- break;
- case 4:
- if (video->size < 704*576)
- {
- status = PV_FAIL;
- goto return_point;
- }
- video->displayWidth = video->width = 704;
- video->displayHeight = video->height = 576;
- break;
- case 5:
- if (video->size < 1408*1152)
- {
- status = PV_FAIL;
- goto return_point;
- }
- video->displayWidth = video->width = 1408;
- video->displayHeight = video->height = 1152;
- break;
- case 7:
- extended_PTYPE = TRUE;
- break;
- default:
- /* Msg("H.263 source format not legal\n"); */
- status = PV_FAIL;
- goto return_point;
- }
- currVop->roundingType = 0;
- if (extended_PTYPE == FALSE)
- {
- currVop->predictionType = (int) BitstreamRead1Bits(stream);
- /* four_reserved_zero_bits */
- if (BitstreamReadBits16(stream, 4))
- {
- mp4dec_log("DecodeShortHeader(): Reserved bits wrong.\n");
- status = PV_FAIL;
- goto return_point;
- }
- }
- else
- {
- UFEP = BitstreamReadBits16(stream, 3);
- if (UFEP == 1)
- {
- /* source format */
- switch (BitstreamReadBits16(stream, 3))
- {
- case 1:
- if (video->size < 128*96)
- {
- status = PV_FAIL;
- goto return_point;
- }
- video->displayWidth = video->width = 128;
- video->displayHeight = video->height = 96;
- break;
- case 2:
- if (video->size < 176*144)
- {
- status = PV_FAIL;
- goto return_point;
- }
- video->displayWidth = video->width = 176;
- video->displayHeight = video->height = 144;
- break;
- case 3:
- if (video->size < 352*288)
- {
- status = PV_FAIL;
- goto return_point;
- }
- video->displayWidth = video->width = 352;
- video->displayHeight = video->height = 288;
- break;
- case 4:
- if (video->size < 704*576)
- {
- status = PV_FAIL;
- goto return_point;
- }
- video->displayWidth = video->width = 704;
- video->displayHeight = video->height = 576;
- break;
- case 5:
- if (video->size < 1408*1152)
- {
- status = PV_FAIL;
- goto return_point;
- }
- video->displayWidth = video->width = 1408;
- video->displayHeight = video->height = 1152;
- break;
- case 6:
- custom_PFMT = TRUE;
- break;
- default:
- /* Msg("H.263 source format not legal\n"); */
- status = PV_FAIL;
- goto return_point;
- }
- custom_PCF = BitstreamRead1Bits(stream);
- /* unrestricted MV */
- if (BitstreamRead1Bits(stream))
- {
- status = PV_FAIL;
- goto return_point;
- }
- /* SAC */
- if (BitstreamRead1Bits(stream))
- {
- status = PV_FAIL;
- goto return_point;
- }
- /* AP */
- if (BitstreamRead1Bits(stream))
- {
- status = PV_FAIL;
- goto return_point;
- }
- video->advanced_INTRA = BitstreamRead1Bits(stream);
- video->deblocking = BitstreamRead1Bits(stream);
- video->slice_structure = BitstreamRead1Bits(stream);
- /* RPS, ISD, AIV */
- if (BitstreamReadBits16(stream, 3))
- {
- status = PV_FAIL;
- goto return_point;
- }
- video->modified_quant = BitstreamRead1Bits(stream);
- /* Marker Bit and reserved*/
- if (BitstreamReadBits16(stream, 4) != 8)
- {
- status = PV_FAIL;
- goto return_point;
- }
- }
- #ifndef PV_ANNEX_IJKT_SUPPORT
- if (video->advanced_INTRA | video->deblocking | video->modified_quant | video->modified_quant)
- {
- status = PV_FAIL;
- goto return_point;
- }
- #endif
- if (UFEP == 0 || UFEP == 1)
- {
- tmpvar = BitstreamReadBits16(stream, 3);
- if (tmpvar > 1)
- {
- status = PV_FAIL;
- goto return_point;
- }
- currVop->predictionType = tmpvar;
- /* RPR */
- if (BitstreamRead1Bits(stream))
- {
- status = PV_FAIL;
- goto return_point;
- }
- /* RRU */
- if (BitstreamRead1Bits(stream))
- {
- status = PV_FAIL;
- goto return_point;
- }
- currVop->roundingType = (int) BitstreamRead1Bits(stream);
- if (BitstreamReadBits16(stream, 3) != 1)
- {
- status = PV_FAIL;
- goto return_point;
- }
- }
- else
- {
- status = PV_FAIL;
- goto return_point;
- }
- /* CPM */
- if (BitstreamRead1Bits(stream))
- {
- status = PV_FAIL;
- goto return_point;
- }
- /* CPFMT */
- if (custom_PFMT == 1 && UFEP == 1)
- {
- /* aspect ratio */
- tmpvar = BitstreamReadBits16(stream, 4);
- if (tmpvar == 0)
- {
- status = PV_FAIL;
- goto return_point;
- }
- /* Extended PAR */
- if (tmpvar == 0xF)
- {
- /* Read par_width and par_height but do nothing */
- /* par_width */
- tmpvar = BitstreamReadBits16(stream, 8);
- /* par_height */
- tmpvar = BitstreamReadBits16(stream, 8);
- }
- tmpvar = BitstreamReadBits16(stream, 9);
- video->displayWidth = (tmpvar + 1) << 2;
- video->width = (video->displayWidth + 15) & -16;
- /* marker bit */
- if (!BitstreamRead1Bits(stream))
- {
- status = PV_FAIL;
- goto return_point;
- }
- tmpvar = BitstreamReadBits16(stream, 9);
- if (tmpvar == 0)
- {
- status = PV_FAIL;
- goto return_point;
- }
- video->displayHeight = tmpvar << 2;
- video->height = (video->displayHeight + 15) & -16;
- if (video->height * video->width > video->size)
- {
- status = PV_FAIL;
- goto return_point;
- }
- video->nTotalMB = video->width / MB_SIZE * video->height / MB_SIZE;
- if (video->nTotalMB <= 48)
- {
- video->nBitsForMBID = 6;
- }
- else if (video->nTotalMB <= 99)
- {
- video->nBitsForMBID = 7;
- }
- else if (video->nTotalMB <= 396)
- {
- video->nBitsForMBID = 9;
- }
- else if (video->nTotalMB <= 1584)
- {
- video->nBitsForMBID = 11;
- }
- else if (video->nTotalMB <= 6336)
- {
- video->nBitsForMBID = 13 ;
- }
- else if (video->nTotalMB <= 9216)
- {
- video->nBitsForMBID = 14 ;
- }
- else
- {
- status = PV_FAIL;
- goto return_point;
- }
- }
- if (UFEP == 1 && custom_PCF == 1)
- {
- BitstreamRead1Bits(stream);
- tmpvar = BitstreamReadBits16(stream, 7);
- if (tmpvar == 0)
- {
- status = PV_FAIL;
- goto return_point;
- }
- }
- if (custom_PCF == 1)
- {
- currVop->ETR = BitstreamReadBits16(stream, 2);
- }
- if (UFEP == 1 && video->slice_structure == 1)
- {
- /* SSS */
- tmpvar = BitstreamReadBits16(stream, 2);
- if (tmpvar != 0)
- {
- status = PV_FAIL;
- goto return_point;
- }
- }
- }
- /* Recalculate number of macroblocks per row & col since */
- /* the frame size can change. 04/23/2001. */
- video->nMBinGOB = video->nMBPerRow = video->width / MB_SIZE;
- video->nGOBinVop = video->nMBPerCol = video->height / MB_SIZE;
- video->nTotalMB = video->nMBPerRow * video->nMBPerCol;
- if (custom_PFMT == 0 || UFEP == 0)
- {
- video->nBitsForMBID = CalcNumBits((uint)video->nTotalMB - 1); /* otherwise calculate above */
- }
- size = (int32)video->width * video->height;
- if (currVop->predictionType == P_VOP && size > video->videoDecControls->size)
- {
- status = PV_FAIL;
- goto return_point;
- }
- video->videoDecControls->size = size;
- video->currVop->uChan = video->currVop->yChan + size;
- video->currVop->vChan = video->currVop->uChan + (size >> 2);
- video->prevVop->uChan = video->prevVop->yChan + size;
- video->prevVop->vChan = video->prevVop->uChan + (size >> 2);
- currVop->quantizer = (int16) BitstreamReadBits16(stream, 5);
- if (currVop->quantizer == 0) /* 04/03/01 */
- {
- currVop->quantizer = video->prevVop->quantizer;
- status = PV_FAIL;
- goto return_point;
- }
- /* Zero bit */
- if (extended_PTYPE == FALSE)
- {
- if (BitstreamRead1Bits(stream))
- {
- mp4dec_log("DecodeShortHeader(): Zero bit wrong.\n");
- status = PV_FAIL;
- goto return_point;
- }
- }
- /* pei */
- tmpvar = (uint32) BitstreamRead1Bits(stream);
- while (tmpvar)
- {
- tmpvar = (uint32) BitstreamReadBits16(stream, 8); /* "PSPARE" */
- tmpvar = (uint32) BitstreamRead1Bits(stream); /* "PEI" */
- }
- if (video->slice_structure) /* ANNEX_K */
- {
- if (!BitstreamRead1Bits(stream)) /* SEPB1 */
- {
- status = PV_FAIL;
- goto return_point;
- }
- // if (currVol->nBitsForMBID //
- if (BitstreamReadBits16(stream, video->nBitsForMBID))
- {
- status = PV_FAIL; /* no ASO, RS support for Annex K */
- goto return_point;
- }
- if (!BitstreamRead1Bits(stream)) /*SEPB3 */
- {
- status = PV_FAIL;
- goto return_point;
- }
- }
- /* Setting of other VOP-header parameters */
- currVop->gobNumber = 0;
- currVop->vopCoded = 1;
- currVop->intraDCVlcThr = 0;
- currVop->gobFrameID = 0; /* initial value, 05/22/00 */
- currVol->errorResDisable = 0;
- /*PutVopInterlaced(0,curr_vop); no implemented yet */
- if (currVop->predictionType != I_VOP)
- currVop->fcodeForward = 1;
- else
- currVop->fcodeForward = 0;
- return_point:
- return status;
- }
- /***********************************************************CommentBegin******
- *
- * -- PV_DecodeVop -- Decodes the VOP information from the bitstream
- *
- * 04/12/2000
- * Initial port to the new PV decoder library format.
- * This function is different from the one in MoMuSys MPEG-4
- * visual decoder. We handle combined mode with or withput
- * error resilience and H.263 mode through…
Large files files are truncated, but you can click here to view the full file