webrtc/modules/rtp_rtcp/source/h263_information.cc

1473 lines
69 KiB
C++

/*
* 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 <string.h>
#include <cassert>
#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<WebRtc_UWord8>(index);
} else
{
vmv1[numOfMB] = static_cast<WebRtc_UWord8>(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