Changeset 5001
General spy cleanup.
Adding a new spy is now an O(1) operation.
Common some common code factored into a function.
- New public function:
cw_spy_get_frames: Get only the frames that both parts can give.
Committed by:
karvan
Date:
Jun 27 2008 * 15:38 (5 months ago)
Affected files:
callweaver/branches/karvan/apps/app_chanspy.c (diff)
callweaver/branches/karvan/apps/app_muxmon.c (diff)
callweaver/branches/karvan/corelib/channel.c (diff)
callweaver/branches/karvan/include/callweaver/channel.h (diff)
callweaver/branches/karvan/apps/app_chanspy.c (unified diff)
| r5000 | r5001 | |
|---|---|---|
| 259 | 259 | |
| 260 | 260 | struct chanspy_translation_helper *csth = data; |
| 261 | 261 | struct cw_frame frame, *f0, *f1, *f; |
| 262 | unsigned left, right; | |
| 263 | unsigned same; | |
| 264 | unsigned ii; | |
| 265 | 262 | int len0 = 0; |
| 266 | 263 | int len1 = 0; |
| 267 | 264 | int samp0 = 0; |
| --- | --- | |
| 281 | 278 | |
| 282 | 279 | len = sample * sizeof(int16_t); |
| 283 | 280 | |
| 284 | pthread_mutex_lock(&csth->spy.lock); | |
| 285 | left = csth->spy.queue[0].count; | |
| 286 | right = csth->spy.queue[1].count; | |
| 287 | same = left < right ? left : right; | |
| 288 | if (same == 0) { | |
| 289 | pthread_mutex_unlock(&csth->spy.lock); | |
| 290 | return 0; | |
| 291 | } | |
| 292 | ii = 0; | |
| 293 | for (ii = 0, f0 = csth->spy.queue[0].head, f1 = csth->spy.queue[1].head ; ii < same; ++ii) { | |
| 294 | f0 = f0->next; | |
| 295 | f1 = f1->next; | |
| 296 | } | |
| 297 | f = csth->spy.queue[0].head; | |
| 298 | csth->spy.queue[0].head = f0; | |
| 299 | csth->spy.queue[0].count -= same; | |
| 300 | if (!csth->spy.queue[0].count) | |
| 301 | csth->spy.queue[0].tail = NULL; | |
| 302 | f0 = f; | |
| 303 | f = csth->spy.queue[1].head; | |
| 304 | csth->spy.queue[1].head = f1; | |
| 305 | csth->spy.queue[1].count -= same; | |
| 306 | if (!csth->spy.queue[1].count) | |
| 307 | csth->spy.queue[1].tail = NULL; | |
| 308 | f1 = f; | |
| 309 | pthread_mutex_unlock(&csth->spy.lock); | |
| 281 | cw_spy_get_frames(&csth->spy, &f0, &f1); | |
| 310 | 282 | while (f0) { |
| 311 | struct cw_frame *f = f0->next; | |
| 283 | struct cw_frame *f = f0->next; | |
| 312 | 284 | cw_slinfactory_feed(&csth->slinfactory[0], f0); |
| 313 | 285 | cw_fr_free(f0); |
| 314 | f0 = f; | |
| 286 | f0 = f; | |
| 315 | 287 | } |
| 316 | 288 | while (f1) { |
| 317 | struct cw_frame *f = f1->next; | |
| 289 | struct cw_frame *f = f1->next; | |
| 318 | 290 | cw_slinfactory_feed(&csth->slinfactory[1], f1); |
| 319 | 291 | cw_fr_free(f1); |
| 320 | f1 = f; | |
| 292 | f1 = f; | |
| 321 | 293 | } |
| 322 | 294 | |
| 323 | 295 | if (csth->slinfactory[0].size < len || csth->slinfactory[1].size < len) |
| --- | --- | |
| 393 | 365 | |
| 394 | 366 | static void start_spying(struct cw_channel *chan, struct cw_channel *spychan, struct cw_channel_spy *spy) |
| 395 | 367 | { |
| 396 | ||
| 397 | struct cw_channel_spy *cptr=NULL; | |
| 398 | 368 | struct cw_channel *peer; |
| 399 | ||
| 400 | 369 | cw_log(LOG_WARNING, "Attaching %s to %s\n", spychan->name, chan->name); |
| 401 | 370 | |
| 402 | 371 | cw_mutex_lock(&chan->lock); |
| 403 | if (chan->spiers) | |
| 404 | { | |
| 405 | for (cptr = chan->spiers; cptr && cptr->next; cptr = cptr->next) | |
| 406 | ; | |
| 407 | cptr->next = spy; | |
| 408 | } | |
| 409 | else | |
| 410 | { | |
| 411 | chan->spiers = spy; | |
| 412 | } | |
| 372 | spy->next = chan->spiers; | |
| 373 | chan->spiers = spy; | |
| 413 | 374 | cw_mutex_unlock(&chan->lock); |
| 414 | 375 | if ( cw_test_flag(chan, CW_FLAG_NBRIDGE) && (peer = cw_bridged_channel(chan))) |
| 415 | 376 | cw_softhangup(peer, CW_SOFTHANGUP_UNBRIDGE); |
| --- | --- | |
| 439 | 400 | { |
| 440 | 401 | chan->spiers = NULL; |
| 441 | 402 | } |
| 403 | break; | |
| 442 | 404 | } |
| 443 | 405 | prev = cptr; |
| 444 | 406 | } |
callweaver/branches/karvan/apps/app_muxmon.c (unified diff)
| r4998 | r5001 | |
|---|---|---|
| 152 | 152 | else |
| 153 | 153 | chan->spiers = cptr->next; |
| 154 | 154 | cptr->next = NULL; |
| 155 | break; | |
| 155 | 156 | } |
| 156 | 157 | prev = cptr; |
| 157 | 158 | } |
| --- | --- | |
| 168 | 169 | if (chan) |
| 169 | 170 | { |
| 170 | 171 | cw_mutex_lock(&chan->lock); |
| 171 | if (chan->spiers) | |
| 172 | { | |
| 173 | for (cptr = chan->spiers; cptr && cptr->next; cptr = cptr->next); | |
| 174 | cptr->next = spy; | |
| 175 | } | |
| 176 | else | |
| 177 | { | |
| 178 | chan->spiers = spy; | |
| 179 | } | |
| 172 | spy->next = chan->spiers; | |
| 173 | chan->spiers = spy; | |
| 180 | 174 | cw_mutex_unlock(&chan->lock); |
| 181 | 175 | |
| 182 | 176 | if (cw_test_flag(chan, CW_FLAG_NBRIDGE) && (peer = cw_bridged_channel(chan))) |
| --- | --- | |
| 189 | 183 | struct cw_slinfactory *slinfactory1) |
| 190 | 184 | { |
| 191 | 185 | struct cw_frame *f, *f0, *f1; |
| 192 | unsigned left, right; | |
| 193 | unsigned same; | |
| 194 | unsigned ii; | |
| 195 | ||
| 196 | pthread_mutex_lock(&spy->lock); | |
| 197 | left = spy->queue[0].count; | |
| 198 | right = spy->queue[1].count; | |
| 199 | same = left < right ? left : right; | |
| 200 | if (same == 0) { | |
| 201 | pthread_mutex_unlock(&spy->lock); | |
| 202 | return 0; | |
| 203 | } | |
| 204 | ii = 0; | |
| 205 | for (ii = 0, f0 = spy->queue[0].head, f1 = spy->queue[1].head ; ii < same; ++ii) { | |
| 206 | f0 = f0->next; | |
| 207 | f1 = f1->next; | |
| 208 | } | |
| 209 | f = spy->queue[0].head; | |
| 210 | spy->queue[0].head = f0; | |
| 211 | spy->queue[0].count -= same; | |
| 212 | if (!spy->queue[0].count) | |
| 213 | spy->queue[0].tail = NULL; | |
| 214 | f0 = f; | |
| 215 | f = spy->queue[1].head; | |
| 216 | spy->queue[1].head = f1; | |
| 217 | spy->queue[1].count -= same; | |
| 218 | if (!spy->queue[1].count) | |
| 219 | spy->queue[1].tail = NULL; | |
| 220 | f1 = f; | |
| 221 | pthread_mutex_unlock(&spy->lock); | |
| 186 | ||
| 187 | cw_spy_get_frames(spy, &f0, &f1); | |
| 222 | 188 | while (f0) { |
| 223 | 189 | f = f0->next; |
| 224 | 190 | cw_slinfactory_feed(slinfactory0, f0); |
| 225 | 191 | cw_fr_free(f0); |
| 226 | f0 = f; | |
| 192 | f0 = f; | |
| 227 | 193 | } |
| 228 | 194 | while (f1) { |
| 229 | 195 | f = f1->next; |
| 230 | 196 | cw_slinfactory_feed(slinfactory1, f1); |
| 231 | 197 | cw_fr_free(f1); |
| 232 | f1 = f; | |
| 198 | f1 = f; | |
| 233 | 199 | } |
| 234 | 200 | return 0; |
| 235 | 201 | } |
callweaver/branches/karvan/corelib/channel.c (unified diff)
| r4997 | r5001 | |
|---|---|---|
| 1074 | 1074 | cw_device_state_changed_literal(name); |
| 1075 | 1075 | } |
| 1076 | 1076 | |
| 1077 | /*--- cw_spy_get_frames: Get as many frames as BOTH parts can give. */ | |
| 1078 | /** Get as many frames as BOTH parts can give. | |
| 1079 | * This will make \c f0 point to a list of frames from the first queue and \c f1 | |
| 1080 | * point to a list of frames from the second queue. Both list will have the same | |
| 1081 | * number of elements. | |
| 1082 | * | |
| 1083 | * After calling this function the queues will have released the specified | |
| 1084 | * frames and it's the caller's responsibility to deallocate them. | |
| 1085 | * | |
| 1086 | * @param spy The (unlocked) spy. | |
| 1087 | * @param f0 The start of the frames from the first queue. This can become NULL | |
| 1088 | * if no frames were available in either queue. | |
| 1089 | * @param f1 The start of the frames from the second queue. This can become NULL | |
| 1090 | * if no frames were available in either queue. | |
| 1091 | */ | |
| 1092 | void cw_spy_get_frames(struct cw_channel_spy *spy, struct cw_frame **f0, struct cw_frame **f1) | |
| 1093 | { | |
| 1094 | unsigned left, right; | |
| 1095 | unsigned same; | |
| 1096 | cw_mutex_lock(&spy->lock); | |
| 1097 | left = spy->queue[0].count; | |
| 1098 | right = spy->queue[1].count; | |
| 1099 | same = left < right ? left : right; | |
| 1100 | if (same == 0) { | |
| 1101 | *f0 = *f1 = NULL; | |
| 1102 | } else { | |
| 1103 | int ii; | |
| 1104 | struct cw_frame *f = spy->queue[0].head; | |
| 1105 | for (ii = 1; ii < same; ++ii) | |
| 1106 | f = f->next; | |
| 1107 | *f0 = spy->queue[0].head; | |
| 1108 | spy->queue[0].head = f; | |
| 1109 | spy->queue[0].count -= same; | |
| 1110 | if (spy->queue[0].count == 0) | |
| 1111 | spy->queue[0].tail = NULL; | |
| 1112 | f = spy->queue[1].head; | |
| 1113 | for (ii = 1; ii < same; ++ii) | |
| 1114 | f = f->next; | |
| 1115 | *f1 = spy->queue[1].head; | |
| 1116 | spy->queue[1].head = f; | |
| 1117 | spy->queue[1].count -= same; | |
| 1118 | if (spy->queue[1].count == 0) | |
| 1119 | spy->queue[1].tail = NULL; | |
| 1120 | } | |
| 1121 | cw_mutex_unlock(&spy->lock); | |
| 1122 | } | |
| 1123 | ||
| 1077 | 1124 | static void cw_spy_detach(struct cw_channel *chan) |
| 1078 | 1125 | { |
| 1079 | 1126 | struct cw_channel_spy *chanspy; |
| --- | --- | |
| 1757 | 1804 | } |
| 1758 | 1805 | else |
| 1759 | 1806 | { |
| 1760 | if (chan->spiers) | |
| 1761 | { | |
| 1762 | struct cw_channel_spy *spying; | |
| 1807 | struct cw_channel_spy *spying; | |
| 1763 | 1808 | |
| 1764 | for (spying = chan->spiers; spying; spying = spying->next) | |
| 1765 | cw_queue_spy_frame(spying, f, 0); | |
| 1766 | } | |
| 1809 | for (spying = chan->spiers; spying; spying = spying->next) | |
| 1810 | cw_queue_spy_frame(spying, f, 0); | |
| 1767 | 1811 | if (chan->monitor && chan->monitor->read_stream) |
| 1768 | 1812 | { |
| 1769 | 1813 | #ifndef MONITOR_CONSTANT_DELAY |
| --- | --- | |
| 2191 | 2235 | * let the channel driver use a writer thread |
| 2192 | 2236 | * to actually write the stuff, for example. */ |
| 2193 | 2237 | |
| 2194 | if (f->frametype == CW_FRAME_VOICE && chan->spiers) | |
| 2195 | { | |
| 2238 | if (f->frametype == CW_FRAME_VOICE) { | |
| 2196 | 2239 | struct cw_channel_spy *spying; |
| 2197 | ||
| 2198 | 2240 | for (spying = chan->spiers; spying; spying = spying->next) |
| 2199 | 2241 | cw_queue_spy_frame(spying, f, 1); |
| 2200 | 2242 | } |
callweaver/branches/karvan/include/callweaver/channel.h (unified diff)
| r4997 | r5001 | |
|---|---|---|
| 374 | 374 | /* Spy stuff */ |
| 375 | 375 | void cw_queue_spy_frame(struct cw_channel_spy *spy, struct cw_frame *f, int q); |
| 376 | 376 | void cw_spy_empty_queues(struct cw_channel_spy *spy, struct cw_frame **f0, |
| 377 | struct cw_frame **f1); | |
| 377 | struct cw_frame **f1); | |
| 378 | void cw_spy_get_frames(struct cw_channel_spy *spy, struct cw_frame **f0, | |
| 379 | struct cw_frame **f1); | |
| 378 | 380 | |
| 379 | 381 | /* Channel tech properties: */ |
| 380 | 382 | /* Channels have this property if they can accept input with jitter; i.e. most VoIP channels */ |
![Home changeset 5001 [home]](/images/logo.png?1180520111)
RSS Feeds