| /* ------------------------------------------------------------------ |
| * Copyright (C) 1998-2009 PacketVideo |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either |
| * express or implied. |
| * See the License for the specific language governing permissions |
| * and limitations under the License. |
| * ------------------------------------------------------------------- |
| */ |
| #include "h223_api.h" |
| #include "h223.h" |
| const uint gMuxStuffingSz[] = {1, 2, 4, 5, 6, 0}; |
| const uint gMuxFlagSz[] = {1, 2, 4, 2, 2, 0}; |
| const uint gMaxStuffingSz[] = {3, 3, 5, 5, 6, 0}; |
| const uint8 gNumOnes[] = {0, 1, 1, 2, 1, 2, 2, 3, // 0 |
| 1, 2, 2, 3, 2, 3, 3, 4, // 8 |
| 1, 2, 2, 3, 2, 3, 3, 4, // 16 |
| 2, 3, 3, 4, 3, 4, 4, 5, // 24 |
| 1, 2, 2, 3, 2, 3, 3, 4, // 32 |
| 2, 3, 3, 4, 3, 4, 4, 5, // 40 |
| 2, 3, 3, 4, 3, 4, 4, 5, // 48 |
| 3, 4, 4, 5, 4, 5, 5, 6, // 56 |
| 1, 2, 2, 3, 2, 3, 3, 4, // 64 |
| 2, 3, 3, 4, 3, 4, 4, 5, // 72 |
| 2, 3, 3, 4, 3, 4, 4, 5, // 80 |
| 3, 4, 4, 5, 4, 5, 5, 6, // 88 |
| 2, 3, 3, 4, 3, 4, 4, 5, // 96 |
| 3, 4, 4, 5, 4, 5, 5, 6, // 104 |
| 3, 4, 4, 5, 4, 5, 5, 6, // 112 |
| 4, 5, 5, 6, 5, 6, 6, 7, // 120 |
| 1, 2, 2, 3, 2, 3, 3, 4, // 128 |
| 2, 3, 3, 4, 3, 4, 4, 5, // 136 |
| 2, 3, 3, 4, 3, 4, 4, 5, // 144 |
| 3, 4, 4, 5, 4, 5, 5, 6, // 152 |
| 2, 3, 3, 4, 3, 4, 4, 5, // 160 |
| 3, 4, 4, 5, 4, 5, 5, 6, // 168 |
| 3, 4, 4, 5, 4, 5, 5, 6, // 176 |
| 4, 5, 5, 6, 5, 6, 6, 7, // 184 |
| 2, 3, 3, 4, 3, 4, 4, 5, // 192 |
| 3, 4, 4, 5, 4, 5, 5, 6, // 200 |
| 3, 4, 4, 5, 4, 5, 5, 6, // 208 |
| 4, 5, 5, 6, 5, 6, 6, 7, // 216 |
| 3, 4, 4, 5, 4, 5, 5, 6, // 224 |
| 4, 5, 5, 6, 5, 6, 6, 7, // 232 |
| 4, 5, 5, 6, 5, 6, 6, 7, // 240 |
| 5, 6, 6, 7, 6, 7, 7, 8 |
| }; // 248 |
| |
| /* Delete this */ |
| OSCL_EXPORT_REF CPVH223Multiplex* AllocateH223Mux(TPVLoopbackMode aLoopbackMode) |
| { |
| return OSCL_NEW(CPVH223Multiplex, (aLoopbackMode)); |
| } |
| |
| OSCL_EXPORT_REF void DeallocateH223Mux(CPVH223Multiplex* h223mux) |
| { |
| OSCL_DELETE(h223mux); |
| } |
| |
| uint H223GetMuxStuffingSz(TPVH223Level flat_level) |
| { |
| return gMuxStuffingSz[flat_level]; |
| } |
| |
| uint H223GetMuxFlagSz(TPVH223Level flat_level) |
| { |
| return gMuxFlagSz[flat_level]; |
| } |
| |
| uint H223GetMaxStuffingSz(TPVH223Level flat_level) |
| { |
| return gMaxStuffingSz[flat_level]; |
| } |
| |
| uint H223MuxStuffing(TPVH223Level level, uint8* pPdu, uint bufSz) |
| { |
| int32 stuffing_size = (int32)H223GetMuxStuffingSz(level); |
| if (stuffing_size == 0) |
| return 0; |
| |
| int32 size_left = bufSz; |
| while (size_left >= stuffing_size) |
| { |
| switch (level) |
| { |
| case H223_LEVEL0: // level 0 |
| *(pPdu) = 0x7e; |
| break; |
| case H223_LEVEL1: // level 1 |
| case H223_LEVEL1_DF: // H223DoubleFlag == TRUE |
| *(pPdu) = 0xe1; |
| *(pPdu + 1) = 0x4d; |
| if (level == H223_LEVEL1) |
| break; |
| *(pPdu + 2) = 0xe1; |
| *(pPdu + 3) = 0x4d; |
| break; |
| case H223_LEVEL2: // level 2 |
| case H223_LEVEL2_OH: // H223OptionalHeader==1 |
| *(pPdu) = 0xe1; |
| *(pPdu + 1) = 0x4d; |
| *(pPdu + 2) = 0; |
| *(pPdu + 3) = 0; |
| *(pPdu + 4) = 0; |
| if (level == H223_LEVEL2) |
| break; |
| *(pPdu + 5) = 0; |
| break; |
| default: |
| return 0; |
| } |
| pPdu += stuffing_size; |
| size_left -= stuffing_size; |
| } |
| return (bufSz - size_left); |
| } |
| |
| bool H223CheckSync(TPVH223Level level, uint8* buf, uint bufSz, uint tolerance) |
| { |
| if (bufSz < H223GetMuxFlagSz(level)) |
| return false; |
| uint mismatch_cnt = 0; |
| switch (level) |
| { |
| case H223_LEVEL0: |
| mismatch_cnt = gNumOnes[(buf[0] ^ 0x7E)]; |
| break; |
| case H223_LEVEL1: |
| case H223_LEVEL1_DF: |
| mismatch_cnt = (uint16)(gNumOnes[(buf[0] ^ 0xE1)] + gNumOnes[(buf[1] ^ 0x4D)]); |
| if (level == H223_LEVEL1) |
| break; |
| mismatch_cnt += (uint16)(gNumOnes[(buf[2] ^ 0xE1)] + gNumOnes[(buf[3] ^ 0x4D)]); |
| break; |
| case H223_LEVEL2_OH: |
| if (bufSz >= 6) |
| mismatch_cnt = (uint16)(gNumOnes[buf[5]]); |
| case H223_LEVEL2: |
| mismatch_cnt += (uint16)(gNumOnes[(buf[0] ^ 0xE1)] + gNumOnes[(buf[1] ^ 0x4D)]); |
| if (bufSz >= 5) |
| { |
| mismatch_cnt += (uint16)(gNumOnes[buf[2]]); |
| mismatch_cnt += (uint16)(gNumOnes[buf[3]]); |
| mismatch_cnt += (uint16)(gNumOnes[buf[4]]); |
| } |
| break; |
| default: |
| return false; |
| } |
| return (mismatch_cnt <= tolerance); |
| } |