/*
* 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