1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13 * express or implied.
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
17 */
18 #include "h223_api.h"
19 #include "h223.h"
20 const uint gMuxStuffingSz[] = {1, 2, 4, 5, 6, 0};
21 const uint gMuxFlagSz[] = {1, 2, 4, 2, 2, 0};
22 const uint gMaxStuffingSz[] = {3, 3, 5, 5, 6, 0};
23 const uint8 gNumOnes[] = {0, 1, 1, 2, 1, 2, 2, 3, // 0
24 1, 2, 2, 3, 2, 3, 3, 4, // 8
25 1, 2, 2, 3, 2, 3, 3, 4, // 16
26 2, 3, 3, 4, 3, 4, 4, 5, // 24
27 1, 2, 2, 3, 2, 3, 3, 4, // 32
28 2, 3, 3, 4, 3, 4, 4, 5, // 40
29 2, 3, 3, 4, 3, 4, 4, 5, // 48
30 3, 4, 4, 5, 4, 5, 5, 6, // 56
31 1, 2, 2, 3, 2, 3, 3, 4, // 64
32 2, 3, 3, 4, 3, 4, 4, 5, // 72
33 2, 3, 3, 4, 3, 4, 4, 5, // 80
34 3, 4, 4, 5, 4, 5, 5, 6, // 88
35 2, 3, 3, 4, 3, 4, 4, 5, // 96
36 3, 4, 4, 5, 4, 5, 5, 6, // 104
37 3, 4, 4, 5, 4, 5, 5, 6, // 112
38 4, 5, 5, 6, 5, 6, 6, 7, // 120
39 1, 2, 2, 3, 2, 3, 3, 4, // 128
40 2, 3, 3, 4, 3, 4, 4, 5, // 136
41 2, 3, 3, 4, 3, 4, 4, 5, // 144
42 3, 4, 4, 5, 4, 5, 5, 6, // 152
43 2, 3, 3, 4, 3, 4, 4, 5, // 160
44 3, 4, 4, 5, 4, 5, 5, 6, // 168
45 3, 4, 4, 5, 4, 5, 5, 6, // 176
46 4, 5, 5, 6, 5, 6, 6, 7, // 184
47 2, 3, 3, 4, 3, 4, 4, 5, // 192
48 3, 4, 4, 5, 4, 5, 5, 6, // 200
49 3, 4, 4, 5, 4, 5, 5, 6, // 208
50 4, 5, 5, 6, 5, 6, 6, 7, // 216
51 3, 4, 4, 5, 4, 5, 5, 6, // 224
52 4, 5, 5, 6, 5, 6, 6, 7, // 232
53 4, 5, 5, 6, 5, 6, 6, 7, // 240
54 5, 6, 6, 7, 6, 7, 7, 8
55 }; // 248
56
57 /* Delete this */
AllocateH223Mux(TPVLoopbackMode aLoopbackMode)58 OSCL_EXPORT_REF CPVH223Multiplex* AllocateH223Mux(TPVLoopbackMode aLoopbackMode)
59 {
60 return OSCL_NEW(CPVH223Multiplex, (aLoopbackMode));
61 }
62
DeallocateH223Mux(CPVH223Multiplex * h223mux)63 OSCL_EXPORT_REF void DeallocateH223Mux(CPVH223Multiplex* h223mux)
64 {
65 OSCL_DELETE(h223mux);
66 }
67
H223GetMuxStuffingSz(TPVH223Level flat_level)68 uint H223GetMuxStuffingSz(TPVH223Level flat_level)
69 {
70 return gMuxStuffingSz[flat_level];
71 }
72
H223GetMuxFlagSz(TPVH223Level flat_level)73 uint H223GetMuxFlagSz(TPVH223Level flat_level)
74 {
75 return gMuxFlagSz[flat_level];
76 }
77
H223GetMaxStuffingSz(TPVH223Level flat_level)78 uint H223GetMaxStuffingSz(TPVH223Level flat_level)
79 {
80 return gMaxStuffingSz[flat_level];
81 }
82
H223MuxStuffing(TPVH223Level level,uint8 * pPdu,uint bufSz)83 uint H223MuxStuffing(TPVH223Level level, uint8* pPdu, uint bufSz)
84 {
85 int32 stuffing_size = (int32)H223GetMuxStuffingSz(level);
86 if (stuffing_size == 0)
87 return 0;
88
89 int32 size_left = bufSz;
90 while (size_left >= stuffing_size)
91 {
92 switch (level)
93 {
94 case H223_LEVEL0: // level 0
95 *(pPdu) = 0x7e;
96 break;
97 case H223_LEVEL1: // level 1
98 case H223_LEVEL1_DF: // H223DoubleFlag == TRUE
99 *(pPdu) = 0xe1;
100 *(pPdu + 1) = 0x4d;
101 if (level == H223_LEVEL1)
102 break;
103 *(pPdu + 2) = 0xe1;
104 *(pPdu + 3) = 0x4d;
105 break;
106 case H223_LEVEL2: // level 2
107 case H223_LEVEL2_OH: // H223OptionalHeader==1
108 *(pPdu) = 0xe1;
109 *(pPdu + 1) = 0x4d;
110 *(pPdu + 2) = 0;
111 *(pPdu + 3) = 0;
112 *(pPdu + 4) = 0;
113 if (level == H223_LEVEL2)
114 break;
115 *(pPdu + 5) = 0;
116 break;
117 default:
118 return 0;
119 }
120 pPdu += stuffing_size;
121 size_left -= stuffing_size;
122 }
123 return (bufSz - size_left);
124 }
125
H223CheckSync(TPVH223Level level,uint8 * buf,uint bufSz,uint tolerance)126 bool H223CheckSync(TPVH223Level level, uint8* buf, uint bufSz, uint tolerance)
127 {
128 if (bufSz < H223GetMuxFlagSz(level))
129 return false;
130 uint mismatch_cnt = 0;
131 switch (level)
132 {
133 case H223_LEVEL0:
134 mismatch_cnt = gNumOnes[(buf[0] ^ 0x7E)];
135 break;
136 case H223_LEVEL1:
137 case H223_LEVEL1_DF:
138 mismatch_cnt = (uint16)(gNumOnes[(buf[0] ^ 0xE1)] + gNumOnes[(buf[1] ^ 0x4D)]);
139 if (level == H223_LEVEL1)
140 break;
141 mismatch_cnt += (uint16)(gNumOnes[(buf[2] ^ 0xE1)] + gNumOnes[(buf[3] ^ 0x4D)]);
142 break;
143 case H223_LEVEL2_OH:
144 if (bufSz >= 6)
145 mismatch_cnt = (uint16)(gNumOnes[buf[5]]);
146 case H223_LEVEL2:
147 mismatch_cnt += (uint16)(gNumOnes[(buf[0] ^ 0xE1)] + gNumOnes[(buf[1] ^ 0x4D)]);
148 if (bufSz >= 5)
149 {
150 mismatch_cnt += (uint16)(gNumOnes[buf[2]]);
151 mismatch_cnt += (uint16)(gNumOnes[buf[3]]);
152 mismatch_cnt += (uint16)(gNumOnes[buf[4]]);
153 }
154 break;
155 default:
156 return false;
157 }
158 return (mismatch_cnt <= tolerance);
159 }
160