--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/videoeditorengine/h263decoder/src/viddemux_mpeg.cpp Fri Jan 29 14:08:33 2010 +0200
@@ -0,0 +1,4687 @@
+/*
+* Copyright (c) 2010 Ixonos Plc.
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - Initial contribution
+*
+* Contributors:
+* Ixonos Plc
+*
+* Description:
+* MPEG-4 bitstream parsing.
+*
+*/
+
+
+/*
+ * Includes
+ */
+
+#include "h263dConfig.h"
+#include "viddemux.h"
+#include "vdxint.h"
+#include "mpegcons.h"
+#include "sync.h"
+#include "vdcaic.h"
+#include "zigzag.h"
+#include "debug.h"
+#include "biblin.h"
+/* MVE */
+#include "MPEG4Transcoder.h"
+// <--
+
+/*
+ * Local function prototypes
+ */
+
+/* Macroblock Layer */
+
+static int vdxGetIntraDCSize(bibBuffer_t *inBuffer, int compnum, int *IntraDCSize,
+ int *bitErrorIndication);
+
+static int vdxGetRVLCIndex(u_int32 bits, u_int32 *index, int *length, int intra_luma,
+ int *bitErrorIndication);
+
+
+/*
+ * Picture Layer Global Functions
+ */
+
+
+/*
+ *
+ * vdxGetVolHeader
+ *
+ * Parameters:
+ * inBuffer pointer to bit buffer instance
+ * header output parameters: VOL header
+ * bitErrorIndication non-zero if a bit error has been detected
+ * within the bits accessed in this function,
+ * see biterr.h for possible values
+ *
+ * Function:
+ * This function reads the VO and VOL header from inBuffer.
+ *
+ * Returns:
+ * VDX_OK the function was successful
+ * VDX_OK_BUT_BIT_ERROR the function behaved normally, but a bit error
+ * occured
+ * VDX_ERR_BIB an error occured when accessing bit buffer
+ * VDX_ERR_NO_START_CODE if start code is not found
+ * VDX_ERR_NOT_SUPPORTED if VOL header
+ *
+ *
+ */
+
+int vdxGetVolHeader(
+ bibBuffer_t *inBuffer,
+ vdxVolHeader_t *header,
+ int *bitErrorIndication,
+ int getInfo, int *aByteIndex, int *aBitIndex, CMPEG4Transcoder *hTranscoder)
+{
+ int bitsGot, sncCode, fUseDefaultVBVParams = 0, num_bits;
+ int16 bibError = 0;
+ u_int32 bits;
+
+ memset(header, 0, sizeof(vdxVolHeader_t));
+ *bitErrorIndication = 0;
+
+ /* if Visual Object Sequence Start Code is present */
+ bits = bibShowBits(MP4_VOS_START_CODE_LENGTH, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ if (bits == MP4_VOS_START_CODE) {
+
+ /* vos_start_code */
+ bibFlushBits(MP4_VOS_START_CODE_LENGTH, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+
+ /* profile_and_level_indication (8 bits) */
+ bits = bibGetBits(8, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ /* If fatal bit error occurred (lost segment/packet etc.) */
+ /*
+ 1: Simple Profile Level 1 (from ISO/IEC 14496-2:1999/FPDAM4 [N4350] July 2001)
+ 2: Simple Profile Level 2 (from ISO/IEC 14496-2:1999/FPDAM4 [N4350] July 2001)
+ 3: Simple Profile Level 3 (from ISO/IEC 14496-2:1999/FPDAM4 [N4350] July 2001)
+ 8: Simple Profile Level 0 (from ISO/IEC 14496-2:1999/FPDAM4 [N5743] July 2003)
+ 9: Simple Profile Level 0b (from ISO/IEC 14496-2:1999/FPDAM4 [N5743] July 2003)
+ */
+#if 0
+ // Disabled since some clips have this set incorrectly, and this is not used for anything important.
+ // Only simple profile clips seem to be available so this should not cause any harm.
+ // Further, it is still checked in vedVolReader which is always used before editing. It is not checked only when creating thumbnails
+
+
+ if (bits != 1 && bits != 2 && bits != 3 && bits != 8 && bits != 9) {
+ /* this is not a supported simple profile stream */
+ deb("vdxGetMPEGVolHeader: ERROR - This is not a supported simple profile stream\n");
+ goto notSupported;
+ }
+#endif
+ if (bits != 8 && bits != 9)
+ header->profile_level = (int) bits;
+ else
+ header->profile_level = 0;
+
+ /* User data if available */
+ bits = bibShowBits(32, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ if (bits == MP4_USER_DATA_START_CODE)
+ {
+ if (!header->user_data) {
+ header->user_data = (char *) malloc(MAX_USER_DATA_LENGTH);
+ header->user_data_length = 0;
+ }
+
+ if (vdxGetUserData(inBuffer, header->user_data, &(header->user_data_length), bitErrorIndication) != VDX_OK)
+ /* also bibError will be handled in exitAfterBitError */
+ goto exitAfterBitError;
+ }
+ }
+
+ /* if Visual Object Start Code is present */
+ bits = bibShowBits(MP4_VO_START_CODE_LENGTH, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ if (bits == MP4_VO_START_CODE) {
+
+ /* visual_object_start_code */
+ bibFlushBits(MP4_VO_START_CODE_LENGTH, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+
+ /* is_visual_object_identifier (1 bit) */
+ bits = bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ if (bits) {
+
+ /* visual_object_ver_id (4 bits) */
+ bits = bibGetBits(4, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ if (bits != 1) {
+ /* this is not an MPEG-4 version 1 stream */
+ deb("vdxGetMPEGVolHeader: ERROR - This is not an MPEG-4 version 1 stream\n");
+ goto notSupported;
+ }
+
+ /* visual_object_priority (3 bits) */
+ bits = bibGetBits(3, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ header->vo_priority = (int) bits;
+
+ } else {
+ header->vo_priority = 0;
+ }
+
+ /* visual_object_type (4 bits) */
+ bits = bibGetBits(4, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ if (bits != 1) {
+ /* this is not a video object */
+ deb("vdxGetMPEGVolHeader: ERROR - This is not a video object\n");
+ goto notSupported;
+ }
+
+ /* is_video_signal_type (1 bit) */
+ bits = bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ if (bits) {
+
+ /* Note: The following fields in the bitstream give information about the
+ video signal type before encoding. These parameters don't influence the
+ decoding algorithm, but the composition at the output of the video decoder.
+ There is no normative requirement however to utilize this information
+ during composition, therefore until a way to utilize them is found in
+ MoViDe, these fields are just dummyly read, but not interpreted.
+ For interpretation see the MPEG-4 Visual standard */
+
+ /* video_format (3 bits) */
+ bits = bibGetBits(3, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ header->video_format = (int) bits;
+
+ /* video_range (1 bit) */
+ bits = bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ header->video_range = (int) bits;
+
+ /* colour_description (1 bit) */
+ bits = bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ if (bits) {
+
+ /* colour_primaries (8 bits) */
+ bits = bibGetBits(8, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ header->colour_primaries = (int) bits;
+
+ /* transfer_characteristics (8 bits) */
+ bits = bibGetBits(8, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ header->transfer_characteristics = (int) bits;
+
+ /* matrix_coefficients (8 bits) */
+ bits = bibGetBits(8, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ header->matrix_coefficients = (int) bits;
+ } else {
+
+ header->colour_primaries = 1; /* default: ITU-R BT.709 */
+ header->transfer_characteristics = 1; /* default: ITU-R BT.709 */
+ header->matrix_coefficients = 1; /* default: ITU-R BT.709 */
+ }
+
+ } else {
+
+ /* default values */
+ header->video_format = 5; /* Unspecified video format */
+ header->video_range = 0; /* Y range 16-235 pixel values */
+ header->colour_primaries = 1; /* ITU-R BT.709 */
+ header->transfer_characteristics = 1; /* ITU-R BT.709 */
+ header->matrix_coefficients = 1; /* ITU-R BT.709 */
+ }
+
+ /* check the next start code */
+ sncCode = sncCheckMpegSync(inBuffer, 0, &bibError);
+
+ /* If User data is available */
+ if (sncCode == SNC_USERDATA)
+ {
+ if (!header->user_data) {
+ header->user_data = (char *) malloc(MAX_USER_DATA_LENGTH);
+ header->user_data_length = 0;
+ }
+
+ if (vdxGetUserData(inBuffer, header->user_data, &(header->user_data_length), bitErrorIndication) != VDX_OK)
+ /* also bibError will be handled in exitAfterBitError */
+ goto exitAfterBitError;
+
+ } else if (sncCode != SNC_VID) {
+
+ deb("vdxGetMPEGVolHeader: ERROR. No Start code after VO header\n");
+ goto exitAfterBitError;
+ }
+ }
+
+ /* if Video Object Start Code is present */
+ bits = bibShowBits(MP4_VID_START_CODE_LENGTH, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ if (bits == MP4_VID_START_CODE) {
+ /* video_object_start_code */
+ bibFlushBits(MP4_VID_START_CODE_LENGTH, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+
+ /* video_object_id */
+ bits = bibGetBits(MP4_VID_ID_CODE_LENGTH, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ header->vo_id = (int) bits;
+ }
+
+ /* MVE */
+ /* dummy indication of the position before VOL start code, only for recoginition of shortheader */
+ if (!getInfo)
+ {
+ hTranscoder->ErrorResilienceInfo(NULL, inBuffer->getIndex, inBuffer->bitIndex);
+ }
+
+ /* vol_start_code */
+ bits = bibShowBits(MP4_VOL_START_CODE_LENGTH, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ if(bits != MP4_VOL_START_CODE)
+ {
+ /* If H.263 PSC, this is a short header stream, i.e. H.263 baseline */
+ if ( (bits >> 6) == 32 ) {
+ return VDX_OK;
+ } else {
+ deb("vdxGetMPEGVolHeader: ERROR - Bitstream does not start with MP4_VOL_START_CODE\n");
+ goto exitAfterBitError;
+ }
+ }
+
+ bibFlushBits(MP4_VOL_START_CODE_LENGTH, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+
+ /* vol_id */
+ bits = bibGetBits(MP4_VOL_ID_CODE_LENGTH, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ header->vol_id = (int) bits;
+
+ /* random_accessible_vol (1 bit) */
+ bits = bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ header->random_accessible_vol = (u_char) bits;
+
+ /* video_object_type_indication (8 bits) */
+ bits = bibGetBits(8, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ if (bits != 1) {
+ /* this is not a simple video object stream */
+ deb("vdxGetMPEGVolHeader: ERROR - This is not a simple video object stream\n");
+ goto notSupported;
+ }
+
+ /* is_object_layer_identifier (1 bit) */
+ bits = bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ if (bits) {
+ /* video_object_layer_verid (4 bits) */
+ bits = bibGetBits(4, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ if (bits != 1) {
+ /* this is not an MPEG-4 version 1 stream */
+ deb("vdxGetMPEGVolHeader: ERROR - This is not an MPEG-4 version 1 stream\n");
+ goto notSupported;
+ }
+
+ /* video_object_layer_priority (3 bits) */
+ bits = bibGetBits(3, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ header->vo_priority = (int) bits;
+ }
+
+ /* aspect_ratio_info: `0010`- 12:11 (625-type for 4:3 picture) */
+ bits = bibGetBits(4, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ header->pixel_aspect_ratio = (int) bits;
+
+ /* extended par */
+ if (bits == 15) {
+ /* par_width */
+ bits = bibGetBits(8, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ /* par_height */
+ bits = bibGetBits(8, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ }
+
+ /* vol_control_parameters flag */
+ bits = bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ if (bits) {
+
+ /* chroma_format (2 bits) */
+ bits = bibGetBits(2, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ if (bits != 1) {
+ goto exitAfterBitError;
+ }
+
+ /* low_delay (1 bits) */
+ bits = bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+
+ /* vbv_parameters (1 bits) */
+ bits = bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ if (bits) {
+
+ /* first_half_bitrate (15 bits) */
+ bits = bibGetBits(15, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ header->bit_rate = (bits << 15);
+
+ /* marker_bit */
+ if (!bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &bibError))
+ goto exitAfterBitError;
+
+ /* latter_half_bitrate (15 bits) */
+ bits = bibGetBits(15, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ header->bit_rate += bits;
+ header->bit_rate *= 400;
+
+ /* marker_bit */
+ if (!bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &bibError))
+ goto exitAfterBitError;
+
+ /* first_half_vbv_buffer_size (15 bits) */
+ bits = bibGetBits(15, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ header->vbv_buffer_size = (bits << 3);
+
+ /* marker_bit */
+ if (!bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &bibError))
+ goto exitAfterBitError;
+
+ /* latter_half_vbv_buffer_size (3 bits) */
+ bits = bibGetBits(3, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ header->vbv_buffer_size += bits;
+ header->vbv_buffer_size <<= 14 /**= 16384*/;
+
+ /* first_half_vbv_occupancy (11 bits) */
+ bits = bibGetBits(11, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ header->vbv_occupancy = (bits << 15);
+
+ /* marker_bit */
+ if (!bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &bibError))
+ goto exitAfterBitError;
+
+ /* latter_half_vbv_occupancy (15 bits) */
+ bits = bibGetBits(15, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ header->vbv_occupancy += bits;
+ header->vbv_occupancy <<= 6 /**= 64*/;
+
+ /* marker_bit */
+ if (!bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &bibError))
+ goto exitAfterBitError;
+
+ } else {
+ fUseDefaultVBVParams = 1;
+ }
+ } else {
+ fUseDefaultVBVParams = 1;
+ }
+
+ if (fUseDefaultVBVParams) {
+
+ /* default values */
+ header->vbv_buffer_size =
+ ((header->profile_level == 0 || header->profile_level == 1) ? 5 : 20);
+ header->vbv_occupancy = header->vbv_buffer_size*170;
+ header->bit_rate =
+ ((header->profile_level == 0 || header->profile_level == 1) ? 64 :
+ ((header->profile_level == 2) ? 128 : 384));
+
+ header->vbv_occupancy <<= 6 /**= 64*/;
+ header->vbv_buffer_size <<= 14 /**= 16384*/;
+ header->bit_rate <<= 10 /**= 1024*/;
+ }
+
+ /* vol_shape (2 bits) */
+ bits = bibGetBits(2, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ /* rectangular_shape = '00' */
+ if (bits != 0) {
+ deb("vdxGetMPEGVolHeader: ERROR - Not rectangular shape is not supported\n");
+ goto notSupported;
+ }
+
+ /* marker_bit */
+ if (!bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &bibError))
+ goto exitAfterBitError;
+
+ /* MVE */
+ if (!getInfo)
+ {
+ hTranscoder->MPEG4TimerResolution(inBuffer->getIndex, inBuffer->bitIndex);
+ }
+
+ /* time_increment_resolution */
+ bits = bibGetBits(16, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ header->time_increment_resolution = (int) bits;
+
+ /* marker_bit */
+ if (!bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &bibError))
+ goto exitAfterBitError;
+
+ /* fixed_vop_rate */
+ bits = bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+
+ /* MVE */
+ header->fixed_vop_rate = (u_char)bits;
+
+ /* fixed_vop_time_increment (1-15 bits) */
+ if (bits) {
+ for (num_bits = 1; ((header->time_increment_resolution-1) >> num_bits) != 0; num_bits++)
+ {
+ }
+
+ bits = bibGetBits(num_bits, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ }
+
+ /* if rectangular_shape !always! */
+
+ /* marker_bit */
+ if (!bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &bibError))
+ goto exitAfterBitError;
+
+ /* vol_width (13 bits) */
+ bits = bibGetBits(13, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ header->lumWidth = (int) bits;
+
+ /* marker_bit */
+ if (!bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &bibError))
+ goto exitAfterBitError;
+
+ /* vol_height (13 bits) */
+ bits = bibGetBits(13, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ header->lumHeight = (int) bits;
+
+ /* endif rectangular_shape */
+
+ /* marker_bit */
+ if (!bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &bibError))
+ goto exitAfterBitError;
+
+ /* interlaced (1 bit) */
+ bits = bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ if (bits)
+ {
+ deb("vdxGetMPEGVolHeader: ERROR - Interlaced VOP not supported\n");
+ goto notSupported;
+ }
+
+ /* OBMC_disable */
+ bits = bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ if (!bits) {
+ deb("vdxGetMPEGVolHeader: ERROR - Overlapped motion compensation not supported\n");
+ goto notSupported;
+ }
+
+ /* sprite_enable (1 bit) */
+ bits = bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ if (bits) {
+ deb("vdxGetMPEGVolHeader: ERROR - Sprites not supported\n");
+ goto notSupported;
+ }
+
+ /* not_8_bit (1 bit) */
+ bits = bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ if (bits) {
+ deb("vdxGetMPEGVolHeader: ERROR - Not 8 bits/pixel not supported\n");
+ goto notSupported;
+ }
+
+ /* quant_type (1 bit) */
+ bits = bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ if (bits) {
+ deb("vdxGetMPEGVolHeader: ERROR - H.263/MPEG-2 Quant Table switch not supported\n");
+ goto notSupported;
+ }
+
+ /* complexity_estimation_disable (1 bit) */
+ bits = bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ if (!bits) {
+ deb("vdxGetMPEGVolHeader: ERROR - Complexity estimation header not supported\n");
+ goto notSupported;
+ }
+
+ /* MVE */
+ if (!getInfo)
+ {
+ hTranscoder->ErrorResilienceInfo(NULL, inBuffer->getIndex, inBuffer->bitIndex);
+ }
+ else
+ {
+ *aByteIndex = inBuffer->getIndex;
+ *aBitIndex = inBuffer->bitIndex;
+ }
+
+ /* resync_marker_disable (1 bit) */
+ bits = bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ header->error_res_disable = (u_char) bits;
+
+ /* data_partitioned (1 bit) */
+ bits = bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ header->data_partitioned = (u_char) bits;
+
+ if (header->data_partitioned) {
+ /* reversible_vlc (1 bit) */
+ bits = bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ header->reversible_vlc = (u_char) bits;
+ }
+
+ /* MVE */
+ if (!getInfo)
+ {
+ hTranscoder->ErrorResilienceInfo(header, 0, 0);
+ }
+
+ /* scalability (1 bit) */
+ bits = bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ if (bits) {
+ deb("vdxGetMPEGVolHeader: ERROR - Scalability not supported\n");
+ goto notSupported;
+ }
+
+ /* check the next start code */
+ sncCode = sncCheckMpegSync(inBuffer, 0, &bibError);
+
+ /* Removed since the VOL header may be followed by another header (H.245 & MPEG-4 signaling)
+ and sncCheckMpegSync does not recognize VOS start code
+ if (sncCode == SNC_NO_SYNC || bibError)
+ {
+ deb("vdxGetMPEGVolHeader: ERROR. No Start code after VOL header\n");
+ goto exitAfterBitError;
+ }
+ */
+ /* If User data is available */
+ if (sncCode == SNC_USERDATA && !bibError)
+ {
+ if (!header->user_data) {
+ header->user_data = (char *) malloc(MAX_USER_DATA_LENGTH);
+ header->user_data_length = 0;
+ }
+
+ if (vdxGetUserData(inBuffer, header->user_data, &(header->user_data_length), bitErrorIndication) != VDX_OK)
+ /* also bibError will be handled in exitAfterBitError */
+ goto exitAfterBitError;
+ }
+
+ /* If no error in bit buffer functions */
+ if (!bibError)
+ return VDX_OK;
+
+ /* Else if ran out of data (i.e. decoding out of sync) */
+ else if (bibError == ERR_BIB_NOT_ENOUGH_DATA) {
+ return VDX_OK_BUT_BIT_ERROR;
+ }
+
+ /* Else other error in bit buffer functions */
+ else
+ return VDX_ERR_BIB;
+
+ exitAfterBitError:
+ if (bibError && bibError != ERR_BIB_NOT_ENOUGH_DATA)
+ return VDX_ERR_BIB;
+
+ return VDX_OK_BUT_BIT_ERROR;
+
+ notSupported:
+ return VDX_ERR_NOT_SUPPORTED;
+}
+
+/* {{-output"vdxGetGovHeader.txt"}} */
+/*
+ *
+ * vdxGetGovHeader
+ *
+ * Parameters:
+ * inBuffer pointer to bit buffer instance
+ * header output parameters: picture header
+ * bitErrorIndication non-zero if a bit error has been detected
+ * within the bits accessed in this function,
+ * see biterr.h for possible values
+ *
+ * Function:
+ * This function reads the GOV header from inBuffer.
+ *
+ * Returns:
+ * VDX_OK the function was successful
+ * VDX_OK_BUT_BIT_ERROR the function behaved normally, but a bit error
+ * occured
+ * VDX_ERR_BIB an error occured when accessing bit buffer
+ * VDX_ERR_NO_START_CODE if start code is not found
+ * VDX_ERR_NOT_SUPPORTED if broken_link and closed_gov conflict
+ *
+ */
+
+int vdxGetGovHeader(
+ bibBuffer_t *inBuffer,
+ vdxGovHeader_t *header,
+ int *bitErrorIndication)
+/* {{-output"vdxGetGovHeader.txt"}} */
+{
+ int tmpvar;
+ u_int32 bits;
+ int time_s;
+ int bitsGot, sncCode;
+ int16 bibError = 0;
+
+ vdxAssert(inBuffer != NULL);
+ vdxAssert(header != NULL);
+ vdxAssert(bitErrorIndication != NULL);
+
+ memset(header, 0, sizeof(vdxGovHeader_t));
+ *bitErrorIndication = 0;
+
+ /* group_start_code (32 bits) */
+ bits = bibGetBits(32, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+
+ if ( bibError )
+ goto exitAfterBitError;
+ if( bits != MP4_GROUP_START_CODE )
+ {
+ deb0p("ERROR. Bitstream does not start with MP4_GROUP_START_CODE\n");
+ goto exitAfterBitError;
+ }
+
+ /* time_code_hours (5 bits) */
+ tmpvar = (int) bibGetBits(5, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+
+ if ( bibError )
+ goto exitAfterBitError;
+
+ time_s= tmpvar*3600;
+
+ /* time_code_minutes (6 bits) */
+ tmpvar = (int) bibGetBits(6, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+
+ if ( bibError )
+ goto exitAfterBitError;
+
+ time_s += tmpvar*60;
+
+ /* marker_bit (1 bit) */
+ tmpvar = bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ if ( bibError )
+ goto exitAfterBitError;
+ if ( !tmpvar )
+ goto exitAfterBitError;
+
+ /* time_code_seconds (6 bits) */
+ tmpvar = (int) bibGetBits(6, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+
+ time_s += tmpvar;
+
+ /* closed_gov (1 bit) */
+ bits = bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ if ( bibError )
+ goto exitAfterBitError;
+
+ header->closed_gov= (u_char) bits;
+
+ /* broken_link (1 bit) */
+ bits = bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ if ( bibError )
+ goto exitAfterBitError;
+
+ header->broken_link = (u_char) bits;
+
+ if ( (header->closed_gov == 0)&&(header->broken_link == 1) )
+ {
+ deb0p("ERROR. GOVHeader: closed_gov = 0\tbroken_link = 1\n");
+ goto exitAfterBitError;
+ }
+
+ /* Stuff the bits before the next start code */
+ sncCode = sncCheckMpegSync(inBuffer, 1, &bibError);
+ if ((sncCode == SNC_NO_SYNC) || bibError)
+ {
+ deb0p("ERROR. No VOP Start code after GOV header\n");
+ /* also bibError will be handled in exitAfterBitError */
+ goto exitAfterBitError;
+ }
+
+ /* If User data is available */
+ if (sncCode == SNC_USERDATA)
+ {
+ if (!header->user_data) {
+ header->user_data = (char *) malloc(MAX_USER_DATA_LENGTH);
+ header->user_data_length = 0;
+ }
+
+ if (vdxGetUserData(inBuffer, header->user_data, &(header->user_data_length), bitErrorIndication) != VDX_OK)
+ /* also bibError will be handled in exitAfterBitError */
+ goto exitAfterBitError;
+ }
+
+ header->time_stamp = time_s;
+
+ /* If no error in bit buffer functions */
+ if (!bibError)
+ return VDX_OK;
+
+ /* Else if ran out of data (i.e. decoding out of sync) */
+ else if (bibError == ERR_BIB_NOT_ENOUGH_DATA) {
+ return VDX_OK_BUT_BIT_ERROR;
+ }
+
+ /* Else other error in bit buffer functions */
+ else
+ return VDX_ERR_BIB;
+
+ exitAfterBitError:
+ if (bibError && bibError != ERR_BIB_NOT_ENOUGH_DATA)
+ return VDX_ERR_BIB;
+
+ return VDX_OK_BUT_BIT_ERROR;
+
+}
+
+/* {{-output"vdxGetVopHeader.txt"}} */
+/*
+ *
+ * vdxGetVopHeader
+ *
+ * Parameters:
+ * inBuffer pointer to bit buffer instance
+ * inParam input parameters
+ * header output parameters: picture header
+ * bitErrorIndication non-zero if a bit error has been detected
+ * within the bits accessed in this function,
+ * see biterr.h for possible values
+ *
+ * Function:
+ * This function reads the VOP header from inBuffer.
+ *
+ * Returns:
+ * VDX_OK the function was successful
+ * VDX_OK_BUT_BIT_ERROR the function behaved normally, but a bit error
+ * occured
+ * VDX_ERR_BIB an error occured when accessing bit buffer
+ * VDX_ERR_NO_START_CODE if start code is not found
+ * VDX_ERR_NOT_SUPPORTED if broken_link and closed_gov conflict
+ *
+ *
+ */
+
+int vdxGetVopHeader(
+ bibBuffer_t *inBuffer,
+ const vdxGetVopHeaderInputParam_t *inpParam,
+ vdxVopHeader_t *header,
+ int * ModuloByteIndex,
+ int * ModuloBitIndex,
+ int * ByteIndex,
+ int * BitIndex,
+ int *bitErrorIndication)
+/* {{-output"vdxGetVopHeader.txt"}} */
+{
+
+ int tmpvar;
+ u_int32 bits;
+ int bitsGot;
+ int time_base_incr = 0,
+ num_bits;
+ int16
+ bibError = 0;
+
+ vdxAssert(inBuffer != NULL);
+ vdxAssert(header != NULL);
+ vdxAssert(bitErrorIndication != NULL);
+
+ memset(header, 0, sizeof(vdxVopHeader_t));
+ *bitErrorIndication = 0;
+
+ /* vop_start_code (32 bits) */
+ bits = bibGetBits(MP4_VOP_START_CODE_LENGTH, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ if ( bibError )
+ goto exitFunction;
+
+ if( bits != MP4_VOP_START_CODE )
+ {
+ deb0p("ERROR. Bitstream does not start with MP4_VOP_START_CODE\n");
+ goto exitAfterBitError;
+ }
+
+ *bitErrorIndication = 0;
+
+ /* vop_prediction_type (2 bits) */
+ bits = bibGetBits(2, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ if ( bibError )
+ goto exitAfterBitError;
+
+ if ( (bits != VDX_VOP_TYPE_P && bits != VDX_VOP_TYPE_I) )
+ {
+ deb("ERROR. Not supported VOP prediction type\n");
+ goto exitAfterBitError;
+ }
+
+ header->coding_type = (u_char) bits;
+
+ /* MVE */
+ *ModuloByteIndex = inBuffer->numBytesRead;
+ *ModuloBitIndex = inBuffer->bitIndex;
+
+ /* modulo_time_base (? bits) */
+ tmpvar = (int) bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ if ( bibError )
+ goto exitAfterBitError;
+
+ while( tmpvar == 1 && !bibError )
+ {
+ tmpvar = (int) bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ time_base_incr++;
+ }
+ if ( bibError )
+ goto exitAfterBitError;
+
+ header->time_base_incr = time_base_incr;
+
+ /* marker_bit (1 bit) */
+ tmpvar = bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ if ( bibError )
+ goto exitAfterBitError;
+ if ( !tmpvar )
+ goto exitAfterBitError;
+
+ /* MVE */
+ *ByteIndex = inBuffer->numBytesRead;
+ *BitIndex = inBuffer->bitIndex;
+
+ /* vop_time_increment (1-16 bits) */
+ for (num_bits = 1; ((inpParam->time_increment_resolution-1) >> num_bits) != 0; num_bits++)
+ {
+ }
+
+ tmpvar = (int) bibGetBits(num_bits, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ if ( bibError )
+ goto exitAfterBitError;
+
+ header->time_inc = tmpvar;
+
+ /* marker_bit (1 bit) */
+ tmpvar = bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ if ( bibError )
+ goto exitAfterBitError;
+ if ( !tmpvar )
+ goto exitAfterBitError;
+
+ /* vop_coded (1 bit) */
+ header->vop_coded = (u_char) bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ if ( bibError )
+ goto exitAfterBitError;
+
+ if ( !header->vop_coded ) {
+ goto exitAfterBitError;
+ }
+
+ /* vop_rounding_type (1 bit) */
+ if (header->coding_type == VDX_VOP_TYPE_P)
+ {
+ bits = bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ if ( bibError )
+ goto exitAfterBitError;
+ header->rounding_type = (int) bits;
+ } else
+ header->rounding_type = 0;
+
+ /* intra_dc_vlc_thr (3 bits) */
+ bits = bibGetBits(3, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ if ( bibError )
+ goto exitAfterBitError;
+
+ header->intra_dc_vlc_thr = (int) bits;
+
+ /* vop_quant (5 bits) */
+ bits = bibGetBits(5, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ if ( bibError )
+ goto exitAfterBitError;
+
+ header->quant = (int) bits;
+
+ /* vop_fcode_forward (3 bits) */
+ if (header->coding_type == VDX_VOP_TYPE_P)
+ {
+ bits = bibGetBits(3, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ if ( bibError )
+ goto exitAfterBitError;
+ header->fcode_forward = (int) bits;
+ } else {
+ /* In case of an Intra Frame to calculate the length of the
+ VP resynchronization marker later on fcode_forward should be
+ assumed to have the value 1. */
+ header->fcode_forward = 1;
+ }
+
+ exitFunction:
+
+ /* If no error in bit buffer functions */
+ if (!bibError)
+ return VDX_OK;
+
+ /* Else if ran out of data (i.e. decoding out of sync) */
+ else if (bibError == ERR_BIB_NOT_ENOUGH_DATA) {
+ return VDX_OK_BUT_BIT_ERROR;
+ }
+
+ /* Else other error in bit buffer functions */
+ else
+ return VDX_ERR_BIB;
+
+ exitAfterBitError:
+
+ if (bibError && bibError != ERR_BIB_NOT_ENOUGH_DATA)
+ return VDX_ERR_BIB;
+
+ return VDX_OK_BUT_BIT_ERROR;
+
+}
+
+/*
+ * vdxGetUserData
+ *
+ *
+ * Parameters:
+ * inBuffer pointer to bit buffer instance
+ * user_data string of user data read byte-by-byte from
+ * the stream
+ * user_data_length number of bytes of user data
+ * bitErrorIndication non-zero if a bit error has been detected
+ * within the bits accessed in this function,
+ * see biterr.h for possible values
+ *
+ * Function:
+ * This function reads a string of bytes as user data from the bitsream
+ * It is called from te VOL header or GOV header
+ *
+ * Returns:
+ * VDX_OK the function was successful
+ * VDX_OK_BUT_BIT_ERROR the function behaved normally, but a bit error
+ * occured
+ * VDX_ERR_BIB an error occured when accessing bit buffer
+ *
+ *
+ */
+int vdxGetUserData(bibBuffer_t *inBuffer,
+ char *user_data, int *user_data_length,
+ int *bitErrorIndication)
+{
+ int i;
+ u_int32 bits;
+ int bitsGot;
+ int16 ownError=0;
+
+ /* user_data_start_code (32 bits) */
+ bits = bibGetBits(32, inBuffer, &bitsGot, bitErrorIndication, &ownError);
+ if ( ownError )
+ goto exitFunction;
+
+ if (bits != MP4_USER_DATA_START_CODE)
+ {
+ deb0p("ERROR. Bitstream does not start with MP4_USER_DATA_START_CODE\n");
+ goto exitFunction;
+ }
+
+ /* read until start_code 0x000001 */
+ for ( i=(*user_data_length);
+ (((bits = bibShowBits(24, inBuffer, &bitsGot, bitErrorIndication, &ownError)) != 0x000001)&&(ownError==0));
+ i++ )
+ {
+ bits = bibGetBits(8, inBuffer, &bitsGot, bitErrorIndication, &ownError);
+ if (ownError)
+ goto exitFunction;
+
+ if (i<MAX_USER_DATA_LENGTH)
+ {
+ user_data[i] = (u_char) bits;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+
+ *user_data_length = (i>=MAX_USER_DATA_LENGTH) ? MAX_USER_DATA_LENGTH : i++;
+
+ exitFunction:
+
+ /* If no error in bit buffer functions */
+ if (!ownError)
+ return VDX_OK;
+
+ /* Else if ran out of data (i.e. decoding out of sync) */
+ else if (ownError == ERR_BIB_NOT_ENOUGH_DATA) {
+ return VDX_OK_BUT_BIT_ERROR;
+ }
+
+ /* Else other error in bit buffer functions */
+ else
+ return VDX_ERR_BIB;
+
+}
+
+/*
+ * Video Packet Layer Global Functions
+ */
+
+/* {{-output"vdxGetVideoPacketHeader.txt"}} */
+/*
+ *
+ * vdxGetVideoPacketHeader
+ *
+ * Parameters:
+ * inBuffer pointer to bit buffer instance
+ * header output parameters: picture header
+ * bitErrorIndication non-zero if a bit error has been detected
+ * within the bits accessed in this function,
+ * see biterr.h for possible values
+ *
+ * Function:
+ * This function reads the Video Packet header from inBuffer.
+ *
+ * Returns:
+ * VDX_OK the function was successful
+ * VDX_OK_BUT_BIT_ERROR the function behaved normally, but a bit error
+ * occured
+ * VDX_ERR_BIB an error occured when accessing bit buffer
+ * VDX_ERR_NO_START_CODE if start code is not found
+ * VDX_ERR_NOT_SUPPORTED if broken_link and closed_gov conflict
+ *
+ *
+ */
+
+int vdxGetVideoPacketHeader(
+ bibBuffer_t *inBuffer,
+ const vdxGetVideoPacketHeaderInputParam_t *inpParam,
+ vdxVideoPacketHeader_t *header,
+ int *bitErrorIndication)
+/* {{-output"vdxGetVideoPacketHeader.txt"}} */
+{
+ int tmpvar, num_bits, bitsGot;
+ u_int32 bits;
+ int MBNumLength,
+ time_base_incr = 0;
+ int16
+ bibError = 0;
+
+ vdxAssert(inBuffer != NULL);
+ vdxAssert(header != NULL);
+ vdxAssert(bitErrorIndication != NULL);
+
+ memset(header, 0, sizeof(vdxVideoPacketHeader_t));
+ *bitErrorIndication = 0;
+
+ /* resync marker */
+ tmpvar = bibGetBits(16 + inpParam->fcode_forward, inBuffer, &bitsGot,
+ bitErrorIndication, &bibError);
+ if ( bibError )
+ goto exitAfterBitError;
+ if ( (int) tmpvar != MP4_RESYNC_MARKER )
+ {
+ deb("ERROR. No Resync Marker found\n");
+ goto exitAfterBitError;
+ }
+
+ /* Macroblock Number */
+ for (MBNumLength = 1; ((inpParam->numOfMBs-1) >> MBNumLength) != 0; MBNumLength++)
+ {
+ }
+
+ header->currMBNum = (int) bibGetBits(MBNumLength, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ if ( bibError )
+ goto exitAfterBitError;
+
+ /* quant_scale (5 bits) */
+ bits = bibGetBits(5, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ if ( bibError )
+ goto exitAfterBitError;
+
+ header->quant = (int) bits;
+
+ /* header_extension_code (1 bit) */
+ header->fHEC = (u_char) bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ if ( bibError )
+ goto exitAfterBitError;
+
+ if(header->fHEC) {
+ /* modulo_time_base (? bits) */
+ tmpvar = (int) bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ if ( bibError )
+ goto exitAfterBitError;
+
+ while (tmpvar == 1 && !bibError)
+ {
+ tmpvar = (int) bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ time_base_incr++;
+ }
+ if ( bibError )
+ goto exitAfterBitError;
+
+ header->time_base_incr = time_base_incr;
+
+ /* marker_bit (1 bit) */
+ tmpvar = bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ if ( bibError )
+ goto exitAfterBitError;
+ if ( !tmpvar )
+ goto exitAfterBitError;
+
+ /* vop_time_increment (1-15 bits) */
+ for (num_bits = 1; ((inpParam->time_increment_resolution-1) >> num_bits) != 0; num_bits++)
+ {
+ }
+
+ tmpvar = (int) bibGetBits(num_bits, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ if ( bibError )
+ goto exitAfterBitError;
+
+ header->time_inc = tmpvar;
+
+ /* marker_bit (1 bit) */
+ tmpvar = bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ if ( bibError )
+ goto exitAfterBitError;
+ if (!tmpvar)
+ goto exitAfterBitError;
+
+ /* vop_prediction_type (2 bits) */
+ bits = bibGetBits(2, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ if ( bibError )
+ goto exitAfterBitError;
+
+ if ((bits != VDX_VOP_TYPE_P && bits != VDX_VOP_TYPE_I))
+ {
+ deb("ERROR. Not supported VOP prediction type\n");
+ goto exitAfterBitError;
+ }
+
+ header->coding_type = (u_char) bits;
+
+ /* intra_dc_vlc_thr (3 bits) */
+ bits = bibGetBits(3, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ if ( bibError )
+ goto exitAfterBitError;
+
+ header->intra_dc_vlc_thr = (int) bits;
+
+ /* vop_fcode_forward (3 bits) */
+ if (header->coding_type == VDX_VOP_TYPE_P)
+ {
+ bits = bibGetBits(3, inBuffer, &bitsGot, bitErrorIndication, &bibError);
+ if ( bibError )
+ goto exitAfterBitError;
+ header->fcode_forward = (int) bits;
+ } else
+ header->fcode_forward = 1;
+ }
+
+ /* Check success and return */
+
+ /* If no error in bit buffer functions */
+ if (!bibError)
+ return VDX_OK;
+
+ /* Else if ran out of data (i.e. decoding out of sync) */
+ else if (bibError == ERR_BIB_NOT_ENOUGH_DATA) {
+ return VDX_OK_BUT_BIT_ERROR;
+ }
+
+ /* Else other error in bit buffer functions */
+ else
+ return VDX_ERR_BIB;
+
+ exitAfterBitError:
+ if (bibError && bibError != ERR_BIB_NOT_ENOUGH_DATA)
+ return VDX_ERR_BIB;
+
+ return VDX_OK_BUT_BIT_ERROR;
+}
+
+/*
+ * Macroblock Layer Global Functions
+ */
+
+/*
+ *
+ * vdxGetDataPartitionedIMBLayer_Part1
+ *
+ * Parameters:
+ * inBuffer input buffer
+ * inpParam input parameters
+ * MBList a double-linked list for soring
+ * MB parameters + DC values in the VP
+ * bitErrorIndication
+ * non-zero if a bit error has been detected
+ * within the bits accessed in this function,
+ * see biterr.h for possible values
+ *
+ * Function:
+ * This function gets the first (DC) partition of a data
+ * partitioned encoded Video Packet in an Intra-VOP.
+ * The parameters MCBPC, DQUANT and DC values of all the MBs
+ * in the VP are read and stored in the linked list.
+ *
+ * Returns:
+ * VDX_OK the function was successful
+ * VDX_OK_BUT_BIT_ERROR the function behaved normally, but a bit error
+ * occured
+ * VDX_ERR_BIB an error occured when accessing bit buffer
+ *
+ * Error codes:
+ * error codes returned by bibFlushBits/bibGetBits/bibShowBits
+ *
+ *
+ */
+
+int vdxGetDataPartitionedIMBLayer_Part1(
+ bibBuffer_t *inBuffer, bibBuffer_t *outBuffer, bibBufferEdit_t *bufEdit,
+ int aColorEffect, int *aStartByteIndex, int *aStartBitIndex,
+ CMPEG4Transcoder *hTranscoder,
+ const vdxGetDataPartitionedIMBLayerInputParam_t *inpParam,
+ dlst_t *MBList,
+ int *bitErrorIndication)
+{
+
+ int mcbpcIndex,
+ retValue = VDX_OK,
+ fDQUANT,
+ new_quant, previous_quant,
+ bitsGot,
+ i,
+ IntraDC_size,
+ IntraDC_delta;
+
+ /* MVE */
+ int StartByteIndex;
+ int StartBitIndex;
+
+ int16 error=0;
+ vdxIMBListItem_t *MBinstance = NULL;
+
+
+ vdxAssert(inpParam != NULL);
+ vdxAssert(inBuffer != NULL);
+ vdxAssert(bitErrorIndication != NULL);
+
+ previous_quant = inpParam->quant;
+
+ /* MVE */
+ int stuffingStartByteIndex, stuffingStartBitIndex, stuffingEndByteIndex, stuffingEndBitIndex;
+ stuffingStartByteIndex = stuffingEndByteIndex = inBuffer->getIndex;
+ stuffingStartBitIndex = stuffingEndBitIndex = inBuffer->bitIndex;
+
+ while (bibShowBits(MP4_DC_MARKER_LENGTH, inBuffer, &bitsGot, bitErrorIndication, &error) != MP4_DC_MARKER && !error)
+ {
+ /* MVE */
+ StartByteIndex = inBuffer->getIndex;
+ StartBitIndex = inBuffer->bitIndex;
+
+ retValue = vdxGetMCBPCIntra(inBuffer, &mcbpcIndex, bitErrorIndication);
+ if (retValue != VDX_OK)
+ goto exitFunction;
+
+ if (mcbpcIndex == 8)
+ {
+ /* MVE */
+ stuffingEndByteIndex = inBuffer->getIndex;
+ stuffingEndBitIndex = inBuffer->bitIndex;
+
+ continue; /* skip stuffing */
+ }
+
+ /* Create new MBInstance for the next MB */
+ MBinstance = (vdxIMBListItem_t *) malloc(sizeof(vdxIMBListItem_t));
+ if (!MBinstance)
+ {
+ deb("ERROR - MBinstance creation failed\n");
+ retValue = H263D_ERROR;
+ goto exitFunction;
+ }
+ memset(MBinstance, 0, sizeof(vdxIMBListItem_t));
+
+ /* CBPC (2 LSBs of MCBPC) */
+ MBinstance->cbpc = mcbpcIndex & 3;
+
+ /* MVE */
+ MBinstance->mcbpc = mcbpcIndex;
+ VDT_SET_START_POSITION(MBinstance,11,stuffingStartByteIndex,stuffingStartBitIndex); // 11: MB stuffing bits
+ VDT_SET_END_POSITION(MBinstance,11,stuffingEndByteIndex,stuffingEndBitIndex); // 11: MB stuffing bits
+
+ VDT_SET_START_POSITION(MBinstance,0,StartByteIndex,StartBitIndex); // 0: mcbpc
+ VDT_SET_END_POSITION(MBinstance,0,inBuffer->getIndex,inBuffer->bitIndex); // 0: mcbpc
+ VDT_SET_START_POSITION(MBinstance,1,inBuffer->getIndex,inBuffer->bitIndex); // 1: dquant
+
+ /* DQUANT is given for MCBPC indexes 4..7 */
+ fDQUANT = mcbpcIndex & 4;
+
+ if (fDQUANT) {
+ retValue = vdxUpdateQuant(inBuffer, 0, previous_quant,
+ &new_quant, bitErrorIndication);
+ if (retValue != VDX_OK)
+ goto exitFunction;
+ }
+ /* Else no DQUANT */
+ else
+ new_quant = previous_quant;
+
+ MBinstance->dquant = fDQUANT ? new_quant - previous_quant : 0;
+ MBinstance->quant = previous_quant = new_quant;
+
+ /* MVE */
+ VDT_SET_END_POSITION(MBinstance,1,inBuffer->getIndex,inBuffer->bitIndex); // 1: dquant
+ VDT_SET_START_POSITION(MBinstance,4,inBuffer->getIndex,inBuffer->bitIndex); // 4: intraDC
+ VDT_SET_START_POSITION(MBinstance,5,inBuffer->getIndex,inBuffer->bitIndex); // 5: intraDC
+ VDT_SET_START_POSITION(MBinstance,6,inBuffer->getIndex,inBuffer->bitIndex); // 6: intraDC
+ VDT_SET_START_POSITION(MBinstance,7,inBuffer->getIndex,inBuffer->bitIndex); // 7: intraDC
+ VDT_SET_START_POSITION(MBinstance,8,inBuffer->getIndex,inBuffer->bitIndex); // 8: intraDC
+ VDT_SET_START_POSITION(MBinstance,9,inBuffer->getIndex,inBuffer->bitIndex); // 9: intraDC
+
+ VDT_SET_END_POSITION(MBinstance,4,inBuffer->getIndex,inBuffer->bitIndex); // 4: intraDC
+ VDT_SET_END_POSITION(MBinstance,5,inBuffer->getIndex,inBuffer->bitIndex); // 5: intraDC
+ VDT_SET_END_POSITION(MBinstance,6,inBuffer->getIndex,inBuffer->bitIndex); // 6: intraDC
+ VDT_SET_END_POSITION(MBinstance,7,inBuffer->getIndex,inBuffer->bitIndex); // 7: intraDC
+ VDT_SET_END_POSITION(MBinstance,8,inBuffer->getIndex,inBuffer->bitIndex); // 8: intraDC
+ VDT_SET_END_POSITION(MBinstance,9,inBuffer->getIndex,inBuffer->bitIndex); // 9: intraDC
+
+ /* Color Toning */
+ hTranscoder->AfterMBLayer(new_quant);
+
+
+ MBinstance->switched = aicIntraDCSwitch(inpParam->intra_dc_vlc_thr,new_quant);
+
+ /* Intra_DC_Coeffs */
+ if(!MBinstance->switched) {
+ for (i=0; i<6; i++) {
+
+ /* MVE */
+ VDT_SET_START_POSITION(MBinstance,i+4,inBuffer->getIndex,inBuffer->bitIndex); // 6: intraDC,chrominance
+
+ retValue = vdxGetIntraDC(inBuffer, outBuffer, bufEdit, aColorEffect, aStartByteIndex, aStartBitIndex,
+ i, &IntraDC_size, &IntraDC_delta, bitErrorIndication);
+
+ /* MVE */
+ VDT_SET_END_POSITION(MBinstance,i+4,inBuffer->getIndex,inBuffer->bitIndex); // 6: intraDC,chrominance
+
+ if (retValue != VDX_OK)
+ goto exitFunction;
+
+ MBinstance->DC[i] = IntraDC_delta;
+ }
+ }
+
+
+ /* Put MBinstance into the queue */
+ dlstAddAfterCurr(MBList, MBinstance);
+ MBinstance = NULL;
+
+ /* MVE */
+ // begin another MB, record the position of MB stuffing
+ stuffingStartByteIndex = stuffingEndByteIndex = inBuffer->getIndex;
+ stuffingStartBitIndex = stuffingEndBitIndex = inBuffer->bitIndex;
+
+ }
+
+exitFunction:
+
+ if (MBinstance)
+ free(MBinstance);
+
+
+ /* If no error in bit buffer functions */
+ if (!error)
+ return retValue;
+
+ /* Else if ran out of data (i.e. decoding out of sync) */
+ else if (error == ERR_BIB_NOT_ENOUGH_DATA) {
+ return VDX_OK_BUT_BIT_ERROR;
+ }
+
+ /* Else other error in bit buffer functions */
+ else
+ return VDX_ERR_BIB;
+}
+
+/*
+ *
+ * vdxGetDataPartitionedIMBLayer_Part2
+ *
+ * Parameters:
+ * inBuffer input buffer
+ * MBList a double-linked list for soring
+ * MB parameters + DC values in the VP
+ * numMBsInVP number of MBs in this VP
+ * bitErrorIndication
+ * non-zero if a bit error has been detected
+ * within the bits accessed in this function,
+ * see biterr.h for possible values
+ *
+ * Function:
+ * This function gets the second (CBPY) partition of a data
+ * partitioned encoded Video Packet in an Intra-VOP.
+ * The parameters CBPY and ac_pred_flag of all the MBs
+ * in the VP are read and stored in the linked list.
+ *
+ * Returns:
+ * VDX_OK the function was successful
+ * VDX_OK_BUT_BIT_ERROR the function behaved normally, but a bit error
+ * occured
+ * VDX_ERR_BIB an error occured when accessing bit buffer
+ *
+ * Error codes:
+ * error codes returned by bibFlushBits/bibGetBits/bibShowBits
+ *
+ *
+ *
+ */
+
+int vdxGetDataPartitionedIMBLayer_Part2(
+ bibBuffer_t *inBuffer, bibBuffer_t */*outBuffer*/, bibBufferEdit_t */*bufEdit*/,
+ int /*aColorEffect*/, int */*aStartByteIndex*/, int */*aStartBitIndex*/,
+ dlst_t *MBList,
+ int numMBsInVP,
+ int *bitErrorIndication)
+{
+
+ int cbpyIndex,
+ i,
+ retValue = VDX_OK,
+ bitsGot;
+
+ int16 error=0;
+ u_char code;
+ vdxIMBListItem_t *MBinstance;
+
+ vdxAssert(inBuffer != NULL);
+ vdxAssert(bitErrorIndication != NULL);
+
+ /* get the first MB of the list */
+ dlstHead(MBList, (void **) &MBinstance);
+
+ /* Get ac_pred_flag and cbpy of all MBs in VP */
+ for (i = 0; i < numMBsInVP; i++)
+ {
+ if (!MBinstance)
+ {
+ retValue = H263D_ERROR;
+ goto exitFunction;
+ }
+
+ /* MVE */
+ VDT_SET_START_POSITION(MBinstance,3,inBuffer->getIndex,inBuffer->bitIndex); // 3: ac_pred_flag
+
+ /* ac_pred_flag (1 bit) */
+ code = (u_char) bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &error);
+ if (error)
+ goto exitFunction;
+
+ /* MVE */
+ VDT_SET_END_POSITION(MBinstance,3,inBuffer->getIndex,inBuffer->bitIndex); // 3: ac_pred_flag
+ VDT_SET_START_POSITION(MBinstance,2,inBuffer->getIndex,inBuffer->bitIndex); // 2: cbpy
+
+ /* CBPY */
+ retValue = vdxGetCBPY(inBuffer, &cbpyIndex, bitErrorIndication);
+ if (retValue != VDX_OK)
+ goto exitFunction;
+
+ /* MVE */
+ VDT_SET_END_POSITION(MBinstance,2,inBuffer->getIndex,inBuffer->bitIndex); // 2: cbpy
+
+ /* add the information to the MB data item.
+ If the Part1 of the VP was decoded without errors (all MBs were
+ attached to the list), MBinstance should always have a valid value. */
+ if (MBinstance != NULL) {
+ MBinstance->ac_pred_flag = code;
+ MBinstance->cbpy = cbpyIndex;
+
+ dlstNext(MBList, (void **) &MBinstance);
+ }
+ }
+
+exitFunction:
+
+
+ /* If no error in bit buffer functions */
+ if (!error)
+ return retValue;
+
+ /* Else if ran out of data (i.e. decoding out of sync) */
+ else if (error == ERR_BIB_NOT_ENOUGH_DATA) {
+ return VDX_OK_BUT_BIT_ERROR;
+ }
+
+ /* Else other error in bit buffer functions */
+ else
+ return VDX_ERR_BIB;
+}
+
+/*
+ *
+ * vdxGetDataPartitionedPMBLayer_Part1
+ *
+ * Parameters:
+ * inBuffer input buffer
+ * inpParam input parameters
+ * MBList a double-linked list for soring
+ * MB parameters + DC values in the VP
+ * bitErrorIndication
+ * non-zero if a bit error has been detected
+ * within the bits accessed in this function,
+ * see biterr.h for possible values
+ *
+ * Function:
+ * This function gets the first (Motion) partition of a data
+ * partitioned encoded Video Packet in an Inter-VOP.
+ * The parameters COD, MCBPC and motion vectors of all the MBs
+ * in the VP are read and stored in the linked list.
+ *
+ * Returns:
+ * VDX_OK the function was successful
+ * VDX_OK_BUT_BIT_ERROR the function behaved normally, but a bit error
+ * occured
+ * VDX_ERR_BIB an error occured when accessing bit buffer
+ *
+ * Error codes:
+ * error codes returned by bibFlushBits/bibGetBits/bibShowBits
+ *
+ *
+ *
+ */
+
+ int vdxGetDataPartitionedPMBLayer_Part1(
+ bibBuffer_t *inBuffer,
+ bibBuffer_t */*outBuffer*/, bibBufferEdit_t */*bufEdit*/,
+ int /*aColorEffect*/, int */*aStartByteIndex*/, int */*aStartBitIndex*/,
+ const vdxGetDataPartitionedPMBLayerInputParam_t *inpParam,
+ dlst_t *MBList,
+ int *bitErrorIndication)
+ {
+
+ static const int mbTypeToMBClass[6] =
+ {VDX_MB_INTER, VDX_MB_INTER, VDX_MB_INTER,
+ VDX_MB_INTRA, VDX_MB_INTRA, VDX_MB_INTER};
+
+ int mvdx, mvdy,
+ numMVs,
+ mcbpcIndex,
+ retValue = VDX_OK,
+ bitsGot;
+
+ int16 error=0;
+ u_char code;
+ vdxPMBListItem_t *MBinstance = NULL;
+
+ /* MVE */
+ int StartByteIndex = 0;
+ int StartBitIndex = 0;
+ int stuffingStartByteIndex, stuffingStartBitIndex, stuffingEndByteIndex, stuffingEndBitIndex;
+
+ stuffingStartByteIndex = stuffingEndByteIndex = inBuffer->getIndex;
+ stuffingStartBitIndex = stuffingEndBitIndex = inBuffer->bitIndex;
+
+ vdxAssert(inpParam != NULL);
+ vdxAssert(inBuffer != NULL);
+ vdxAssert(bitErrorIndication != NULL);
+
+ while (bibShowBits(MP4_MOTION_MARKER_COMB_LENGTH, inBuffer, &bitsGot, bitErrorIndication, &error)
+ != MP4_MOTION_MARKER_COMB && !error)
+ {
+ /* COD */
+ code = (u_char) bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &error);
+ if (error)
+ goto exitFunction;
+
+ if (code == 0)
+ {
+
+ /* MVE */
+ StartByteIndex = inBuffer->getIndex;
+ StartBitIndex = inBuffer->bitIndex;
+
+ /* MCBPC */
+ retValue = vdxGetMCBPCInter(
+ inBuffer,
+ 0, /* No PLUSPTYPE present in MPEG-4 */
+ 1, /* Four motion vectors always possible in MPEG-4 */
+ 0, /* Flag to indicate if this is the first MB of a picture.
+ Since this value is used only for checking if
+ indices 21 - 24 are allowed in H.263, we don't have
+ to set this correctly. (Indices 21 - 24 are not allowed
+ in MPEG-4 at all.) */
+ &mcbpcIndex,
+ bitErrorIndication);
+
+ if (retValue != VDX_OK)
+ goto exitFunction;
+
+ if (mcbpcIndex == 20)
+ {
+ /* MVE */
+ stuffingEndByteIndex = inBuffer->getIndex;
+ stuffingEndBitIndex = inBuffer->bitIndex;
+
+ continue; /* skip stuffing */
+ }
+
+ /* Indices > 20 not allowed */
+ if (mcbpcIndex > 20) {
+ deb0p("vdxGetDataPartitionedPMBLayer_Part1: ERROR - Illegal code.\n");
+ retValue = VDX_OK_BUT_BIT_ERROR;
+ goto exitFunction;
+ }
+
+
+ }
+
+ /* Create new MBInstance for the MB */
+ MBinstance = (vdxPMBListItem_t *) malloc(sizeof(vdxPMBListItem_t));
+ if (!MBinstance)
+ {
+ deb("ERROR - MBinstance creation failed\n");
+ goto exitFunction;
+ }
+ memset(MBinstance, 0, sizeof(vdxPMBListItem_t));
+
+ MBinstance->fCodedMB = (u_char) (code ^ 1);
+
+ if (MBinstance->fCodedMB)
+ {
+ /* MCBPC */
+ MBinstance->cbpc = mcbpcIndex;
+
+ /* MCBPC --> MB type & included data elements */
+ MBinstance->mbType = mcbpcIndex / 4;
+ MBinstance->mbClass = mbTypeToMBClass[MBinstance->mbType];
+
+ /* MVE */
+ MBinstance->mcbpc = mcbpcIndex;
+ VDT_SET_START_POSITION(MBinstance,11,stuffingStartByteIndex,stuffingStartBitIndex); // 11: MB stuffing bits
+ VDT_SET_END_POSITION(MBinstance,11,stuffingEndByteIndex,stuffingEndBitIndex); // 11: MB stuffing bits
+ VDT_SET_START_POSITION(MBinstance,0,StartByteIndex,StartBitIndex); // MCBPC
+ VDT_SET_END_POSITION(MBinstance,0,inBuffer->getIndex,inBuffer->bitIndex);
+
+ VDT_SET_START_POSITION(MBinstance,10,inBuffer->getIndex,inBuffer->bitIndex); // MVs
+
+ /* MVD is included always for PB-frames and always if MB type is INTER */
+ numMVs = MBinstance->numMVs =
+ (MBinstance->mbClass == VDX_MB_INTER) ?
+ ((MBinstance->mbType == 2 || MBinstance->mbType == 5) ? 4 : 1) : 0;
+
+ if (numMVs) {
+ int i;
+ for (i = 0; i < numMVs; i++) {
+ retValue = vdxGetScaledMVD(inBuffer,inpParam->f_code,&mvdx,bitErrorIndication);
+ if (retValue != VDX_OK)
+ goto exitFunction;
+ retValue = vdxGetScaledMVD(inBuffer,inpParam->f_code,&mvdy,bitErrorIndication);
+ if (retValue != VDX_OK)
+ goto exitFunction;
+
+ MBinstance->mvx[i] = mvdx;
+ MBinstance->mvy[i] = mvdy;
+ }
+ }
+
+ /* MVE */
+ VDT_SET_END_POSITION(MBinstance,10,inBuffer->getIndex,inBuffer->bitIndex); // MVs
+
+ }
+
+ /* MVE */
+ // begin another MB, record the position of MB stuffing
+ stuffingStartByteIndex = stuffingEndByteIndex = inBuffer->getIndex;
+ stuffingStartBitIndex = stuffingEndBitIndex = inBuffer->bitIndex;
+
+ /* Put MBinstance into the queue */
+ dlstAddAfterCurr(MBList, MBinstance);
+ MBinstance = NULL;
+ }
+
+exitFunction:
+
+ if (MBinstance)
+ free(MBinstance);
+
+
+ /* If no error in bit buffer functions */
+ if (!error)
+ return retValue;
+
+ /* Else if ran out of data (i.e. decoding out of sync) */
+ else if (error == ERR_BIB_NOT_ENOUGH_DATA) {
+ return VDX_OK_BUT_BIT_ERROR;
+ }
+
+ /* Else other error in bit buffer functions */
+ else
+ return VDX_ERR_BIB;
+
+}
+
+
+/*
+ *
+ * vdxGetDataPartitionedPMBLayer_Part2
+ *
+ * Parameters:
+ * inBuffer input buffer
+ * inpParam input parameters
+ * MBList a double-linked list for soring
+ * MB parameters + DC values in the VP
+ * bitErrorIndication
+ * non-zero if a bit error has been detected
+ * within the bits accessed in this function,
+ * see biterr.h for possible values
+ *
+ * Function:
+ * This function gets the second (CBPY) partition of a data
+ * partitioned encoded Video Packet in an Inter-VOP.
+ * The parameters CBPY, DQUANT and if Intra MB its DC coeffs
+ * of all the MBs in the VP are read and stored in the linked list.
+ *
+ * Returns:
+ * VDX_OK the function was successful
+ * VDX_OK_BUT_BIT_ERROR the function behaved normally, but a bit error
+ * occured
+ * VDX_ERR_BIB an error occured when accessing bit buffer
+ *
+ * Error codes:
+ * error codes returned by bibFlushBits/bibGetBits/bibShowBits
+ *
+ *
+ *
+ */
+
+ int vdxGetDataPartitionedPMBLayer_Part2(
+ bibBuffer_t *inBuffer,
+ bibBuffer_t *outBuffer,
+ bibBufferEdit_t *bufEdit,
+ int aColorEffect, int *aStartByteIndex, int *aStartBitIndex,
+ CMPEG4Transcoder *hTranscoder,
+ const vdxGetDataPartitionedPMBLayerInputParam_t *inpParam,
+ dlst_t *MBList,
+ int *bitErrorIndication)
+ {
+
+ static const int mbTypeToDQUANTI[6] =
+ {0, 1, 0, 0, 1, 1};
+
+ int fDQUANT,
+ cbpyIndex,
+ retValue = VDX_OK,
+ new_quant, previous_quant,
+ bitsGot,
+ i,
+ IntraDC_size,
+ IntraDC_delta;
+
+ int16 error=0;
+ u_char code;
+ vdxPMBListItem_t *MBinstance;
+
+ vdxAssert(inpParam != NULL);
+ vdxAssert(inBuffer != NULL);
+ vdxAssert(bitErrorIndication != NULL);
+
+ previous_quant = inpParam->quant;
+
+ /* Get ac_pred_flag and cbpy of all MBs in VP */
+ for (dlstHead(MBList, (void **) &MBinstance);
+ MBinstance != NULL;
+ dlstNext(MBList, (void **) &MBinstance))
+ {
+
+ if (!MBinstance->fCodedMB) continue;
+
+ /* MVE */
+ VDT_SET_START_POSITION(MBinstance,3,inBuffer->getIndex,inBuffer->bitIndex); // 3 ac_pred_flag
+
+ if (MBinstance->mbClass == VDX_MB_INTRA) {
+
+ /* ac_pred_flag (1 bit) */
+ code = (u_char) bibGetBits(1, inBuffer, &bitsGot, bitErrorIndication, &error);
+ if (error)
+ goto exitFunction;
+
+ MBinstance->ac_pred_flag = code;
+ }
+
+ /* MVE */
+ VDT_SET_END_POSITION(MBinstance,3,inBuffer->getIndex,inBuffer->bitIndex); // 3 ac_pred_flag
+ VDT_SET_START_POSITION(MBinstance,2,inBuffer->getIndex,inBuffer->bitIndex); // 2: cbpy
+
+ /* CBPY */
+ retValue = vdxGetCBPY(inBuffer, &cbpyIndex, bitErrorIndication);
+ if (retValue != VDX_OK)
+ goto exitFunction;
+
+ if (MBinstance->mbClass == VDX_MB_INTER)
+ /* Convert index to INTER CBPY */
+ cbpyIndex = 15 - cbpyIndex;
+
+ MBinstance->cbpy = cbpyIndex;
+
+ /* MVE */
+ VDT_SET_END_POSITION(MBinstance,2,inBuffer->getIndex,inBuffer->bitIndex); //
+ VDT_SET_START_POSITION(MBinstance,1,inBuffer->getIndex,inBuffer->bitIndex); // 1: dquant
+
+ /* DQUANT is given for MCBPC indexes 4..7 */
+ fDQUANT = mbTypeToDQUANTI[MBinstance->mbType];
+
+ if (fDQUANT) {
+ retValue = vdxUpdateQuant(inBuffer, 0, previous_quant,
+ &new_quant, bitErrorIndication);
+ if (retValue != VDX_OK)
+ goto exitFunction;
+ }
+ /* Else no DQUANT */
+ else
+ new_quant = previous_quant;
+
+ MBinstance->dquant = fDQUANT ? new_quant - previous_quant : 0;
+ MBinstance->quant = previous_quant = new_quant;
+
+ /* MVE */
+ VDT_SET_END_POSITION(MBinstance,1,inBuffer->getIndex,inBuffer->bitIndex); // 1: dquant
+ VDT_SET_START_POSITION(MBinstance,4,inBuffer->getIndex,inBuffer->bitIndex); // 4: intraDC
+ VDT_SET_START_POSITION(MBinstance,5,inBuffer->getIndex,inBuffer->bitIndex); // 5: intraDC
+ VDT_SET_START_POSITION(MBinstance,6,inBuffer->getIndex,inBuffer->bitIndex); // 6: intraDC
+ VDT_SET_START_POSITION(MBinstance,7,inBuffer->getIndex,inBuffer->bitIndex); // 7: intraDC
+ VDT_SET_START_POSITION(MBinstance,8,inBuffer->getIndex,inBuffer->bitIndex); // 8: intraDC
+ VDT_SET_START_POSITION(MBinstance,9,inBuffer->getIndex,inBuffer->bitIndex); // 9: intraDC
+
+ VDT_SET_END_POSITION(MBinstance,4,inBuffer->getIndex,inBuffer->bitIndex); // 4: intraDC
+ VDT_SET_END_POSITION(MBinstance,5,inBuffer->getIndex,inBuffer->bitIndex); // 5: intraDC
+ VDT_SET_END_POSITION(MBinstance,6,inBuffer->getIndex,inBuffer->bitIndex); // 6: intraDC
+ VDT_SET_END_POSITION(MBinstance,7,inBuffer->getIndex,inBuffer->bitIndex); // 7: intraDC
+ VDT_SET_END_POSITION(MBinstance,8,inBuffer->getIndex,inBuffer->bitIndex); // 8: intraDC
+ VDT_SET_END_POSITION(MBinstance,9,inBuffer->getIndex,inBuffer->bitIndex); // 9: intraDC
+
+ /* Color Toning */
+ hTranscoder->AfterMBLayer(new_quant);
+
+ if (MBinstance->mbClass == VDX_MB_INTRA) {
+ MBinstance->switched = aicIntraDCSwitch(inpParam->intra_dc_vlc_thr,new_quant);
+
+ /* Intra_DC_Coeffs */
+ if(!MBinstance->switched) {
+ for (i=0; i<6; i++) {
+
+ /* MVE */
+ VDT_SET_START_POSITION(MBinstance,i+4,inBuffer->getIndex,inBuffer->bitIndex); // 6: intraDC,chrominance
+
+ retValue = vdxGetIntraDC(inBuffer, outBuffer, bufEdit, aColorEffect, aStartByteIndex, aStartBitIndex,
+ i, &IntraDC_size, &IntraDC_delta, bitErrorIndication);
+
+ /* MVE */
+ VDT_SET_END_POSITION(MBinstance,i+4,inBuffer->getIndex,inBuffer->bitIndex); // 6: intraDC,chrominance
+
+ if (retValue != VDX_OK)
+ goto exitFunction;
+ MBinstance->DC[i] = IntraDC_delta;
+ }
+ }
+ }
+ }
+
+exitFunction:
+
+
+ /* If no error in bit buffer functions */
+ if (!error)
+ return retValue;
+
+ /* Else if ran out of data (i.e. decoding out of sync) */
+ else if (error == ERR_BIB_NOT_ENOUGH_DATA) {
+ return VDX_OK_BUT_BIT_ERROR;
+ }
+
+ /* Else other error in bit buffer functions */
+ else
+ return VDX_ERR_BIB;
+
+}
+
+/*
+ * Block Layer Global Functions
+ */
+
+/* {{-output"vdxGetMPEGIntraDCTBlock.txt"}} */
+/*
+ * vdxGetMPEGIntraDCTBlock
+ *
+ *
+ * Parameters:
+ * inBuffer pointer to bit buffer instance
+ * startIndex the first index in block where to put data
+ * block DCT coefficients of the block
+ * in zigzag order
+ * bitErrorIndication non-zero if a bit error has been detected
+ * within the bits accessed in this function,
+ * see biterr.h for possible values
+ *
+ * Function:
+ * This function gets the DCT coefficients for one INTRA block.
+ *
+ * Returns:
+ * VDX_OK the function was successful
+ * VDX_OK_BUT_BIT_ERROR the function behaved normally, but a bit error
+ * occured
+ * VDX_ERR_BIB an error occured when accessing bit buffer
+ *
+ *
+ *
+ */
+
+int vdxGetMPEGIntraDCTBlock(
+ bibBuffer_t *inBuffer,
+ int startIndex,
+ int *block,
+ int *bitErrorIndication)
+/* {{-output"vdxGetMPEGIntraDCTBlock.txt"}} */
+{
+ int
+ numBitsGot,
+ retValue = VDX_OK,
+ tmpvar;
+ int16
+ bibError = 0;
+
+ static const vdxVLCTable_t Intra_tcoefTab0[] = {
+ {0x10401, 7}, {0x10301, 7}, {0x00601, 7}, {0x10501, 7},
+ {0x00701, 7}, {0x00202, 7}, {0x00103, 7}, {0x00009, 7},
+ {0x10002, 6}, {0x10002, 6}, {0x00501, 6}, {0x00501, 6},
+ {0x10201, 6}, {0x10201, 6}, {0x10101, 6}, {0x10101, 6},
+ {0x00401, 6}, {0x00401, 6}, {0x00301, 6}, {0x00301, 6},
+ {0x00008, 6}, {0x00008, 6}, {0x00007, 6}, {0x00007, 6},
+ {0x00102, 6}, {0x00102, 6}, {0x00006, 6}, {0x00006, 6},
+ {0x00201, 5}, {0x00201, 5}, {0x00201, 5}, {0x00201, 5},
+ {0x00005, 5}, {0x00005, 5}, {0x00005, 5}, {0x00005, 5},
+ {0x00004, 5}, {0x00004, 5}, {0x00004, 5}, {0x00004, 5},
+ {0x10001, 4}, {0x10001, 4}, {0x10001, 4}, {0x10001, 4},
+ {0x10001, 4}, {0x10001, 4}, {0x10001, 4}, {0x10001, 4},
+ {0x00001, 2}, {0x00001, 2}, {0x00001, 2}, {0x00001, 2},
+ {0x00001, 2}, {0x00001, 2}, {0x00001, 2}, {0x00001, 2},
+ {0x00001, 2}, {0x00001, 2}, {0x00001, 2}, {0x00001, 2},
+ {0x00001, 2}, {0x00001, 2}, {0x00001, 2}, {0x00001, 2},
+ {0x00001, 2}, {0x00001, 2}, {0x00001, 2}, {0x00001, 2},
+ {0x00001, 2}, {0x00001, 2}, {0x00001, 2}, {0x00001, 2},
+ {0x00001, 2}, {0x00001, 2}, {0x00001, 2}, {0x00001, 2},
+ {0x00001, 2}, {0x00001, 2}, {0x00001, 2}, {0x00001, 2},
+ {0x00002, 3}, {0x00002, 3}, {0x00002, 3}, {0x00002, 3},
+ {0x00002, 3}, {0x00002, 3}, {0x00002, 3}, {0x00002, 3},
+ {0x00002, 3}, {0x00002, 3}, {0x00002, 3}, {0x00002, 3},
+ {0x00002, 3}, {0x00002, 3}, {0x00002, 3}, {0x00002, 3},
+ {0x00101, 4}, {0x00101, 4}, {0x00101, 4}, {0x00101, 4},
+ {0x00101, 4}, {0x00101, 4}, {0x00101, 4}, {0x00101, 4},
+ {0x00003, 4}, {0x00003, 4}, {0x00003, 4}, {0x00003, 4},
+ {0x00003, 4}, {0x00003, 4}, {0x00003, 4}, {0x00003, 4},
+ };
+
+
+ static const vdxVLCTable_t Intra_tcoefTab1[] = {
+ {0x00012,10}, {0x00011,10}, {0x10e01, 9}, {0x10e01, 9},
+ {0x10d01, 9}, {0x10d01, 9}, {0x10c01, 9}, {0x10c01, 9},
+ {0x10b01, 9}, {0x10b01, 9}, {0x10a01, 9}, {0x10a01, 9},
+ {0x10102, 9}, {0x10102, 9}, {0x10004, 9}, {0x10004, 9},
+ {0x00c01, 9}, {0x00c01, 9}, {0x00b01, 9}, {0x00b01, 9},
+ {0x00702, 9}, {0x00702, 9}, {0x00602, 9}, {0x00602, 9},
+ {0x00502, 9}, {0x00502, 9}, {0x00303, 9}, {0x00303, 9},
+ {0x00203, 9}, {0x00203, 9}, {0x00106, 9}, {0x00106, 9},
+ {0x00105, 9}, {0x00105, 9}, {0x00010, 9}, {0x00010, 9},
+ {0x00402, 9}, {0x00402, 9}, {0x0000f, 9}, {0x0000f, 9},
+ {0x0000e, 9}, {0x0000e, 9}, {0x0000d, 9}, {0x0000d, 9},
+ {0x10801, 8}, {0x10801, 8}, {0x10801, 8}, {0x10801, 8},
+ {0x10701, 8}, {0x10701, 8}, {0x10701, 8}, {0x10701, 8},
+ {0x10601, 8}, {0x10601, 8}, {0x10601, 8}, {0x10601, 8},
+ {0x10003, 8}, {0x10003, 8}, {0x10003, 8}, {0x10003, 8},
+ {0x00a01, 8}, {0x00a01, 8}, {0x00a01, 8}, {0x00a01, 8},
+ {0x00901, 8}, {0x00901, 8}, {0x00901, 8}, {0x00901, 8},
+ {0x00801, 8}, {0x00801, 8}, {0x00801, 8}, {0x00801, 8},
+ {0x10901, 8}, {0x10901, 8}, {0x10901, 8}, {0x10901, 8},
+ {0x00302, 8}, {0x00302, 8}, {0x00302, 8}, {0x00302, 8},
+ {0x00104, 8}, {0x00104, 8}, {0x00104, 8}, {0x00104, 8},
+ {0x0000c, 8}, {0x0000c, 8}, {0x0000c, 8}, {0x0000c, 8},
+ {0x0000b, 8}, {0x0000b, 8}, {0x0000b, 8}, {0x0000b, 8},
+ {0x0000a, 8}, {0x0000a, 8}, {0x0000a, 8}, {0x0000a, 8},
+ };
+
+ static const vdxVLCTable_t Intra_tcoefTab2[] = {
+ {0x10007,11}, {0x10007,11}, {0x10006,11}, {0x10006,11},
+ {0x00016,11}, {0x00016,11}, {0x00015,11}, {0x00015,11},
+ {0x10202,10}, {0x10202,10}, {0x10202,10}, {0x10202,10},
+ {0x10103,10}, {0x10103,10}, {0x10103,10}, {0x10103,10},
+ {0x10005,10}, {0x10005,10}, {0x10005,10}, {0x10005,10},
+ {0x00d01,10}, {0x00d01,10}, {0x00d01,10}, {0x00d01,10},
+ {0x00503,10}, {0x00503,10}, {0x00503,10}, {0x00503,10},
+ {0x00802,10}, {0x00802,10}, {0x00802,10}, {0x00802,10},
+ {0x00403,10}, {0x00403,10}, {0x00403,10}, {0x00403,10},
+ {0x00304,10}, {0x00304,10}, {0x00304,10}, {0x00304,10},
+ {0x00204,10}, {0x00204,10}, {0x00204,10}, {0x00204,10},
+ {0x00107,10}, {0x00107,10}, {0x00107,10}, {0x00107,10},
+ {0x00014,10}, {0x00014,10}, {0x00014,10}, {0x00014,10},
+ {0x00013,10}, {0x00013,10}, {0x00013,10}, {0x00013,10},
+ {0x00017,11}, {0x00017,11}, {0x00018,11}, {0x00018,11},
+ {0x00108,11}, {0x00108,11}, {0x00902,11}, {0x00902,11},
+ {0x10302,11}, {0x10302,11}, {0x10402,11}, {0x10402,11},
+ {0x10f01,11}, {0x10f01,11}, {0x11001,11}, {0x11001,11},
+ {0x00019,12}, {0x0001a,12}, {0x0001b,12}, {0x00109,12},
+ {0x00603,12}, {0x0010a,12}, {0x00205,12}, {0x00703,12},
+ {0x00e01,12}, {0x10008,12}, {0x10502,12}, {0x10602,12},
+ {0x11101,12}, {0x11201,12}, {0x11301,12}, {0x11401,12},
+ {0x01bff, 7}, {0x01bff, 7}, {0x01bff, 7}, {0x01bff, 7},
+ {0x01bff, 7}, {0x01bff, 7}, {0x01bff, 7}, {0x01bff, 7},
+ {0x01bff, 7}, {0x01bff, 7}, {0x01bff, 7}, {0x01bff, 7},
+ {0x01bff, 7}, {0x01bff, 7}, {0x01bff, 7}, {0x01bff, 7},
+ {0x01bff, 7}, {0x01bff, 7}, {0x01bff, 7}, {0x01bff, 7},
+ {0x01bff, 7}, {0x01bff, 7}, {0x01bff, 7}, {0x01bff, 7},
+ {0x01bff, 7}, {0x01bff, 7}, {0x01bff, 7}, {0x01bff, 7},
+ {0x01bff, 7}, {0x01bff, 7}, {0x01bff, 7}, {0x01bff, 7},
+ };
+
+ static const int intra_max_level[2][64] = {
+ {27, 10, 5, 4, 3, 3, 3, 3,
+ 2, 2, 1, 1, 1, 1, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ },
+
+ {8, 3, 2, 2, 2, 2, 2, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0
+ }
+ };
+
+ static const int intra_max_run0[28] = { 999, 14, 9, 7, 3, 2, 1,
+ 1, 1, 1, 1, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0
+ };
+
+ static const int intra_max_run1[9] = { 999, 20, 6,
+ 1, 0, 0,
+ 0, 0, 0
+ };
+
+ int
+ code, /* bits got from bit buffer */
+ index, /* index to zigzag table running from 1 to 63 */
+ run, /* RUN code */
+ level; /* LEVEL code */
+
+ u_int32
+ last, /* LAST code (see standard) */
+ sign; /* sign for level */
+
+ vdxVLCTable_t const *tab; /* pointer to lookup table */
+
+ vdxAssert(inBuffer != NULL);
+ vdxAssert(startIndex == 0 || startIndex == 1);
+ vdxAssert(block != NULL);
+ vdxAssert(bitErrorIndication != NULL);
+
+ index = startIndex;
+
+ do {
+ code = (int) bibShowBits(12, inBuffer, &numBitsGot, bitErrorIndication,
+ &bibError);
+ if (bibError == ERR_BIB_NOT_ENOUGH_DATA) {
+ deb("vdxGetDCTBlock: bibShowBits returned not enough data --> "
+ "try to use the data available.\n");
+ code <<= 12 - numBitsGot;
+ bibError = 0;
+ }
+ else if (bibError ) {
+ goto exitFunction;
+ }
+
+ /* Select the right table and index for the codeword */
+ if (code >= 512)
+ tab = &Intra_tcoefTab0[(code >> 5) - 16];
+ else if (code >= 128)
+ tab = &Intra_tcoefTab1[(code >> 2) - 32];
+ else if (code >= 8)
+ tab = &Intra_tcoefTab2[code - 8];
+ else {
+ deb("ERROR - illegal TCOEF\n");
+ retValue = VDX_OK_BUT_BIT_ERROR;
+ goto exitFunction;
+ }
+
+ /* Flush the codeword from the buffer */
+ bibFlushBits(tab->len, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+ if (bibError)
+ goto exitFunction;
+
+ /* the following is modified for 3-mode escape */
+ if (tab->val == 7167) /* ESCAPE */
+ {
+
+ int run_offset=0,
+ level_offset=0;
+
+ code = (int) bibShowBits(2, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+ if (bibError) {
+ goto exitFunction;
+ }
+
+ if (code<=2) {
+
+ /* escape modes: level or run is offset */
+ if (code==2) run_offset=1;
+ else level_offset=1;
+
+ /* Flush the escape code from the buffer */
+ if (run_offset)
+ bibFlushBits(2, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+ else
+ bibFlushBits(1, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+
+ if (bibError)
+ goto exitFunction;
+ /* Read next codeword */
+ code = (int) bibShowBits(12, inBuffer, &numBitsGot, bitErrorIndication,
+ &bibError);
+ if (bibError == ERR_BIB_NOT_ENOUGH_DATA) {
+ deb("vdxGetDCTBlock: bibShowBits returned not enough data --> "
+ "try to use the data available.\n");
+ code <<= 12 - numBitsGot;
+ bibError = 0;
+ }
+ else if (bibError) {
+ goto exitFunction;
+ }
+
+ /* Select the right table and index for the codeword */
+ if (code >= 512)
+ tab = &Intra_tcoefTab0[(code >> 5) - 16];
+ else if (code >= 128)
+ tab = &Intra_tcoefTab1[(code >> 2) - 32];
+ else if (code >= 8)
+ tab = &Intra_tcoefTab2[code - 8];
+ else {
+ deb("ERROR - illegal TCOEF\n");
+ retValue = VDX_OK_BUT_BIT_ERROR;
+ goto exitFunction;
+ }
+
+ bibFlushBits(tab->len, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+ if (bibError)
+ goto exitFunction;
+
+ run = (tab->val >> 8) & 255;
+ level = tab->val & 255;
+ last = (tab->val >> 16) & 1;
+
+ /* need to add back the max level */
+ if (level_offset)
+ level = level + intra_max_level[last][run];
+ else if (last)
+ run = run + intra_max_run1[level]+1;
+ else
+ run = run + intra_max_run0[level]+1;
+
+ sign = bibGetBits(1, inBuffer, &numBitsGot, bitErrorIndication,
+ &bibError);
+
+ if ( bibError )
+ goto exitFunction;
+
+ if (sign)
+ level = -level;
+
+ } else {
+
+ /* Flush the codeword from the buffer */
+ bibFlushBits(2, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+ if (bibError)
+ goto exitFunction;
+
+ /* LAST */
+ last = bibGetBits(1, inBuffer, &numBitsGot, bitErrorIndication,
+ &bibError);
+ if ( bibError )
+ goto exitFunction;
+ /* RUN */
+ run = (int) bibGetBits(6, inBuffer, &numBitsGot, bitErrorIndication,
+ &bibError);
+ if ( bibError )
+ goto exitFunction;
+ /* MARKER BIT */
+ tmpvar = bibGetBits(1, inBuffer, &numBitsGot, bitErrorIndication,&bibError);
+ if ( bibError )
+ goto exitFunction;
+ if (!tmpvar) {
+
+ retValue = VDX_OK_BUT_BIT_ERROR;
+ goto exitFunction;
+ }
+ /* LEVEL */
+ level = (int) bibGetBits(12, inBuffer, &numBitsGot, bitErrorIndication,
+ &bibError);
+ if ( bibError )
+ goto exitFunction;
+ /* MARKER BIT */
+ tmpvar = bibGetBits(1, inBuffer, &numBitsGot, bitErrorIndication,&bibError);
+ if ( bibError )
+ goto exitFunction;
+ if(!tmpvar) {
+
+ retValue = VDX_OK_BUT_BIT_ERROR;
+ goto exitFunction;
+ }
+
+ /* 0000 0000 0000 and 1000 0000 0000 is forbidden unless in MQ mode */
+ if (level == 0 || level == 2048) {
+ deb("ERROR - illegal level.\n");
+ retValue = VDX_OK_BUT_BIT_ERROR;
+ goto exitFunction;
+ }
+
+ /* Codes 1000 0000 0001 .. 1111 1111 1111 */
+ if (level > 2048)
+ level -= 4096;
+
+ } /* flc */
+ }
+ else {
+
+ run = (tab->val >> 8) & 255;
+ level = tab->val & 255;
+ last = (tab->val >> 16) & 1;
+
+ sign = bibGetBits(1, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+ if ( bibError )
+ goto exitFunction;
+
+ if (sign)
+ level = -level;
+ }
+
+ /* If too many coefficients */
+ if (index + run > 63) {
+ deb("ERROR - too many TCOEFs.\n");
+ retValue = VDX_OK_BUT_BIT_ERROR;
+ goto exitFunction;
+ }
+
+ /* Do run-length decoding */
+ while (run--)
+ block[index++] = 0;
+
+ block[index++] = level;
+
+ } while (!last);
+
+ exitFunction:
+
+ /* Set the rest of the coefficients to zero */
+ while (index <= 63) {
+ block[index++] = 0;
+ }
+
+ if (!bibError)
+ return retValue;
+
+ else if (bibError == ERR_BIB_NOT_ENOUGH_DATA) {
+ return VDX_OK_BUT_BIT_ERROR;
+ }
+
+ else
+ return VDX_ERR_BIB;
+}
+
+/*
+ * Macroblock Layer Local Functions
+ */
+
+/*
+ *
+ * vdxGetScaledMVD
+ *
+ *
+ * Parameters:
+ * inBuffer input buffer
+ * f_code f_code for current Vop
+ * error error code
+ * *mvd10 returned MV value (10x)
+ * *bitErrorIndication
+ *
+ * Function:
+ * Calculates a component of a block (or MB) vector by decoding
+ * the magnitude & residual of the diff. vector, making the prediction,
+ * and combining the decoded diff. and the predicted values
+ *
+ * Returns:
+ * VDX_OK the function was successful
+ * VDX_OK_BUT_BIT_ERROR the function behaved normally, but a bit error
+ * occured
+ * VDX_ERR_BIB an error occured when accessing bit buffer
+ *
+ *
+ */
+
+
+int vdxGetScaledMVD(bibBuffer_t *inBuffer, int f_code,
+ int *mvd10, int *bitErrorIndication)
+{
+
+ int residual=0, vlc_code_mag=0;
+ int diff_vector,
+ retValue = VDX_OK,
+ numBitsGot;
+ int16 bibError = 0;
+
+ /* decode component */
+ retValue = vdxGetMVD(inBuffer,&vlc_code_mag,bitErrorIndication);
+ if (retValue < 0)
+ goto exitFunction;
+
+ if ((f_code > 1) && (vlc_code_mag != 0))
+ {
+ vlc_code_mag /= 5;
+
+ residual = (int)
+ bibGetBits(f_code-1, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+ if (bibError)
+ goto exitFunction;
+
+ diff_vector = ((abs(vlc_code_mag)-1)<<(f_code-1)) + residual + 1;
+ if (vlc_code_mag < 0)
+ diff_vector = -diff_vector;
+
+ *mvd10 = diff_vector * 5;
+ } else
+ *mvd10 = vlc_code_mag;
+
+ exitFunction:
+
+ if (bibError) {
+ if (bibError == ERR_BIB_NOT_ENOUGH_DATA) {
+ return VDX_OK_BUT_BIT_ERROR;
+ }
+ return VDX_ERR_BIB;
+ }
+
+ return retValue;
+}
+
+/*
+ * vdxGetIntraDC
+ *
+ *
+ * Parameters:
+ * inBuffer pointer to bit buffer instance
+ * compnum number of the block component in the
+ * 4:2:2 YUV scheme
+ * (0..3) luma, (4..5) chroma
+ * IntraDCDelta the read Intra DC value (quantized)
+ * bitErrorIndication non-zero if a bit error has been detected
+ * within the bits accessed in this function,
+ * see biterr.h for possible values
+ *
+ * Function:
+ * This function gets the Intra DC value
+ *
+ * Returns:
+ * VDX_OK the function was successful
+ * VDX_OK_BUT_BIT_ERROR the function behaved normally, but a bit error
+ * occured
+ * VDX_ERR_BIB an error occured when accessing bit buffer
+ *
+ *
+ *
+ */
+
+int vdxGetIntraDC(bibBuffer_t *inBuffer, bibBuffer_t */*outBuffer*/, bibBufferEdit_t */*bufEdit*/, int /*aColorEffect*/,
+ int */*aStartByteIndex*/, int */*aStartBitIndex*/, int compnum, int *IntraDC_size, int *IntraDCDelta,
+ int *bitErrorIndication)
+{
+ u_int32 code;
+ int16 bibError=0;
+ int first_bit,
+ numBitsGot,
+ retValue,
+ IntraDCSize=0,
+ tmpvar;
+
+ vdxAssert(inBuffer != NULL);
+ vdxAssert(IntraDCDelta != NULL);
+ vdxAssert(bitErrorIndication != NULL);
+
+ /* read DC size 2 - 8 bits */
+ retValue = vdxGetIntraDCSize(inBuffer, compnum, &IntraDCSize, bitErrorIndication);
+ if (retValue != VDX_OK)
+ return retValue;
+
+ *IntraDC_size = IntraDCSize;
+ if (IntraDCSize == 0) {
+
+ *IntraDCDelta = 0;
+
+ } else {
+
+ /* read delta DC 0 - 8 bits */
+ code = bibGetBits(IntraDCSize,inBuffer,&numBitsGot,bitErrorIndication, &bibError);
+
+ if (bibError) {
+ if (bibError == ERR_BIB_NOT_ENOUGH_DATA) {
+ return VDX_OK_BUT_BIT_ERROR;
+ }
+ return VDX_ERR_BIB;
+ }
+
+ first_bit = code >> (IntraDCSize-1);
+
+ if (first_bit == 0 )
+ { /* negative delta INTRA DC */
+ *IntraDCDelta = -1 * (int) (code ^ ((1 << IntraDCSize)-1));
+ }
+ else
+ { /* positive delta INTRA DC */
+ *IntraDCDelta = (int) code;
+ }
+
+ if (IntraDCSize > 8) {
+ /* Marker Bit */
+ tmpvar = bibGetBits(1,inBuffer,&numBitsGot,bitErrorIndication, &bibError);
+ if( !tmpvar ) {
+ return VDX_OK_BUT_BIT_ERROR;
+ }
+ }
+ }
+
+ return VDX_OK;
+}
+
+/*
+ * vdxGetIntraDCSize
+ *
+ *
+ * Parameters:
+ * inBuffer pointer to bit buffer instance
+ * compnum number of the block component in the
+ * 4:2:2 YUV scheme
+ * (0..3) luma, (4..5) chroma
+ * IntraDCSize Size of the following Intra DC FLC
+ * bitErrorIndication non-zero if a bit error has been detected
+ * within the bits accessed in this function,
+ * see biterr.h for possible values
+ *
+ * Function:
+ * This function gets the IntraDCSize VLC for luma or chroma
+ *
+ * Returns:
+ * VDX_OK the function was successful
+ * VDX_OK_BUT_BIT_ERROR the function behaved normally, but a bit error
+ * occured
+ * VDX_ERR_BIB an error occured when accessing bit buffer
+ *
+ *
+ *
+ */
+
+static int vdxGetIntraDCSize(bibBuffer_t *inBuffer, int compnum, int *IntraDCSize,
+ int *bitErrorIndication)
+{
+ u_int32 code;
+ int numBitsGot,
+ retValue = VDX_OK;
+ int16
+ bibError = 0;
+
+ if( compnum >=0 && compnum < 4 ) /* luminance block */
+ {
+ code = bibShowBits(11, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+ if (bibError && (bibError != ERR_BIB_NOT_ENOUGH_DATA)) {
+ return VDX_ERR_BIB;
+ }
+
+ if ((bibError == ERR_BIB_NOT_ENOUGH_DATA) && (numBitsGot != 0)) {
+ code <<= (11-numBitsGot);
+ bibError = 0;
+ }
+
+ if ( code == 1)
+ {
+ *IntraDCSize = 12;
+ bibFlushBits(11, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+ goto exitFunction;
+ }
+
+ code >>= 1;
+ if ( code == 1)
+ {
+ *IntraDCSize = 11;
+ bibFlushBits(10, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+ goto exitFunction;
+ }
+
+ code >>= 1;
+ if ( code == 1)
+ {
+ *IntraDCSize = 10;
+ bibFlushBits(9, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+ goto exitFunction;
+ }
+
+ code >>= 1;
+ if ( code == 1)
+ {
+ *IntraDCSize = 9;
+ bibFlushBits(8, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+ goto exitFunction;
+ }
+
+ code >>= 1;
+ if ( code == 1)
+ {
+ *IntraDCSize = 8;
+ bibFlushBits(7, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+ goto exitFunction;
+ }
+ code >>= 1;
+ if ( code == 1)
+ {
+ *IntraDCSize = 7;
+ bibFlushBits(6, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+ goto exitFunction;
+ }
+ code >>= 1;
+ if ( code == 1)
+ {
+ *IntraDCSize = 6;
+ bibFlushBits(5, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+ goto exitFunction;
+ }
+ code >>= 1;
+ if ( code == 1)
+ {
+ *IntraDCSize = 5;
+ bibFlushBits(4, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+ goto exitFunction;
+ }
+ code >>= 1;
+ if ( code == 1)
+ {
+ *IntraDCSize = 4;
+ bibFlushBits(3, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+ goto exitFunction;
+ } else if (code == 2) {
+ *IntraDCSize = 3;
+ bibFlushBits(3, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+ goto exitFunction;
+ } else if (code ==3) {
+ *IntraDCSize = 0;
+ bibFlushBits(3, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+ goto exitFunction;
+ }
+ code >>= 1;
+ if ( code == 2)
+ {
+ *IntraDCSize = 2;
+ bibFlushBits(2, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+ goto exitFunction;
+ } else if (code == 3) {
+ *IntraDCSize = 1;
+ bibFlushBits(2, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+ goto exitFunction;
+ }
+
+ }
+ else /* chrominance block */
+ {
+ code = bibShowBits(12, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+ if (bibError && (bibError != ERR_BIB_NOT_ENOUGH_DATA)) {
+ return VDX_ERR_BIB;
+ }
+
+ if ((bibError == ERR_BIB_NOT_ENOUGH_DATA) && (numBitsGot != 0)) {
+ code <<= (12-numBitsGot);
+ bibError = 0;
+ }
+
+ if ( code == 1)
+ {
+ *IntraDCSize = 12;
+ bibFlushBits(12, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+ goto exitFunction;
+ }
+
+ code >>= 1;
+ if ( code == 1)
+ {
+ *IntraDCSize = 11;
+ bibFlushBits(11, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+ goto exitFunction;
+ }
+
+ code >>= 1;
+ if ( code == 1)
+ {
+ *IntraDCSize = 10;
+ bibFlushBits(10, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+ goto exitFunction;
+ }
+
+ code >>= 1;
+ if ( code == 1)
+ {
+ *IntraDCSize = 9;
+ bibFlushBits(9, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+ goto exitFunction;
+ }
+
+ code >>= 1;
+ if ( code == 1)
+ {
+ *IntraDCSize = 8;
+ bibFlushBits(8, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+ goto exitFunction;
+ }
+ code >>= 1;
+ if ( code == 1)
+ {
+ *IntraDCSize = 7;
+ bibFlushBits(7, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+ goto exitFunction;
+ }
+ code >>= 1;
+ if ( code == 1)
+ {
+ *IntraDCSize = 6;
+ bibFlushBits(6, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+ goto exitFunction;
+ }
+ code >>= 1;
+ if ( code == 1)
+ {
+ *IntraDCSize = 5;
+ bibFlushBits(5, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+ goto exitFunction;
+ }
+ code >>= 1;
+ if ( code == 1)
+ {
+ *IntraDCSize = 4;
+ bibFlushBits(4, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+ goto exitFunction;
+ }
+ code >>= 1;
+ if ( code == 1)
+ {
+ *IntraDCSize = 3;
+ bibFlushBits(3, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+ goto exitFunction;
+ }
+ code >>= 1;
+ {
+ *IntraDCSize = 3-code;
+ bibFlushBits(2, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+ goto exitFunction;
+ }
+ }
+
+exitFunction:
+
+ /* If no error in bit buffer functions */
+ if (!bibError)
+ return retValue;
+
+ /* Else if ran out of data (i.e. decoding out of sync) */
+ else if (bibError == ERR_BIB_NOT_ENOUGH_DATA) {
+ return VDX_OK_BUT_BIT_ERROR;
+ }
+
+ /* Else other error in bit buffer functions */
+ else
+ return VDX_ERR_BIB;
+}
+
+/*
+ * vdxGetRVLCIndex
+ *
+ *
+ * Parameters:
+ * bits input: the bits read from the stream
+ * index output: the RVLC table index corresponding
+ * to "bits"
+ * length output: length of the codeword
+ * intra_luma indicates an intra "1" or inter "0" Block
+ * bitErrorIndication non-zero if a bit error has been detected
+ * within the bits accessed in this function,
+ * see biterr.h for possible values
+ *
+ * Function:
+ * This function finds the RVLC table index (LAST,RUN.LEVEL) and length
+ * of the code belonging to the input codeword.
+ *
+ * Returns:
+ * VDX_OK the function was successful
+ * VDX_OK_BUT_BIT_ERROR no such codeword exists in the table
+ *
+ *
+ */
+
+int vdxGetRVLCIndex(
+ u_int32 bits,
+ u_int32 *index,
+ int *length,
+ int intra_luma,
+ int *bitErrorIndication)
+{
+
+ /* The indexes in the RVLC tables are written in equal RUN groups with
+ LEVEL increasing */
+
+ /* Intra RVLC table */
+ static const vdxVLCTable_t RvlcTcoefTab0[] = {
+ /* [0] --> e.g.: RUN = 0; LEVEL = 1..27 */
+ {1,3}, {2,3}, {3,4}, {4,5}, {5,6}, {6,6}, {7,7}, {8,8},
+ {9,8}, {10,9}, {11,9}, {12,10}, {13,10}, {14,10}, {15,11}, {16,11},
+ {17,11}, {18,12}, {19,12}, {20,13}, {21,13}, {22,12}, {23,13}, {24,14},
+ {25,14}, {26,14}, {27,15},
+ /* [27] */
+ {257,4}, {258,5}, {259,7}, {260,8}, {261,8}, {262,9},{263,10},{264,11},
+ {265,11},{266,12},{267,13},{268,14},{269,14},
+ /* [40] */
+ {513,5}, {514,7}, {515,9},{516,10},{517,11},{518,11},{519,13},{520,13},
+ {521,13},{522,14},{523,14},
+ /* [51] */
+ {769,5}, {770,8}, {771,9},{772,11},{773,12},{774,13},{775,14},{776,14},
+ {777,15},
+ /* [60] */
+ {1025,6},{1026,8},{1027,10},{1028,12},{1029,12},{1030,14},
+ /* [66] */
+ {1281,6},{1282,9},{1283,11},{1284,12},{1285,14},{1286,14},
+ /* [72] */
+ {1537,7},{1538,10},{1539,11},{1540,12},{1541,15},
+ /* [77] */
+ {1793,7},{1794,10},{1795,11},{1796,13},{1797,15},
+ /* [82] */
+ {2049,8},{2050,10},{2051,13},{2052,14},
+ /* [86] */
+ {2305,8},{2306,11},{2307,13},{2308,15},
+ /* [90] */
+ {2561,9},{2562,12},
+ /* [92] */
+ {2817,10},{2818,13},
+ /* [94] */
+ {3073,10},{3074,15},
+ /* [96] */
+ {3329,11},
+ {3585,13},
+ {3841,13},
+ {4097,14},
+ {4353,14},
+ {4609,14},
+ {4865,15},
+
+ /* [103] --> LAST = 1 */
+ {65537,4},{65538,8},{65539,11},{65540,13},{65541,14},
+ /* [108] */
+ {65793,5},{65794,9},{65795,12},{65796,14},{65797,15},
+ /* [113] */
+ {66049,5},{66050,11},{66051,15},
+ /* [116] */
+ {66305,6},{66306,12},
+ /* [118] */
+ {66561,6},{66562,12},
+ /* [120] */
+ {66817,6},{66818,13},
+ /* [122] */
+ {67073,6},{67074,13},
+ /* [124] */
+ {67329,7},{67330,13},
+ /* [126] */
+ {67585,7},{67586,13},
+ /* [128] */
+ {67841,7},{67842,13},
+ /* [130] */
+ {68097,7},{68098,14},
+ /* [132] */
+ {68353,7},{68354,14},
+ /* [134] */
+ {68609,8},{68610,14},
+ /* [136] */
+ {68865,8},{68866,15},
+ /* [138] */
+ {69121,8},
+ {69377,9},
+ {69633,9},
+ {69889,9},
+ {70145,9},
+ {70401,9},
+ {70657,9},
+ {70913,10},
+ {71169,10},
+ {71425,10},
+ {71681,10},
+ {71937,10},
+ {72193,11},
+ {72449,11},
+ {72705,11},
+ {72961,12},
+ {73217,12},
+ {73473,12},
+ {73729,12},
+ {73985,12},
+ {74241,12},
+ {74497,12},
+ {74753,13},
+ {75009,13},
+ {75265,14},
+ {75521,14},
+ {75777,14},
+ {76033,15},
+ {76289,15},
+ {76545,15},
+ {76801,15},
+
+ /* [169] */
+ {7167,4} /* last entry: escape code */
+
+};
+
+ /* Inter RVLC table */
+ static const vdxVLCTable_t RvlcTcoefTab1[] = {
+ /* [0] */
+ {1,3}, {2,4}, {3,5}, {4,7}, {5,8}, {6,8}, {7,9}, {8,10},
+ {9,10}, {10,11}, {11,11}, {12,12}, {13,13}, {14,13}, {15,13}, {16,13},
+ {17,14}, {18,14}, {19,15},
+ /* [19] */
+ {257,3}, {258,6}, {259,8}, {260,9},{261,10},{262,11},{263,12},{264,13},
+ {265,14},{266,14},
+ /* [29] */
+ {513,4}, {514,7}, {515,9},{516,11},{517,12},{518,14},{519,14},
+ /* [36] */
+ {769,5}, {770,8},{771,10},{772,12},{773,13},{774,14},{775,15},
+ /* [43] */
+ {1025,5},{1026,8},{1027,11},{1028,13},{1029,15},
+ /* [48] */
+ {1281,5},{1282,9},{1283,11},{1284,13},
+ /* [52] */
+ {1537,6},{1538,10},{1539,12},{1540,14},
+ /* [56] */
+ {1793,6},{1794,10},{1795,12},{1796,15},
+ /* [60] */
+ {2049,6},{2050,10},{2051,13},
+ /* [63] */
+ {2305,7},{2306,10},{2307,14},
+ /* [66] */
+ {2561,7},{2562,11},
+ /* [68] */
+ {2817,7},{2818,12},
+ /* [70] */
+ {3073,8},{3074,13},
+ /* [72] */
+ {3329,8},{3330,14},
+ /* [74] */
+ {3585,8},{3586,14},
+ /* [76] */
+ {3841,9},{3842,14},
+ /* [78] */
+ {4097,9},{4098,14},
+ /* [80] */
+ {4353,9},{4354,15},
+ /* [82] */
+ {4609,10},
+ {4865,10},
+ {5121,10},
+ {5377,11},
+ {5633,11},
+ {5889,11},
+ {6145,11},
+ {6401,11},
+ {6657,11},
+ {6913,12},
+ {7169,12},
+ {7425,12},
+ {7681,13},
+ {7937,13},
+ {8193,13},
+ {8449,13},
+ {8705,14},
+ {8961,14},
+ {9217,14},
+ {9473,15},
+ {9729,15},
+
+ /* [103] --> LAST = 1 */
+ {65537,4},{65538,8},{65539,11},{65540,13},{65541,14},
+ /* [108] */
+ {65793,5},{65794,9},{65795,12},{65796,14},{65797,15},
+ /* [113] */
+ {66049,5},{66050,11},{66051,15},
+ /* [116] */
+ {66305,6},{66306,12},
+ /* [118] */
+ {66561,6},{66562,12},
+ /* [120] */
+ {66817,6},{66818,13},
+ /* [122] */
+ {67073,6},{67074,13},
+ /* [124] */
+ {67329,7},{67330,13},
+ /* [126] */
+ {67585,7},{67586,13},
+ /* [128] */
+ {67841,7},{67842,13},
+ /* [130] */
+ {68097,7},{68098,14},
+ /* [132] */
+ {68353,7},{68354,14},
+ /* [134] */
+ {68609,8},{68610,14},
+ /* [136] */
+ {68865,8},{68866,15},
+ /* [138] */
+ {69121,8},
+ {69377,9},
+ {69633,9},
+ {69889,9},
+ {70145,9},
+ {70401,9},
+ {70657,9},
+ {70913,10},
+ {71169,10},
+ {71425,10},
+ {71681,10},
+ {71937,10},
+ {72193,11},
+ {72449,11},
+ {72705,11},
+ {72961,12},
+ {73217,12},
+ {73473,12},
+ {73729,12},
+ {73985,12},
+ {74241,12},
+ {74497,12},
+ {74753,13},
+ {75009,13},
+ {75265,14},
+ {75521,14},
+ {75777,14},
+ {76033,15},
+ {76289,15},
+ {76545,15},
+ {76801,15},
+
+ /* [169] */
+ {7167,4} /* last entry: escape code */
+};
+
+ vdxVLCTable_t const *tab; /* pointer to lookup table */
+
+ vdxAssert(bitErrorIndication != NULL);
+
+ switch(bits) {
+
+ case 0x0:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[169];
+ else
+ tab = &RvlcTcoefTab1[169];
+ break;
+
+ case 0x1:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[27];
+ else
+ tab = &RvlcTcoefTab1[1];
+ break;
+
+ case 0x4:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[40];
+ else
+ tab = &RvlcTcoefTab1[2];
+ break;
+
+ case 0x5:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[51];
+ else
+ tab = &RvlcTcoefTab1[36];
+ break;
+
+ case 0x6:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[0];
+ else
+ tab = &RvlcTcoefTab1[0];
+ break;
+
+ case 0x7:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[1];
+ else
+ tab = &RvlcTcoefTab1[19];
+ break;
+
+ case 0x8:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[28];
+ else
+ tab = &RvlcTcoefTab1[43];
+ break;
+
+ case 0x9:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[3];
+ else
+ tab = &RvlcTcoefTab1[48];
+ break;
+
+ case 0xa:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[2];
+ else
+ tab = &RvlcTcoefTab1[29];
+ break;
+
+ case 0xb:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[103];
+ else
+ tab = &RvlcTcoefTab1[103];
+ break;
+
+ case 0xc:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[60];
+ else
+ tab = &RvlcTcoefTab1[20];
+ break;
+
+ case 0xd:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[66];
+ else
+ tab = &RvlcTcoefTab1[52];
+ break;
+
+ case 0x12:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[108];
+ else
+ tab = &RvlcTcoefTab1[108];
+ break;
+
+ case 0x13:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[113];
+ else
+ tab = &RvlcTcoefTab1[113];
+ break;
+
+ case 0x14:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[4];
+ else
+ tab = &RvlcTcoefTab1[56];
+ break;
+
+ case 0x15:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[5];
+ else
+ tab = &RvlcTcoefTab1[60];
+ break;
+
+ case 0x18:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[116];
+ else
+ tab = &RvlcTcoefTab1[116];
+ break;
+
+ case 0x19:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[118];
+ else
+ tab = &RvlcTcoefTab1[118];
+ break;
+
+ case 0x1c:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[72];
+ else
+ tab = &RvlcTcoefTab1[3];
+ break;
+
+ case 0x1d:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[77];
+ else
+ tab = &RvlcTcoefTab1[30];
+ break;
+
+ case 0x22:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[120];
+ else
+ tab = &RvlcTcoefTab1[120];
+ break;
+
+ case 0x23:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[122];
+ else
+ tab = &RvlcTcoefTab1[122];
+ break;
+
+ case 0x2c:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[41];
+ else
+ tab = &RvlcTcoefTab1[63];
+ break;
+
+ case 0x2d:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[29];
+ else
+ tab = &RvlcTcoefTab1[66];
+ break;
+
+ case 0x34:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[6];
+ else
+ tab = &RvlcTcoefTab1[68];
+ break;
+
+ case 0x35:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[124];
+ else
+ tab = &RvlcTcoefTab1[124];
+ break;
+
+ case 0x38:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[126];
+ else
+ tab = &RvlcTcoefTab1[126];
+ break;
+
+ case 0x39:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[128];
+ else
+ tab = &RvlcTcoefTab1[128];
+ break;
+
+ case 0x3c:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[82];
+ else
+ tab = &RvlcTcoefTab1[4];
+ break;
+
+ case 0x3d:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[86];
+ else
+ tab = &RvlcTcoefTab1[5];
+ break;
+
+ case 0x42:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[130];
+ else
+ tab = &RvlcTcoefTab1[130];
+ break;
+
+ case 0x43:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[132];
+ else
+ tab = &RvlcTcoefTab1[132];
+ break;
+
+ case 0x5c:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[52];
+ else
+ tab = &RvlcTcoefTab1[21];
+ break;
+
+ case 0x5d:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[61];
+ else
+ tab = &RvlcTcoefTab1[37];
+ break;
+
+ case 0x6c:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[30];
+ else
+ tab = &RvlcTcoefTab1[44];
+ break;
+
+ case 0x6d:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[31];
+ else
+ tab = &RvlcTcoefTab1[70];
+ break;
+
+ case 0x74:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[7];
+ else
+ tab = &RvlcTcoefTab1[72];
+ break;
+
+ case 0x75:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[8];
+ else
+ tab = &RvlcTcoefTab1[74];
+ break;
+
+ case 0x78:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[104];
+ else
+ tab = &RvlcTcoefTab1[104];
+ break;
+
+ case 0x79:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[134];
+ else
+ tab = &RvlcTcoefTab1[134];
+ break;
+
+ case 0x7c:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[90];
+ else
+ tab = &RvlcTcoefTab1[6];
+ break;
+
+ case 0x7d:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[67];
+ else
+ tab = &RvlcTcoefTab1[22];
+ break;
+
+ case 0x82:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[136];
+ else
+ tab = &RvlcTcoefTab1[136];
+ break;
+
+ case 0x83:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[138];
+ else
+ tab = &RvlcTcoefTab1[138];
+ break;
+
+ case 0xbc:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[42];
+ else
+ tab = &RvlcTcoefTab1[31];
+ break;
+
+ case 0xbd:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[53];
+ else
+ tab = &RvlcTcoefTab1[49];
+ break;
+
+ case 0xdc:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[32];
+ else
+ tab = &RvlcTcoefTab1[76];
+ break;
+
+ case 0xdd:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[9];
+ else
+ tab = &RvlcTcoefTab1[78];
+ break;
+
+ case 0xec:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[10];
+ else
+ tab = &RvlcTcoefTab1[80];
+ break;
+
+ case 0xed:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[109];
+ else
+ tab = &RvlcTcoefTab1[109];
+ break;
+
+ case 0xf4:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[139];
+ else
+ tab = &RvlcTcoefTab1[139];
+ break;
+
+ case 0xf5:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[140];
+ else
+ tab = &RvlcTcoefTab1[140];
+ break;
+
+ case 0xf8:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[141];
+ else
+ tab = &RvlcTcoefTab1[141];
+ break;
+
+ case 0xf9:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[142];
+ else
+ tab = &RvlcTcoefTab1[142];
+ break;
+
+ case 0xfc:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[92];
+ else
+ tab = &RvlcTcoefTab1[7];
+ break;
+
+ case 0xfd:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[94];
+ else
+ tab = &RvlcTcoefTab1[8];
+ break;
+
+ case 0x102:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[143];
+ else
+ tab = &RvlcTcoefTab1[143];
+ break;
+
+ case 0x103:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[144];
+ else
+ tab = &RvlcTcoefTab1[144];
+ break;
+
+ case 0x17c:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[73];
+ else
+ tab = &RvlcTcoefTab1[23];
+ break;
+
+ case 0x17d:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[78];
+ else
+ tab = &RvlcTcoefTab1[38];
+ break;
+
+ case 0x1bc:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[83];
+ else
+ tab = &RvlcTcoefTab1[53];
+ break;
+
+ case 0x1bd:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[62];
+ else
+ tab = &RvlcTcoefTab1[57];
+ break;
+
+ case 0x1dc:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[43];
+ else
+ tab = &RvlcTcoefTab1[61];
+ break;
+
+ case 0x1dd:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[33];
+ else
+ tab = &RvlcTcoefTab1[64];
+ break;
+
+ case 0x1ec:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[11];
+ else
+ tab = &RvlcTcoefTab1[82];
+ break;
+
+ case 0x1ed:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[12];
+ else
+ tab = &RvlcTcoefTab1[83];
+ break;
+
+ case 0x1f4:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[13];
+ else
+ tab = &RvlcTcoefTab1[84];
+ break;
+
+ case 0x1f5:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[145];
+ else
+ tab = &RvlcTcoefTab1[145];
+ break;
+
+ case 0x1f8:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[146];
+ else
+ tab = &RvlcTcoefTab1[146];
+ break;
+
+ case 0x1f9:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[147];
+ else
+ tab = &RvlcTcoefTab1[147];
+ break;
+
+ case 0x1fc:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[96];
+ else
+ tab = &RvlcTcoefTab1[9];
+ break;
+
+ case 0x1fd:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[87];
+ else
+ tab = &RvlcTcoefTab1[10];
+ break;
+
+ case 0x202:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[148];
+ else
+ tab = &RvlcTcoefTab1[148];
+ break;
+
+ case 0x203:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[149];
+ else
+ tab = &RvlcTcoefTab1[149];
+ break;
+
+ case 0x2fc:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[68];
+ else
+ tab = &RvlcTcoefTab1[24];
+ break;
+
+ case 0x2fd:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[74];
+ else
+ tab = &RvlcTcoefTab1[32];
+ break;
+
+ case 0x37c:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[79];
+ else
+ tab = &RvlcTcoefTab1[45];
+ break;
+
+ case 0x37d:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[54];
+ else
+ tab = &RvlcTcoefTab1[50];
+ break;
+
+ case 0x3bc:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[44];
+ else
+ tab = &RvlcTcoefTab1[67];
+ break;
+
+ case 0x3bd:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[45];
+ else
+ tab = &RvlcTcoefTab1[85];
+ break;
+
+ case 0x3dc:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[34];
+ else
+ tab = &RvlcTcoefTab1[86];
+ break;
+
+ case 0x3dd:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[35];
+ else
+ tab = &RvlcTcoefTab1[87];
+ break;
+
+ case 0x3ec:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[14];
+ else
+ tab = &RvlcTcoefTab1[88];
+ break;
+
+ case 0x3ed:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[15];
+ else
+ tab = &RvlcTcoefTab1[89];
+ break;
+
+ case 0x3f4:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[16];
+ else
+ tab = &RvlcTcoefTab1[90];
+ break;
+
+ case 0x3f5:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[105];
+ else
+ tab = &RvlcTcoefTab1[105];
+ break;
+
+ case 0x3f8:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[114];
+ else
+ tab = &RvlcTcoefTab1[114];
+ break;
+
+ case 0x3f9:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[150];
+ else
+ tab = &RvlcTcoefTab1[150];
+ break;
+
+ case 0x3fc:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[91];
+ else
+ tab = &RvlcTcoefTab1[11];
+ break;
+
+ case 0x3fd:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[63];
+ else
+ tab = &RvlcTcoefTab1[25];
+ break;
+
+ case 0x402:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[151];
+ else
+ tab = &RvlcTcoefTab1[151];
+ break;
+
+ case 0x403:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[152];
+ else
+ tab = &RvlcTcoefTab1[152];
+ break;
+
+ case 0x5fc:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[69];
+ else
+ tab = &RvlcTcoefTab1[33];
+ break;
+
+ case 0x5fd:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[75];
+ else
+ tab = &RvlcTcoefTab1[39];
+ break;
+
+ case 0x6fc:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[55];
+ else
+ tab = &RvlcTcoefTab1[54];
+ break;
+
+ case 0x6fd:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[64];
+ else
+ tab = &RvlcTcoefTab1[58];
+ break;
+
+ case 0x77c:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[36];
+ else
+ tab = &RvlcTcoefTab1[69];
+ break;
+
+ case 0x77d:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[17];
+ else
+ tab = &RvlcTcoefTab1[91];
+ break;
+
+ case 0x7bc:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[18];
+ else
+ tab = &RvlcTcoefTab1[92];
+ break;
+
+ case 0x7bd:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[21];
+ else
+ tab = &RvlcTcoefTab1[93];
+ break;
+
+ case 0x7dc:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[110];
+ else
+ tab = &RvlcTcoefTab1[110];
+ break;
+
+ case 0x7dd:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[117];
+ else
+ tab = &RvlcTcoefTab1[117];
+ break;
+
+ case 0x7ec:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[119];
+ else
+ tab = &RvlcTcoefTab1[119];
+ break;
+
+ case 0x7ed:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[153];
+ else
+ tab = &RvlcTcoefTab1[153];
+ break;
+
+ case 0x7f4:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[154];
+ else
+ tab = &RvlcTcoefTab1[154];
+ break;
+
+ case 0x7f5:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[155];
+ else
+ tab = &RvlcTcoefTab1[155];
+ break;
+
+ case 0x7f8:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[156];
+ else
+ tab = &RvlcTcoefTab1[156];
+ break;
+
+ case 0x7f9:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[157];
+ else
+ tab = &RvlcTcoefTab1[157];
+ break;
+
+ case 0x7fc:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[97];
+ else
+ tab = &RvlcTcoefTab1[12];
+ break;
+
+ case 0x7fd:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[98];
+ else
+ tab = &RvlcTcoefTab1[13];
+ break;
+
+ case 0x802:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[158];
+ else
+ tab = &RvlcTcoefTab1[158];
+ break;
+
+ case 0x803:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[159];
+ else
+ tab = &RvlcTcoefTab1[159];
+ break;
+
+ case 0xbfc:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[93];
+ else
+ tab = &RvlcTcoefTab1[14];
+ break;
+
+ case 0xbfd:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[84];
+ else
+ tab = &RvlcTcoefTab1[15];
+ break;
+
+ case 0xdfc:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[88];
+ else
+ tab = &RvlcTcoefTab1[26];
+ break;
+
+ case 0xdfd:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[80];
+ else
+ tab = &RvlcTcoefTab1[40];
+ break;
+
+ case 0xefc:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[56];
+ else
+ tab = &RvlcTcoefTab1[46];
+ break;
+
+ case 0xefd:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[46];
+ else
+ tab = &RvlcTcoefTab1[51];
+ break;
+
+ case 0xf7c:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[47];
+ else
+ tab = &RvlcTcoefTab1[62];
+ break;
+
+ case 0xf7d:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[48];
+ else
+ tab = &RvlcTcoefTab1[71];
+ break;
+
+ case 0xfbc:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[37];
+ else
+ tab = &RvlcTcoefTab1[94];
+ break;
+
+ case 0xfbd:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[19];
+ else
+ tab = &RvlcTcoefTab1[95];
+ break;
+
+ case 0xfdc:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[20];
+ else
+ tab = &RvlcTcoefTab1[96];
+ break;
+
+ case 0xfdd:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[22];
+ else
+ tab = &RvlcTcoefTab1[97];
+ break;
+
+ case 0xfec:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[106];
+ else
+ tab = &RvlcTcoefTab1[106];
+ break;
+
+ case 0xfed:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[121];
+ else
+ tab = &RvlcTcoefTab1[121];
+ break;
+
+ case 0xff4:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[123];
+ else
+ tab = &RvlcTcoefTab1[123];
+ break;
+
+ case 0xff5:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[125];
+ else
+ tab = &RvlcTcoefTab1[125];
+ break;
+
+ case 0xff8:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[127];
+ else
+ tab = &RvlcTcoefTab1[127];
+ break;
+
+ case 0xff9:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[129];
+ else
+ tab = &RvlcTcoefTab1[129];
+ break;
+
+ case 0xffc:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[99];
+ else
+ tab = &RvlcTcoefTab1[16];
+ break;
+
+ case 0xffd:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[100];
+ else
+ tab = &RvlcTcoefTab1[17];
+ break;
+
+ case 0x1002:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[160];
+ else
+ tab = &RvlcTcoefTab1[160];
+ break;
+
+ case 0x1003:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[161];
+ else
+ tab = &RvlcTcoefTab1[161];
+ break;
+
+ case 0x17fc:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[101];
+ else
+ tab = &RvlcTcoefTab1[27];
+ break;
+
+ case 0x17fd:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[85];
+ else
+ tab = &RvlcTcoefTab1[28];
+ break;
+
+ case 0x1bfc:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[70];
+ else
+ tab = &RvlcTcoefTab1[34];
+ break;
+
+ case 0x1bfd:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[65];
+ else
+ tab = &RvlcTcoefTab1[35];
+ break;
+
+ case 0x1dfc:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[71];
+ else
+ tab = &RvlcTcoefTab1[41];
+ break;
+
+ case 0x1dfd:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[57];
+ else
+ tab = &RvlcTcoefTab1[55];
+ break;
+
+ case 0x1efc:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[58];
+ else
+ tab = &RvlcTcoefTab1[65];
+ break;
+
+ case 0x1efd:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[49];
+ else
+ tab = &RvlcTcoefTab1[73];
+ break;
+
+ case 0x1f7c:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[50];
+ else
+ tab = &RvlcTcoefTab1[75];
+ break;
+
+ case 0x1f7d:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[38];
+ else
+ tab = &RvlcTcoefTab1[77];
+ break;
+
+ case 0x1fbc:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[39];
+ else
+ tab = &RvlcTcoefTab1[79];
+ break;
+
+ case 0x1fbd:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[23];
+ else
+ tab = &RvlcTcoefTab1[98];
+ break;
+
+ case 0x1fdc:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[24];
+ else
+ tab = &RvlcTcoefTab1[99];
+ break;
+
+ case 0x1fdd:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[25];
+ else
+ tab = &RvlcTcoefTab1[100];
+ break;
+
+ case 0x1fec:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[107];
+ else
+ tab = &RvlcTcoefTab1[107];
+ break;
+
+ case 0x1fed:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[111];
+ else
+ tab = &RvlcTcoefTab1[111];
+ break;
+
+ case 0x1ff4:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[131];
+ else
+ tab = &RvlcTcoefTab1[131];
+ break;
+
+ case 0x1ff5:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[133];
+ else
+ tab = &RvlcTcoefTab1[133];
+ break;
+
+ case 0x1ff8:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[135];
+ else
+ tab = &RvlcTcoefTab1[135];
+ break;
+
+ case 0x1ff9:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[162];
+ else
+ tab = &RvlcTcoefTab1[162];
+ break;
+
+ case 0x1ffc:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[26];
+ else
+ tab = &RvlcTcoefTab1[18];
+ break;
+
+ case 0x1ffd:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[59];
+ else
+ tab = &RvlcTcoefTab1[42];
+ break;
+
+ case 0x2002:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[163];
+ else
+ tab = &RvlcTcoefTab1[163];
+ break;
+
+ case 0x2003:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[164];
+ else
+ tab = &RvlcTcoefTab1[164];
+ break;
+
+ case 0x2ffc:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[76];
+ else
+ tab = &RvlcTcoefTab1[47];
+ break;
+
+ case 0x2ffd:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[81];
+ else
+ tab = &RvlcTcoefTab1[59];
+ break;
+
+ case 0x37fc:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[89];
+ else
+ tab = &RvlcTcoefTab1[81];
+ break;
+
+ case 0x37fd:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[95];
+ else
+ tab = &RvlcTcoefTab1[101];
+ break;
+
+ case 0x3bfc:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[102];
+ else
+ tab = &RvlcTcoefTab1[102];
+ break;
+
+ case 0x3bfd:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[112];
+ else
+ tab = &RvlcTcoefTab1[112];
+ break;
+
+ case 0x3dfc:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[115];
+ else
+ tab = &RvlcTcoefTab1[115];
+ break;
+
+ case 0x3dfd:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[137];
+ else
+ tab = &RvlcTcoefTab1[137];
+ break;
+
+ case 0x3efc:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[165];
+ else
+ tab = &RvlcTcoefTab1[165];
+ break;
+
+ case 0x3efd:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[166];
+ else
+ tab = &RvlcTcoefTab1[166];
+ break;
+
+ case 0x3f7c:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[167];
+ else
+ tab = &RvlcTcoefTab1[167];
+ break;
+
+ case 0x3f7d:
+ if (intra_luma)
+ tab = &RvlcTcoefTab0[168];
+ else
+ tab = &RvlcTcoefTab1[168];
+ break;
+
+ default:
+ deb("ERROR - illegal RVLC TCOEF\n");
+ return VDX_OK_BUT_BIT_ERROR;
+ }
+
+ *index = tab->val;
+ *length = tab->len;
+
+ return VDX_OK;
+}
+
+/*
+ * vdxGetRVLCDCTBlock
+ *
+ *
+ * Parameters:
+ * inBuffer pointer to bit buffer instance
+ * startIndex the first index in block where to put data
+ * block array for block (length 64)
+ * fIntraBlock indicates an intra "1" or inter "0" Block
+ * bitErrorIndication non-zero if a bit error has been detected
+ * within the bits accessed in this function,
+ * see biterr.h for possible values
+ *
+ * Function:
+ * This function reads a block from bit buffer using Huffman codes listed
+ * in RVLC TCOEF table. The place, where the block is read is given as a
+ * pointer parameter.
+ *
+ * Returns:
+ * VDX_OK the function was successful
+ * VDX_OK_BUT_BIT_ERROR the function behaved normally, but a bit error
+ * occured
+ * VDX_ERR_BIB an error occured when accessing bit buffer
+ *
+ *
+ *
+ */
+
+int vdxGetRVLCDCTBlock(
+ bibBuffer_t *inBuffer,
+ int startIndex,
+ int fIntraBlock,
+ int *block,
+ int *bitErrorIndication)
+{
+ int numBitsGot,
+ retValue = VDX_OK,
+ index = startIndex, /* index to zigzag table running from 1 to 63 */
+ tmpvar;
+ u_int32
+ bits,
+ RVLCIndex = 0,
+ RVLCLength = 0;
+ int16
+ bibError = 0;
+
+ int run, /* RUN code */
+ level; /* LEVEL code */
+ u_int32
+ last, /* LAST code (see standard) */
+ sign; /* sign for level */
+
+ vdxAssert(inBuffer != NULL);
+ vdxAssert(startIndex == 0 || startIndex == 1);
+ vdxAssert(block != NULL);
+ vdxAssert(bitErrorIndication != NULL);
+
+ do {
+
+ /* Read next codeword */
+ bits = (int) bibShowBits(15, inBuffer, &numBitsGot, bitErrorIndication,
+ &bibError);
+ if (bibError == ERR_BIB_NOT_ENOUGH_DATA) {
+ deb("vdxGetRVLCDCTBlock: bibShowBits returned not enough data --> "
+ "try to use the data available.\n");
+ bits <<= (15 - numBitsGot);
+ bibError = 0;
+ }
+ else if (bibError ) {
+ deb("vdxGetRVLCDCTBlock: ERROR - bibShowBits failed.\n");
+ goto exitFunction;
+ }
+
+ /* Identifying the codeword in the read bits */
+ {
+ int count, len = 1;
+ u_int32 mask = 0x4000; /* mask 100000000000000 */
+
+ if (bits & mask) {
+ count = 1;
+ for (len = 1; count > 0 && len < 15; len++) {
+ mask = mask >> 1;
+ if (bits & mask)
+ count--;
+ }
+ } else {
+ count = 2;
+ for (len = 1; count > 0 && len < 15; len++) {
+ mask = mask >> 1;
+ if (!(bits & mask))
+ count--;
+ }
+ }
+
+ if (len >= 15) {
+ deb("vdxGetRVLCDCTBlock:ERROR - illegal RVLC codeword.\n");
+ retValue = VDX_OK_BUT_BIT_ERROR;
+ goto exitFunction;
+ }
+
+ bits = bits & 0x7fff;
+ bits = bits >> (15 - (len + 1));
+ }
+
+ /* Get the RVLC table Index and length belonging to the codeword */
+ if (vdxGetRVLCIndex(bits, &RVLCIndex, (int *) &RVLCLength, fIntraBlock, bitErrorIndication) != VDX_OK)
+ goto exitFunction;
+
+ /* Flush the codeword from the buffer */
+ bibFlushBits(RVLCLength, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+ if (bibError)
+ goto exitFunction;
+
+ if (RVLCIndex == 7167) /* ESCAPE */
+ {
+ /* Flush the rest of the ESCAPE code from the buffer */
+ bibFlushBits(1, inBuffer, &numBitsGot, bitErrorIndication, &bibError);
+ if (bibError)
+ goto exitFunction;
+
+ /* LAST */
+ last = bibGetBits(1, inBuffer, &numBitsGot, bitErrorIndication,
+ &bibError);
+ if (bibError)
+ goto exitFunction;
+ /* RUN */
+ run = (int) bibGetBits(6, inBuffer, &numBitsGot, bitErrorIndication,
+ &bibError);
+ if (bibError)
+ goto exitFunction;
+ /* MARKER BIT */
+ tmpvar = bibGetBits(1, inBuffer, &numBitsGot, bitErrorIndication,&bibError);
+ if (bibError)
+ goto exitFunction;
+ if (!tmpvar) {
+ deb("vdxGetRVLCDCTBlock:ERROR - Wrong marker bit.\n");
+ retValue = VDX_OK_BUT_BIT_ERROR;
+ goto exitFunction;
+ }
+ /* LEVEL */
+ level = (int) bibGetBits(11, inBuffer, &numBitsGot, bitErrorIndication,
+ &bibError);
+ if (bibError)
+ goto exitFunction;
+ if (level == 0) {
+ deb("vdxGetRVLCDCTBlock:ERROR - Escape level invalid.\n");
+ retValue = VDX_OK_BUT_BIT_ERROR;
+ goto exitFunction;
+ }
+ /* MARKER BIT */
+ tmpvar = bibGetBits(1, inBuffer, &numBitsGot, bitErrorIndication,&bibError);
+ if (bibError)
+ goto exitFunction;
+ if (!tmpvar) {
+ deb("vdxGetRVLCDCTBlock:ERROR - Wrong marker bit.\n");
+ retValue = VDX_OK_BUT_BIT_ERROR;
+ goto exitFunction;
+ }
+ /* SIGN */
+ sign = bibGetBits(5, inBuffer, &numBitsGot, bitErrorIndication,
+ &bibError);
+ if (bibError)
+ goto exitFunction;
+
+ if (sign == 1) {
+ level = -level;
+ } else if (sign != 0) {
+ deb("vdxGetRVLCDCTBlock:ERROR - illegal sign.\n");
+ retValue = VDX_OK_BUT_BIT_ERROR;
+ goto exitFunction;
+ }
+
+ } else {
+
+ last = (RVLCIndex >> 16) & 1;
+ run = (RVLCIndex >> 8) & 255;
+ level = RVLCIndex & 255;
+
+ sign = bibGetBits(1, inBuffer, &numBitsGot, bitErrorIndication,
+ &bibError);
+ if (bibError)
+ goto exitFunction;
+
+ if (sign)
+ level = -level;
+ }
+
+ /* If too many coefficients */
+ if (index + run > 63) {
+ deb("vdxGetRVLCDCTBlock:ERROR - too many TCOEFs.\n");
+ retValue = VDX_OK_BUT_BIT_ERROR;
+ goto exitFunction;
+ }
+
+ /* Do run-length decoding */
+ while (run--)
+ block[index++] = 0;
+
+ block[index++] = level;
+
+ } while (!last);
+
+ exitFunction:
+
+ /* Set the rest of the coefficients to zero */
+ while (index <= 63) {
+ block[index++] = 0;
+ }
+
+ if (!bibError)
+ return retValue;
+
+ else if (bibError == ERR_BIB_NOT_ENOUGH_DATA) {
+ return VDX_OK_BUT_BIT_ERROR;
+ }
+
+ else
+ return VDX_ERR_BIB;
+}
+
+/*
+ * vdxGetRVLCDCTBlockBackwards
+ *
+ *
+ * Parameters:
+ * inBuffer pointer to bit buffer instance
+ * startIndex the first index in block where to put data
+ * fIntraBlock indicates an intra "1" or inter "0" Block
+ * BitPosBeforeRVLC bit position of inBuffer before the RVLC block,
+ * indicates the point to stop decoding backwards
+ * block array for block (length 64)
+ * bitErrorIndication non-zero if a bit error has been detected
+ * within the bits accessed in this function,
+ * see biterr.h for possible values
+ *
+ * Function:
+ * This function reads a block in backwards direction from the bit buffer
+ * using Huffman codes listed in RVLC TCOEF table. The bit position of the
+ * buffer at return from the function is where the DCT data of the current
+ * block starts.
+ *
+ * Returns:
+ * VDX_OK the function was successful
+ * VDX_OK_BUT_BIT_ERROR the function behaved normally, but a bit error
+ * occured
+ * VDX_ERR_BIB an error occured when accessing bit buffer
+ *
+ *
+ *
+ */
+
+int vdxGetRVLCDCTBlockBackwards(
+ bibBuffer_t *inBuffer,
+ int startIndex,
+ int fIntraBlock,
+// u_int32 BitPosBeforeRVLC,
+ int *block,
+ int *bitErrorIndication)
+{
+ int numBitsGot,
+ retValue = VDX_OK,
+ index = 63; /* index to zigzag table running from 1 to 63 */
+ u_int32
+ bits,
+ RVLCIndex = 0,
+ RVLCLength = 0;
+ int16
+ bibError = 0;
+
+ int run, /* RUN code */
+ level; /* LEVEL code */
+ u_int32
+ last, /* LAST code (see standard) */
+ sign, /* sign for level */
+ escape;
+
+ vdxAssert(inBuffer != NULL);
+ vdxAssert(startIndex == 0 || startIndex == 1);
+ vdxAssert(block != NULL);
+ vdxAssert(bitErrorIndication != NULL);
+
+ do {
+ /* SIGN */
+ bibRewindBits(1, inBuffer, &bibError);
+ if (bibError)
+ goto exitFunction;
+ sign = bibShowBits(1, inBuffer, &numBitsGot, bitErrorIndication,
+ &bibError);
+ if (bibError) {
+ goto exitFunction;
+ }
+
+ /* Read next codeword */
+ bibRewindBits(15, inBuffer, &bibError);
+ if (bibError)
+ goto exitFunction;
+ bits = (int) bibGetBits(15, inBuffer, &numBitsGot, bitErrorIndication,
+ &bibError);
+ if (bibError == ERR_BIB_NOT_ENOUGH_DATA) {
+ deb("vdxGetRVLCDCTBlockBackwards: bibShowBits returned not enough data --> "
+ "try to use the data available.\n");
+ bits <<= (15 - numBitsGot);
+ bibError = 0;
+ }
+ else if (bibError) {
+ deb("vdxGetRVLCDCTBlockBackwards: ERROR - bibGetBits failed.\n");
+ goto exitFunction;
+ }
+
+ /* Identifying the codeword in the read bits */
+ {
+ int count, len = 1;
+ u_int32 mask = 2; /* mask 000000000000010 */
+
+ if (bits & mask) {
+ count = 1;
+ for (len = 1; count > 0 && len < 15; len++) {
+ mask = mask << 1;
+ if (bits & mask)
+ count--;
+ }
+ } else {
+ count = 2;
+ for (len = 1; count > 0 && len < 15; len++) {
+ mask = mask << 1;
+ if (!(bits & mask))
+ count--;
+ }
+ }
+
+ if (len >= 15) {
+ deb("vdxGetRVLCDCTBlockBackwards:ERROR - illegal RVLC codeword.\n");
+ retValue = VDX_OK_BUT_BIT_ERROR;
+ goto exitFunction;
+ }
+
+ bits = bits & (0x7fff >> (15 - (len + 1)));
+ }
+
+ /* Get the RVLC table Index and length belonging to the codeword */
+ if (vdxGetRVLCIndex(bits, &RVLCIndex, (int *) &RVLCLength, fIntraBlock, bitErrorIndication) != VDX_OK)
+ goto exitFunction;
+
+ /* Flush the codeword from the buffer */
+ bibRewindBits(RVLCLength, inBuffer, &bibError);
+ if (bibError)
+ goto exitFunction;
+
+ if (RVLCIndex == 7167) /* ESCAPE */
+ {
+ /* MARKER BIT */
+ bibRewindBits(1, inBuffer, &bibError);
+ if (bibError)
+ goto exitFunction;
+ if(!bibShowBits(1, inBuffer, &numBitsGot, bitErrorIndication,&bibError)
+ || bibError ) {
+ deb("vdxGetRVLCDCTBlockBackwards:ERROR - Wrong marker bit.\n");
+ if ( !bibError )
+ retValue = VDX_OK_BUT_BIT_ERROR;
+ goto exitFunction;
+ }
+ /* LEVEL */
+ bibRewindBits(11, inBuffer, &bibError);
+ if (bibError)
+ goto exitFunction;
+ level = (int) bibShowBits(11, inBuffer, &numBitsGot, bitErrorIndication,
+ &bibError);
+ if (level == 0 || bibError ) {
+ if (!bibError) {
+ deb("vdxGetRVLCDCTBlockBackwards:ERROR - Invalid Level.\n");
+ retValue = VDX_OK_BUT_BIT_ERROR;
+ }
+ goto exitFunction;
+ }
+ /* MARKER BIT */
+ bibRewindBits(1, inBuffer, &bibError);
+ if (bibError)
+ goto exitFunction;
+ if(!bibShowBits(1, inBuffer, &numBitsGot, bitErrorIndication,&bibError)
+ || bibError ) {
+ if ( !bibError ) {
+ deb("vdxGetRVLCDCTBlockBackwards:ERROR - Wrong marker bit.\n");
+ retValue = VDX_OK_BUT_BIT_ERROR;
+ }
+ goto exitFunction;
+ }
+ /* RUN */
+ bibRewindBits(6, inBuffer, &bibError);
+ if (bibError)
+ goto exitFunction;
+ run = (int) bibShowBits(6, inBuffer, &numBitsGot, bitErrorIndication,
+ &bibError);
+ if (bibError) {
+ goto exitFunction;
+ }
+ /* LAST */
+ bibRewindBits(1, inBuffer, &bibError);
+ if (bibError)
+ goto exitFunction;
+ last = bibShowBits(1, inBuffer, &numBitsGot, bitErrorIndication,
+ &bibError);
+ if (bibError) {
+ goto exitFunction;
+ }
+
+ /* Get the first ESCAPE code from the buffer */
+ bibRewindBits(5, inBuffer, &bibError);
+ if (bibError)
+ goto exitFunction;
+ escape = bibShowBits(5, inBuffer, &numBitsGot, bitErrorIndication,
+ &bibError);
+ if (bibError) {
+ goto exitFunction;
+ }
+
+ if (escape != 1) {
+ deb("vdxGetRVLCDCTBlockBackwards:ERROR - illegal escape code.\n");
+ retValue = VDX_OK_BUT_BIT_ERROR;
+ goto exitFunction;
+ }
+
+ RVLCLength += 25;
+
+ } else {
+
+ last = (RVLCIndex >> 16) & 1;
+ run = (RVLCIndex >> 8) & 255;
+ level = RVLCIndex & 255;
+ }
+
+ if (sign)
+ level = -level;
+
+ if (index == 63) {
+ if (!last) {
+ deb("vdxGetRVLCDCTBlockBackwards:ERROR - last TCOEFF problem.\n");
+ retValue = VDX_OK_BUT_BIT_ERROR;
+ goto exitFunction;
+ } else
+ last = 0;
+ }
+
+ if (last) {
+ bibFlushBits((RVLCLength + 1), inBuffer, &numBitsGot, bitErrorIndication,
+ &bibError);
+ if (bibError)
+ goto exitFunction;
+
+ } else if (index - run < startIndex) {
+ deb("vdxGetRVLCDCTBlockBackwards:ERROR - too many TCOEFFs.\n");
+ retValue = VDX_OK_BUT_BIT_ERROR;
+ goto exitFunction;
+
+ } else {
+ /* Do run-length decoding. Since we are decoding backwards, level has to be inserted first */
+ block[index--] = level;
+
+ while (run--)
+ block[index--] = 0;
+
+ }
+
+ } while (!last);
+
+ exitFunction:
+
+ {
+ int i;
+ for(i=startIndex,index++; i<=63; i++,index++)
+ block[i]= (index <= 63) ? block[index] : 0;
+ }
+
+
+ if (!bibError)
+ return retValue;
+ else if (bibError == ERR_BIB_NOT_ENOUGH_DATA) {
+ return VDX_OK_BUT_BIT_ERROR;
+ } else
+ return VDX_ERR_BIB;
+}
+
+// End of File