diff -r 000000000000 -r 951a5db380a0 videoeditorengine/h263decoder/src/vlb.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/videoeditorengine/h263decoder/src/vlb.cpp Fri Jan 29 14:08:33 2010 +0200 @@ -0,0 +1,1434 @@ +/* +* 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: +* Implementation for MPEG4(H263) video transcoder. +* VLC encoding for RVLC -> VLC AC/DCT coeficients in the transcoder. +* +*/ + + +#include "biblin.h" +#include "common.h" + + +/* Run-length coding */ +typedef struct{ + int16 run; + int level; + int16 last; +} tEvent; + +/* Variable length coding */ +typedef struct{ + u_int16 code; + u_int16 length; +} tVLCTable; + + +/* + * Function Declarations + */ +int32 vlbPutACCoeffSVH(int32 coeffStart, int16* block, bibBuffer_t * outBuf, + int32 svh, int32 lastPos); +int32 vlbPutACVLCCoeff(bibBuffer_t *outBuf, tEvent *event, int32 svh); +int32 vlbPutDCCoeffCMT(int val, bibBuffer_t * outBuf, int32 blkCnt); +int32 vlbPutIntraACCoeffCMTDP(bibBuffer_t *outBuf, tEvent *event); +int32 vlbPutIntraACCoeffCMT(int32 coeffStart, int* block, bibBuffer_t * outBuf); +void vdtPutBits (void *outBuf, int numBits, unsigned int value); + + +/* + * Function Definitions + */ + + +/* {{-output"vlbPutBits.txt"}} */ +/* +* vlbPutBits +* +* Parameters: +* outBuf output buffer +* numBits number of bits to write +* value value to write +* +* Function: +* This function puts some bits to the output buffer +* +* Returns: +* Nothing. +* +* Error codes: +* None. +* +*/ +void vlbPutBits (bibBuffer_t *outBuf, + int32 numBits, + u_int32 value) +{ + // To be compatible with the old codes, I don't change the interface + vdtPutBits((void *)outBuf, numBits, value); +} + + +/* + * Look-up tables + */ + +/* INTRA VLC tables */ + +/* run == 0 && level < 28 */ +const tVLCTable vlbVLCTable1IntraAC[28] = +{ + {NOT_VALID,NOT_VALID}, {0x04,0x03}, {0x0c,0x04}, + {0x1e,0x05}, {0x1a,0x06}, {0x18,0x06}, {0x2a,0x07}, + {0x26,0x07}, {0x24,0x07}, {0x2e,0x08}, {0x3e,0x09}, + {0x3c,0x09}, {0x3a,0x09}, {0x4a,0x0a}, {0x48,0x0a}, + {0x46,0x0a}, {0x42,0x0a}, {0x42,0x0b}, {0x40,0x0b}, + {0x1e,0x0b}, {0x1c,0x0b}, {0x0e,0x0c}, {0x0c,0x0c}, + {0x40,0x0c}, {0x42,0x0c}, {0xa0,0x0d}, {0xa2,0x0d}, + {0xa4,0x0d} +}; + +/* run == 1 && level < 11 */ +const tVLCTable vlbVLCTable2IntraAC[11] = +{ + {NOT_VALID, NOT_VALID}, {0x1c,0x05}, {0x28,0x07}, + {0x2c,0x08}, {0x38,0x09}, {0x40,0x0a}, {0x3e,0x0a}, + {0x1a,0x0b}, {0x44,0x0c}, {0xa6,0x0d}, {0xaa,0x0d} +}; + +/* run == 2 && level < 6 */ +const tVLCTable vlbVLCTable3IntraAC[6] = +{ + {NOT_VALID, NOT_VALID}, {0x16,0x06}, {0x2a,0x08}, + {0x3c,0x0a}, {0x18,0x0b}, {0xac,0x0d} +}; + +/* run == 3 && level < 5 */ +const tVLCTable vlbVLCTable4IntraAC[5] = +{ + {NOT_VALID, NOT_VALID}, {0x22,0x07}, {0x36,0x09}, + {0x3a,0x0a}, {0x16,0x0b} +}; + +/* 4 <= run < 8 && level < 4 */ +const tVLCTable vlbVLCTable5IntraAC[4][4] = +{ + { + {NOT_VALID, NOT_VALID}, {0x20,0x07}, {0x44,0x0a}, + {0x14,0x0b} + }, + { + {NOT_VALID, NOT_VALID}, {0x1a,0x07}, {0x38,0x0a}, + {0x10,0x0b} + }, + { + {NOT_VALID, NOT_VALID}, {0x24,0x08}, {0x36,0x0a}, + {0xa8,0x0d} + }, + { + {NOT_VALID, NOT_VALID}, {0x28,0x08}, {0x34,0x0a}, + {0xae,0x0d} + } +}; + +/* 8 <= run < 10 && level < 3 */ +const tVLCTable vlbVLCTable6IntraAC[2][3] = +{ + { + {NOT_VALID, NOT_VALID}, {0x32,0x09}, {0x12,0x0b} + }, + { + {NOT_VALID, NOT_VALID}, {0x30,0x09}, {0x46,0x0c} + } +}; + +/* 10 <= run < 15 && level < 2 */ +const tVLCTable vlbVLCTable7IntraAC[5][2] = +{ + { + {NOT_VALID, NOT_VALID}, {0x2e,0x09} + }, + { + {NOT_VALID, NOT_VALID}, {0x32,0x0a} + }, + { + {NOT_VALID, NOT_VALID}, {0x30,0x0a} + }, + { + {NOT_VALID, NOT_VALID}, {0x0e,0x0b} + }, + { + {NOT_VALID, NOT_VALID}, {0xb0,0x0d} + } +}; + +/* run == 0 && level < 9 */ +const tVLCTable vlbVLCTable8IntraAC[9] = +{ + {NOT_VALID, NOT_VALID}, {0x0e,0x05}, {0x18,0x07}, + {0x2c,0x09}, {0x2e,0x0a}, {0x0c,0x0b}, {0x0a,0x0c}, + {0x08,0x0c}, {0xb2,0x0d} +}; + +/* run == 1 && level < 4 */ +const tVLCTable vlbVLCTable9IntraAC[4] = +{ + {NOT_VALID, NOT_VALID}, {0x1e,0x07}, {0x2c,0x0a}, + {0x0a,0x0b} +}; + +/* 2 <= run < 7 && level < 3 */ +const tVLCTable vlbVLCTable10IntraAC[5][3] = +{ + { + {NOT_VALID, NOT_VALID}, {0x1c,0x07}, {0x08,0x0b} + }, + { + {NOT_VALID, NOT_VALID}, {0x22,0x08}, {0x48,0x0c} + }, + { + {NOT_VALID, NOT_VALID}, {0x20,0x08}, {0x4a,0x0c} + }, + { + {NOT_VALID, NOT_VALID}, {0x26,0x08}, {0xb4,0x0d} + }, + { + {NOT_VALID, NOT_VALID}, {0x2a,0x09}, {0xb6,0x0d} + } +}; + +/* 7 <= run < 21 && level == 1 */ +const tVLCTable vlbVLCTable11IntraAC[14][2] = +{ + { + {NOT_VALID, NOT_VALID}, {0x28,0x09} + }, + { + {NOT_VALID, NOT_VALID}, {0x26,0x09} + }, + { + {NOT_VALID, NOT_VALID}, {0x34,0x09} + }, + { + {NOT_VALID, NOT_VALID}, {0x2a,0x0a} + }, + { + {NOT_VALID, NOT_VALID}, {0x28,0x0a} + }, + { + {NOT_VALID, NOT_VALID}, {0x26,0x0a} + }, + { + {NOT_VALID, NOT_VALID}, {0x24,0x0a} + }, + { + {NOT_VALID, NOT_VALID}, {0x22,0x0a} + }, + { + {NOT_VALID, NOT_VALID}, {0x4c,0x0c} + }, + { + {NOT_VALID, NOT_VALID}, {0x4e,0x0c} + }, + { + {NOT_VALID, NOT_VALID}, {0xb8,0x0d} + }, + { + {NOT_VALID, NOT_VALID}, {0xba,0x0d} + }, + { + {NOT_VALID, NOT_VALID}, {0xbc,0x0d} + }, + { + {NOT_VALID, NOT_VALID}, {0xbe,0x0d} + } +}; + + +/* Inter AC VLC tables */ + +const tVLCTable vlbVLCTable1InterAC[13] = +{ + {NOT_VALID, NOT_VALID}, + {0x04,0x03}, {0x1e,0x05}, {0x2a,0x07}, {0x2e,0x08}, + {0x3e,0x09}, {0x4a,0x0a}, {0x48,0x0a}, {0x42,0x0b}, + {0x40,0x0b}, {0x0e,0x0c}, {0x0c,0x0c}, {0x40,0x0c} +}; + +const tVLCTable vlbVLCTable2InterAC[7] = +{ + {NOT_VALID, NOT_VALID}, {0x0c,0x04}, {0x28,0x07}, + {0x3c,0x09}, {0x1e,0x0b}, {0x42,0x0c}, {0xa0,0x0d} +}; + +const tVLCTable vlbVLCTable3InterAC[5] = +{ + {NOT_VALID, NOT_VALID}, {0x1c,0x05}, {0x3a,0x09}, + {0x1c,0x0b}, {0xa2,0x0d} +}; + +const tVLCTable vlbVLCTable4InterAC[4][4] = +{ + { + {NOT_VALID, NOT_VALID}, {0x1a,0x06}, {0x46,0x0a}, + {0x1a,0x0b} + }, + { + {NOT_VALID, NOT_VALID}, {0x18,0x06}, {0x44,0x0a}, + {0xa4,0x0d} + }, + { + {NOT_VALID, NOT_VALID}, {0x16,0x06}, {0x18,0x0b}, + {0xa6,0x0d} + }, + { + {NOT_VALID, NOT_VALID}, {0x26,0x07}, {0x16,0x0b}, + {0xa8,0x0d} + } +}; + +const tVLCTable vlbVLCTable5InterAC[4][3] = +{ + { + {NOT_VALID, NOT_VALID}, {0x24,0x07}, {0x14,0x0b} + }, + { + {NOT_VALID, NOT_VALID}, {0x22,0x07}, {0x12,0x0b} + }, + { + {NOT_VALID, NOT_VALID}, {0x20,0x07}, {0x10,0x0b} + }, + { + {NOT_VALID, NOT_VALID}, {0x2c,0x08}, {0xaa,0x0d} + } +}; + +const tVLCTable vlbVLCTable6InterAC[16] = +{ + {0x2a,0x08}, {0x28,0x08}, {0x38,0x09}, {0x36,0x09}, + {0x42,0x0a}, {0x40,0x0a}, {0x3e,0x0a}, {0x3c,0x0a}, + {0x3a,0x0a}, {0x38,0x0a}, {0x36,0x0a}, {0x34,0x0a}, + {0x44,0x0c}, {0x46,0x0c}, {0xac,0x0d}, {0xae,0x0d} +}; + +const tVLCTable vlbVLCTable7InterAc[4] = +{ + {NOT_VALID, NOT_VALID}, {0x0e,0x05}, {0x32,0x0a}, + {0x0a,0x0c} +}; + +const tVLCTable vlbVLCTable8InterAC[3] = +{ + {NOT_VALID, NOT_VALID}, {0x1e,0x07}, {0x08,0x0c} +}; + +const tVLCTable vlbVLCTable9InterAC[39] = +{ + {0x1c,0x07}, {0x1a,0x07}, {0x18,0x07}, {0x26,0x08}, + {0x24,0x08}, {0x22,0x08}, {0x20,0x08}, {0x34,0x09}, + {0x32,0x09}, {0x30,0x09}, {0x2e,0x09}, {0x2c,0x09}, + {0x2a,0x09}, {0x28,0x09}, {0x26,0x09}, {0x30,0x0a}, + {0x2e,0x0a}, {0x2c,0x0a}, {0x2a,0x0a}, {0x28,0x0a}, + {0x26,0x0a}, {0x24,0x0a}, {0x22,0x0a}, {0x0e,0x0b}, + {0x0c,0x0b}, {0x0a,0x0b}, {0x08,0x0b}, {0x48,0x0c}, + {0x4a,0x0c}, {0x4c,0x0c}, {0x4e,0x0c}, {0xb0,0x0d}, + {0xb2,0x0d}, {0xb4,0x0d}, {0xb6,0x0d}, {0xb8,0x0d}, + {0xba,0x0d}, {0xbc,0x0d}, {0xbe,0x0d} +}; + + +const int8 vlbVLCRun0InterAC[64] = +{ + 0x0d, 0x07, 0x05, 0x04, 0x04, 0x04, 0x04, 0x03, + 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const int8 vlbVLCRun1InterAC[64] = +{ + 0x04, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +/* other tables */ +const int8 vlbLMaxTableIntra[36] = +{ + 0x1b, 0x0a, 0x05, 0x04, 0x03, 0x03, + 0x03, 0x03, 0x02, 0x02, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x08, 0x03, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 +}; + +const int8 vlbLMaxTableInter[68] = +{ + 0x0c, 0x06, 0x04, 0x03, 0x03, 0x03, + 0x03, 0x02, 0x02, 0x02, 0x02, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x03, 0x02, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01 +}; + +const int8 vlbRMaxTableIntra[35] = +{ + 0x0f, 0x0a, 0x08, 0x04, 0x03, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x15, 0x07, 0x02, + 0x01, 0x01, 0x01, 0x01, 0x01 +}; + +const int8 vlbRMaxTableInter[15] = +{ + 0x1b, 0x0b, 0x07, 0x03, 0x02, 0x02, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x29, 0x02, 0x01 +}; + + +const u_int32 vlbZigzagScan[64] = +{ + 0x00, 0x01, 0x08, 0x10, 0x09, 0x02, 0x03, 0x0a, + 0x11, 0x18, 0x20, 0x19, 0x12, 0x0b, 0x04, 0x05, + 0x0c, 0x13, 0x1a, 0x21, 0x28, 0x30, 0x29, 0x22, + 0x1b, 0x14, 0x0d, 0x06, 0x07, 0x0e, 0x15, 0x1c, + 0x23, 0x2a, 0x31, 0x38, 0x39, 0x32, 0x2b, 0x24, + 0x1d, 0x16, 0x0f, 0x17, 0x1e, 0x25, 0x2c, 0x33, + 0x3a, 0x3b, 0x34, 0x2d, 0x26, 0x1f, 0x27, 0x2e, + 0x35, 0x3c, 0x3d, 0x36, 0x2f, 0x37, 0x3e, 0x3f +}; + +const u_int32 vlbInvZigzagScan[64] = +{ + 0x00, 0x01, 0x05, 0x06, 0x0e, 0x0f, 0x1b, 0x1c, + 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1d, 0x2a, + 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2b, + 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2c, 0x35, + 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x3c, + 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3d, + 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3e, 0x3f +}; + + +const tVLCTable vlbLumaTableIntraDC[13] = +{ + {0x03,0x03}, {0x03,0x02}, {0x02,0x02}, {0x02,0x03}, + {0x01,0x03}, {0x01,0x04}, {0x01,0x05}, {0x01,0x06}, + {0x01,0x07}, {0x01,0x08}, {0x01,0x09}, {0x01,0x0a}, + {0x01,0x0b} +}; + +const tVLCTable vlbChromaTableIntraDC[13] = +{ + {0x03,0x02}, {0x02,0x02}, {0x01,0x02}, {0x01,0x03}, + {0x01,0x04}, {0x01,0x05}, {0x01,0x06}, {0x01,0x07}, + {0x01,0x08}, {0x01,0x09}, {0x01,0x0a}, {0x01,0x0b} +}; + +/* Array of pointers for AC VLC (INTER)tables */ +const tVLCTable * const vlbVLCTablePointer0[27] = +{ + vlbVLCTable1InterAC, + vlbVLCTable2InterAC, + vlbVLCTable3InterAC, + vlbVLCTable4InterAC[0], + vlbVLCTable4InterAC[1], + vlbVLCTable4InterAC[2], + vlbVLCTable4InterAC[3], + vlbVLCTable5InterAC[0], + vlbVLCTable5InterAC[1], + vlbVLCTable5InterAC[2], + vlbVLCTable5InterAC[3], + vlbVLCTable6InterAC - 0x01, // this pointer is going outside the range, but it is used only with condition (level < vlbVLCRun0InterAC[run]) which results having indexes > 0 and hence the array is never indexed below its base address + vlbVLCTable6InterAC , + vlbVLCTable6InterAC + 0x01, + vlbVLCTable6InterAC + 0x02, + vlbVLCTable6InterAC + 0x03, + vlbVLCTable6InterAC + 0x04, + vlbVLCTable6InterAC + 0x05, + vlbVLCTable6InterAC + 0x06, + vlbVLCTable6InterAC + 0x07, + vlbVLCTable6InterAC + 0x08, + vlbVLCTable6InterAC + 0x09, + vlbVLCTable6InterAC + 0x0a, + vlbVLCTable6InterAC + 0x0b, + vlbVLCTable6InterAC + 0x0c, + vlbVLCTable6InterAC + 0x0d, + vlbVLCTable6InterAC + 0x0e + +}; + +const tVLCTable * const vlbVLCTablePointer1[41] = +{ + vlbVLCTable7InterAc, + vlbVLCTable8InterAC, + vlbVLCTable9InterAC - 0x01, // this pointer is going outside the range, but it is used only with condition (level < vlbVLCRun1InterAC[run]) which results having indexes > 0 and hence the array is never indexed below its base address + vlbVLCTable9InterAC , + vlbVLCTable9InterAC + 0x01, + vlbVLCTable9InterAC + 0x02, + vlbVLCTable9InterAC + 0x03, + vlbVLCTable9InterAC + 0x04, + vlbVLCTable9InterAC + 0x05, + vlbVLCTable9InterAC + 0x06, + vlbVLCTable9InterAC + 0x07, + vlbVLCTable9InterAC + 0x08, + vlbVLCTable9InterAC + 0x09, + vlbVLCTable9InterAC + 0x0a, + vlbVLCTable9InterAC + 0x0b, + vlbVLCTable9InterAC + 0x0c, + vlbVLCTable9InterAC + 0x0d, + vlbVLCTable9InterAC + 0x0e, + vlbVLCTable9InterAC + 0x0f, + vlbVLCTable9InterAC + 0x10, + vlbVLCTable9InterAC + 0x11, + vlbVLCTable9InterAC + 0x12, + vlbVLCTable9InterAC + 0x13, + vlbVLCTable9InterAC + 0x14, + vlbVLCTable9InterAC + 0x15, + vlbVLCTable9InterAC + 0x16, + vlbVLCTable9InterAC + 0x17, + vlbVLCTable9InterAC + 0x18, + vlbVLCTable9InterAC + 0x19, + vlbVLCTable9InterAC + 0x1a, + vlbVLCTable9InterAC + 0x1b, + vlbVLCTable9InterAC + 0x1c, + vlbVLCTable9InterAC + 0x1d, + vlbVLCTable9InterAC + 0x1e, + vlbVLCTable9InterAC + 0x1f, + vlbVLCTable9InterAC + 0x20, + vlbVLCTable9InterAC + 0x21, + vlbVLCTable9InterAC + 0x22, + vlbVLCTable9InterAC + 0x23, + vlbVLCTable9InterAC + 0x24, + vlbVLCTable9InterAC + 0x25, +}; + +const int8 vlbVLCRun0IntraAC[64] = +{ + 0x1c, 0x0b, 0x06, 0x05, 0x04, 0x04, 0x04, 0x04, + 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +const int8 vlbVLCRun1IntraAC[64] = +{ + 0x09, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +/* array of table pointers for AC VLC INTRA tables*/ + +const tVLCTable * const vlbVLCTableIntraPointer0[15] = +{ + vlbVLCTable1IntraAC, + vlbVLCTable2IntraAC, + vlbVLCTable3IntraAC, + vlbVLCTable4IntraAC, + vlbVLCTable5IntraAC[0], + vlbVLCTable5IntraAC[1], + vlbVLCTable5IntraAC[2], + vlbVLCTable5IntraAC[3], + vlbVLCTable6IntraAC[0], + vlbVLCTable6IntraAC[1], + vlbVLCTable7IntraAC[0], + vlbVLCTable7IntraAC[1], + vlbVLCTable7IntraAC[2], + vlbVLCTable7IntraAC[3], + vlbVLCTable7IntraAC[4], +}; + +const tVLCTable * const vlbVLCTableIntraPointer1[21] = +{ + vlbVLCTable8IntraAC, + vlbVLCTable9IntraAC, + vlbVLCTable10IntraAC[0], + vlbVLCTable10IntraAC[1], + vlbVLCTable10IntraAC[2], + vlbVLCTable10IntraAC[3], + vlbVLCTable10IntraAC[4], + vlbVLCTable11IntraAC[0], + vlbVLCTable11IntraAC[1], + vlbVLCTable11IntraAC[2], + vlbVLCTable11IntraAC[3], + vlbVLCTable11IntraAC[4], + vlbVLCTable11IntraAC[5], + vlbVLCTable11IntraAC[6], + vlbVLCTable11IntraAC[7], + vlbVLCTable11IntraAC[8], + vlbVLCTable11IntraAC[9], + vlbVLCTable11IntraAC[10], + vlbVLCTable11IntraAC[11], + vlbVLCTable11IntraAC[12], + vlbVLCTable11IntraAC[13], +}; + + +/* {{-output"vdtPutIntraMBCMT.txt"}} */ +/* +* vdtPutIntraMBCMT +* +* Parameters: +* outBuf output buffer +* coeff pointer to the coefficients that must be in scanned order +* numTextureBits pointer to store the number of bits taken to encode the macro block. +* index block Index +* skipDC whether to skip INTRA DC +* skipAC whether to skip INTRA AC +* +* Function: +* This function forms the bitstream for INTRA macroblock in combined motion and +* texture mode for the transcoding module +* +* Returns: +* Nothing. +* +* Error codes: +* None. +* +*/ +void vdtPutIntraMBCMT(bibBuffer_t *outBuf, int *coeff, int *numTextureBits, int index, int skipDC, int skipAC) +{ + int32 textureBits; + textureBits = 0; + + // DC coefficient VLC + if (!skipDC) + { + textureBits += vlbPutDCCoeffCMT(coeff[0], outBuf, index); + } + + //AC coefficient VLC + if (!skipAC) + { + textureBits += vlbPutIntraACCoeffCMT(1, coeff, outBuf); + *numTextureBits = textureBits; + } + + return; +} + + +/* {{-output"vdtPutInterMBCMT.txt"}} */ +/* +* vdtPutInterMBCMT +* +* Parameters: +* outBuf output buffer +* coeff pointer to the coefficients that must be in scanned order +* numTextureBits pointer to store the number of bits taken to encode the macro block. +* svh flag to indicate short video header +* +* Function: +* This function forms the bitstream for INTER macroblock in combined motion and +* texture mode for the transcoding module +* +* Returns: +* Nothing. +* +* Error codes: +* None. +* +*/ +void vdtPutInterMBCMT(bibBuffer_t *outBuf, int coeffStart, int *coeff, int *numTextureBits, int svh) +{ + int32 textureBits; + int16 coeffInt16[64]; + + /* encode texture coefficients */ + textureBits = 0; + /* find out the last nonzero coeficients */ + int nonZeroDCT = 0; + for (int i = 0; i < 64; i++) + { + nonZeroDCT = coeff[i] != 0 ? i : nonZeroDCT; + coeffInt16[i] = (int16)coeff[i]; + } + textureBits += vlbPutACCoeffSVH(coeffStart, coeffInt16, outBuf, svh, nonZeroDCT); + *numTextureBits = textureBits; + + return; +} + + + +/* {{-output"vlbPutDCCoeffCMT.txt"}} */ +/* +* vlbPutDCCoeffCMT +* +* Parameters: +* outBuf output buffer +* val value of the DC coefficient +* blkCnt block number in the macro block +* +* Function: +* This function puts DC coefficient in CMT mode into the bitstream +* +* Returns: +* number of bits outputted. +* +* Error codes: +* None. +* +*/ +int32 vlbPutDCCoeffCMT(int val, bibBuffer_t * outBuf, int32 blkCnt) +{ + int32 absVal; + int32 numBits; + int32 size; + + absVal = ABS(val); + size = 0; + + while(absVal > 0) + { + size++; + absVal >>= 1; + } + + numBits = size; + if(blkCnt < 4) + { + vlbPutBits(outBuf, vlbLumaTableIntraDC[size].length, vlbLumaTableIntraDC[size].code); + numBits += vlbLumaTableIntraDC[size].length; + } + else + { + vlbPutBits(outBuf, vlbChromaTableIntraDC[size].length, vlbChromaTableIntraDC[size].code); + numBits += vlbChromaTableIntraDC[size].length; + } + + if(size) + { + if(val > 0) + { + vlbPutBits(outBuf, size, val); + } + else + { + absVal = ((1 << size) - 1); + vlbPutBits(outBuf, size, (absVal + val)); + } + } + + if(size > 8) + { + vlbPutBits(outBuf, 1, 1); + numBits++; + } + + return numBits; +} + + + +/* {{-output"vlbPutIntraACCoeffCMT.txt"}} */ +/* +* vlbPutIntraACCoeffCMT +* +* Parameters: +* outBuf output buffer +* coeffStart coefficient number from where the coding is to start +* block pointer to the texture block data +* +* Function: +* This function puts AC coefficients in CMT mode into the bitstream +* +* Returns: +* number of bits outputted. +* +* Error codes: +* None. +* +*/ +int32 vlbPutIntraACCoeffCMT(int32 coeffStart, int* block, bibBuffer_t * outBuf) +{ + tEvent prevEvent; + tEvent currEvent; + int32 i; + int32 numBits; + tEvent *prev = &prevEvent; + tEvent *curr = &currEvent; + int level; + + curr->run = 0; + prev->last = 0; + numBits = 0; + + for(i = coeffStart; i < 64; i++) + { + level = block[i]; + if(level == 0) + { + curr->run++; + } + else + { + prev->level = level; + prev->run = curr->run; + curr->run = 0; + break; + } + } + + for(i = i+1; i < 64; i++) + { + level = block[i]; + if(level == 0) + { + curr->run++; + } + else + { + numBits += vlbPutIntraACCoeffCMTDP(outBuf, &prevEvent); + prev->level = level; + prev->run = curr->run; + curr->run = 0; + } + } + + prev->last = 1; + numBits += vlbPutIntraACCoeffCMTDP(outBuf, &prevEvent); + + return numBits; +} + + + +/* {{-output"vlbFindRMax.txt"}} */ +/* +* vlbFindRMax +* +* Parameters: +* event pointer to the event being coded +* mbType macro block encoding type (INTER/INTRA) +* +* Function: +* This function finds RMAX value to subtract from run for escape coding +* when reversible VLC is OFF +* +* Returns: +* RMAX value +* +* Error codes: +* None. +* +*/ +int32 vlbFindRMax(tEvent *event, int16 mbType) +{ + int32 level; + + level = ABS(event->level); + + if(mbType == INTRA) + { + if(event->last == 0) + { + return level <= 27 ? vlbRMaxTableIntra[level - 1] : + NOT_VALID; + } + else + { + return level <= 8 ? vlbRMaxTableIntra[level + 26] : + NOT_VALID; + } + } + else + { + if (event->last == 0) + { + return level <= 12 ? vlbRMaxTableInter[level - 1] : + NOT_VALID; + } + else + { + return level <= 3 ? vlbRMaxTableInter[level + 11] + : NOT_VALID; + } + } +} + + + +/* {{-output"vlbFindLMax.txt"}} */ +/* +* vlbFindLMax +* +* Parameters: +* event pointer to the event being coded +* mbType macro block encoding type (INTER/INTRA) +* +* Function: +* This function finds LMAX value to subtract from run for escape coding +* when reversible VLC is OFF +* +* Returns: +* LMAX value +* +* Error codes: +* None. +* +*/ +int32 vlbFindLMax(tEvent *event, int16 mbType) +{ + if (mbType == INTRA) + { + if (event->last == 0) + { + if (event->run <= 14) + { + return vlbLMaxTableIntra[event->run]; + } + else + { + return NOT_VALID; + } + } + else + { + if (event->run <= 20) + { + return vlbLMaxTableIntra[event->run + 15]; + } + else + { + return NOT_VALID; + } + } + } + else + { + if (event->last == 0) + { + return event->run <= 26 ? vlbLMaxTableInter[event->run] : + NOT_VALID; + } + else + { + return event->run <= 40 ? vlbLMaxTableInter[event->run + 27] : + NOT_VALID; + } + } +} + + + +/* {{-output"vlbPutIntraACCoeffCMTDP.txt"}} */ +/* +* vlbPutIntraACCoeffCMTDP +* +* Parameters: +* outBuf output buffer +* event pointer to the event being coded +* +* Function: +* This function encodes AC coefficient for Intra blocks in combined motion texture + mode and data partitioned mode +* +* Returns: +* number of bits outputted. +* +* Error codes: +* None. +* +*/ +int32 vlbPutIntraACCoeffCMTDP(bibBuffer_t *outBuf, tEvent *event) +{ + int32 sign; + int32 level; + int32 run; + int32 status; + int32 count; + const tVLCTable *vlcTable=NULL; + int32 lmax; + int32 rmax; + + sign = (event->level >> 15) & (0x1); + level = ABS(event->level); + run = event->run; + count = 0; + + do + { + status = CODE_FOUND; + if(event->last == 0) + { + if(level < vlbVLCRun0IntraAC[run] ) + { + vlcTable = vlbVLCTableIntraPointer0[run]; + } + else + { + status = CODE_NOT_FOUND; + } + } + else + { + if(level < vlbVLCRun1IntraAC[run] ) + { + vlcTable = vlbVLCTableIntraPointer1[run]; + } + else + { + status = CODE_NOT_FOUND; + } + } + + if (status == CODE_NOT_FOUND) + { + switch (++count) + { + case 1: + { + lmax = vlbFindLMax(event, INTRA); + if (lmax == NOT_VALID) + { + count = 2; + } + else + { + level -= lmax; + break; + } + } + case 2: + { + rmax = vlbFindRMax(event, INTRA); + if (rmax != NOT_VALID) + { + level = ABS(event->level); + run = event->run - rmax; + break; + } + else + { + count = 3; + } + } + case 3: + { + status = CODE_FOUND; + } + } + } + + } while (status != CODE_FOUND); + + switch (count) + { + case 0: + vlbPutBits(outBuf, vlcTable[level].length, vlcTable[level].code | sign); + return vlcTable[level].length; + + case 1: + vlbPutBits(outBuf, ESCAPE_CODE_LENGTH_VLC, ESCAPE_CODE_VLC); + vlbPutBits(outBuf, 1, 0); + vlbPutBits(outBuf, vlcTable[level].length, vlcTable[level].code | sign); + return vlcTable[level].length + 1 + ESCAPE_CODE_LENGTH_VLC; + + case 2: + vlbPutBits(outBuf, ESCAPE_CODE_LENGTH_VLC, ESCAPE_CODE_VLC); + vlbPutBits(outBuf, 2, 0x2); + vlbPutBits(outBuf, vlcTable[level].length, vlcTable[level].code | sign); + return vlcTable[level].length + 2 + ESCAPE_CODE_LENGTH_VLC; + + case 3: + vlbPutBits(outBuf, ESCAPE_CODE_LENGTH_VLC, ESCAPE_CODE_VLC); + vlbPutBits(outBuf, 2, 0x3); + vlbPutBits(outBuf, 8, (event->last << 7) | (event->run << 1) | 1); + vlbPutBits(outBuf, 13, ((event->level & 0x0fff) << 1) | 1); + return 23 + ESCAPE_CODE_LENGTH_VLC; + + default: + return E_FAILURE; + } +} + + + +/* {{-output"vlbPutACCoeffSVH.txt"}} */ +/* +* vlbPutACCoeffSVH +* +* Parameters: +* outBuf output buffer +* coeffStart coefficient number from where the coding to be started +* block pointer to the texture block data. Coeficients must be in zigzag order +* svh flag indicating whether short video header mode is ON +* lastPos value of last non-zero position of block +* +* Function: +* This function puts AC coefficients in SVH mode into the bitstream +* +* Returns: +* number of bits outputted. +* +* Error codes: +* None. +* +*/ +int32 vlbPutACCoeffSVH(int32 coeffStart, int16* block, bibBuffer_t * outBuf, + int32 svh, int32 lastPos) + +{ + tEvent prevEvent; + tEvent currEvent; + int32 i; + int32 numBits; + tEvent *prev ; + tEvent *curr ; + int32 level; + int32 lastPosition = lastPos; + + prev = &prevEvent; + curr = &currEvent; + curr->run = 0; + prev->last = 0; + numBits = 0; + + for(i = coeffStart; i <= lastPosition; i++) + { + level = (int16)block[i]; + if(level == 0) + { + curr->run++; + } + else + { + // clip the coeff (MPEG-4 has larger range than H.263) requantization of the whole block is too complicated for this minor use case + if ( level < -127 ) + { + level = -127; + } + else if ( level > 127 ) + { + level = 127; + } + prev->level = level; + prev->run = curr->run; + curr->run = 0; + break; + } + } + + for(i = i+1; i <= lastPosition; i++) + { + level = (int16)block[i]; + if(level == 0) + { + curr->run++; + } + else + { + numBits += vlbPutACVLCCoeff(outBuf, &prevEvent,svh); + + // clip the coeff (MPEG-4 has larger range than H.263) requantization of the whole block is too complicated for this minor use case + if ( level < -127 ) + { + level = -127; + } + else if ( level > 127 ) + { + level = 127; + } + prev->level = level; + prev->run = curr->run; + curr->run = 0; + } + } + + prev->last = 1; + numBits += vlbPutACVLCCoeff(outBuf, &prevEvent,svh); + + return numBits; +} + + + +/* {{-output"vlbCodeACCoeffsSVHWithZigZag.txt"}} */ +/* +* vlbCodeACCoeffsSVHWithZigZag +* +* Parameters: +* outBuf output buffer +* coeffStart coefficient number from where the coding to be started +* block pointer to the texture block data. Coeficients must be in zigzag order +* svh flag indicating whether short video header mode is ON +* lastPos value of last non-zero position of block +* +* Function: +* This function puts AC coefficients in SVH mode with zigzag into the bitstream +* +* Returns: +* number of bits outputted. +* +* Error codes: +* None. +* +*/ +int32 vlbCodeACCoeffsSVHWithZigZag(int32 coeffStart, int16* block, bibBuffer_t * outBuf, + int32 svh, int32 lastPos) + +{ + tEvent prevEvent; + tEvent currEvent; + int32 i; + int32 numBits; + tEvent *prev ; + tEvent *curr ; + int32 level; + int32 lastPosition = vlbInvZigzagScan[lastPos]; + + prev = &prevEvent; + curr = &currEvent; + curr->run = 0; + prev->last = 0; + numBits = 0; + + for(i = coeffStart; i <= lastPosition; i++) + { + level = block[vlbZigzagScan[i]]; + if(level == 0) + { + curr->run++; + } + else + { + prev->level = level; + prev->run = curr->run; + curr->run = 0; + break; + } + } + + for(i = i+1; i <= lastPosition; i++) + { + level = block[vlbZigzagScan[i]]; + if(level == 0) + { + curr->run++; + } + else + { + numBits += vlbPutACVLCCoeff(outBuf, &prevEvent,svh); + prev->level = level; + prev->run = curr->run; + curr->run = 0; + } + } + + prev->last = 1; + numBits += vlbPutACVLCCoeff(outBuf, &prevEvent,svh); + + return numBits; +} + + + + +/* {{-output"vlbPutACVLCCoeff.txt"}} */ +/* +* vlbPutACVLCCoeff +* +* Parameters: +* outBuf output buffer +* event pointer to the event being coded +* svh flag indicating whether short video header mode is ON +* +* Function: +* This function encodes AC coefficients for Inter and Intra blocks in SVH mode and +* inter blocks in non-SVH mode +* +* Returns: +* number of bits outputted. +* +* Error codes: +* None. +* +*/ +int32 vlbPutACVLCCoeff(bibBuffer_t *outBuf, tEvent *event, int32 svh) +{ + int32 sign; + int32 run; + int32 level; + int32 status; + int32 count; + const tVLCTable *vlcTable= NULL; + int32 lmax; + int32 rmax; + + sign = (event->level >> 15) & (0x1); + level = ABS(event->level); + run = event->run; + count = 0; + + do + { + status = CODE_FOUND; + if(event->last == 0) + { + if(level < vlbVLCRun0InterAC[run] ) + { + vlcTable = vlbVLCTablePointer0[run]; + } + else + { + status = CODE_NOT_FOUND; + } + } + else + { + if(level < vlbVLCRun1InterAC[run] ) + { + vlcTable = vlbVLCTablePointer1[run]; + } + else + { + status = CODE_NOT_FOUND; + } + } + + if (status == CODE_NOT_FOUND) + { + if (svh == ON) + { + count = 4; + status = CODE_FOUND; + } + else + { + switch (++count) + { + case 1: + { + lmax = vlbFindLMax(event, INTER); + if (lmax == NOT_VALID) + { + count = 2; + } + else + { + level = ABS(event->level) - lmax; + break; + } + } + case 2: + { + rmax = vlbFindRMax(event, INTER); + if (rmax != NOT_VALID) + { + level = ABS(event->level); + run = event->run - rmax; + break; + } + else + { + count = 3; + } + } + case 3: + { + status = CODE_FOUND; + break; + } + default: + { + return E_FAILURE; + } + } + } + } + + } while (status != CODE_FOUND); + + switch (count) + { + case 0: + { + vlbPutBits(outBuf, vlcTable[level].length, vlcTable[level].code | sign); + return vlcTable[level].length; + } + case 1: + { + vlbPutBits(outBuf, ESCAPE_CODE_LENGTH_VLC, ESCAPE_CODE_VLC); + vlbPutBits(outBuf, 1, 0); + vlbPutBits(outBuf, vlcTable[level].length, vlcTable[level].code | sign); + return vlcTable[level].length + 1 + ESCAPE_CODE_LENGTH_VLC; + } + case 2: + { + vlbPutBits(outBuf, ESCAPE_CODE_LENGTH_VLC, ESCAPE_CODE_VLC); + vlbPutBits(outBuf, 2, 0x2); + vlbPutBits(outBuf, vlcTable[level].length, vlcTable[level].code | sign); + return vlcTable[level].length + 2 + ESCAPE_CODE_LENGTH_VLC; + } + case 3: + { + vlbPutBits(outBuf, ESCAPE_CODE_LENGTH_VLC, ESCAPE_CODE_VLC); + vlbPutBits(outBuf, 2, 0x3); + /* Fixed Length Coding of Events */ + vlbPutBits(outBuf, 8, (event->last << 7) | (event->run << 1) | 1); + vlbPutBits(outBuf, 13, ((event->level & 0x0fff) << 1) | 1); + return 23 + ESCAPE_CODE_LENGTH_VLC; + } + case 4: + { + vlbPutBits(outBuf, ESCAPE_CODE_LENGTH_VLC, ESCAPE_CODE_VLC); + vlbPutBits(outBuf, 7, (event->last << 6) | event->run); + vlbPutBits(outBuf, 8, event->level & 0x0ff); + return 15 + ESCAPE_CODE_LENGTH_VLC; + } + default: + { + return E_FAILURE; + } + } +} + +/* End of vlb.cpp */ + +