/* * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #include #include #include "h263_information.h" namespace webrtc { // MCBPC --- static const WebRtc_Word32 MCBPC_I_MAX_CODE_LENGTH = 2; static const WebRtc_Word32 MCBPC_I_TABLE_LENGTH = 9; static const WebRtc_UWord8 MCBPC_I_CODE[9][2] = {{0x80,0x00}, //1 {0x20,0x00}, //001 {0x40,0x00}, //010 {0x60,0x00}, //011 {0x10,0x00}, //0001 {0x04,0x00}, //0000 01 {0x08,0x00}, //0000 10 {0x0C,0x00}, //0000 11 {0x00,0x80}}; //0000 0000 1 static const WebRtc_UWord8 MCBPC_I_MASK[9][2] = {{0x80,0x00}, //1 {0xE0,0x00}, //001 {0xE0,0x00}, //010 {0xE0,0x00}, //011 {0xF0,0x00}, //0001 {0xFC,0x00}, //0000 01 {0xFC,0x00}, //0000 10 {0xFC,0x00}, //0000 11 {0xFF,0x80}}; //0000 0000 1 static const WebRtc_Word32 MCBPC_I_MBTYPE[9] = {3,3,3,3,4,4,4,4,6}; static const WebRtc_Word32 MCBPC_I_SIZE[9] = {1,3,3,3,4,6,6,6,9}; static const char MCBPC_I_CBPC[9][2] = {{0,0},{0,1},{1,0},{1,1},{0,0},{0,1},{1,0},{1,1},{0,0}}; static const WebRtc_Word32 MCBPC_P_MAX_CODE_LENGTH = 2; static const WebRtc_Word32 MCBPC_P_TABLE_LENGTH = 25; static const WebRtc_UWord8 MCBPC_P_CODE[25][2] = {{0x80,0x00}, //1 {0x30,0x00}, //0011 {0x20,0x00}, //0010 {0x14,0x00}, //0001 01 {0x60,0x00}, //011 {0x0E,0x00}, //0000 111 {0x0C,0x00}, //0000 110 {0x02,0x80}, //0000 0010 1 {0x40,0x00}, //010 {0x0A,0x00}, //0000 101 {0x08,0x00}, //0000 100 {0x05,0x00}, //0000 0101 {0x18,0x00}, //0001 1 {0x04,0x00}, //0000 0100 {0x03,0x00}, //0000 0011 {0x06,0x00}, //0000 011 {0x10,0x00}, //0001 00 {0x02,0x00}, //0000 0010 0 {0x01,0x80}, //0000 0001 1 {0x01,0x00}, //0000 0001 0 {0x00,0x80}, //0000 0000 1 {0x00,0x40}, //0000 0000 010 {0x00,0x60}, //0000 0000 0110 0 {0x00,0x70}, //0000 0000 0111 0 {0x00,0x78}}; //0000 0000 0111 1 static const WebRtc_UWord8 MCBPC_P_MASK[25][2] = {{0x80,0x00}, //1 {0xF0,0x00}, //0011 {0xF0,0x00}, //0010 {0xFC,0x00}, //0001 01 {0xE0,0x00}, //011 {0xFE,0x00}, //0000 111 {0xFE,0x00}, //0000 110 {0xFF,0x80}, //0000 0010 1 {0xE0,0x00}, //010 {0xFE,0x00}, //0000 101 {0xFE,0x00}, //0000 100 {0xFF,0x00}, //0000 0101 {0xF8,0x00}, //0001 1 {0xFF,0x00}, //0000 0100 {0xFF,0x00}, //0000 0011 {0xFE,0x00}, //0000 011 {0xFC,0x00}, //0001 00 {0xFF,0x80}, //0000 0010 0 {0xFF,0x80}, //0000 0001 1 {0xFF,0x80}, //0000 0001 0 {0xFF,0x80}, //0000 0000 1 {0xFF,0xE0}, //0000 0000 010 {0xFF,0xF8}, //0000 0000 0110 0 {0xFF,0xF8}, //0000 0000 0111 0 {0xFF,0xF8}}; //0000 0000 0111 1 static const WebRtc_Word32 MCBPC_P_MBTYPE[25] = {0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,6, 5, 5, 5, 5}; static const WebRtc_Word32 MCBPC_P_SIZE[25] = {1,4,4,6,3,7,7,9,3,7,7,8,5,8,8,7,6,9,9,9,9,11,13,13,13}; static const char MCBPC_P_CBPC[25][2] = {{0,0},{0,1},{1,0},{1,1}, {0,0},{0,1},{1,0},{1,1}, {0,0},{0,1},{1,0},{1,1}, {0,0},{0,1},{1,0},{1,1}, {0,0},{0,1},{1,0},{1,1}, {0,0}, {0,0},{0,1},{1,0},{1,1}}; // CBPY --- static const WebRtc_Word32 CBPY_MAX_CODE_LENGTH = 1; static const WebRtc_Word32 CBPY_TABLE_LENGTH = 16; static const WebRtc_UWord8 CBPY_CODE[16][1] = {{0x30}, //0011 {0x28}, //0010 1 {0x20}, //0010 0 {0x90}, //1001 {0x18}, //0001 1 {0x70}, //0111 {0x08}, //0000 10 {0xB0}, //1011 {0x10}, //0001 0 {0x0C}, //0000 11 {0x50}, //0101 {0xA0}, //1010 {0x40}, //0100 {0x80}, //1000 {0x60}, //0110 {0xC0}}; //11 static const WebRtc_UWord8 CBPY_MASK[16][1] = {{0xF0}, //0011 {0xF8}, //0010 1 {0xF8}, //0010 0 {0xF0}, //1001 {0xF8}, //0001 1 {0xF0}, //0111 {0xFC}, //0000 10 {0xF0}, //1011 {0xF8}, //0001 0 {0xFC}, //0000 11 {0xF0}, //0101 {0xF0}, //1010 {0xF0}, //0100 {0xF0}, //1000 {0xF0}, //0110 {0xC0}}; //11 static const WebRtc_Word32 CBPY_SIZE[16] = {4,5,5,4,5,4,6,4,5,6,4,4,4,4,4,2}; static const char CBPY_CBPY[16][4] = {{0,0,0,0},{0,0,0,1},{0,0,1,0},{0,0,1,1}, {0,1,0,0},{0,1,0,1},{0,1,1,0},{0,1,1,1}, {1,0,0,0},{1,0,0,1},{1,0,1,0},{1,0,1,1}, {1,1,0,0},{1,1,0,1},{1,1,1,0},{1,1,1,1}}; // MVD --- static const WebRtc_Word32 MVD_MAX_CODE_LENGTH = 2; static const WebRtc_Word32 MVD_TABLE_LENGTH = 64; static const WebRtc_UWord8 MVD_CODE[64][2] = {{0x00,0x28}, //0000 0000 0010 1 {0x00,0x38}, //0000 0000 0011 1 {0x00,0x50}, //0000 0000 0101 {0x00,0x70}, //0000 0000 0111 {0x00,0x90}, //0000 0000 1001 {0x00,0xB0}, //0000 0000 1011 {0x00,0xD0}, //0000 0000 1101 {0x00,0xF0}, //0000 0000 1111 {0x01,0x20}, //0000 0001 001 {0x01,0x60}, //0000 0001 011 {0x01,0xA0}, //0000 0001 101 {0x01,0xE0}, //0000 0001 111 {0x02,0x20}, //0000 0010 001 {0x02,0x60}, //0000 0010 011 {0x02,0xA0}, //0000 0010 101 {0x02,0xE0}, //0000 0010 111 {0x03,0x20}, //0000 0011 001 {0x03,0x60}, //0000 0011 011 {0x03,0xA0}, //0000 0011 101 {0x03,0xE0}, //0000 0011 111 {0x04,0x20}, //0000 0100 001 {0x04,0x60}, //0000 0100 011 {0x04,0xC0}, //0000 0100 11 {0x05,0x40}, //0000 0101 01 {0x05,0xC0}, //0000 0101 11 {0x07,0x00}, //0000 0111 {0x09,0x00}, //0000 1001 {0x0B,0x00}, //0000 1011 {0x0E,0x00}, //0000 111 {0x18,0x00}, //0001 1 {0x30,0x00}, //0011 {0x60,0x00}, //011 {0x80,0x00}, //1 {0x40,0x00}, //010 {0x20,0x00}, //0010 {0x10,0x00}, //0001 0 {0x0C,0x00}, //0000 110 {0x0A,0x00}, //0000 1010 {0x08,0x00}, //0000 1000 {0x06,0x00}, //0000 0110 {0x05,0x80}, //0000 0101 10 {0x05,0x00}, //0000 0101 00 {0x04,0x80}, //0000 0100 10 {0x04,0x40}, //0000 0100 010 {0x04,0x00}, //0000 0100 000 {0x03,0xC0}, //0000 0011 110 {0x03,0x80}, //0000 0011 100 {0x03,0x40}, //0000 0011 010 {0x03,0x00}, //0000 0011 000 {0x02,0xC0}, //0000 0010 110 {0x02,0x80}, //0000 0010 100 {0x02,0x40}, //0000 0010 010 {0x02,0x00}, //0000 0010 000 {0x01,0xC0}, //0000 0001 110 {0x01,0x80}, //0000 0001 100 {0x01,0x40}, //0000 0001 010 {0x01,0x00}, //0000 0001 000 {0x00,0xE0}, //0000 0000 1110 {0x00,0xC0}, //0000 0000 1100 {0x00,0xA0}, //0000 0000 1010 {0x00,0x80}, //0000 0000 1000 {0x00,0x60}, //0000 0000 0110 {0x00,0x40}, //0000 0000 0100 {0x00,0x30}}; //0000 0000 0011 0 static const WebRtc_UWord8 MVD_MASK[64][2] = {{0xFF,0xF8}, //0000 0000 0010 1 {0xFF,0xF8}, //0000 0000 0011 1 {0xFF,0xF0}, //0000 0000 0101 {0xFF,0xF0}, //0000 0000 0111 {0xFF,0xF0}, //0000 0000 1001 {0xFF,0xF0}, //0000 0000 1011 {0xFF,0xF0}, //0000 0000 1101 {0xFF,0xF0}, //0000 0000 1111 {0xFF,0xE0}, //0000 0001 001 {0xFF,0xE0}, //0000 0001 011 {0xFF,0xE0}, //0000 0001 101 {0xFF,0xE0}, //0000 0001 111 {0xFF,0xE0}, //0000 0010 001 {0xFF,0xE0}, //0000 0010 011 {0xFF,0xE0}, //0000 0010 101 {0xFF,0xE0}, //0000 0010 111 {0xFF,0xE0}, //0000 0011 001 {0xFF,0xE0}, //0000 0011 011 {0xFF,0xE0}, //0000 0011 101 {0xFF,0xE0}, //0000 0011 111 {0xFF,0xE0}, //0000 0100 001 {0xFF,0xE0}, //0000 0100 011 {0xFF,0xC0}, //0000 0100 11 {0xFF,0xC0}, //0000 0101 01 {0xFF,0xC0}, //0000 0101 11 {0xFF,0x00}, //0000 0111 {0xFF,0x00}, //0000 1001 {0xFF,0x00}, //0000 1011 {0xFE,0x00}, //0000 111 {0xF8,0x00}, //0001 1 {0xF0,0x00}, //0011 {0xE0,0x00}, //011 {0x80,0x00}, //1 {0xE0,0x00}, //010 {0xF0,0x00}, //0010 {0xF8,0x00}, //0001 0 {0xFE,0x00}, //0000 110 {0xFF,0x00}, //0000 1010 {0xFF,0x00}, //0000 1000 {0xFF,0x00}, //0000 0110 {0xFF,0xC0}, //0000 0101 10 {0xFF,0xC0}, //0000 0101 00 {0xFF,0xC0}, //0000 0100 10 {0xFF,0xE0}, //0000 0100 010 {0xFF,0xE0}, //0000 0100 000 {0xFF,0xE0}, //0000 0011 110 {0xFF,0xE0}, //0000 0011 100 {0xFF,0xE0}, //0000 0011 010 {0xFF,0xE0}, //0000 0011 000 {0xFF,0xE0}, //0000 0010 110 {0xFF,0xE0}, //0000 0010 100 {0xFF,0xE0}, //0000 0010 010 {0xFF,0xE0}, //0000 0010 000 {0xFF,0xE0}, //0000 0001 110 {0xFF,0xE0}, //0000 0001 100 {0xFF,0xE0}, //0000 0001 010 {0xFF,0xE0}, //0000 0001 000 {0xFF,0xF0}, //0000 0000 1110 {0xFF,0xF0}, //0000 0000 1100 {0xFF,0xF0}, //0000 0000 1010 {0xFF,0xF0}, //0000 0000 1000 {0xFF,0xF0}, //0000 0000 0110 {0xFF,0xF0}, //0000 0000 0100 {0xFF,0xF8}}; //0000 0000 0011 0 static const WebRtc_Word32 MVD_SIZE[64] = {13,13,12,12,12,12,12,12,11,11,11,11,11,11,11,11,11,11,11,11, 11,11,10,10,10, 8, 8, 8, 7, 5, 4, 3, 1, 3, 4, 5, 7, 8, 8, 8, 10,10,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12, 12,12,12,13}; // TCOEF --- static const WebRtc_Word32 TCOEF_MAX_CODE_LENGTH = 2; static const WebRtc_Word32 TCOEF_TABLE_LENGTH = 103; static const WebRtc_UWord8 TCOEF_CODE[103][2] = {{0x80,0x00}, //10s {0xF0,0x00}, //1111s {0x54,0x00}, //0101 01s {0x2E,0x00}, //0010 111s {0x1F,0x00}, //0001 1111s {0x12,0x80}, //0001 0010 1s {0x12,0x00}, //0001 0010 0s {0x08,0x40}, //0000 1000 01s {0x08,0x00}, //0000 1000 00s {0x00,0xE0}, //0000 0000 111s {0x00,0xC0}, //0000 0000 110s {0x04,0x00}, //0000 0100 000s {0xC0,0x00}, //110s {0x50,0x00}, //0101 00s {0x1E,0x00}, //0001 1110s {0x03,0xC0}, //0000 0011 11s {0x04,0x20}, //0000 0100 001s {0x05,0x00}, //0000 0101 0000s {0xE0,0x00}, //1110s {0x1D,0x00}, //0001 1101s {0x03,0x80}, //0000 0011 10s {0x05,0x10}, //0000 0101 0001s {0x68,0x00}, //0110 1s {0x11,0x80}, //0001 0001 1s {0x03,0x40}, //0000 0011 01s {0x60,0x00}, //0110 0s {0x11,0x00}, //0001 0001 0s {0x05,0x20}, //0000 0101 0010s {0x58,0x00}, //0101 1s {0x03,0x00}, //0000 0011 00s {0x05,0x30}, //0000 0101 0011s {0x4C,0x00}, //0100 11s {0x02,0xC0}, //0000 0010 11s {0x05,0x40}, //0000 0101 0100s {0x48,0x00}, //0100 10s {0x02,0x80}, //0000 0010 10s {0x44,0x00}, //0100 01s {0x02,0x40}, //0000 0010 01s {0x40,0x00}, //0100 00s {0x02,0x00}, //0000 0010 00s {0x2C,0x00}, //0010 110s {0x05,0x50}, //0000 0101 0101s {0x2A,0x00}, //0010 101s {0x28,0x00}, //0010 100s {0x1C,0x00}, //0001 1100s {0x1B,0x00}, //0001 1011s {0x10,0x80}, //0001 0000 1s {0x10,0x00}, //0001 0000 0s {0x0F,0x80}, //0000 1111 1s {0x0F,0x00}, //0000 1111 0s {0x0E,0x80}, //0000 1110 1s {0x0E,0x00}, //0000 1110 0s {0x0D,0x80}, //0000 1101 1s {0x0D,0x00}, //0000 1101 0s {0x04,0x40}, //0000 0100 010s {0x04,0x60}, //0000 0100 011s {0x05,0x60}, //0000 0101 0110s {0x05,0x70}, //0000 0101 0111s {0x70,0x00}, //0111s //last=1 --------------------- {0x0C,0x80}, //0000 1100 1s {0x00,0xA0}, //0000 0000 101s {0x3C,0x00}, //0011 11s {0x00,0x80}, //0000 0000 100s {0x38,0x00}, //0011 10s {0x34,0x00}, //0011 01s {0x30,0x00}, //0011 00s {0x26,0x00}, //0010 011s {0x24,0x00}, //0010 010s {0x22,0x00}, //0010 001s {0x20,0x00}, //0010 000s {0x1A,0x00}, //0001 1010s {0x19,0x00}, //0001 1001s {0x18,0x00}, //0001 1000s {0x17,0x00}, //0001 0111s {0x16,0x00}, //0001 0110s {0x15,0x00}, //0001 0101s {0x14,0x00}, //0001 0100s {0x13,0x00}, //0001 0011s {0x0C,0x00}, //0000 1100 0s {0x0B,0x80}, //0000 1011 1s {0x0B,0x00}, //0000 1011 0s {0x0A,0x80}, //0000 1010 1s {0x0A,0x00}, //0000 1010 0s {0x09,0x80}, //0000 1001 1s {0x09,0x00}, //0000 1001 0s {0x08,0x80}, //0000 1000 1s {0x01,0xC0}, //0000 0001 11s {0x01,0x80}, //0000 0001 10s {0x01,0x40}, //0000 0001 01s {0x01,0x00}, //0000 0001 00s {0x04,0x80}, //0000 0100 100s {0x04,0xA0}, //0000 0100 101s {0x04,0xC0}, //0000 0100 110s {0x04,0xE0}, //0000 0100 111s {0x05,0x80}, //0000 0101 1000s {0x05,0x90}, //0000 0101 1001s {0x05,0xA0}, //0000 0101 1010s {0x05,0xB0}, //0000 0101 1011s {0x05,0xC0}, //0000 0101 1100s {0x05,0xD0}, //0000 0101 1101s {0x05,0xE0}, //0000 0101 1110s {0x05,0xF0}, //0000 0101 1111s {0x06,0x00}}; //0000 011 (escape) static const WebRtc_UWord8 TCOEF_MASK[103][2] = {{0xC0,0x00}, //10s {0xF0,0x00}, //1111s {0xFC,0x00}, //0101 01s {0xFE,0x00}, //0010 111s {0xFF,0x00}, //0001 1111s {0xFF,0x80}, //0001 0010 1s {0xFF,0x80}, //0001 0010 0s {0xFF,0xC0}, //0000 1000 01s {0xFF,0xC0}, //0000 1000 00s {0xFF,0xE0}, //0000 0000 111s {0xFF,0xE0}, //0000 0000 110s {0xFF,0xE0}, //0000 0100 000s {0xE0,0x00}, //110s {0xFC,0x00}, //0101 00s {0xFF,0x00}, //0001 1110s {0xFF,0xC0}, //0000 0011 11s {0xFF,0xE0}, //0000 0100 001s {0xFF,0xF0}, //0000 0101 0000s {0xF0,0x00}, //1110s {0xFF,0x00}, //0001 1101s {0xFF,0xC0}, //0000 0011 10s {0xFF,0xF0}, //0000 0101 0001s {0xF8,0x00}, //0110 1s {0xFF,0x80}, //0001 0001 1s {0xFF,0xC0}, //0000 0011 01s {0xF8,0x00}, //0110 0s {0xFF,0x80}, //0001 0001 0s {0xFF,0xF0}, //0000 0101 0010s {0xF8,0x00}, //0101 1s {0xFF,0xC0}, //0000 0011 00s {0xFF,0xF0}, //0000 0101 0011s {0xFC,0x00}, //0100 11s {0xFF,0xC0}, //0000 0010 11s {0xFF,0xF0}, //0000 0101 0100s {0xFC,0x00}, //0100 10s {0xFF,0xC0}, //0000 0010 10s {0xFC,0x00}, //0100 01s {0xFF,0xC0}, //0000 0010 01s {0xFC,0x00}, //0100 00s {0xFF,0xC0}, //0000 0010 00s {0xFE,0x00}, //0010 110s {0xFF,0xF0}, //0000 0101 0101s {0xFE,0x00}, //0010 101s {0xFE,0x00}, //0010 100s {0xFF,0x00}, //0001 1100s {0xFF,0x00}, //0001 1011s {0xFF,0x80}, //0001 0000 1s {0xFF,0x80}, //0001 0000 0s {0xFF,0x80}, //0000 1111 1s {0xFF,0x80}, //0000 1111 0s {0xFF,0x80}, //0000 1110 1s {0xFF,0x80}, //0000 1110 0s {0xFF,0x80}, //0000 1101 1s {0xFF,0x80}, //0000 1101 0s {0xFF,0xE0}, //0000 0100 010s {0xFF,0xE0}, //0000 0100 011s {0xFF,0xF0}, //0000 0101 0110s {0xFF,0xF0}, //0000 0101 0111s {0xF0,0x00}, //0111s //last=1 ---- {0xFF,0x80}, //0000 1100 1s {0xFF,0xE0}, //0000 0000 101s {0xFC,0x00}, //0011 11s {0xFF,0xE0}, //0000 0000 100s {0xFC,0x00}, //0011 10s {0xFC,0x00}, //0011 01s {0xFC,0x00}, //0011 00s {0xFE,0x00}, //0010 011s {0xFE,0x00}, //0010 010s {0xFE,0x00}, //0010 001s {0xFE,0x00}, //0010 000s {0xFF,0x00}, //0001 1010s {0xFF,0x00}, //0001 1001s {0xFF,0x00}, //0001 1000s {0xFF,0x00}, //0001 0111s {0xFF,0x00}, //0001 0110s {0xFF,0x00}, //0001 0101s {0xFF,0x00}, //0001 0100s {0xFF,0x00}, //0001 0011s {0xFF,0x80}, //0000 1100 0s {0xFF,0x80}, //0000 1011 1s {0xFF,0x80}, //0000 1011 0s {0xFF,0x80}, //0000 1010 1s {0xFF,0x80}, //0000 1010 0s {0xFF,0x80}, //0000 1001 1s {0xFF,0x80}, //0000 1001 0s {0xFF,0x80}, //0000 1000 1s {0xFF,0xC0}, //0000 0001 11s {0xFF,0xC0}, //0000 0001 10s {0xFF,0xC0}, //0000 0001 01s {0xFF,0xC0}, //0000 0001 00s {0xFF,0xE0}, //0000 0100 100s {0xFF,0xE0}, //0000 0100 101s {0xFF,0xE0}, //0000 0100 110s {0xFF,0xE0}, //0000 0100 111s {0xFF,0xF0}, //0000 0101 1000s {0xFF,0xF0}, //0000 0101 1001s {0xFF,0xF0}, //0000 0101 1010s {0xFF,0xF0}, //0000 0101 1011s {0xFF,0xF0}, //0000 0101 1100s {0xFF,0xF0}, //0000 0101 1101s {0xFF,0xF0}, //0000 0101 1110s {0xFF,0xF0}, //0000 0101 1111s {0xFE,0x00}}; //0000 011 (escape) static const WebRtc_Word32 TCOEF_SIZE[103] = { 3, 5, 7, 8, 9,10,10,11,11,12,12,12, 4, 7, 9,11,12,13, 5, 9, 11,13, 6,10,11, 6,10,13, 6,11,13, 7,11,13, 7,11, 7,11, 7,11, 8,13, 8, 8, 9, 9,10,10,10,10,10,10,10,10,12,12,13,13, 5,10, 12, 7,12, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9,10,10, 10,10,10,10,10,10,11,11,11,11,12,12,12,12,13,13,13,13,13,13, 13,13, 8}; static const char TCOEF_LAST[103] = {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,0, 0,0,0,0,0,0,0,0,1,1, 1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1, 1,1,0}; // -------------------------------------- // -------------------------------------- // -------------------------------------- WebRtc_Word32 H263Info::CalculateMBOffset(const WebRtc_UWord8 numOfGOB) const { // calculate the number of MBs before this GOB // sanity if( numOfGOBs < numOfGOB) { assert(false); return -1; } WebRtc_Word32 numMBs = 0; for(WebRtc_UWord8 GOB = 0; GOB< numOfGOB; GOB++) { numMBs += ptrNumOfMBs[GOB]; } return numMBs; } H263Information::H263Information() { } H263Information::~H263Information() { _infoMB.bufferSize = 0; if (_infoMB.ptrBuffer) { delete [] _infoMB.ptrBuffer; delete [] _infoMB.ptrBufferHMV; delete [] _infoMB.ptrBufferVMV; _infoMB.ptrBuffer = 0; _infoMB.ptrBufferHMV = 0; _infoMB.ptrBufferVMV = 0; } } void H263Information::Reset() { _info.uiH263PTypeFmt = 0; _info.codecBits = 0; _info.pQuant = 0; _info.numOfGOBs = 0; _info.cpmBit = 0; _info.fType = 0; memset(_info.ptrGOBbuffer, 0, sizeof(_info.ptrGOBbuffer)); memset(_info.ptrGOBbufferSBit, 0, sizeof(_info.ptrGOBbufferSBit)); memset(_info.ptrGQuant, 0, sizeof(_info.ptrGQuant)); memset(_info.ptrNumOfMBs, 0, sizeof(_info.ptrNumOfMBs)); memset(_info.ptrGroupNum, 0, sizeof(_info.ptrGroupNum)); if (_infoMB.ptrBuffer) { memset(_infoMB.ptrBuffer, 0, sizeof(WebRtc_UWord32) * _infoMB.bufferSize); memset(_infoMB.ptrBufferHMV, 0, sizeof(WebRtc_UWord8) * _infoMB.bufferSize); memset(_infoMB.ptrBufferVMV, 0, sizeof(WebRtc_UWord8) * _infoMB.bufferSize); } } /******************************************************************************* * WebRtc_Word32 GetInfo(const WebRtc_UWord8* ptrEncodedBuffer, * const WebRtc_UWord32 length, * const H263Info*& ptrInfo); * * Gets information from an encoded stream. * * Input: * - ptrEncodedBuffer : Pointer to encoded stream. * - length : Length in bytes of encoded stream. * * Output: * - ptrInfo : Pointer to struct with H263 info. * * Return value: * - 0 : ok * - (-1) : Error */ WebRtc_Word32 H263Information::GetInfo(const WebRtc_UWord8* ptrEncodedBuffer, const WebRtc_UWord32 length, const H263Info*& ptrInfo) { if (!ptrEncodedBuffer || length < 8) { return -1; } if (!HasInfo(length)) { if (-1 == FindInfo(ptrEncodedBuffer, length)) { Reset(); return -1; } } ptrInfo = &_info; return 0; } RtpVideoCodecTypes H263Information::Type() { return kRtpH263Video; } /******************************************************************************* * WebRtc_Word32 GetMBInfo(const WebRtc_UWord8* ptrEncodedBuffer, * const WebRtc_UWord32 length, * WebRtc_Word32 numOfGOB, * const H263MBInfo*& ptrInfoMB); * * Gets macroblock positions for a GOB. * Also, the horizontal and vertical motion vector for each MB are returned. * * Input: * - ptrEncodedBuffer : Pointer to encoded stream. * - length : Length in bytes of encoded stream. * - numOfGOB : Group number of current GOB. * * Output: * - infoMB : Pointer to struct with MB positions in bits for a GOB. * Horizontal and vertical motion vector for each MB. * * Return value: * - 0 : ok * - (-1) : Error */ WebRtc_Word32 H263Information::GetMBInfo(const WebRtc_UWord8* ptrEncodedBuffer, const WebRtc_UWord32 length, const WebRtc_UWord8 numOfGOB, const H263MBInfo*& ptrInfoMB) { if (!ptrEncodedBuffer || numOfGOB > _info.numOfGOBs - 1) { return -1; } if (-1 == VerifyAndAllocateMB()) { return -1; } if (length != _info.ptrGOBbuffer[_info.numOfGOBs]) { return -1; } if (!HasMBInfo(numOfGOB)) { if (-1 == FindMBs(ptrEncodedBuffer, numOfGOB, length)) { Reset(); return -1; } } ptrInfoMB = &_infoMB; return 0; } bool H263Information::HasInfo(const WebRtc_UWord32 length) { if (!_info.ptrGOBbuffer) { return false; } if (_info.ptrGOBbuffer[0] == 0) { return false; } // has info, make sure current length matches info length if (length != _info.ptrGOBbuffer[_info.numOfGOBs - 1]) { Reset(); return false; } return true; } WebRtc_Word32 H263Information::FindInfo(const WebRtc_UWord8* ptrEncodedBuffer, const WebRtc_UWord32 length) { _ptrData = ptrEncodedBuffer; if (!PictureStartCode()) { return -1; } // Gets picture size if (-1 == FindPTypeFMT()) { return -1; } FindFType(); FindCodecBits(); FindPQUANT(); FindCPMbit(); if (-1 == FindGOBs(length)) { return -1; } if (-1 == SetNumOfMBs()) { return -1; } return 0; } WebRtc_Word32 H263Information::SetNumOfMBs() { // Source format: 000 - forbidden // 001 - SQCIF 1 GOB - one macroblock row // 010 - QCIF 1 GOB - one macroblock row // 011 - CIF 1 GOB - one macroblock row // 100 - 4CIF 1 GOB - two macroblock rows // 101 - 16CIF 1 GOB - four macroblock rows // 110 - reserved // 111 - extended PTYPE WebRtc_UWord16 numOfMBsPerGOB = 0; switch (_info.uiH263PTypeFmt) { case 1: // SQCIF numOfMBsPerGOB = 8; _info.totalNumOfMBs = 8 * 6; //128x96 break; case 2: // QCIF numOfMBsPerGOB = 11; _info.totalNumOfMBs = 11 * 9; break; case 3: // CIF numOfMBsPerGOB = 22; _info.totalNumOfMBs = 22 * 18; break; case 4: // 4CIF numOfMBsPerGOB = 88; _info.totalNumOfMBs = 88 * 18; break; case 5: // 16CIF numOfMBsPerGOB = 352; _info.totalNumOfMBs = 352 * 18; break; default: return -1; } // loop through all GOBs WebRtc_UWord16 numberOfMBs = 0; for(WebRtc_UWord8 GOB = 0; GOB < (_info.numOfGOBs -1); GOB++) { _info.ptrNumOfMBs[GOB] = numOfMBsPerGOB * (_info.ptrGroupNum[GOB+1] - _info.ptrGroupNum[GOB]); numberOfMBs += _info.ptrNumOfMBs[GOB]; } _info.ptrNumOfMBs[_info.numOfGOBs -1] = _info.totalNumOfMBs - numberOfMBs; return 0; } bool H263Information::PictureStartCode() { // Picture start code (PSC) (22 bits) // ----0--------1-------2---- // |00000000|00000000|100000xx| // -------------------------- if ( _ptrData[0] == 0 && _ptrData[1] == 0 && (_ptrData[2] & 0x80) && (_ptrData[2] & 0x7C) == 0) { return true; } return false; } WebRtc_Word32 H263Information::FindPTypeFMT() { // Type Information (PTYPE) (Variable Length)(8/13 bits) // ----3--------4--------5--- // |xxxxxxPP|PPPPPPpp|pppxxxxx| // -------------------------- // Source format (bits 6-8) _info.uiH263PTypeFmt = (_ptrData[4] >> 2) & 0x07; return 0; } void H263Information::FindFType() { // Type Information (PTYPE) (13 bits, source format != 111, not extended PTYPE) // ----3--------4--------5--- // |xxxxxxPP|PPPPPPPP|PPPxxxxx| // -------------------------- // Picture coding type (bit 9) _info.fType = (_ptrData[4] & 0x02) >> 1; // 0 = I-frame, 1 = P-frame } void H263Information::FindCodecBits() { // Type Information (PTYPE) (13 bits) // ----3--------4--------5--- // |xxxxxxPP|PPPPPPPP|PPPxxxxx| // -------------------------- // Bits 9-12 // bit 10: Unrestricted Motion Vector mode (annex D) 0-off, 1-on _info.codecBits = (_ptrData[4] & 0x03) << 2; // bit 11: Syntax-based Arithmetic Coding mode (annex E) _info.codecBits += (_ptrData[5] & 0xC0) >> 6; // bit 12: Advanced Prediction mode (annex F) } void H263Information::FindPQUANT() { // Quantizer Information (PQUANT) (5 bits) // ----5--- // |xxxQQQQQ| // -------- _info.pQuant = _ptrData[5] & 0x1F; } void H263Information::FindCPMbit() { // Continuous presence multipoWebRtc_Word32 and Video multiplex (CPM) (1 bit) // ----6--- // |Cxxxxxxx| // -------- _info.cpmBit = IsBitOne(48); // 0-off, 1-on } WebRtc_Word32 H263Information::FindGOBs(const WebRtc_UWord32 length) { // Group of block layer (GOB). // GOB header followed by data for (one or more rows) of macroblocks. // Stuffing (GSTUF) (Variable length) consisting of less than 8 zero-bits. May be // inserted by encoders so that the start of the GBSC is byte aligned. // Group of block start code (GBSC) (17 bits). May be byte aligned. // Group Number (GN) (5 bits). Group numbers 1-17 used for standard picture formats. // 0 used in PSC. // -------------------------------- // |GSTUF|00000000|00000000|1GGGGGxx| // -------------------------------- WebRtc_UWord8 numOfGOB = 0; WebRtc_UWord8 groupNum = 0; WebRtc_UWord8 sBit = 0; _info.ptrGroupNum[numOfGOB] = 0; _info.ptrGOBbuffer[numOfGOB] = 0; _info.ptrGOBbufferSBit[numOfGOB] = 0; numOfGOB++; for (WebRtc_UWord32 i = 3; (i < length - 2); i++) { if (_ptrData[i] == 0) { if (_ptrData[i + 1] == 0) { if (_ptrData[i + 2] & 0x80) { // GBSC byte aligned groupNum = (_ptrData[i + 2] >> 2) & 0x1f; _info.ptrGroupNum[numOfGOB] = groupNum; _info.ptrGOBbuffer[numOfGOB] = i; _info.ptrGOBbufferSBit[numOfGOB] = 0; numOfGOB++; } }else { // check for non byte aligned GBSC if ((_ptrData[i - 1] & 0x7F) == 0 && (_ptrData[i + 1] & 0xC0) == 0x40) { // |x0000000|00000000|01GGGGGx| sBit = 1; groupNum = (_ptrData[i + 1] >> 1) & 0x1f; } else if ((_ptrData[i - 1] & 0x3F) == 0 && (_ptrData[i + 1] & 0xE0) == 0x20) { // |xx000000|00000000|001GGGGG| sBit = 2; groupNum = (_ptrData[i + 1]) & 0x1f; } else if ((_ptrData[i - 1] & 0x1F) == 0 && (_ptrData[i + 1] & 0xF0) == 0x10) { // |xxx00000|00000000|0001GGGG|G sBit = 3; groupNum = ((_ptrData[i + 1] & 0x0F) << 1) | ((_ptrData[i + 2] >> 7) & 0x01); } else if ((_ptrData[i - 1] & 0x0F) == 0 && (_ptrData[i + 1] & 0xF8) == 0x08) { // |xxxx0000|00000000|00001GGG|GG sBit = 4; groupNum = ((_ptrData[i + 1] & 0x07) << 2) | ((_ptrData[i + 2] >> 6) & 0x03); } else if ((_ptrData[i - 1] & 0x07) == 0 && (_ptrData[i + 1] & 0xFC) == 0x04) { // |xxxxx000|00000000|000001GG|GGG sBit = 5; groupNum = ((_ptrData[i + 1] & 0x03) << 3) | ((_ptrData[i + 2] >> 5) & 0x07); } else if ((_ptrData[i - 1] & 0x03) == 0 && (_ptrData[i + 1] & 0xFE) == 0x02) { // |xxxxxx00|00000000|0000001G|GGGG sBit = 6; groupNum = ((_ptrData[i + 1] & 0x01) << 4) | ((_ptrData[i + 2] >> 4) & 0x0F); } else if ((_ptrData[i - 1] & 0x01) == 0 && _ptrData[i + 1] == 0x01) { // |xxxxxxx0|00000000|00000001|GGGGG sBit = 7; groupNum = (_ptrData[i + 2] >> 3) & 0x1f; } else { sBit = 0; groupNum = 0; } if (sBit) { _info.ptrGroupNum[numOfGOB] = groupNum; _info.ptrGOBbuffer[numOfGOB] = i - 1; _info.ptrGOBbufferSBit[numOfGOB] = sBit; numOfGOB++; } } if(numOfGOB >= MAX_NUMBER_OF_H263_GOB) { return -1; } } } _info.numOfGOBs = numOfGOB; _info.ptrGOBbuffer[numOfGOB] = length; _info.ptrGOBbufferSBit[numOfGOB] = 0; return 0; } WebRtc_Word32 H263Information::VerifyAndAllocateMB() { WebRtc_UWord32 minimumSize = _info.totalNumOfMBs; if (minimumSize == 0) { return -1; } if (minimumSize > _infoMB.bufferSize) { // make sure that our buffer is big enough if (_infoMB.ptrBuffer) { delete [] _infoMB.ptrBuffer; delete [] _infoMB.ptrBufferHMV; delete [] _infoMB.ptrBufferVMV; } _infoMB.ptrBuffer = new WebRtc_UWord32[minimumSize]; _infoMB.ptrBufferHMV = new WebRtc_UWord8[minimumSize]; _infoMB.ptrBufferVMV = new WebRtc_UWord8[minimumSize]; _infoMB.bufferSize = minimumSize; // reset memory memset(_infoMB.ptrBuffer, 0, sizeof(WebRtc_UWord32) * _infoMB.bufferSize); memset(_infoMB.ptrBufferHMV, 0, sizeof(WebRtc_UWord8) * _infoMB.bufferSize); memset(_infoMB.ptrBufferVMV, 0, sizeof(WebRtc_UWord8) * _infoMB.bufferSize); } return 0; } bool H263Information::HasMBInfo(const WebRtc_UWord8 numOfGOB) { if (!_infoMB.ptrBuffer) { return false; } WebRtc_Word32 offset = _info.CalculateMBOffset(numOfGOB); if (_infoMB.ptrBuffer[offset] == 0) { return false; } return true; } WebRtc_Word32 H263Information::FindMBs(const WebRtc_UWord8 *ptrEncodedBuffer, const WebRtc_UWord8 numOfGOB, const WebRtc_UWord32 length) { _bitCnt = 0; WebRtc_Word32 bitCntOffset = 0; _ptrData = ptrEncodedBuffer; WebRtc_UWord32 payloadBytesToSend = length; if (numOfGOB > 0) { // Point at current GOB _ptrData += _info.ptrGOBbuffer[numOfGOB ]; payloadBytesToSend -= _info.ptrGOBbuffer[numOfGOB]; // Start bits to ignore _bitCnt += _info.ptrGOBbufferSBit[numOfGOB]; // Byte with start bits has already been sent, start counting from next byte if (_info.ptrGOBbufferSBit[numOfGOB]) { bitCntOffset = 8; } } WebRtc_Word32 offset = _info.CalculateMBOffset(numOfGOB); WebRtc_UWord32 *sizeOfMBs = &_infoMB.ptrBuffer[offset]; WebRtc_UWord8 *hmv1 = &_infoMB.ptrBufferHMV[offset]; WebRtc_UWord8 *vmv1 = &_infoMB.ptrBufferVMV[offset]; // Header data if (numOfGOB == 0) { // Picture layer // ----------------------- // | Picture header | GOBs | // For GOB number 0, empty GOB header // ----------------------- _bitCnt = 49; if (_info.cpmBit) { _bitCnt += 2; } WebRtc_Word32 peiBit = IsBitOne(_bitCnt); _bitCnt++; if (peiBit) { _bitCnt += 8; peiBit = IsBitOne(_bitCnt); _bitCnt++; if (peiBit) { _bitCnt += 9; } } } else if (numOfGOB < _info.numOfGOBs) { // Group of block layer (GOB). // Group of block start code (GBSC) (17 bits). // Group Number (GN) (5 bits). // GOB Sub-Stream Indicator (GSBI) (2 bits). Only present if CPM = 1. // GOB Frame ID (GFID) (2 bits). // Quantizer Information (GQUANT) (5 bits). // ---------------------------------------------------- // | GBSC | GN | GSBI | GFID | GQUANT | Macroblock data | // ---------------------------------------------------- _bitCnt += 24; if (_info.cpmBit) { _bitCnt += 2; } FindGQUANT(numOfGOB); _bitCnt += 5; } else { return -1; } // Start of macroblock data // ----------------------- // | MB header | blockdata | // ----------------------- for (WebRtc_Word32 j = 0; j < _info.ptrNumOfMBs[numOfGOB]; j++) { // MB header // ------------------------------------------------ // | COD(inter) | MCBPC | CBPY | DQUANT |MVD(inter) | // ------------------------------------------------ WebRtc_Word32 codBit = 0; if (_info.fType) { codBit = IsBitOne(_bitCnt); _bitCnt++; } if (codBit == 0) // if codBit == 1, no further info transmitted for this MB { WebRtc_Word32 mbType = 0; char cbp[6]; // Get MB type & coded block pattern for chrominance (MCBPC) WebRtc_Word32 size = FindMCBPC(mbType, cbp); _bitCnt += size; if (size == -1) { return -1; } // Get coded block pattern for luminance (CBPY) size = FindCBPY(mbType, cbp); _bitCnt += size; if (size == -1) { return -1; } // Quantizer information (DQUANT), change in QUANT if (mbType == 1 || mbType == 4) { _bitCnt += 2; } // Get motion vector data (MVD) (inter-frames) if (_info.fType && (mbType < 3 || mbType == 5)) { // Horizontal and vertical component for (WebRtc_Word32 k = 0; k < 2; k++) { size = FindMVD(j, k, hmv1, vmv1); _bitCnt += size; if (size == -1) { return -1; } } } // Block data. 1MB = 6 blocks (4 luminance blocks + 2 color blocks) // ----------------- // | intraDC | TCOEF | // ----------------- WebRtc_Word32 numOfBlocks = 6; WebRtc_Word32 WebRtc_Word32raDC = 0; if (mbType == 3 || mbType == 4) { WebRtc_Word32raDC = 8; } for (WebRtc_Word32 i = 0; i < numOfBlocks; i++) { // Get WebRtc_Word32raDC coefficient _bitCnt += WebRtc_Word32raDC; // Get non-WebRtc_Word32RA dc coefficients if (cbp[i]) // presence indicated by CBPY and CBPC { WebRtc_Word32 last = 0; while (last == 0) { // Get transform coefficient (TCOEF) size = FindTCOEF(last); _bitCnt += size; if (size == -1) { return -1; } } } } // end of MB sizeOfMBs[j] = _bitCnt - bitCntOffset; } else { // end of MB sizeOfMBs[j] = _bitCnt - bitCntOffset; } } // end of MBs WebRtc_Word32 nextByte = _bitCnt >> 3; WebRtc_Word32 nextByteRem = _bitCnt % 8; if (nextByteRem) { nextByte++; } // Check for next GOB/end of picture if (numOfGOB < (_info.numOfGOBs - 1)) { // Test with GSTUF, GBSC (0000 0000 0000 0000 1) if (_ptrData[nextByte] == 0 && _ptrData[nextByte + 1] == 0 && _ptrData[nextByte + 2] & 0x80) { sizeOfMBs[_info.ptrNumOfMBs[numOfGOB] - 1] = (nextByte << 3) - bitCntOffset; return 1; // ok, next GOB } // ...without GSTUF if (IsGBSC()) { return 1; // ok, next GOB } } else if (numOfGOB == (_info.numOfGOBs - 1)) { // Picture end code may be included, (PSTUF (optional), EOS (22bits), ESTUF) if (((WebRtc_UWord32) nextByte == payloadBytesToSend) || ((WebRtc_UWord32)(nextByte + 2) == payloadBytesToSend) || ((WebRtc_UWord32)(nextByte + 3) == payloadBytesToSend)) { sizeOfMBs[_info.ptrNumOfMBs[numOfGOB] - 1] = (payloadBytesToSend << 3) - bitCntOffset; return 1; // ok, end of picture layer } } else { return -1; } return -1; } WebRtc_Word32 H263Information::FindMCBPC(WebRtc_Word32 &mbType, char *cbp) { if (_info.fType == 0) // intra frame { ByteAlignData(MCBPC_I_MAX_CODE_LENGTH); WebRtc_Word32 i; for (i = 0; i < MCBPC_I_TABLE_LENGTH - 1; i++) { if ((_dataShifted[0] & MCBPC_I_MASK[i][0]) == MCBPC_I_CODE[i][0]) { cbp[4] = MCBPC_I_CBPC[i][0]; cbp[5] = MCBPC_I_CBPC[i][1]; mbType = MCBPC_I_MBTYPE[i]; return MCBPC_I_SIZE[i]; } } // last row i = MCBPC_I_TABLE_LENGTH - 1; if ((_dataShifted[0] & MCBPC_I_MASK[i][0]) == MCBPC_I_CODE[i][0] && (_dataShifted[1] & MCBPC_I_MASK[i][1]) == MCBPC_I_CODE[i][1]) { cbp[4] = MCBPC_I_CBPC[i][0]; cbp[5] = MCBPC_I_CBPC[i][1]; mbType = MCBPC_I_MBTYPE[i]; return MCBPC_I_SIZE[i]; } return -1; } else // inter frame { ByteAlignData(MCBPC_P_MAX_CODE_LENGTH); for (WebRtc_Word32 i = 0; i < MCBPC_P_TABLE_LENGTH; i++) { if ((_dataShifted[0] & MCBPC_P_MASK[i][0]) == MCBPC_P_CODE[i][0] && (_dataShifted[1] & MCBPC_P_MASK[i][1]) == MCBPC_P_CODE[i][1]) { cbp[4] = MCBPC_P_CBPC[i][0]; cbp[5] = MCBPC_P_CBPC[i][1]; mbType = MCBPC_P_MBTYPE[i]; return MCBPC_P_SIZE[i]; } } } return -1; } WebRtc_Word32 H263Information::FindCBPY(WebRtc_Word32 mbType, char *cbp) { ByteAlignData(CBPY_MAX_CODE_LENGTH); for (WebRtc_Word32 i = 0; i < CBPY_TABLE_LENGTH; i++) { if ((_dataShifted[0] & CBPY_MASK[i][0]) == CBPY_CODE[i][0]) { cbp[0] = CBPY_CBPY[i][0]; cbp[1] = CBPY_CBPY[i][1]; cbp[2] = CBPY_CBPY[i][2]; cbp[3] = CBPY_CBPY[i][3]; if (mbType == 0 || mbType == 1) { for (WebRtc_Word32 k = 0; k < 4; k++) { if (cbp[k]) { cbp[k] = 0; } else { cbp[k] = 1; } } } return CBPY_SIZE[i]; } } return -1; } WebRtc_Word32 H263Information::FindMVD(WebRtc_Word32 numOfMB, WebRtc_Word32 verORhor, WebRtc_UWord8 *hmv1, WebRtc_UWord8 *vmv1) { ByteAlignData(MVD_MAX_CODE_LENGTH); for (WebRtc_Word32 i = 0; i < MVD_TABLE_LENGTH; i++) { if ((_dataShifted[0] & MVD_MASK[i][0]) == MVD_CODE[i][0] && (_dataShifted[1] & MVD_MASK[i][1]) == MVD_CODE[i][1]) { // Store horizontal/vertical motion vector predictor (2's complement number) WebRtc_Word32 index = i - 32; if (index < 0) { index = ~ (-index-1); } if (verORhor == 0) { hmv1[numOfMB] = static_cast(index); } else { vmv1[numOfMB] = static_cast(index); } return MVD_SIZE[i]; } } return -1; } WebRtc_Word32 H263Information::FindTCOEF(WebRtc_Word32 &last) { ByteAlignData(TCOEF_MAX_CODE_LENGTH); for (WebRtc_Word32 i = 0; i < TCOEF_TABLE_LENGTH; i++) { if ((_dataShifted[0] & TCOEF_MASK[i][0]) == TCOEF_CODE[i][0] && (_dataShifted[1] & TCOEF_MASK[i][1]) == TCOEF_CODE[i][1]) { last = TCOEF_LAST[i]; if (i == (TCOEF_TABLE_LENGTH - 1)) { if (IsBitOne(_bitCnt + 7)) { last = 1; } return 22; } return TCOEF_SIZE[i]; } } return -1; } bool H263Information::IsGBSC() { // Group of block layer (GOB). // Stuffing (GSTUF) (Variable length) consisting of less than 8 zero-bits. May be // inserted by encoders so that the start of the GBSC is byte aligned. // Group of block start code (GBSC) (17 bits). May be byte aligned. // Group Number (GN) (5 bits). Group numbers 1-17 used for standard picture formats. // -------------------------------- // |GSTUF|00000000|00000000|1GGGGGxx| // -------------------------------- ByteAlignData(3); if (_dataShifted[0] == 0 && _dataShifted[1] == 0 && (_dataShifted[2] & 0x80) == 0x80) { return true; } return false; } void H263Information::FindGQUANT(WebRtc_Word32 numOfGOB) { ByteAlignData(1); _info.ptrGQuant[numOfGOB] = (_dataShifted[0] >> 3) & 0x1F; } WebRtc_UWord8 H263Information::IsBitOne(const WebRtc_Word32 bitCnt) const { WebRtc_Word32 curByte = bitCnt >> 3; WebRtc_Word32 bit = bitCnt % 8; switch(bit) { case 0: return _ptrData[curByte] & 0x80; case 1: return _ptrData[curByte] & 0x40; case 2: return _ptrData[curByte] & 0x20; case 3: return _ptrData[curByte] & 0x10; case 4: return _ptrData[curByte] & 0x08; case 5: return _ptrData[curByte] & 0x04; case 6: return _ptrData[curByte] & 0x02; case 7: return _ptrData[curByte] & 0x01; default: return 0; } } void H263Information::ByteAlignData(WebRtc_Word32 numOfBytes) { WebRtc_Word32 sByte = _bitCnt >> 3; WebRtc_Word32 sBit = _bitCnt % 8; // Shift to byte align WebRtc_Word32 i = 0; do { _dataShifted[i] = _ptrData[sByte] << sBit; _dataShifted[i++] += _ptrData[++sByte] >> (8 - sBit); } while (i < numOfBytes); } } // namespace webrtc