[server] / trunk / server / src / ipmdevice.cxx Repository:
ViewVC logotype

Annotation of /trunk/server/src/ipmdevice.cxx

Parent Directory Parent Directory | Revision Log Revision Log


Revision 536 - (view) (download)

1 : jtarlton 41 /*
2 : jtarlton 355 * This file is part of Project DiaStar Server.
3 : jtarlton 41 *
4 : amartin 143 * More information about this project can be found at:
5 : jtarlton 355 * http://www.projectdiastar.org.
6 : jtarlton 41 *
7 : amartin 143 * Copyright (C) 2009 Dialogic Corp.
8 : jtarlton 41 *
9 : amartin 143 * This program is free software; you can redistribute it and/or
10 :     * modify it under the terms of the GNU General Public License
11 :     * as published by the Free Software Foundation; either version 2
12 :     * of the License, or (at your option) any later version.
13 :     *
14 :     * This program is distributed in the hope that it will be useful,
15 :     * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 :     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 :     * GNU General Public License for more details.
18 :     *
19 :     * You should have received a copy of the GNU General Public License
20 :     * along with this program; if not, write to the Free Software
21 :     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 :     * 02110-1301, USA.
23 :     * Alternatively see <http://www.gnu.org/licenses/>.
24 :     * Or see the LICENSE file included within the source tree.
25 :     *
26 : jtarlton 41 */
27 :    
28 :     /*!
29 : jtarlton 45 * \file ipmdevice.cxx
30 : jtarlton 59 * \brief Dialogic IPM device
31 : jtarlton 41 * \author Antony Martin <antony.martin@dialogic.com>
32 : jtarlton 162 * \author John Tarlton <john.tarlton@dialogic.com>
33 : jtarlton 87 * \version 2-APR-2009
34 : jtarlton 41 */
35 :    
36 : jtarlton 87 /*------------------------------ Dependencies --------------------------------*/
37 : jtarlton 41
38 :     #include "logger.h"
39 : jtarlton 162 #include "string-util.h"
40 :    
41 : jtarlton 394 #include "dialogicchannelmanager.h"
42 : jtarlton 393 #include "mmdevice.h"
43 : jtarlton 395 #include "gciptdevice.h"
44 : jtarlton 41 #include "ipmdevice.h"
45 :    
46 : jtarlton 87 /*----------------------------------------------------------------------------*/
47 : jtarlton 41
48 :     /*
49 :     * ctor
50 :     */
51 : jtarlton 87 IpmDevice::IpmDevice( const std::string& name,
52 : jtarlton 431 DialogicChannelManager& channelMgr )
53 : jtarlton 87 : DialogicDevice(name, channelMgr)
54 : jtarlton 41 {
55 : jtarlton 431 ipt_ = 0; /* standalone mode */
56 : jtarlton 323 busy_ = false;
57 :    
58 : jtarlton 464 /* Use the most preferred audio coder as the default.
59 :     */
60 :     const Coders::audio_coders_t& audioCoders = channelMgr_.getAudioCoders();
61 :     Coders::audio_coders_t::const_iterator i = audioCoders.begin();
62 :     if ( i != audioCoders.end() )
63 :     {
64 :     localAudioCoder_ = *i;
65 :     }
66 :     else /* PCMU */
67 :     {
68 :     localAudioCoder_.coderType = CODER_TYPE_G711ULAW64K;
69 :     localAudioCoder_.coderPayloadType = 0;
70 :     localAudioCoder_.coderFramesize = CODER_FRAMESIZE_20;
71 :     localAudioCoder_.framesPerPkt = 1;
72 :     localAudioCoder_.vadEnable = CODER_VAD_ENABLE;
73 :     localAudioCoder_.redPayloadType = 0;
74 :     }
75 : jtarlton 431
76 : jtarlton 464 /* Use the most preferred video coder as the default.
77 :     */
78 :     const Coders::video_coders_t& videoCoders = channelMgr_.getVideoCoders();
79 :     Coders::video_coders_t::const_iterator j = videoCoders.begin();
80 :     if ( j != videoCoders.end() )
81 :     {
82 :     localVideoCoder_ = *j;
83 :     }
84 : jtarlton 471 else /* H.263 */
85 : jtarlton 464 {
86 :     localVideoCoder_.coderType = CODER_TYPE_H263;
87 :     localVideoCoder_.coderPayloadType = 34;
88 :     localVideoCoder_.profile = VIDEO_PROFILE_0_H263;
89 :     localVideoCoder_.level = VIDEO_LEVEL_10_H263;
90 : jtarlton 500 localVideoCoder_.bitRate = 384000;
91 : jtarlton 464 localVideoCoder_.samplingRate = VIDEO_SAMPLING_RATE_DEFAULT;
92 : jtarlton 471
93 :     /* QCIF=2 */
94 :     localVideoCoder_.active_fmt.imageWidth = VIDEO_IMAGE_WIDTH_176;
95 :     localVideoCoder_.active_fmt.imageHeight = VIDEO_IMAGE_HEIGHT_144;
96 :     localVideoCoder_.active_fmt.framesPerSec = VIDEO_FRAMESPERSEC_15;
97 :    
98 :     localVideoCoder_.available_fmts.push_back(localVideoCoder_.active_fmt);
99 : jtarlton 464 }
100 : jtarlton 431
101 :     remoteAudioCoder_ = localAudioCoder_;
102 :     remoteVideoCoder_ = localVideoCoder_;
103 :    
104 : jtarlton 490 dtmf_mode_ = DTMF_RFC2833;
105 :     rfc2833_payload_type_ = 101; /* may be changed by sdp processing */
106 :    
107 : jtarlton 41 /* Number of steps in the initialisation sequence, decremented by event
108 : jtarlton 394 * handlers. When zero, state is changed to IDLE.
109 : jtarlton 64 *
110 :     * IPMEV_OPEN,
111 :     * DMEV_GET_RX_PORT_INFO,
112 :     * DMEV_GET_TX_PORT_INFO
113 : jtarlton 41 */
114 :     initStepsRemaining_ = 3;
115 :     }
116 :    
117 :    
118 :     /*
119 :     * dtor
120 :     */
121 :     IpmDevice::~IpmDevice()
122 :     {
123 :     }
124 :    
125 :    
126 :     /*
127 : jtarlton 321 * Process a command that was queueued because an async operation was in progress
128 :     * when it was initially requested.
129 :     */
130 :     void IpmDevice::processPendingCommand()
131 :     {
132 : jtarlton 418 while ( !busy_ && !pending_.empty() )
133 : jtarlton 321 {
134 : jtarlton 419 LOGDEBUG("IpmDevice::processPendingCommand()");
135 : jtarlton 321 switch( pending_.front().cmd )
136 :     {
137 :     case IpmCommand::START:
138 :     startMedia();
139 :     break;
140 : jtarlton 536
141 : jtarlton 321 case IpmCommand::STOP:
142 :     stop(pending_.front().operation);
143 :     break;
144 : jtarlton 536
145 : jtarlton 321 case IpmCommand::LISTEN:
146 :     listen(pending_.front().other);
147 :     break;
148 : jtarlton 536
149 : jtarlton 321 case IpmCommand::UNLISTEN:
150 :     unListen();
151 :     break;
152 : jtarlton 536
153 : amartin 402 case IpmCommand::CONNECT:
154 :     connect(pending_.front().other);
155 :     break;
156 : jtarlton 536
157 : amartin 402 case IpmCommand::DISCONNECT:
158 :     disconnect();
159 :     break;
160 : jtarlton 536
161 : jtarlton 321 default:
162 :     break;
163 :     }
164 :     pending_.pop();
165 :     }
166 :     }
167 :    
168 :    
169 :     /*
170 : jtarlton 64 * Open the device.
171 : jtarlton 41 */
172 : jtarlton 45 bool IpmDevice::open()
173 : jtarlton 41 {
174 : jtarlton 455 LOGDEBUG("IpmDevice::open() device: " << getDeviceName());
175 : jtarlton 45
176 : jtarlton 455 devHandle_ = ipm_Open(getDeviceName().c_str(), NULL, EV_ASYNC);
177 : jtarlton 41 if ( devHandle_ < 0 )
178 :     {
179 :     LOGERROR("ipm_Open() failed");
180 :     return false;
181 :     }
182 :     state_ = IPM_OPENING;
183 :     return true;
184 :     }
185 :    
186 :    
187 :     /*
188 : jtarlton 64 * Close the device
189 : jtarlton 41 */
190 : jtarlton 45 bool IpmDevice::close()
191 : jtarlton 41 {
192 : jtarlton 455 LOGDEBUG("IpmDevice::close() device: " << getDeviceName());
193 : jtarlton 45
194 : jtarlton 41 if ( devHandle_ > 0 )
195 :     {
196 :     if ( ipm_Close(devHandle_, NULL) < 0 )
197 :     {
198 : jtarlton 104 LOGERROR("ipm_Close() failed");
199 : jtarlton 41 return false;
200 :     }
201 : jtarlton 64 devHandle_ = 0;
202 : jtarlton 41 }
203 :     return true;
204 :     }
205 :    
206 :    
207 :     /*
208 : jtarlton 64 * Connect media.
209 : jtarlton 41 */
210 : jtarlton 45 bool IpmDevice::listen( DialogicDevice* other )
211 : jtarlton 41 {
212 : jtarlton 413 if ( busy_ )
213 :     {
214 :     pending_.push(IpmCommand(IpmCommand::LISTEN, other));
215 :     return true;
216 :     }
217 :    
218 : jtarlton 417 if ( other_ != other )
219 : jtarlton 316 {
220 : jtarlton 455 LOGDEBUG("IpmDevice::listen() device: " << getDeviceName() <<
221 : jtarlton 317 " other: " << other->getDeviceName());
222 : jtarlton 401
223 : jtarlton 317 SC_TSINFO tsinfo;
224 :     tsinfo.sc_numts = 1;
225 :     tsinfo.sc_tsarrayp = other->getXmitTimeslotPtr();
226 : jtarlton 41
227 : jtarlton 317 if ( ipm_Listen(devHandle_, &tsinfo, EV_ASYNC) == -1 )
228 :     {
229 : jtarlton 455 LOGERROR("ipm_Listen() failed on device: " << getDeviceName() <<
230 : jtarlton 317 " " << ATDV_ERRMSGP(devHandle_));
231 :     return false;
232 :     }
233 : jtarlton 417 other_ = other;
234 : jtarlton 401 busy_ = true;
235 :     }
236 :     return true;
237 :     }
238 :    
239 :    
240 :     /*
241 :     * Disconnect media.
242 :     */
243 :     bool IpmDevice::unListen()
244 :     {
245 : jtarlton 413 if ( busy_ )
246 :     {
247 :     pending_.push(IpmCommand(IpmCommand::UNLISTEN));
248 :     return true;
249 :     }
250 :    
251 : jtarlton 417 if ( other_ )
252 : jtarlton 401 {
253 : jtarlton 455 LOGDEBUG("IpmDevice::unListen() device: " << getDeviceName());
254 : jtarlton 401
255 :     if ( ipm_UnListen(devHandle_, EV_ASYNC) == -1)
256 :     {
257 : jtarlton 455 LOGERROR("ipm_UnListen() failed on device: " << getDeviceName() <<
258 : jtarlton 401 " " << ATDV_ERRMSGP(devHandle_));
259 :     return false;
260 :     }
261 : jtarlton 417 other_ = 0;
262 : jtarlton 401 busy_ = true;
263 :     }
264 :     return true;
265 :     }
266 :    
267 :    
268 :     /*
269 :     * Connect media.
270 :     */
271 :     bool IpmDevice::connect( DialogicDevice* other )
272 :     {
273 : jtarlton 413 if ( busy_ )
274 :     {
275 :     pending_.push(IpmCommand(IpmCommand::CONNECT, other));
276 :     return true;
277 :     }
278 :    
279 : jtarlton 417 if ( !other_ )
280 : jtarlton 401 {
281 : jtarlton 455 LOGDEBUG("IpmDevice::connect() device: " << getDeviceName() <<
282 : jtarlton 413 " to: " << other->getDeviceName());
283 : jtarlton 401
284 : jtarlton 390 DM_PORT_CONNECT_INFO_LIST portConnectInfoList;
285 : jtarlton 413 memset(&portConnectInfoList, 0, sizeof(portConnectInfoList));
286 : jtarlton 390 INIT_DM_PORT_CONNECT_INFO_LIST(&portConnectInfoList);
287 : jtarlton 393 int count = 0;
288 : jtarlton 390
289 : jtarlton 393 INIT_DM_PORT_CONNECT_INFO(&portConnectInfoList.port_connect_info[count]);
290 : jtarlton 413 portConnectInfoList.port_connect_info[count].unFlags = DMFL_TRANSCODE_ON;
291 : jtarlton 393 portConnectInfoList.port_connect_info[count].port_info_tx = getAudioTxPortInfo();
292 : jtarlton 401 portConnectInfoList.port_connect_info[count].port_info_rx = other->getAudioRxPortInfo();
293 : jtarlton 393 count++;
294 : jtarlton 390
295 : jtarlton 393 INIT_DM_PORT_CONNECT_INFO(&portConnectInfoList.port_connect_info[count]);
296 : jtarlton 413 portConnectInfoList.port_connect_info[count].unFlags = DMFL_TRANSCODE_ON;
297 : jtarlton 393 portConnectInfoList.port_connect_info[count].port_info_tx = getVideoTxPortInfo();
298 : jtarlton 401 portConnectInfoList.port_connect_info[count].port_info_rx = other->getVideoRxPortInfo();
299 : jtarlton 393 count++;
300 : jtarlton 416
301 : jtarlton 393 portConnectInfoList.unCount = count;
302 : jtarlton 390 if ( dev_PortConnect(devHandle_, &portConnectInfoList, NULL) != DEV_SUCCESS )
303 :     {
304 : jtarlton 455 LOGERROR("IpmDevice::connect() dev_PortConnect() failed on device: " << getDeviceName() <<
305 : jtarlton 390 " " << ATDV_ERRMSGP(devHandle_));
306 :     return false;
307 :     }
308 :    
309 : jtarlton 417 other_ = other;
310 : jtarlton 321 busy_ = true;
311 : jtarlton 41 }
312 : amartin 405 else
313 :     {
314 : jtarlton 417 if ( other_ != other )
315 :     {
316 : jtarlton 455 LOGERROR("IpmDevice::connect() " << getDeviceName() <<
317 : jtarlton 417 " unable to connect to device: " << other->getDeviceName() <<
318 :     " already connected to device: " << other_->getDeviceName());
319 :     }
320 : amartin 405 }
321 : jtarlton 41 return true;
322 :     }
323 :    
324 :    
325 :     /*
326 : jtarlton 64 * Disconnect media.
327 : jtarlton 41 */
328 : jtarlton 401 bool IpmDevice::disconnect()
329 : jtarlton 41 {
330 : jtarlton 413 if ( busy_ )
331 :     {
332 :     pending_.push(IpmCommand(IpmCommand::DISCONNECT));
333 :     return true;
334 :     }
335 :    
336 : jtarlton 417 if ( other_ )
337 : jtarlton 316 {
338 : jtarlton 455 LOGDEBUG("IpmDevice::disconnect() device: " << getDeviceName() <<
339 : jtarlton 417 " from: " << other_->getDeviceName());
340 : jtarlton 316
341 : jtarlton 390 DM_PORT_CONNECT_INFO_LIST portConnectInfoList;
342 : jtarlton 413 memset(&portConnectInfoList, 0, sizeof(portConnectInfoList));
343 : jtarlton 390 INIT_DM_PORT_CONNECT_INFO_LIST(&portConnectInfoList);
344 : jtarlton 393 int count = 0;
345 : jtarlton 390
346 : jtarlton 393 INIT_DM_PORT_CONNECT_INFO(&portConnectInfoList.port_connect_info[count]);
347 :     portConnectInfoList.port_connect_info[count].port_info_tx = getAudioTxPortInfo();
348 : jtarlton 451 portConnectInfoList.port_connect_info[count].port_info_rx = other_->getAudioRxPortInfo();
349 : jtarlton 393 count++;
350 : jtarlton 390
351 : jtarlton 393 INIT_DM_PORT_CONNECT_INFO(&portConnectInfoList.port_connect_info[count]);
352 :     portConnectInfoList.port_connect_info[count].port_info_tx = getVideoTxPortInfo();
353 : jtarlton 451 portConnectInfoList.port_connect_info[count].port_info_rx = other_->getVideoRxPortInfo();
354 : jtarlton 393 count++;
355 : jtarlton 390
356 : jtarlton 393 portConnectInfoList.unCount = count;
357 : jtarlton 390 if ( dev_PortDisconnect(devHandle_, &portConnectInfoList, NULL) != DEV_SUCCESS )
358 :     {
359 : jtarlton 455 LOGERROR("IpmDevice::disconnect() dev_PortDisconnect() failed on device: " << getDeviceName() <<
360 : jtarlton 390 " " << ATDV_ERRMSGP(devHandle_));
361 :     return false;
362 :     }
363 :    
364 : jtarlton 417 other_ = 0;
365 : jtarlton 321 busy_ = true;
366 : jtarlton 41 }
367 :     return true;
368 :     }
369 :    
370 :    
371 :     /*
372 : jtarlton 131 * Search localMediaInfo_ for the requested information.
373 : jtarlton 41 */
374 : jtarlton 390 bool IpmDevice::getLocalMediaInfo( eIPM_MEDIA_TYPE type,
375 : jtarlton 131 IpInfo& rtp_media ) const
376 : jtarlton 41 {
377 : jtarlton 390 switch ( type )
378 : jtarlton 41 {
379 : jtarlton 390 case MEDIATYPE_AUDIO_LOCAL_RTP_INFO:
380 :     rtp_media = localRtpAudio_;
381 : jtarlton 41 break;
382 : jtarlton 390
383 :     case MEDIATYPE_AUDIO_LOCAL_RTCP_INFO:
384 :     rtp_media = localRtcpAudio_;
385 :     break;
386 :    
387 :     case MEDIATYPE_VIDEO_LOCAL_RTP_INFO:
388 :     rtp_media = localRtpVideo_;
389 :     break;
390 :    
391 :     case MEDIATYPE_VIDEO_LOCAL_RTCP_INFO:
392 :     rtp_media = localRtcpVideo_;
393 :     break;
394 :    
395 :     default:
396 :     return false;
397 : jtarlton 41 }
398 : jtarlton 390 return true;
399 : jtarlton 41 }
400 :    
401 :    
402 :     /*
403 : jtarlton 491 * Save the remote params, the RTCP port is assumed to be media + 1.
404 : jtarlton 41 */
405 : jtarlton 131 void IpmDevice::setRemoteMediaInfo( eIPM_MEDIA_TYPE type,
406 :     const IpInfo& rtp_info )
407 : jtarlton 41 {
408 : jtarlton 390 if ( type == MEDIATYPE_AUDIO_REMOTE_RTP_INFO )
409 : jtarlton 210 {
410 :     remoteRtpAudio_ = rtp_info;
411 :     remoteRtcpAudio_ = rtp_info;
412 : jtarlton 286 remoteRtcpAudio_.setPort(remoteRtpAudio_.getPort() + 1);
413 : jtarlton 411
414 : jtarlton 455 LOGDEBUG("IpmDevice::setRemoteMediaInfo() device: " << getDeviceName() <<
415 : jtarlton 411 " a=" << remoteRtpAudio_);
416 : jtarlton 210 }
417 : jtarlton 390 if ( type == MEDIATYPE_VIDEO_REMOTE_RTP_INFO )
418 :     {
419 :     remoteRtpVideo_ = rtp_info;
420 :     remoteRtcpVideo_ = rtp_info;
421 :     remoteRtcpVideo_.setPort(remoteRtpVideo_.getPort() + 1);
422 : jtarlton 455 LOGDEBUG("IpmDevice::setRemoteMediaInfo() device: " << getDeviceName() <<
423 : jtarlton 411 " v=" << remoteRtpVideo_);
424 : jtarlton 390 }
425 : jtarlton 41 }
426 :    
427 :    
428 :     /*
429 :     * Stop the IPM streaming and/or digit reception
430 :     */
431 :     bool IpmDevice::stop( eIPM_STOP_OPERATION operation )
432 :     {
433 :     if ( state_ == IPM_IDLE )
434 :     {
435 : jtarlton 294 return true; /* already stopped */
436 : jtarlton 41 }
437 :    
438 : jtarlton 321 if ( busy_ )
439 :     {
440 :     pending_.push(IpmCommand(IpmCommand::STOP, operation));
441 :     return true;
442 :     }
443 :    
444 : jtarlton 41 if ( ipm_Stop(devHandle_, operation, EV_ASYNC) == -1 )
445 :     {
446 : jtarlton 455 LOGERROR("ipm_Stop() on device: " << getDeviceName() << " failed: " <<
447 : jtarlton 41 ATDV_LASTERR(devHandle_));
448 :     return false;
449 :     }
450 : jtarlton 411
451 :     LOGDEBUG("IpmDevice::stopMedia() stopping RTP streaming on device: " <<
452 : jtarlton 455 getDeviceName());
453 : jtarlton 411
454 : jtarlton 41 state_ = IPM_STOPPING;
455 : jtarlton 321 busy_ = true;
456 :    
457 : jtarlton 41 return true;
458 :     }
459 :    
460 :    
461 :     /*
462 : jtarlton 431 * Start RTP streaming to peer using the current settings.
463 : jtarlton 41 */
464 :     bool IpmDevice::startMedia()
465 :     {
466 : jtarlton 390 return startMedia(remoteRtpAudio_,
467 :     remoteRtcpAudio_,
468 :     remoteRtpVideo_,
469 :     remoteRtcpVideo_);
470 : jtarlton 41 }
471 :    
472 :    
473 :     /*
474 : jtarlton 491 * Start RTP streaming: audio and possibly video.
475 : jtarlton 41 */
476 : jtarlton 131 bool IpmDevice::startMedia( const IpInfo& remote_rtp_audio,
477 : jtarlton 390 const IpInfo& remote_rtcp_audio,
478 :     const IpInfo& remote_rtp_video,
479 :     const IpInfo& remote_rtcp_video )
480 : jtarlton 41 {
481 : jtarlton 411 if ( busy_ )
482 : jtarlton 41 {
483 : jtarlton 411 pending_.push(IpmCommand(IpmCommand::START));
484 :     return true;
485 : jtarlton 41 }
486 :    
487 : jtarlton 411 if ( state_ == IPM_STREAMING )
488 : jtarlton 321 {
489 : jtarlton 411 /* already started, ignore */
490 :     LOGDEBUG("IpmDevice::startMedia() already streaming on device: " <<
491 : jtarlton 455 getDeviceName());
492 : jtarlton 321 return true;
493 :     }
494 :    
495 : jtarlton 419 if ( !remote_rtp_audio.isValid() && !remote_rtp_video.isValid() )
496 :     {
497 : jtarlton 451 LOGERROR("IpmDevice::startMedia() no remote rtp media for device: " <<
498 : jtarlton 455 getDeviceName());
499 : jtarlton 419 return false;
500 :     }
501 :    
502 : jtarlton 490 setDtmfMode(dtmf_mode_);
503 : jtarlton 390
504 : jtarlton 41 IPM_MEDIA_INFO mediaInfo;
505 :     memset(&mediaInfo, 0, sizeof(IPM_MEDIA_INFO));
506 :    
507 : jtarlton 131 int mediaCnt = 0; /* limit MAX_MEDIA_INFO */
508 : jtarlton 41
509 : jtarlton 491 /* local audio.
510 : jtarlton 41 */
511 : jtarlton 431 mediaInfo.MediaData[mediaCnt].eMediaType = MEDIATYPE_AUDIO_LOCAL_CODER_INFO;
512 : jtarlton 510 mediaInfo.MediaData[mediaCnt].mediaInfo.CoderInfo.eCoderType = remoteAudioCoder_.coderType;
513 :     mediaInfo.MediaData[mediaCnt].mediaInfo.CoderInfo.eFrameSize = remoteAudioCoder_.coderFramesize;
514 :     mediaInfo.MediaData[mediaCnt].mediaInfo.CoderInfo.unFramesPerPkt = remoteAudioCoder_.framesPerPkt;
515 :     mediaInfo.MediaData[mediaCnt].mediaInfo.CoderInfo.eVadEnable = remoteAudioCoder_.vadEnable;
516 :     mediaInfo.MediaData[mediaCnt].mediaInfo.CoderInfo.unCoderPayloadType = remoteAudioCoder_.coderPayloadType;
517 :     mediaInfo.MediaData[mediaCnt].mediaInfo.CoderInfo.unRedPayloadType = remoteAudioCoder_.redPayloadType;
518 : jtarlton 41 mediaCnt++;
519 :    
520 : jtarlton 491 /* remote audio.
521 : jtarlton 131 */
522 : jtarlton 431 mediaInfo.MediaData[mediaCnt].eMediaType = MEDIATYPE_AUDIO_REMOTE_CODER_INFO;
523 :     mediaInfo.MediaData[mediaCnt].mediaInfo.CoderInfo.eCoderType = remoteAudioCoder_.coderType;
524 :     mediaInfo.MediaData[mediaCnt].mediaInfo.CoderInfo.eFrameSize = remoteAudioCoder_.coderFramesize;
525 :     mediaInfo.MediaData[mediaCnt].mediaInfo.CoderInfo.unFramesPerPkt = remoteAudioCoder_.framesPerPkt;
526 :     mediaInfo.MediaData[mediaCnt].mediaInfo.CoderInfo.eVadEnable = remoteAudioCoder_.vadEnable;
527 :     mediaInfo.MediaData[mediaCnt].mediaInfo.CoderInfo.unCoderPayloadType = remoteAudioCoder_.coderPayloadType;
528 :     mediaInfo.MediaData[mediaCnt].mediaInfo.CoderInfo.unRedPayloadType = remoteAudioCoder_.redPayloadType;
529 : jtarlton 41 mediaCnt++;
530 :    
531 : jtarlton 491 /* remote audio ports and IP addresses.
532 : jtarlton 41 */
533 :     mediaInfo.MediaData[mediaCnt].eMediaType = MEDIATYPE_AUDIO_REMOTE_RTP_INFO;
534 : jtarlton 162 copy_string_to_c_array(remote_rtp_audio.getAddress(),
535 :     mediaInfo.MediaData[mediaCnt].mediaInfo.PortInfo.cIPAddress,
536 : jtarlton 210 IP_ADDR_SIZE);
537 : jtarlton 131 mediaInfo.MediaData[mediaCnt].mediaInfo.PortInfo.unPortId = remote_rtp_audio.getPort();
538 : jtarlton 41 mediaCnt++;
539 :    
540 : jtarlton 390 mediaInfo.MediaData[mediaCnt].eMediaType = MEDIATYPE_AUDIO_REMOTE_RTCP_INFO;
541 : jtarlton 162 copy_string_to_c_array(remote_rtcp_audio.getAddress(),
542 :     mediaInfo.MediaData[mediaCnt].mediaInfo.PortInfo.cIPAddress,
543 : jtarlton 210 IP_ADDR_SIZE);
544 : jtarlton 131 mediaInfo.MediaData[mediaCnt].mediaInfo.PortInfo.unPortId = remote_rtcp_audio.getPort();
545 : jtarlton 41 mediaCnt++;
546 :    
547 : jtarlton 451 if ( remote_rtp_video.isValid() )
548 :     {
549 : jtarlton 491 /* local video.
550 : jtarlton 451 */
551 :     mediaInfo.MediaData[mediaCnt].eMediaType = MEDIATYPE_VIDEO_LOCAL_CODER_INFO;
552 :     INIT_IPM_VIDEO_CODER_INFO(&mediaInfo.MediaData[mediaCnt].mediaInfo.VideoCoderInfo);
553 : jtarlton 509 mediaInfo.MediaData[mediaCnt].mediaInfo.VideoCoderInfo.eCoderType = remoteVideoCoder_.coderType;
554 :     mediaInfo.MediaData[mediaCnt].mediaInfo.VideoCoderInfo.unCoderPayloadType = remoteVideoCoder_.coderPayloadType;
555 : jtarlton 390
556 : jtarlton 451 IPM_VIDEO_CODER_INFO_EX localVideoCoderInfoEx;
557 :     INIT_IPM_VIDEO_CODER_INFO_EX(&localVideoCoderInfoEx);
558 : jtarlton 509 localVideoCoderInfoEx.eProfile = remoteVideoCoder_.profile;
559 :     localVideoCoderInfoEx.eLevel = remoteVideoCoder_.level;
560 :     localVideoCoderInfoEx.eImageWidth = remoteVideoCoder_.active_fmt.imageWidth;
561 :     localVideoCoderInfoEx.eImageHeight = remoteVideoCoder_.active_fmt.imageHeight;
562 :     localVideoCoderInfoEx.eFramesPerSec = remoteVideoCoder_.active_fmt.framesPerSec;
563 :     localVideoCoderInfoEx.unBitRate = remoteVideoCoder_.bitRate;
564 :     localVideoCoderInfoEx.eSamplingRate = remoteVideoCoder_.samplingRate;
565 : jtarlton 451 localVideoCoderInfoEx.unVisualConfigSize = 0;
566 :     localVideoCoderInfoEx.szVisualConfiguration = NULL;
567 :     mediaInfo.MediaData[mediaCnt].mediaInfo.VideoCoderInfo.pExtraCoderInfo = &localVideoCoderInfoEx;
568 : jtarlton 515 //LOGINFO("IpmDevice::startMedia() Local VideoCoderInfo: " << std::endl << mediaInfo.MediaData[mediaCnt].mediaInfo.VideoCoderInfo);
569 : jtarlton 451 mediaCnt++;
570 : jtarlton 390
571 : jtarlton 491 /* remote video.
572 : jtarlton 451 */
573 : jtarlton 431 mediaInfo.MediaData[mediaCnt].eMediaType = MEDIATYPE_VIDEO_REMOTE_CODER_INFO;
574 :     INIT_IPM_VIDEO_CODER_INFO(&mediaInfo.MediaData[mediaCnt].mediaInfo.VideoCoderInfo);
575 : jtarlton 500 mediaInfo.MediaData[mediaCnt].mediaInfo.VideoCoderInfo.eCoderType = remoteVideoCoder_.coderType;
576 :     mediaInfo.MediaData[mediaCnt].mediaInfo.VideoCoderInfo.unCoderPayloadType = remoteVideoCoder_.coderPayloadType;
577 : jtarlton 390
578 : jtarlton 431 IPM_VIDEO_CODER_INFO_EX remoteVideoCoderInfoEx;
579 :     INIT_IPM_VIDEO_CODER_INFO_EX(&remoteVideoCoderInfoEx);
580 :     remoteVideoCoderInfoEx.eProfile = remoteVideoCoder_.profile;
581 :     remoteVideoCoderInfoEx.eLevel = remoteVideoCoder_.level;
582 : jtarlton 471 remoteVideoCoderInfoEx.eImageWidth = remoteVideoCoder_.active_fmt.imageWidth;
583 :     remoteVideoCoderInfoEx.eImageHeight = remoteVideoCoder_.active_fmt.imageHeight;
584 :     remoteVideoCoderInfoEx.eFramesPerSec = remoteVideoCoder_.active_fmt.framesPerSec;
585 : jtarlton 431 remoteVideoCoderInfoEx.unBitRate = remoteVideoCoder_.bitRate;
586 :     remoteVideoCoderInfoEx.eSamplingRate = remoteVideoCoder_.samplingRate;
587 :     remoteVideoCoderInfoEx.unVisualConfigSize = 0;
588 :     remoteVideoCoderInfoEx.szVisualConfiguration = NULL;
589 :     mediaInfo.MediaData[mediaCnt].mediaInfo.VideoCoderInfo.pExtraCoderInfo = &remoteVideoCoderInfoEx;
590 : jtarlton 515 //LOGINFO("IpmDevice::startMedia() Remote VideoCoderInfo: " << std::endl << mediaInfo.MediaData[mediaCnt].mediaInfo.VideoCoderInfo);
591 : jtarlton 431 mediaCnt++;
592 : jtarlton 390
593 : jtarlton 491 /* remote video ports and IP addresses.
594 : jtarlton 431 */
595 :     mediaInfo.MediaData[mediaCnt].eMediaType = MEDIATYPE_VIDEO_REMOTE_RTP_INFO;
596 :     copy_string_to_c_array(remote_rtp_video.getAddress(),
597 :     mediaInfo.MediaData[mediaCnt].mediaInfo.PortInfo.cIPAddress,
598 :     IP_ADDR_SIZE);
599 :     mediaInfo.MediaData[mediaCnt].mediaInfo.PortInfo.unPortId = remote_rtp_video.getPort();
600 :     mediaCnt++;
601 :    
602 :     mediaInfo.MediaData[mediaCnt].eMediaType = MEDIATYPE_VIDEO_REMOTE_RTCP_INFO;
603 :     copy_string_to_c_array(remote_rtcp_video.getAddress(),
604 :     mediaInfo.MediaData[mediaCnt].mediaInfo.PortInfo.cIPAddress,
605 :     IP_ADDR_SIZE);
606 :     mediaInfo.MediaData[mediaCnt].mediaInfo.PortInfo.unPortId = remote_rtcp_video.getPort();
607 :     mediaCnt++;
608 :     }
609 :    
610 : jtarlton 491 /* done.
611 : jtarlton 390 */
612 : jtarlton 41 mediaInfo.unCount = mediaCnt;
613 :    
614 : jtarlton 455 LOGDEBUG("IpmDevice::startMedia() starting audio on device: " <<
615 :     getDeviceName() <<
616 : jtarlton 451 " remote_rtp: " << remote_rtp_audio <<
617 :     " remote_rtcp: " << remote_rtcp_audio);
618 : jtarlton 41
619 : jtarlton 451 if ( remote_rtp_video.isValid() )
620 :     {
621 : jtarlton 455 LOGDEBUG("IpmDevice::startMedia() starting video on device: " <<
622 :     getDeviceName() <<
623 : jtarlton 451 " remote_rtp: " << remote_rtp_video <<
624 :     " remote_rtcp: " << remote_rtcp_video);
625 :     }
626 :    
627 : jtarlton 41 if ( ipm_StartMedia(devHandle_, &mediaInfo, DATA_IP_TDM_BIDIRECTIONAL, EV_ASYNC) == -1 )
628 :     {
629 : jtarlton 455 LOGERROR("ipm_StartMedia failed for device: " << getDeviceName() <<
630 : jtarlton 41 " with error: " << ATDV_ERRMSGP(devHandle_));
631 :     return false;
632 :     }
633 : jtarlton 131
634 :     state_ = IPM_STARTING;
635 : jtarlton 321 busy_ = true;
636 :    
637 : jtarlton 41 return true;
638 :     }
639 :    
640 :    
641 :     /*
642 : jtarlton 103 * Forward to event specific handler.
643 :     */
644 :     bool IpmDevice::processEvent( METAEVENT& metaevent )
645 :     {
646 :     switch ( metaevent.evttype )
647 :     {
648 :     case IPMEV_OPEN:
649 :     onOpen();
650 :     break;
651 :    
652 :     case IPMEV_EVENT_ENABLED:
653 : jtarlton 131 onEventEnabled();
654 : jtarlton 103 break;
655 :    
656 :     case IPMEV_GET_LOCAL_MEDIA_INFO:
657 : jtarlton 154 onLocalMediaInfo((IPM_MEDIA_INFO*)sr_getevtdatap());
658 : jtarlton 103 break;
659 :    
660 :     case IPMEV_STARTMEDIA:
661 :     onStartMedia();
662 :     break;
663 :    
664 :     case IPMEV_STOPPED:
665 : jtarlton 275 onStopped();
666 : jtarlton 103 break;
667 :    
668 : amartin 307 case IPMEV_LISTEN:
669 :     onListen();
670 :     break;
671 :    
672 :     case IPMEV_UNLISTEN:
673 :     onUnListen();
674 :     break;
675 :    
676 : jtarlton 103 case IPMEV_ERROR:
677 :     onError();
678 :     break;
679 :    
680 : jtarlton 390 case IPMEV_TELEPHONY_EVENT:
681 : jtarlton 394 onTelephonyEvent((IPM_TELEPHONY_INFO*)sr_getevtdatap());
682 : jtarlton 390 break;
683 :    
684 : jtarlton 103 case DMEV_GET_TX_PORT_INFO:
685 : jtarlton 154 onGetTxPortInfo((DM_PORT_INFO_LIST*)sr_getevtdatap());
686 : jtarlton 103 break;
687 :    
688 :     case DMEV_GET_RX_PORT_INFO:
689 : jtarlton 154 onGetRxPortInfo((DM_PORT_INFO_LIST*)sr_getevtdatap());
690 : jtarlton 103 break;
691 :    
692 :     case DMEV_GET_TX_PORT_INFO_FAIL:
693 :     onPortGetFail();
694 :     break;
695 :    
696 :     case DMEV_GET_RX_PORT_INFO_FAIL:
697 :     onPortGetFail();
698 :     break;
699 :    
700 :     case DMEV_PORT_CONNECT:
701 :     onPortConnect();
702 :     break;
703 :    
704 : jtarlton 390 case DMEV_PORT_CONNECT_FAIL:
705 : amartin 403 onPortConnectFail();
706 : jtarlton 390 break;
707 :    
708 :     case DMEV_PORT_DISCONNECT:
709 :     onPortDisconnect();
710 :     break;
711 :    
712 :     case DMEV_PORT_DISCONNECT_FAIL:
713 : jtarlton 455 LOGERROR("IpmDevice::onPortDisconnectFail() device: " << getDeviceName());
714 : jtarlton 390 break;
715 :    
716 : jtarlton 103 default:
717 : jtarlton 131 LOGWARN("IpmDevice::processEvent() unhandled event: 0x" <<
718 : jtarlton 455 std::hex << metaevent.evttype << " for device: " << getDeviceName());
719 : jtarlton 103 return false;
720 :     }
721 :     return true;
722 :     }
723 :    
724 :    
725 :     /*
726 : jtarlton 64 * Handler for IPMEV_OPEN events.
727 : jtarlton 41 */
728 :     void IpmDevice::onOpen()
729 :     {
730 : jtarlton 455 LOGINFO("IpmDevice::onOpen() device: " << getDeviceName());
731 : jtarlton 41
732 : jtarlton 417 other_ = 0;
733 : jtarlton 316
734 : jtarlton 491 /* Get and save the transmit timeslot on CTBus.
735 : jtarlton 162 */
736 : jtarlton 103 SC_TSINFO tsinfo;
737 : jtarlton 41 tsinfo.sc_numts = 1;
738 : jtarlton 162 tsinfo.sc_tsarrayp = getXmitTimeslotPtr();
739 : jtarlton 41 if ( ipm_GetXmitSlot(devHandle_, &tsinfo, EV_SYNC) == -1 )
740 :     {
741 : jtarlton 140 LOGERROR("ipm_GetXmitSlot() failed" );
742 : jtarlton 41 }
743 :    
744 : jtarlton 394 /* Enable dtmf events.
745 :     */
746 :     eIPM_EVENT event = EVT_RFC2833;
747 :     if ( ipm_EnableEvents(devHandle_, &event, 1, EV_ASYNC) < 0 )
748 :     {
749 :     LOGERROR("ipm_EnableEvent() failed on device:" << devHandle_);
750 :     }
751 :    
752 : jtarlton 491 /* Request port info.
753 : jtarlton 162 */
754 : jtarlton 103 if ( dev_GetTransmitPortInfo(devHandle_, this) == -1 )
755 : jtarlton 41 {
756 : jtarlton 140 LOGERROR("dev_GetTransmitPortInfo() failed");
757 : jtarlton 41 }
758 : jtarlton 103 if ( dev_GetReceivePortInfo(devHandle_, this) == -1 )
759 : jtarlton 41 {
760 : jtarlton 140 LOGERROR("dev_GetReceivePortInfo() failed");
761 : jtarlton 41 }
762 :    
763 : jtarlton 390 /* Request the local media information.
764 : jtarlton 103 */
765 : jtarlton 390 IPM_MEDIA_INFO media_info;
766 :     memset(&media_info, 0, sizeof(IPM_MEDIA_INFO));
767 :     media_info.unCount = 2;
768 :     media_info.MediaData[0].eMediaType = MEDIATYPE_AUDIO_LOCAL_RTP_INFO;
769 :     media_info.MediaData[1].eMediaType = MEDIATYPE_VIDEO_LOCAL_RTP_INFO;
770 : jtarlton 41
771 : jtarlton 390 if ( ipm_GetLocalMediaInfo(devHandle_, &media_info, EV_ASYNC) == -1 )
772 : jtarlton 103 {
773 : jtarlton 390 LOGERROR("ipm_GetLocalMediaInfo() failed for device: " <<
774 : jtarlton 455 getDeviceName() << " with error: " << ATDV_LASTERR(devHandle_));
775 : jtarlton 103 }
776 :    
777 : jtarlton 491 /* update init state.
778 : jtarlton 103 */
779 : jtarlton 41 state_ = IPM_INITIALIZATION_START;
780 :     initStepsRemaining_--;
781 :     if ( initStepsRemaining_ == 0 )
782 :     {
783 :     state_ = IPM_IDLE;
784 :     }
785 :     }
786 :    
787 :    
788 :     /*
789 : jtarlton 64 * Handler for DMEV_GET_TX_PORT_INFO events.
790 : jtarlton 41 */
791 : jtarlton 390 void IpmDevice::onGetTxPortInfo( DM_PORT_INFO_LIST* portInfoList )
792 : jtarlton 41 {
793 : jtarlton 455 LOGINFO("IpmDevice::onGetTxPortInfo() device: " << getDeviceName());
794 : jtarlton 41
795 : jtarlton 390 txPortInfoList_ = *portInfoList;
796 : jtarlton 459 LOGDEBUG(std::endl << txPortInfoList_);
797 : jtarlton 41
798 : jtarlton 390 for ( unsigned int i = 0; i < txPortInfoList_.unCount; i++ )
799 :     {
800 :     switch ( txPortInfoList_.port_info[i].port_media_type )
801 :     {
802 :     case DM_PORT_MEDIA_TYPE_AUDIO:
803 : jtarlton 413 audioPortTxInfo_ = txPortInfoList_.port_info[i];
804 : jtarlton 390 break;
805 :    
806 :     case DM_PORT_MEDIA_TYPE_VIDEO:
807 : jtarlton 413 videoPortTxInfo_ = txPortInfoList_.port_info[i];
808 : jtarlton 390 break;
809 :    
810 :     default:
811 :     break;
812 :     }
813 :     }
814 :    
815 : jtarlton 41 initStepsRemaining_--;
816 :     if ( initStepsRemaining_ == 0 )
817 :     {
818 :     state_ = IPM_IDLE;
819 :     }
820 :     }
821 :    
822 :    
823 :     /*
824 : jtarlton 64 * Handler for DMEV_GET_RX_PORT_INFO events.
825 : jtarlton 41 */
826 : jtarlton 390 void IpmDevice::onGetRxPortInfo( DM_PORT_INFO_LIST* portInfoList )
827 : jtarlton 41 {
828 : jtarlton 455 LOGINFO("IpmDevice::onGetRxPortInfo() device: " << getDeviceName());
829 : jtarlton 41
830 : jtarlton 390 rxPortInfoList_ = *portInfoList;
831 : jtarlton 459 LOGDEBUG(std::endl << rxPortInfoList_);
832 : jtarlton 41
833 : jtarlton 390 for ( unsigned int i = 0; i < rxPortInfoList_.unCount; i++ )
834 :     {
835 :     switch ( rxPortInfoList_.port_info[i].port_media_type )
836 :     {
837 :     case DM_PORT_MEDIA_TYPE_AUDIO:
838 : jtarlton 413 audioPortRxInfo_ = rxPortInfoList_.port_info[i];
839 : jtarlton 390 break;
840 :    
841 :     case DM_PORT_MEDIA_TYPE_VIDEO:
842 : jtarlton 413 videoPortRxInfo_ = rxPortInfoList_.port_info[i];
843 : jtarlton 390 break;
844 :    
845 :     default:
846 :     break;
847 :     }
848 :     }
849 :    
850 : jtarlton 41 initStepsRemaining_--;
851 :     if ( initStepsRemaining_ == 0 )
852 :     {
853 :     state_ = IPM_IDLE;
854 :     }
855 :     }
856 :    
857 :    
858 :     /*
859 : jtarlton 64 * Handler for DMEV_GET_TX_PORT_INFO_FAIL and DMEV_GET_RX_PORT_INFO_FAIL
860 :     * events.
861 : jtarlton 41 */
862 :     void IpmDevice::onPortGetFail()
863 :     {
864 : jtarlton 455 LOGINFO("IpmDevice::onPortGetFail() device: " << getDeviceName());
865 : jtarlton 103
866 : jtarlton 41 state_ = IPM_INVALID;
867 :     }
868 :    
869 :    
870 :     /*
871 : jtarlton 64 * Handler for IPMEV_ERROR events.
872 : jtarlton 41 */
873 :     void IpmDevice::onError()
874 :     {
875 : jtarlton 455 LOGERROR("IpmDevice::onError() device: " << getDeviceName() <<
876 : jtarlton 41 " error: " << ATDV_ERRMSGP(devHandle_));
877 : jtarlton 103
878 : jtarlton 41 state_ = IPM_INVALID;
879 :     }
880 :    
881 :    
882 :     /*
883 : jtarlton 394 * Handler for IPMEV_TELEPHONY_EVENT events.
884 :     */
885 :     void IpmDevice::onTelephonyEvent( IPM_TELEPHONY_INFO* info )
886 :     {
887 : jtarlton 455 LOGINFO("IpmDevice::processEvent() IPMEV_TELEPHONY_EVENT device: " << getDeviceName() );
888 : jtarlton 394 const std::string dtmf = "0123456789*#";
889 :    
890 :     switch ( info->eTelInfoType )
891 :     {
892 :     case TEL_INFOTYPE_EVENT:
893 :     {
894 :     int event_id = info->TelephonyInfo.TelEvtInfo.eTelephonyEventID;
895 : jtarlton 396 LOGDEBUG("TelephonyEventID: 0x" << std::hex << event_id);
896 : jtarlton 394 if ( event_id >= 0 && event_id <= 11 )
897 :     {
898 : jtarlton 426 channelMgr_.onDtmf(ipt_, dtmf[event_id], 100); /* fake duration */
899 : jtarlton 394 }
900 :     break;
901 :     }
902 :    
903 :     default:
904 :     break;
905 :    
906 :     }
907 :     }
908 :    
909 :    
910 :     /*
911 : jtarlton 390 * Handler for IPMEV_GET_LOCAL_MEDIA_INFO events.
912 :     */
913 :     void IpmDevice::onLocalMediaInfo( IPM_MEDIA_INFO* mediaInfo )
914 :     {
915 : jtarlton 455 LOGINFO("IpmDevice::onLocalMediaInfo() device: " << getDeviceName());
916 : jtarlton 459 LOGDEBUG(std::endl << *mediaInfo);
917 : jtarlton 390
918 :     for( unsigned int i = 0; i < mediaInfo->unCount; i++ )
919 :     {
920 :     switch ( mediaInfo->MediaData[i].eMediaType )
921 :     {
922 :     case MEDIATYPE_AUDIO_LOCAL_RTP_INFO:
923 :     localRtpAudio_.setAddress(mediaInfo->MediaData[i].mediaInfo.PortInfo.cIPAddress);
924 :     localRtpAudio_.setPort(mediaInfo->MediaData[i].mediaInfo.PortInfo.unPortId);
925 :     break;
926 :    
927 :     case MEDIATYPE_AUDIO_LOCAL_RTCP_INFO:
928 :     localRtcpAudio_.setAddress(mediaInfo->MediaData[i].mediaInfo.PortInfo.cIPAddress);
929 :     localRtcpAudio_.setPort(mediaInfo->MediaData[i].mediaInfo.PortInfo.unPortId);
930 :     break;
931 :    
932 :     case MEDIATYPE_VIDEO_LOCAL_RTP_INFO:
933 :     localRtpVideo_.setAddress(mediaInfo->MediaData[i].mediaInfo.PortInfo.cIPAddress);
934 :     localRtpVideo_.setPort(mediaInfo->MediaData[i].mediaInfo.PortInfo.unPortId);
935 :     break;
936 :    
937 :     case MEDIATYPE_VIDEO_LOCAL_RTCP_INFO:
938 :     localRtcpVideo_.setAddress(mediaInfo->MediaData[i].mediaInfo.PortInfo.cIPAddress);
939 :     localRtcpVideo_.setPort(mediaInfo->MediaData[i].mediaInfo.PortInfo.unPortId);
940 :     break;
941 :    
942 :     default:
943 :     break;
944 :     }
945 :     }
946 :     }
947 :    
948 :    
949 :     /*
950 : jtarlton 491 * Handler for IPMEV_EVENT_ENABLED events.
951 : jtarlton 41 */
952 : jtarlton 64 void IpmDevice::onEventEnabled()
953 : jtarlton 41 {
954 : jtarlton 455 LOGINFO("IpmDevice::onEventEnabled() device: " << getDeviceName());
955 : jtarlton 103
956 : jtarlton 41 initStepsRemaining_--;
957 :     if ( initStepsRemaining_ == 0 )
958 :     {
959 :     state_ = IPM_IDLE;
960 :     }
961 :     }
962 :    
963 :    
964 :     /*
965 : jtarlton 64 * Handler for IPMEV_STARTMEDIA events.
966 : jtarlton 41 */
967 :     void IpmDevice::onStartMedia()
968 :     {
969 : jtarlton 455 LOGINFO("IpmDevice::onStartMedia() device: " << getDeviceName());
970 : jtarlton 321 state_ = IPM_STREAMING;
971 :     busy_ = false;
972 :     processPendingCommand();
973 : jtarlton 41 }
974 :    
975 :    
976 :     /*
977 : jtarlton 64 * Handler for IPMEV_STOPPED events.
978 : jtarlton 41 */
979 :     void IpmDevice::onStopped()
980 :     {
981 : jtarlton 455 LOGINFO("IpmDevice::onStopped() device: " << getDeviceName());
982 : jtarlton 41 state_ = IPM_IDLE;
983 : jtarlton 321 busy_ = false;
984 :     processPendingCommand();
985 : jtarlton 41 }
986 :    
987 :    
988 :     /*
989 : jtarlton 390 * Handler for IPMEV_LISTEN events.
990 : jtarlton 41 */
991 : jtarlton 390 void IpmDevice::onListen()
992 : jtarlton 41 {
993 : jtarlton 455 LOGINFO("IpmDevice::onListen() device: " << getDeviceName());
994 : jtarlton 390 busy_ = false;
995 :     processPendingCommand();
996 :     }
997 : jtarlton 103
998 : jtarlton 390
999 :     /*
1000 :     * Handler for IPMEV__UNLISTEN events.
1001 :     */
1002 :     void IpmDevice::onUnListen()
1003 :     {
1004 : jtarlton 455 LOGINFO("IpmDevice::onUnListen() device: " << getDeviceName());
1005 : jtarlton 390 busy_ = false;
1006 :     processPendingCommand();
1007 : jtarlton 41 }
1008 :    
1009 : jtarlton 311
1010 : amartin 307 /*
1011 : jtarlton 390 * Handler for DMEV_PORT_CONNECT events.
1012 : amartin 307 */
1013 : jtarlton 390 void IpmDevice::onPortConnect()
1014 : amartin 307 {
1015 : jtarlton 455 LOGINFO("IpmDevice::onPortConnect() device: " << getDeviceName());
1016 : jtarlton 321 busy_ = false;
1017 :     processPendingCommand();
1018 : amartin 307 }
1019 : jtarlton 41
1020 : amartin 403 /*
1021 :     * Handler for DMEV_PORT_CONNECT_FAIL events.
1022 :     */
1023 :     void IpmDevice::onPortConnectFail()
1024 :     {
1025 : jtarlton 455 LOGERROR("IpmDevice::onPortConnectFail() device: " << getDeviceName());
1026 : amartin 403 busy_ = false;
1027 :     processPendingCommand();
1028 :     }
1029 : jtarlton 311
1030 : amartin 307 /*
1031 : jtarlton 390 * Handler for DMEV_PORT_DISCONNECT events.
1032 : amartin 307 */
1033 : jtarlton 390 void IpmDevice::onPortDisconnect()
1034 : amartin 307 {
1035 : jtarlton 455 LOGINFO("IpmDevice::onPortDisconnect() device: " << getDeviceName());
1036 : jtarlton 321 busy_ = false;
1037 :     processPendingCommand();
1038 : amartin 307 }
1039 : jtarlton 103
1040 : jtarlton 311
1041 : jtarlton 103 /*
1042 : jtarlton 431 * Set the dtmf signalling mode.
1043 : jtarlton 491 * XXX add support for SIP INFO (need to process message body ourselves).
1044 : jtarlton 390 */
1045 : jtarlton 431 void IpmDevice::setDtmfMode( DtmfMode dtmf_mode )
1046 : jtarlton 390 {
1047 : jtarlton 431 IPM_PARM_INFO parmInfo;
1048 :    
1049 :     switch ( dtmf_mode )
1050 :     {
1051 :     case DTMF_RFC2833:
1052 :     {
1053 :     eIPM_DTMFXFERMODE value = DTMFXFERMODE_RFC2833;
1054 :     parmInfo.eParm = PARMCH_DTMFXFERMODE;
1055 :     parmInfo.pvParmValue = &value;
1056 :     LOGINFO("IpmDevice::setDtmfMode() using RFC2833");
1057 :     if ( ipm_SetParm(devHandle_, &parmInfo, EV_SYNC) < 0 )
1058 :     {
1059 : jtarlton 490 LOGERROR("ipm_SetParm() DTMFXFERMODE_RFC2833");
1060 : jtarlton 431 }
1061 :    
1062 :     parmInfo.eParm = PARMCH_RFC2833EVT_TX_PLT;
1063 : jtarlton 490 parmInfo.pvParmValue = &rfc2833_payload_type_;
1064 : jtarlton 431 if ( ipm_SetParm(devHandle_, &parmInfo, EV_SYNC) < 0 )
1065 :     {
1066 : jtarlton 490 LOGERROR("ipm_SetParm() PARMCH_RFC2833EVT_TX_PLT " << rfc2833_payload_type_);
1067 : jtarlton 431 }
1068 :    
1069 :     parmInfo.eParm = PARMCH_RFC2833EVT_RX_PLT;
1070 : jtarlton 490 parmInfo.pvParmValue = &rfc2833_payload_type_;
1071 : jtarlton 431 if ( ipm_SetParm(devHandle_, &parmInfo, EV_SYNC) < 0 )
1072 :     {
1073 : jtarlton 490 LOGERROR("ipm_SetParm() PARMCH_RFC2833EVT_RX_PLT " << rfc2833_payload_type_);
1074 : jtarlton 431 }
1075 :     }
1076 :     break;
1077 :    
1078 :     case DTMF_INBAND:
1079 :     {
1080 :     eIPM_DTMFXFERMODE value = DTMFXFERMODE_INBAND;
1081 :     parmInfo.eParm = PARMCH_DTMFXFERMODE;
1082 :     parmInfo.pvParmValue = &value;
1083 :    
1084 :     LOGINFO("IpmDevice::setDtmfMode() using inband audio");
1085 :     if ( ipm_SetParm(devHandle_, &parmInfo, EV_SYNC) < 0 )
1086 :     {
1087 : jtarlton 490 LOGERROR("ipm_SetParm() DTMFXFERMODE_INBAND");
1088 : jtarlton 431 }
1089 :     }
1090 :     break;
1091 :     }
1092 :     }
1093 :    
1094 :    
1095 : jtarlton 451 /*
1096 : jtarlton 431 * Convert a minimum-picture-interval to frames-per-second.
1097 : jtarlton 491 * RFC4629: fps = 30 / (1.001 * the specified value).
1098 : jtarlton 431 */
1099 : jtarlton 451 int IpmDevice::mpi2fps( int mpi )
1100 : jtarlton 431 {
1101 :     int fps;
1102 :     switch ( mpi )
1103 :     {
1104 :     case 1:
1105 :     fps = VIDEO_FRAMESPERSEC_2997;
1106 :     break;
1107 :    
1108 :     case 2:
1109 :     fps = VIDEO_FRAMESPERSEC_15;
1110 :     break;
1111 :    
1112 :     case 3:
1113 :     fps = VIDEO_FRAMESPERSEC_10;
1114 :     break;
1115 :    
1116 :     case 5:
1117 :     fps = VIDEO_FRAMESPERSEC_6;
1118 :     break;
1119 :    
1120 :     default:
1121 :     fps = VIDEO_FRAMESPERSEC_DEFAULT;
1122 :     break;
1123 :     }
1124 :     return fps;
1125 :     }
1126 :    
1127 : jtarlton 451
1128 :     /*
1129 : jtarlton 431 * Convert frames-per-second to a minimum-picture-interval.
1130 : jtarlton 491 * RFC4629: fps = 30 / (1.001 * the specified value).
1131 : jtarlton 431 */
1132 : jtarlton 451 int IpmDevice::fps2mpi( eVIDEO_FRAMESPERSEC fps )
1133 : jtarlton 431 {
1134 :     int mpi;
1135 :     switch ( fps )
1136 :     {
1137 :     case VIDEO_FRAMESPERSEC_6:
1138 :     mpi = 5;
1139 :     break;
1140 :    
1141 :     case VIDEO_FRAMESPERSEC_10:
1142 :     mpi = 3;
1143 :     break;
1144 :    
1145 :     case VIDEO_FRAMESPERSEC_2997:
1146 :     case VIDEO_FRAMESPERSEC_30:
1147 :     mpi = 1;
1148 :     break;
1149 :    
1150 :     default: /* 15 fps */
1151 :     mpi = 2;
1152 :     break;
1153 :     }
1154 :     return mpi;
1155 :     }
1156 :    
1157 :    
1158 :     /*
1159 :     * offer sdpS contain all available codecs.
1160 :     */
1161 : jtarlton 490 void IpmDevice::buildOfferSdp( SdpSessionDescription& sdp )
1162 : jtarlton 431 {
1163 : jtarlton 390 /* get here so it can be used for the origin address */
1164 : jtarlton 431 IpInfo local_audio_rtp;
1165 :     getLocalMediaInfo(MEDIATYPE_AUDIO_LOCAL_RTP_INFO, local_audio_rtp);
1166 : jtarlton 390
1167 :     sdp.version()->setVersion("0");
1168 :    
1169 :     sdp.origin()->setUserName("DiaStarServer");
1170 :     sdp.origin()->setNetworkType("IN");
1171 :     sdp.origin()->setAddressType("IP4");
1172 : jtarlton 431 sdp.origin()->setAddress(local_audio_rtp.getAddress().c_str());
1173 : jtarlton 390
1174 : jtarlton 451 /* use a common c= for all media */
1175 :     sdp.connection()->setNetworkType("IN");
1176 :     sdp.connection()->setAddressType("IP4");
1177 :     sdp.connection()->setAddress(local_audio_rtp.getAddress().c_str());
1178 :    
1179 : jtarlton 390 time_t t;
1180 :     time(&t);
1181 :     std::stringstream sessionIdandVersion;
1182 :     sessionIdandVersion << t;
1183 :     sdp.origin()->setSessionId(sessionIdandVersion.str().c_str());
1184 :     sdp.origin()->setVersion(sessionIdandVersion.str().c_str());
1185 :    
1186 :     sdp.sessionName()->setName("DiaStarServer");
1187 :    
1188 : jtarlton 431 SdpTimeDescription* timeDescription = sdp.timeDescriptionList()->addItem();
1189 : jtarlton 390 timeDescription->time()->setStart(0);
1190 :     timeDescription->time()->setStop(0);
1191 :    
1192 :     /* media
1193 :     */
1194 : jtarlton 431 SdpMediaDescriptionList* mdList = sdp.mediaDescriptionList();
1195 : jtarlton 390 mdList->clear();
1196 :    
1197 : jtarlton 471 /* m=audio
1198 : jtarlton 390 */
1199 : jtarlton 431 const Coders::audio_coders_t& audioCoders = channelMgr_.getAudioCoders();
1200 : jtarlton 471 if ( audioCoders.size() > 0 )
1201 : jtarlton 431 {
1202 :     SdpMediaDescription* audioMD = mdList->addItem();
1203 :     SdpMedia* audioMedia = audioMD->media();
1204 :     audioMedia->setMedia("audio");
1205 :     audioMedia->setPort(local_audio_rtp.getPort());
1206 :     audioMedia->setTransport("RTP/AVP");
1207 :     audioMedia->setNumPorts(1);
1208 :    
1209 : jtarlton 471 SdpAttributeList* audioAttrList = audioMD->attributeList();
1210 :     SdpAttribute* audioAttribute;
1211 :    
1212 :     Coders::audio_coders_t::const_iterator i;
1213 :     for ( i = audioCoders.begin(); i != audioCoders.end(); ++i )
1214 : jtarlton 431 {
1215 : jtarlton 471 const AudioCoderInfo& audio_coder_info = *i;
1216 :    
1217 :     if ( audio_coder_info.coderType == CODER_TYPE_G711ULAW64K )
1218 :     {
1219 :     audioMedia->addFormat("0");
1220 :     audioAttribute = audioAttrList->addItem();
1221 :     audioAttribute->setProperty("rtpmap");
1222 :     audioAttribute->setPropertyValue("0 PCMU/8000");
1223 :     }
1224 :     else if ( audio_coder_info.coderType == CODER_TYPE_G711ALAW64K )
1225 :     {
1226 :     audioMedia->addFormat("8");
1227 :     audioAttribute = audioAttrList->addItem();
1228 :     audioAttribute->setProperty("rtpmap");
1229 :     audioAttribute->setPropertyValue("8 PCMA/8000");
1230 :     }
1231 :     else
1232 :     {
1233 :     /* more */
1234 :     }
1235 : jtarlton 431 }
1236 : jtarlton 490 if ( dtmf_mode_ == DTMF_RFC2833 )
1237 :     {
1238 :     rfc2833_payload_type_ = 101;
1239 : jtarlton 431
1240 : jtarlton 490 std::stringstream payload;
1241 :     payload << rfc2833_payload_type_;
1242 :     audioMedia->addFormat(payload.str().c_str());
1243 :    
1244 :     audioAttribute = audioAttrList->addItem();
1245 :     audioAttribute->setProperty("rtpmap");
1246 :     std::string rtpmap = payload.str() + " telephone-event/8000";
1247 :     audioAttribute->setPropertyValue(rtpmap.c_str());
1248 :     }
1249 :    
1250 : jtarlton 431 audioAttribute = audioAttrList->addItem();
1251 :     audioAttribute->setProperty("sendrecv");
1252 :     audioAttribute->setPropertyValue("");
1253 :     }
1254 :    
1255 : jtarlton 471 /* m=video
1256 : jtarlton 431 */
1257 :     const Coders::video_coders_t& videoCoders = channelMgr_.getVideoCoders();
1258 : jtarlton 471 if ( videoCoders.size() > 0 )
1259 : jtarlton 431 {
1260 :     IpInfo local_video_rtp;
1261 :     if ( getLocalMediaInfo(MEDIATYPE_VIDEO_LOCAL_RTP_INFO, local_video_rtp) )
1262 :     {
1263 :     SdpMediaDescription* videoMD = mdList->addItem();
1264 :     SdpMedia* videoMedia = videoMD->media();
1265 :     videoMedia->setMedia("video");
1266 :     videoMedia->setPort(local_video_rtp.getPort());
1267 :     videoMedia->setTransport("RTP/AVP");
1268 :     videoMedia->setNumPorts(1);
1269 :    
1270 : jtarlton 471 SdpAttributeList* videoAttrList = videoMD->attributeList();
1271 : jtarlton 533 SdpAttribute* videoAttribute;
1272 : jtarlton 471
1273 :     Coders::video_coders_t::const_iterator j;
1274 :     for ( j = videoCoders.begin(); j != videoCoders.end(); ++j )
1275 : jtarlton 431 {
1276 : jtarlton 533 const VideoCoderInfo& video_coder_info = *j;
1277 : jtarlton 431
1278 : jtarlton 533 if ( (video_coder_info.coderType == CODER_TYPE_H263) ||
1279 : jtarlton 471 (video_coder_info.coderType == CODER_TYPE_H263_1998) )
1280 :     {
1281 :     std::stringstream payload;
1282 :     payload.str("");
1283 :     payload << video_coder_info.coderPayloadType;
1284 :     videoMedia->addFormat(payload.str().c_str());
1285 : jtarlton 464
1286 : jtarlton 533 videoAttribute = videoAttrList->addItem();
1287 : jtarlton 471 std::stringstream rtpmap;
1288 :     rtpmap.str("");
1289 :     rtpmap << video_coder_info.coderPayloadType << " ";
1290 : jtarlton 500 rtpmap << video_coder_info.encoding << '/' << 90000;
1291 : jtarlton 471 videoAttribute->setProperty("rtpmap");
1292 :     videoAttribute->setPropertyValue(rtpmap.str().c_str());
1293 :    
1294 :     videoAttribute = videoAttrList->addItem();
1295 :     videoAttribute->setProperty("fmtp");
1296 :     std::stringstream fmtp;
1297 :     fmtp.str("");
1298 :     fmtp << video_coder_info.coderPayloadType << " ";
1299 :     std::vector<VideoCoderInfo::Fmt>::const_iterator k = video_coder_info.available_fmts.begin();
1300 :     while ( k != video_coder_info.available_fmts.end() )
1301 :     {
1302 :     if ( ((*k).imageWidth == VIDEO_IMAGE_WIDTH_352) &&
1303 :     ((*k).imageHeight == VIDEO_IMAGE_HEIGHT_288) )
1304 :     {
1305 :     fmtp << "CIF=";
1306 :     }
1307 :     else if ( ((*k).imageWidth == VIDEO_IMAGE_WIDTH_176) &&
1308 :     ((*k).imageHeight == VIDEO_IMAGE_HEIGHT_144) )
1309 :     {
1310 :     fmtp << "QCIF=";
1311 :     }
1312 :     else
1313 :     {
1314 :     ;
1315 :     }
1316 :     fmtp << fps2mpi((*k).framesPerSec);
1317 :     if ( ++k != video_coder_info.available_fmts.end() )
1318 :     {
1319 :     fmtp << ';';
1320 :     }
1321 :     }
1322 :     videoAttribute->setPropertyValue(fmtp.str().c_str());
1323 : jtarlton 431 }
1324 : jtarlton 533 else if ( video_coder_info.coderType == CODER_TYPE_MP4V_ES )
1325 :     {
1326 :     std::stringstream payload;
1327 :     payload << video_coder_info.coderPayloadType;
1328 :     videoMedia->addFormat(payload.str().c_str());
1329 : jtarlton 431
1330 : jtarlton 533 videoAttribute = videoAttrList->addItem();
1331 :     std::stringstream rtpmap;
1332 :     rtpmap << video_coder_info.coderPayloadType << " ";
1333 :     rtpmap << video_coder_info.encoding << '/' << 90000;
1334 :     SdpAttributeList* videoAttrList = videoMD->attributeList();
1335 :     SdpAttribute* videoAttribute = videoAttrList->addItem();
1336 :     videoAttribute->setProperty("rtpmap");
1337 :     videoAttribute->setPropertyValue(rtpmap.str().c_str());
1338 :    
1339 :     videoAttribute = videoAttrList->addItem();
1340 :     videoAttribute->setProperty("fmtp");
1341 :     std::stringstream fmtp;
1342 :     fmtp.str("");
1343 :     fmtp << video_coder_info.coderPayloadType << " ";
1344 :     std::vector<VideoCoderInfo::Fmt>::const_iterator k = video_coder_info.available_fmts.begin();
1345 :     while ( k != video_coder_info.available_fmts.end() )
1346 :     {
1347 :     if ( video_coder_info.profile == VIDEO_PROFILE_LEVEL_SP0_MPEG4 )
1348 :     {
1349 :     fmtp << "profile-level-id=0";
1350 :     }
1351 :     else if ( video_coder_info.profile == VIDEO_PROFILE_LEVEL_SP1_MPEG4 )
1352 :     {
1353 :     fmtp << "profile-level-id=1";
1354 :     }
1355 :     else if ( video_coder_info.profile == VIDEO_PROFILE_LEVEL_SP2_MPEG4 )
1356 :     {
1357 :     fmtp << "profile-level-id=2";
1358 :     }
1359 :     else if ( video_coder_info.profile == VIDEO_PROFILE_LEVEL_SP3_MPEG4 )
1360 :     {
1361 :     fmtp << "profile-level-id=3";
1362 :     }
1363 :     if ( ++k != video_coder_info.available_fmts.end() )
1364 :     {
1365 :     fmtp << ';';
1366 :     }
1367 :     }
1368 :     videoAttribute->setPropertyValue(fmtp.str().c_str());
1369 :     }
1370 : jtarlton 431 }
1371 : jtarlton 533
1372 :     videoAttribute = videoAttrList->addItem();
1373 :     videoAttribute->setProperty("sendrecv");
1374 :     videoAttribute->setPropertyValue("");
1375 :    
1376 :     std::stringstream bandwidth;
1377 :     bandwidth << 384;
1378 :     videoMD->bandwidth()->setModifier("AS");
1379 :     videoMD->bandwidth()->setBandwidthValue(bandwidth.str().c_str());
1380 : jtarlton 431 }
1381 :     }
1382 :     }
1383 :    
1384 : jtarlton 455
1385 : jtarlton 431 /*
1386 : jtarlton 471 * Answer sdpS return all 'm' (media) headers that were 'offered'.
1387 :     * Unused/unsupported ones have their port set to 0.
1388 : jtarlton 431 */
1389 : jtarlton 490 void IpmDevice::buildAnswerSdp( SdpSessionDescription& sdp )
1390 : jtarlton 431 {
1391 :     /* get here so it can be used for the origin address */
1392 :     IpInfo local_audio_rtp;
1393 :     getLocalMediaInfo(MEDIATYPE_AUDIO_LOCAL_RTP_INFO, local_audio_rtp);
1394 :    
1395 :     sdp.version()->setVersion("0");
1396 :    
1397 :     sdp.origin()->setUserName("DiaStarServer");
1398 :     sdp.origin()->setNetworkType("IN");
1399 :     sdp.origin()->setAddressType("IP4");
1400 :     sdp.origin()->setAddress(local_audio_rtp.getAddress().c_str());
1401 :    
1402 : jtarlton 451 /* use a common c= for all media */
1403 :     sdp.connection()->setNetworkType("IN");
1404 :     sdp.connection()->setAddressType("IP4");
1405 :     sdp.connection()->setAddress(local_audio_rtp.getAddress().c_str());
1406 :    
1407 : jtarlton 431 time_t t;
1408 :     time(&t);
1409 :     std::stringstream sessionIdandVersion;
1410 :     sessionIdandVersion << t;
1411 :     sdp.origin()->setSessionId(sessionIdandVersion.str().c_str());
1412 :     sdp.origin()->setVersion(sessionIdandVersion.str().c_str());
1413 :    
1414 :     sdp.sessionName()->setName("DiaStarServer");
1415 :    
1416 :     SdpTimeDescription* timeDescription = sdp.timeDescriptionList()->addItem();
1417 :     timeDescription->time()->setStart(0);
1418 :     timeDescription->time()->setStop(0);
1419 :    
1420 : jtarlton 447 /*
1421 :     * media
1422 : jtarlton 431 */
1423 :     SdpMediaDescriptionList* mdList = sdp.mediaDescriptionList();
1424 :     mdList->clear();
1425 :    
1426 : jtarlton 471 /* m=audio
1427 : jtarlton 431 */
1428 : jtarlton 490 SdpMediaDescription* audioMD = mdList->addItem();
1429 :     SdpMedia* audioMedia = audioMD->media();
1430 :     audioMedia->setMedia("audio");
1431 :     audioMedia->setPort(local_audio_rtp.getPort());
1432 :     audioMedia->setTransport("RTP/AVP");
1433 :     audioMedia->setNumPorts(1);
1434 :    
1435 : jtarlton 500 unsigned int accepted = 0;
1436 : jtarlton 447 RemoteMedia::audio_t::const_iterator i;
1437 :     for ( i = offered_media_.audio.begin(); i != offered_media_.audio.end(); ++i )
1438 :     {
1439 : jtarlton 491 /* chosen codec.
1440 : jtarlton 464 */
1441 : jtarlton 490 if ( (*i).coder == remoteAudioCoder_ )
1442 : jtarlton 447 {
1443 :     SdpAttributeList* audioAttrList = audioMD->attributeList();
1444 :     SdpAttribute* audioAttribute = audioAttrList->addItem();
1445 :     audioAttribute->setProperty("rtpmap");
1446 : jtarlton 471
1447 : jtarlton 447 if ( remoteAudioCoder_.coderType == CODER_TYPE_G711ULAW64K )
1448 :     {
1449 : jtarlton 471 audioMedia->addFormat("0");
1450 : jtarlton 447 audioAttribute->setPropertyValue("0 PCMU/8000");
1451 :     }
1452 :     else if ( remoteAudioCoder_.coderType == CODER_TYPE_G711ALAW64K )
1453 :     {
1454 : jtarlton 471 audioMedia->addFormat("8");
1455 : jtarlton 447 audioAttribute->setPropertyValue("8 PCMA/8000");
1456 :     }
1457 : jtarlton 464 else
1458 :     {
1459 :     ;
1460 :     }
1461 : jtarlton 447 audioAttribute = audioAttrList->addItem();
1462 :     audioAttribute->setProperty((*i).direction.c_str());
1463 :     audioAttribute->setPropertyValue("");
1464 : jtarlton 500
1465 :     accepted++;
1466 : jtarlton 490 }
1467 : jtarlton 451
1468 : jtarlton 490 if ( (*i).rfc2833 && (dtmf_mode_ == DTMF_RFC2833) )
1469 :     {
1470 : jtarlton 491 /* save the offered payload type as it may differ from the local default. */
1471 : jtarlton 490 rfc2833_payload_type_ = (*i).coder.coderPayloadType;
1472 :    
1473 :     std::stringstream payload;
1474 :     payload << rfc2833_payload_type_;
1475 :     audioMedia->addFormat(payload.str().c_str());
1476 :    
1477 :     SdpAttributeList* audioAttrList = audioMD->attributeList();
1478 :     SdpAttribute* audioAttribute = audioAttrList->addItem();
1479 :     audioAttribute->setProperty("rtpmap");
1480 :     std::string rtpmap = payload.str() + " telephone-event/8000";
1481 :     audioAttribute->setPropertyValue(rtpmap.c_str());
1482 : jtarlton 500
1483 :     accepted++;
1484 : jtarlton 447 }
1485 : jtarlton 451 }
1486 : jtarlton 490
1487 : jtarlton 471 /* rejected media, send m= with port set to zero.
1488 : jtarlton 451 */
1489 : jtarlton 500 if ( (i == offered_media_.audio.end()) || (offered_media_.audio.size() > accepted) )
1490 : jtarlton 451 {
1491 : jtarlton 490 SdpMediaDescription* audioMD = mdList->addItem();
1492 :     SdpMedia* audioMedia = audioMD->media();
1493 :     audioMedia->setMedia("audio");
1494 :     audioMedia->setPort(0); /* important! */
1495 :     audioMedia->setTransport("RTP/AVP");
1496 :     audioMedia->setNumPorts(1);
1497 :    
1498 : jtarlton 451 for ( i = offered_media_.audio.begin(); i != offered_media_.audio.end(); ++i )
1499 : jtarlton 447 {
1500 : jtarlton 490 if ( ((*i).coder != remoteAudioCoder_ ) &&
1501 :     !((*i).rfc2833 && (dtmf_mode_ == DTMF_RFC2833)) )
1502 :     {
1503 :     std::stringstream payload;
1504 :     payload << (*i).coder.coderPayloadType;
1505 :     audioMedia->addFormat(payload.str().c_str());
1506 :     payload.str("");
1507 :     }
1508 : jtarlton 447 }
1509 : jtarlton 431 }
1510 : jtarlton 390
1511 : jtarlton 471 /* m=video
1512 : jtarlton 390 */
1513 : jtarlton 451 IpInfo local_video_rtp;
1514 :     getLocalMediaInfo(MEDIATYPE_VIDEO_LOCAL_RTP_INFO, local_video_rtp);
1515 :    
1516 :     RemoteMedia::video_t::const_iterator j;
1517 :     for ( j = offered_media_.video.begin(); j != offered_media_.video.end(); ++j )
1518 : jtarlton 390 {
1519 : jtarlton 491 /* chosen codec.
1520 : jtarlton 464 */
1521 : jtarlton 490 if ( (*j).coder == remoteVideoCoder_ )
1522 : jtarlton 447 {
1523 :     SdpMediaDescription* videoMD = mdList->addItem();
1524 :     SdpMedia* videoMedia = videoMD->media();
1525 :     videoMedia->setMedia("video");
1526 :     videoMedia->setPort(local_video_rtp.getPort());
1527 :     videoMedia->setTransport("RTP/AVP");
1528 :     videoMedia->setNumPorts(1);
1529 : jtarlton 390
1530 : jtarlton 536 if ( (remoteVideoCoder_.coderType == CODER_TYPE_H263) ||
1531 : jtarlton 471 (remoteVideoCoder_.coderType == CODER_TYPE_H263_1998) )
1532 : jtarlton 431 {
1533 : jtarlton 471 std::stringstream payload;
1534 :     payload << remoteVideoCoder_.coderPayloadType;
1535 :     videoMedia->addFormat(payload.str().c_str());
1536 : jtarlton 390
1537 : jtarlton 464 std::stringstream rtpmap;
1538 : jtarlton 471 rtpmap << remoteVideoCoder_.coderPayloadType << " ";
1539 : jtarlton 500 rtpmap << remoteVideoCoder_.encoding << '/' << 90000;
1540 : jtarlton 464 SdpAttributeList* videoAttrList = videoMD->attributeList();
1541 :     SdpAttribute* videoAttribute = videoAttrList->addItem();
1542 :     videoAttribute->setProperty("rtpmap");
1543 :     videoAttribute->setPropertyValue(rtpmap.str().c_str());
1544 :    
1545 :     videoAttribute = videoAttrList->addItem();
1546 :     videoAttribute->setProperty("fmtp");
1547 :     std::stringstream fmtp;
1548 : jtarlton 533 fmtp << remoteVideoCoder_.coderPayloadType << " " << remoteVideoCoder_.active_fmt.fmtpName;
1549 : jtarlton 464 videoAttribute->setPropertyValue(fmtp.str().c_str());
1550 : jtarlton 431
1551 : jtarlton 464 videoAttribute = videoAttrList->addItem();
1552 :     videoAttribute->setProperty((*j).direction.c_str());
1553 :     videoAttribute->setPropertyValue("");
1554 : jtarlton 431
1555 : jtarlton 464 std::stringstream bandwidth;
1556 : jtarlton 490 bandwidth << 384;
1557 : jtarlton 464 videoMD->bandwidth()->setModifier("AS");
1558 :     videoMD->bandwidth()->setBandwidthValue(bandwidth.str().c_str());
1559 : jtarlton 431 }
1560 : jtarlton 500 else if ( remoteVideoCoder_.coderType == CODER_TYPE_MP4V_ES )
1561 :     {
1562 :     std::stringstream payload;
1563 :     payload << remoteVideoCoder_.coderPayloadType;
1564 :     videoMedia->addFormat(payload.str().c_str());
1565 :    
1566 :     std::stringstream rtpmap;
1567 :     rtpmap << remoteVideoCoder_.coderPayloadType << " ";
1568 :     rtpmap << remoteVideoCoder_.encoding << '/' << 90000;
1569 :     SdpAttributeList* videoAttrList = videoMD->attributeList();
1570 :     SdpAttribute* videoAttribute = videoAttrList->addItem();
1571 :     videoAttribute->setProperty("rtpmap");
1572 :     videoAttribute->setPropertyValue(rtpmap.str().c_str());
1573 :    
1574 :     videoAttribute = videoAttrList->addItem();
1575 :     videoAttribute->setProperty("fmtp");
1576 :     std::stringstream fmtp;
1577 : jtarlton 533 fmtp << remoteVideoCoder_.coderPayloadType << " " << remoteVideoCoder_.active_fmt.fmtpName;
1578 : jtarlton 500 videoAttribute->setPropertyValue(fmtp.str().c_str());
1579 :    
1580 :     videoAttribute = videoAttrList->addItem();
1581 :     videoAttribute->setProperty((*j).direction.c_str());
1582 :     videoAttribute->setPropertyValue("");
1583 :    
1584 :     std::stringstream bandwidth;
1585 :     bandwidth << 384;
1586 :     videoMD->bandwidth()->setModifier("AS");
1587 :     videoMD->bandwidth()->setBandwidthValue(bandwidth.str().c_str());
1588 :     }
1589 :     else
1590 :     {
1591 :     /* more coders */
1592 :     }
1593 : jtarlton 451 break;
1594 : jtarlton 431 }
1595 : jtarlton 451 }
1596 : jtarlton 471 /* rejected media, send m= with port set to zero.
1597 : jtarlton 451 */
1598 : jtarlton 490 if ( (j == offered_media_.video.end()) || (offered_media_.video.size() > 1) )
1599 : jtarlton 451 {
1600 : jtarlton 490 SdpMediaDescription* videoMD = mdList->addItem();
1601 :     SdpMedia* videoMedia = videoMD->media();
1602 :     videoMedia->setMedia("video");
1603 :     videoMedia->setPort(0); /* important! */
1604 :     videoMedia->setTransport("RTP/AVP");
1605 :     videoMedia->setNumPorts(1);
1606 :    
1607 : jtarlton 451 for ( j = offered_media_.video.begin(); j != offered_media_.video.end(); ++j )
1608 : jtarlton 447 {
1609 : jtarlton 490 if ( (*j).coder != remoteVideoCoder_ )
1610 :     {
1611 :     std::stringstream payload;
1612 :     payload << (*j).coder.coderPayloadType;
1613 :     videoMedia->addFormat(payload.str().c_str());
1614 :     payload.str("");
1615 :     }
1616 : jtarlton 447 }
1617 : jtarlton 390 }
1618 :     }
1619 :    
1620 :    
1621 :     /*
1622 : jtarlton 431 * Extract the media details from the sdp and choose a coder from those offered.
1623 : jtarlton 390 */
1624 : jtarlton 431 void IpmDevice::onSdp( SdpSessionDescription& sdp )
1625 : jtarlton 390 {
1626 : jtarlton 434 parseSdp(sdp); /* parses the sdp into offered_media_ */
1627 : jtarlton 390
1628 : jtarlton 434 setRemoteMediaInfo(MEDIATYPE_AUDIO_REMOTE_RTP_INFO, IpInfo()); /* clear */
1629 :    
1630 : jtarlton 431 const Coders::audio_coders_t& audioCoders = channelMgr_.getAudioCoders();
1631 :     Coders::audio_coders_t::const_iterator i;
1632 :     for ( i = audioCoders.begin(); i != audioCoders.end(); ++i )
1633 : jtarlton 390 {
1634 : jtarlton 431 RemoteMedia::audio_t::const_iterator j;
1635 :     for ( j = offered_media_.audio.begin(); j != offered_media_.audio.end(); ++j )
1636 :     {
1637 :     if ( *i == (*j).coder )
1638 : jtarlton 390 {
1639 : jtarlton 466 LOGINFO("IpmDevice::onSdp() chose: \"" << (*i).encoding << "\" for audio");
1640 : jtarlton 431 remoteAudioCoder_ = (*j).coder;
1641 :     setRemoteMediaInfo(MEDIATYPE_AUDIO_REMOTE_RTP_INFO, (*j).rtp);
1642 :     break;
1643 :     }
1644 :     }
1645 :     if ( j != offered_media_.audio.end() )
1646 :     {
1647 :     break;
1648 :     }
1649 :     }
1650 :    
1651 : jtarlton 434 setRemoteMediaInfo(MEDIATYPE_VIDEO_REMOTE_RTP_INFO, IpInfo()); /* clear */
1652 :    
1653 : jtarlton 431 const Coders::video_coders_t& videoCoders = channelMgr_.getVideoCoders();
1654 :     Coders::video_coders_t::const_iterator k;
1655 :     for ( k = videoCoders.begin(); k != videoCoders.end(); ++k )
1656 :     {
1657 :     RemoteMedia::video_t::const_iterator l;
1658 :     for ( l = offered_media_.video.begin(); l != offered_media_.video.end(); ++l )
1659 :     {
1660 :     if ( *k == (*l).coder )
1661 :     {
1662 : jtarlton 533 LOGINFO("IpmDevice::onSdp() chose: \"" << (*l).coder.encoding << "\" for video");
1663 : jtarlton 431 remoteVideoCoder_ = (*l).coder;
1664 : jtarlton 471 /* use the first fmt offered, there is always at least one */
1665 :     remoteVideoCoder_.active_fmt = (*l).coder.available_fmts[0];
1666 : jtarlton 431 setRemoteMediaInfo(MEDIATYPE_VIDEO_REMOTE_RTP_INFO, (*l).rtp);
1667 :     break;
1668 :     }
1669 :     }
1670 :     if ( l != offered_media_.video.end() )
1671 :     {
1672 :     break;
1673 :     }
1674 :     }
1675 :     }
1676 :    
1677 :    
1678 :     /*
1679 :     * Extract media details from an sdp.
1680 :     */
1681 :     void IpmDevice::parseSdp( SdpSessionDescription& sdp )
1682 :     {
1683 :     offered_media_.audio.clear();
1684 :     offered_media_.video.clear();
1685 :    
1686 :     std::string addr(sdp.connection()->getAddress());
1687 : jtarlton 500 /*
1688 :     int bandwidth = atoi(sdp.bandwidth()->getBandwidthValue());
1689 :     std::string modifier = sdp.bandwidth()->getModifier();
1690 :     */
1691 : jtarlton 471 std::string direction = "sendrecv";
1692 :     SdpAttributeList* attributeList = sdp.attributeList();
1693 :     int nAttribute = attributeList->numItem();
1694 :     for ( int n = 0; n < nAttribute; n++ )
1695 :     {
1696 :     SdpAttribute* attribute = attributeList->getItem(n);
1697 :    
1698 :     if ( !strcmp(attribute->getProperty(), "sendonly") )
1699 :     {
1700 :     direction = "sendonly";
1701 :     }
1702 :     if ( !strcmp(attribute->getProperty(), "recvonly") )
1703 :     {
1704 :     direction = "recvonly";
1705 :     }
1706 :     if ( !strcmp(attribute->getProperty(), "sendrecv") )
1707 :     {
1708 :     direction = "sendrecv";
1709 :     }
1710 :     if ( !strcmp(attribute->getProperty(), "inactive") )
1711 :     {
1712 :     direction = "inactive";
1713 :     }
1714 :     }
1715 :     // TODO add direction check inside each media description
1716 :    
1717 : jtarlton 431 int num_media = sdp.mediaDescriptionList()->numItem();
1718 :     for ( int i = 0; i < num_media; i++ )
1719 :     {
1720 :     SdpMediaDescription* md = sdp.mediaDescriptionList()->getItem(i);
1721 : jtarlton 447
1722 : jtarlton 471 /* m=audio
1723 :     */
1724 :     SdpMedia* media = md->media();
1725 :     if ( !strcmp(media->getMedia(), "audio") &&
1726 :     !strcmp(media->getTransport(), "RTP/AVP") &&
1727 :     (media->getPort() != 0) )
1728 : jtarlton 447 {
1729 : jtarlton 471 IpInfo rtp(addr, media->getPort());
1730 : jtarlton 447
1731 : jtarlton 431 int num_format = media->getNumFormat();
1732 :     for ( int j = 0; j < num_format; j++ )
1733 :     {
1734 : jtarlton 471 RemoteMedia::Audio audio_media;
1735 :     audio_media.rtp = rtp;
1736 : jtarlton 390
1737 : jtarlton 471 audio_media.coder.coderPayloadType = atoi(media->getFormat(j));
1738 :     audio_media.coder.coderType = CODER_TYPE_NONSTANDARD;
1739 : jtarlton 390
1740 : jtarlton 471 /* set defaults for fixed formats, these may be overridden by
1741 :     * an fmtp attribute.
1742 :     */
1743 :     if ( audio_media.coder.coderPayloadType == 0 ) /* PCMU */
1744 :     {
1745 :     audio_media.coder.encoding = "PCMU";
1746 : jtarlton 431 audio_media.coder.coderType = CODER_TYPE_G711ULAW64K;
1747 :     audio_media.coder.coderFramesize = CODER_FRAMESIZE_20;
1748 :     audio_media.coder.framesPerPkt = 1;
1749 :     audio_media.coder.vadEnable = CODER_VAD_ENABLE;
1750 :     audio_media.coder.redPayloadType = 0;
1751 :     }
1752 : jtarlton 471 else if ( audio_media.coder.coderPayloadType == 8 ) /* PCMA */
1753 : jtarlton 390 {
1754 : jtarlton 471 audio_media.coder.encoding = "PCMA";
1755 : jtarlton 431 audio_media.coder.coderType = CODER_TYPE_G711ALAW64K;
1756 :     audio_media.coder.coderFramesize = CODER_FRAMESIZE_20;
1757 :     audio_media.coder.framesPerPkt = 1;
1758 :     audio_media.coder.vadEnable = CODER_VAD_ENABLE;
1759 :     audio_media.coder.redPayloadType = 0;
1760 : jtarlton 471 }
1761 :     else
1762 :     {
1763 : jtarlton 491 /* more payload types go here. */
1764 : jtarlton 471 }
1765 :     audio_media.direction = direction;
1766 :     audio_media.rfc2833 = false;
1767 :     offered_media_.audio.push_back(audio_media);
1768 :     }
1769 : jtarlton 431
1770 : jtarlton 471 SdpAttributeList* attributeList = md->attributeList();
1771 :     int nAttribute = attributeList->numItem();
1772 :     for ( int k = 0; k < nAttribute; k++ )
1773 :     {
1774 :     SdpAttribute* attribute = attributeList->getItem(k);
1775 :    
1776 :     if ( strcmp(attribute->getProperty(), "rtpmap") == 0 )
1777 :     {
1778 :     StringTokeniser rtpmap(attribute->getPropertyValue());
1779 :    
1780 :     int payload = atoi(rtpmap.token(' ').c_str());
1781 :     std::string encoding = rtpmap.token('/');
1782 : jtarlton 490 int clockrate = atoi(rtpmap.token().c_str());
1783 :     if ( clockrate != 8000 )
1784 :     {
1785 :     LOGWARN("IpmDevice::parseSdp() payload: " << payload <<
1786 :     " has an unsupported clockrate: " << clockrate);
1787 :     }
1788 : jtarlton 471 RemoteMedia::audio_t::iterator i;
1789 :     for ( i = offered_media_.audio.begin(); i != offered_media_.audio.end(); ++i )
1790 :     {
1791 :     if ( (*i).coder.coderPayloadType == payload )
1792 :     {
1793 :     (*i).coder.encoding = encoding;
1794 :    
1795 :     if ( strcasecmp((*i).coder.encoding.c_str(), "PCMU") == 0 )
1796 :     {
1797 :     (*i).coder.coderType = CODER_TYPE_G711ULAW64K;
1798 :     }
1799 :     else if ( strcasecmp((*i).coder.encoding.c_str(), "PCMA") == 0 )
1800 :     {
1801 :     (*i).coder.coderType = CODER_TYPE_G711ALAW64K;
1802 :     }
1803 :     else if ( strcasecmp((*i).coder.encoding.c_str(), "telephone-event") == 0 )
1804 :     {
1805 : jtarlton 491 /* not really a codec. */
1806 : jtarlton 471 (*i).coder.coderType = CODER_TYPE_NONSTANDARD;
1807 :     (*i).rfc2833 = true;
1808 :     }
1809 :     else
1810 :     {
1811 :     }
1812 :     break;
1813 :     }
1814 :     }
1815 : jtarlton 390 }
1816 : jtarlton 471 else if ( strcmp(attribute->getProperty(), "fmtp") == 0 )
1817 :     {
1818 :     StringTokeniser fmtp(attribute->getPropertyValue());
1819 :    
1820 :     int format = atoi(fmtp.token(' ').c_str());
1821 :    
1822 :     RemoteMedia::audio_t::iterator i;
1823 :     for ( i = offered_media_.audio.begin(); i != offered_media_.audio.end(); ++i )
1824 :     {
1825 :     if ( (*i).coder.coderPayloadType == format )
1826 :     {
1827 :     if ( ((*i).coder.coderType == CODER_TYPE_NONSTANDARD) && ((*i).rfc2833) )
1828 :     {
1829 :     /* TODO use this */
1830 :     }
1831 :     else
1832 :     {
1833 :     /* more payload types */
1834 :     }
1835 :     break;
1836 :     }
1837 :     }
1838 :     }
1839 : jtarlton 431 else
1840 : jtarlton 390 {
1841 : jtarlton 491 /* more attributes */
1842 : jtarlton 390 }
1843 :     }
1844 : jtarlton 431 }
1845 : jtarlton 390
1846 : jtarlton 471 /* m=video
1847 :     */
1848 :     if ( !strcmp(media->getMedia(), "video") &&
1849 :     !strcmp(media->getTransport(), "RTP/AVP") &&
1850 :     (media->getPort() != 0) )
1851 : jtarlton 431 {
1852 : jtarlton 466 IpInfo rtp(addr, media->getPort());
1853 :    
1854 : jtarlton 431 int num_format = media->getNumFormat();
1855 :     for ( int j = 0; j < num_format; j++ )
1856 : jtarlton 390 {
1857 : jtarlton 466 RemoteMedia::Video video_media;
1858 :     video_media.rtp = rtp;
1859 : jtarlton 390
1860 : jtarlton 466 video_media.coder.coderPayloadType = atoi(media->getFormat(j));
1861 : jtarlton 431
1862 : jtarlton 471 /* set defaults for fixed formats, these may be overridden by
1863 : jtarlton 466 * an fmtp attribute.
1864 :     */
1865 :     if ( video_media.coder.coderPayloadType == 34 ) /* H.263 */
1866 :     {
1867 :     video_media.coder.encoding = "H263";
1868 : jtarlton 431 video_media.coder.coderType = CODER_TYPE_H263;
1869 :     video_media.coder.profile = VIDEO_PROFILE_0_H263;
1870 :     video_media.coder.level = VIDEO_LEVEL_10_H263;
1871 :     video_media.coder.samplingRate = VIDEO_SAMPLING_RATE_DEFAULT;
1872 : jtarlton 500 video_media.coder.bitRate = VIDEO_BITRATE_384K;
1873 : jtarlton 471
1874 : jtarlton 533 /* Set default fmt (rfc4629 8.2.1).
1875 :     * This will be removed if an fmtp attribute is found.
1876 : jtarlton 471 */
1877 :     VideoCoderInfo::Fmt fmt;
1878 :     fmt.imageWidth = VIDEO_IMAGE_WIDTH_176;
1879 :     fmt.imageHeight = VIDEO_IMAGE_HEIGHT_144;
1880 : jtarlton 533 fmt.framesPerSec = VIDEO_FRAMESPERSEC_30;
1881 : jtarlton 471 video_media.coder.available_fmts.push_back(fmt);
1882 : jtarlton 466 }
1883 : jtarlton 471 else
1884 :     {
1885 : jtarlton 500 /* more *known* payload types */
1886 : jtarlton 471 }
1887 : jtarlton 466 video_media.direction = direction;
1888 :     offered_media_.video.push_back(video_media);
1889 :     }
1890 : jtarlton 431
1891 : jtarlton 471 SdpAttributeList* attributeList = md->attributeList();
1892 : jtarlton 466 int nAttribute = attributeList->numItem();
1893 :     for ( int k = 0; k < nAttribute; k++ )
1894 :     {
1895 :     SdpAttribute* attribute = attributeList->getItem(k);
1896 : jtarlton 431
1897 : jtarlton 466 if ( strcmp(attribute->getProperty(), "rtpmap") == 0 )
1898 :     {
1899 :     StringTokeniser rtpmap(attribute->getPropertyValue());
1900 :    
1901 :     int payload = atoi(rtpmap.token(' ').c_str());
1902 : jtarlton 471 std::string encoding = rtpmap.token('/');
1903 : jtarlton 490 int clockrate = atoi(rtpmap.token().c_str());
1904 : jtarlton 500 if ( clockrate != 90000 )
1905 :     {
1906 :     LOGWARN("IpmDevice::parseSdp() payload: " << payload <<
1907 :     " has an unsupported clockrate: " << clockrate);
1908 :     }
1909 : jtarlton 466 RemoteMedia::video_t::iterator i;
1910 :     for ( i = offered_media_.video.begin(); i != offered_media_.video.end(); ++i )
1911 : jtarlton 431 {
1912 : jtarlton 466 if ( (*i).coder.coderPayloadType == payload )
1913 : jtarlton 431 {
1914 : jtarlton 466 (*i).coder.encoding = encoding;
1915 : jtarlton 431
1916 : jtarlton 466 if ( strcasecmp((*i).coder.encoding.c_str(), "H263") == 0 )
1917 : jtarlton 431 {
1918 : jtarlton 500 /* static payload type; defaults already set */
1919 : jtarlton 466 (*i).coder.coderType = CODER_TYPE_H263;
1920 : jtarlton 431 }
1921 : jtarlton 471 else if ( strcasecmp((*i).coder.encoding.c_str(), "H263-1998") == 0 )
1922 :     {
1923 :     (*i).coder.coderType = CODER_TYPE_H263_1998;
1924 :     (*i).coder.profile = VIDEO_PROFILE_0_H263;
1925 :     (*i).coder.level = VIDEO_LEVEL_10_H263;
1926 :     (*i).coder.samplingRate = VIDEO_SAMPLING_RATE_DEFAULT;
1927 : jtarlton 500 (*i).coder.bitRate = VIDEO_BITRATE_384K;
1928 : jtarlton 471
1929 :     /* set default fmt, this will be removed if an
1930 :     * fmtp attribute is found.
1931 :     */
1932 :     VideoCoderInfo::Fmt fmt;
1933 :     fmt.imageWidth = VIDEO_IMAGE_WIDTH_176;
1934 :     fmt.imageHeight = VIDEO_IMAGE_HEIGHT_144;
1935 : jtarlton 533 fmt.framesPerSec = VIDEO_FRAMESPERSEC_30;
1936 : jtarlton 471 (*i).coder.available_fmts.push_back(fmt);
1937 :     }
1938 : jtarlton 533 else if ( (strcasecmp((*i).coder.encoding.c_str(), "MP4V-ES") == 0) ||
1939 :     (strcasecmp((*i).coder.encoding.c_str(), "MPEG4") == 0) )
1940 : jtarlton 500 {
1941 :     (*i).coder.coderType = CODER_TYPE_MP4V_ES;
1942 : jtarlton 533 (*i).coder.profile = VIDEO_PROFILE_LEVEL_SP3_MPEG4;
1943 : jtarlton 500 (*i).coder.level = VIDEO_LEVEL_DEFAULT;
1944 :     (*i).coder.samplingRate = VIDEO_SAMPLING_RATE_DEFAULT;
1945 :     (*i).coder.bitRate = VIDEO_BITRATE_384K;
1946 :    
1947 :     /* set default fmt, this will be removed if an
1948 :     * fmtp attribute is found.
1949 :     */
1950 :     VideoCoderInfo::Fmt fmt;
1951 : jtarlton 533 fmt.imageWidth = VIDEO_IMAGE_WIDTH_352;
1952 :     fmt.imageHeight = VIDEO_IMAGE_HEIGHT_288;
1953 :     fmt.framesPerSec = VIDEO_FRAMESPERSEC_30;
1954 :     fmt.profile = VIDEO_PROFILE_LEVEL_SP3_MPEG4;
1955 : jtarlton 500 (*i).coder.available_fmts.push_back(fmt);
1956 :     }
1957 : jtarlton 431 else
1958 :     {
1959 : jtarlton 491 /* more encodings */
1960 : jtarlton 431 }
1961 :     break;
1962 :     }
1963 : jtarlton 466 }
1964 :     }
1965 : jtarlton 471 else if ( strcmp(attribute->getProperty(), "fmtp") == 0 )
1966 : jtarlton 466 {
1967 :     StringTokeniser fmtp(attribute->getPropertyValue());
1968 :    
1969 :     int format = atoi(fmtp.token(' ').c_str());
1970 :    
1971 :     RemoteMedia::video_t::iterator i;
1972 :     for ( i = offered_media_.video.begin(); i != offered_media_.video.end(); ++i )
1973 :     {
1974 :     if ( (*i).coder.coderPayloadType == format )
1975 : jtarlton 431 {
1976 : jtarlton 533 VideoCoderInfo::Fmt fmt;
1977 :     bool done = false;
1978 :     while ( !done )
1979 : jtarlton 431 {
1980 : jtarlton 533 std::string name = fmtp.token('=');
1981 :     trim(name);
1982 :     if ( name.empty() )
1983 :     {
1984 :     break;
1985 :     }
1986 :     std::string value = fmtp.token("; ");
1987 :     trim(value);
1988 :     if ( value.empty() )
1989 :     {
1990 :     value = fmtp.token();
1991 :     done = true;
1992 :     }
1993 : jtarlton 471
1994 : jtarlton 533 if ( name == "CIF" )
1995 : jtarlton 466 {
1996 : jtarlton 533 fmt.fmtpName = name + "=" + value;
1997 :     fmt.imageWidth = VIDEO_IMAGE_WIDTH_352;
1998 :     fmt.imageHeight = VIDEO_IMAGE_HEIGHT_288;
1999 :     int fps = mpi2fps(atoi(value.c_str()));
2000 :     if ( fps > VIDEO_FRAMESPERSEC_30 )
2001 : jtarlton 471 {
2002 : jtarlton 533 fmt.framesPerSec = VIDEO_FRAMESPERSEC_30;
2003 :     fmt.profile = VIDEO_PROFILE_LEVEL_SP3_MPEG4;
2004 : jtarlton 471 }
2005 : jtarlton 533 else
2006 : jtarlton 471 {
2007 : jtarlton 533 fmt.framesPerSec = (eVIDEO_FRAMESPERSEC)fps;
2008 :     fmt.profile = VIDEO_PROFILE_LEVEL_SP2_MPEG4;
2009 : jtarlton 471 }
2010 : jtarlton 533 (*i).coder.available_fmts.push_back(fmt);
2011 :     }
2012 :     else if ( name == "QCIF" )
2013 :     {
2014 :     fmt.fmtpName = name + "=" + value;
2015 :     fmt.imageWidth = VIDEO_IMAGE_WIDTH_176;
2016 :     fmt.imageHeight = VIDEO_IMAGE_HEIGHT_144;
2017 :     int fps = mpi2fps(atoi(value.c_str()));
2018 :     if ( fps > VIDEO_FRAMESPERSEC_30 )
2019 : jtarlton 471 {
2020 : jtarlton 533 fmt.framesPerSec = VIDEO_FRAMESPERSEC_30;
2021 :     fmt.profile = VIDEO_PROFILE_LEVEL_SP1_MPEG4;
2022 : jtarlton 471 }
2023 :     else
2024 :     {
2025 : jtarlton 533 fmt.framesPerSec = (eVIDEO_FRAMESPERSEC)fps;
2026 :     fmt.profile = VIDEO_PROFILE_LEVEL_SP0_MPEG4;
2027 : jtarlton 471 }
2028 : jtarlton 533 (*i).coder.available_fmts.push_back(fmt);
2029 :     }
2030 :     else if ( name == "Sub-QCIF" )
2031 :     {
2032 :     fmt.fmtpName = name + "=" + value;
2033 :     fmt.imageWidth = VIDEO_IMAGE_WIDTH_128;
2034 :     fmt.imageHeight = VIDEO_IMAGE_HEIGHT_96;
2035 :     int fps = mpi2fps(atoi(value.c_str()));
2036 : jtarlton 471 if ( fps > VIDEO_FRAMESPERSEC_30 )
2037 :     {
2038 :     fmt.framesPerSec = VIDEO_FRAMESPERSEC_30;
2039 : jtarlton 533 fmt.profile = VIDEO_PROFILE_LEVEL_SP1_MPEG4;
2040 : jtarlton 471 }
2041 :     else
2042 :     {
2043 :     fmt.framesPerSec = (eVIDEO_FRAMESPERSEC)fps;
2044 : jtarlton 533 fmt.profile = VIDEO_PROFILE_LEVEL_SP0_MPEG4;
2045 : jtarlton 471 }
2046 :     (*i).coder.available_fmts.push_back(fmt);
2047 : jtarlton 466 }
2048 : jtarlton 533 else if ( name == "profile" )
2049 : jtarlton 466 {
2050 : jtarlton 533 (*i).coder.profile = (eVIDEO_PROFILE)atoi(value.c_str());
2051 : jtarlton 466 }
2052 : jtarlton 533 else if ( name == "level" )
2053 : jtarlton 500 {
2054 : jtarlton 533 (*i).coder.level = (eVIDEO_LEVEL)atoi(value.c_str());
2055 : jtarlton 500 }
2056 : jtarlton 533 else if ( name == "profile-level-id" )
2057 : jtarlton 500 {
2058 : jtarlton 533 fmt.fmtpName = name + "=" + value;
2059 : jtarlton 500 if ( value == "0" )
2060 :     {
2061 :     (*i).coder.profile = VIDEO_PROFILE_LEVEL_SP0_MPEG4;
2062 :     fmt.imageWidth = VIDEO_IMAGE_WIDTH_176;
2063 :     fmt.imageHeight = VIDEO_IMAGE_HEIGHT_144;
2064 :     fmt.framesPerSec = VIDEO_FRAMESPERSEC_15;
2065 : jtarlton 533 fmt.profile = VIDEO_PROFILE_LEVEL_SP0_MPEG4;
2066 : jtarlton 500 (*i).coder.available_fmts.push_back(fmt);
2067 :     }
2068 :     else if ( value == "1" )
2069 :     {
2070 :     (*i).coder.profile = VIDEO_PROFILE_LEVEL_SP1_MPEG4;
2071 :     fmt.imageWidth = VIDEO_IMAGE_WIDTH_176;
2072 :     fmt.imageHeight = VIDEO_IMAGE_HEIGHT_144;
2073 :     fmt.framesPerSec = VIDEO_FRAMESPERSEC_15;
2074 : jtarlton 533 fmt.profile = VIDEO_PROFILE_LEVEL_SP1_MPEG4;
2075 : jtarlton 500 (*i).coder.available_fmts.push_back(fmt);
2076 :     }
2077 :     else if ( value == "2" )
2078 :     {
2079 :     (*i).coder.profile = VIDEO_PROFILE_LEVEL_SP2_MPEG4;
2080 : jtarlton 533 fmt.imageWidth = VIDEO_IMAGE_WIDTH_352;
2081 :     fmt.imageHeight = VIDEO_IMAGE_HEIGHT_288;
2082 :     fmt.framesPerSec = VIDEO_FRAMESPERSEC_15;
2083 :     fmt.profile = VIDEO_PROFILE_LEVEL_SP2_MPEG4;
2084 : jtarlton 500 (*i).coder.available_fmts.push_back(fmt);
2085 :     }
2086 :     else if ( value == "3" )
2087 :     {
2088 :     (*i).coder.profile = VIDEO_PROFILE_LEVEL_SP3_MPEG4;
2089 :     fmt.imageWidth = VIDEO_IMAGE_WIDTH_352;
2090 :     fmt.imageHeight = VIDEO_IMAGE_HEIGHT_288;
2091 :     fmt.framesPerSec = VIDEO_FRAMESPERSEC_30;
2092 : jtarlton 533 fmt.profile = VIDEO_PROFILE_LEVEL_SP3_MPEG4;
2093 : jtarlton 500 (*i).coder.available_fmts.push_back(fmt);
2094 :     }
2095 : jtarlton 533 else
2096 :     {
2097 :     continue;
2098 :     }
2099 : jtarlton 500 }
2100 : jtarlton 533 else if ( name == "MaxBR" )
2101 : jtarlton 500 {
2102 : jtarlton 533 (*i).coder.bitRate = atoi(value.c_str()) * 100;
2103 : jtarlton 500 }
2104 : jtarlton 533 else
2105 :     {
2106 :     continue; /* ignore unsupported params. */
2107 :     }
2108 : jtarlton 500 }
2109 : jtarlton 533
2110 :     /* remove the default fmt, no longer needed. */
2111 :     if ( (*i).coder.available_fmts.size() > 1 )
2112 : jtarlton 431 {
2113 : jtarlton 533 (*i).coder.available_fmts.erase((*i).coder.available_fmts.begin());
2114 : jtarlton 431 }
2115 :     }
2116 : jtarlton 533 else
2117 :     {
2118 :     /* more payload types */
2119 :     }
2120 :     break;
2121 : jtarlton 431 }
2122 : jtarlton 390 }
2123 : jtarlton 471 else
2124 :     {
2125 :     /* more attributes */
2126 :     }
2127 : jtarlton 390 }
2128 : jtarlton 431 }
2129 : jtarlton 390 }
2130 :     }
2131 :    
2132 :    
2133 : jtarlton 431
2134 : jtarlton 41 /* vim:ts=4:set nu:
2135 :     * EOF
2136 :     */

No admin address has been configured
ViewVC Help
Powered by ViewVC 1.0.8