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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 413, Thu Oct 1 16:35:34 2009 UTC revision 524, Thu Dec 3 18:47:57 2009 UTC
# Line 35  Line 35 
35    
36  /*------------------------------ Dependencies --------------------------------*/  /*------------------------------ Dependencies --------------------------------*/
37    
 #include <iomanip>  
   
38  #include "logger.h"  #include "logger.h"
39  #include "string-util.h"  #include "string-util.h"
40    
# Line 47  Line 45 
45    
46  /*----------------------------------------------------------------------------*/  /*----------------------------------------------------------------------------*/
47    
   
48  /*  /*
49   * ctor   * ctor
50   */   */
# Line 58  Line 55 
55          ipt_ = 0;           /* standalone mode */          ipt_ = 0;           /* standalone mode */
56          busy_ = false;          busy_ = false;
57    
58            /* 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    
76            /* 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            else /* H.263 */
85            {
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                    localVideoCoder_.bitRate = 384000;
91                    localVideoCoder_.samplingRate = VIDEO_SAMPLING_RATE_DEFAULT;
92    
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            }
100    
101            remoteAudioCoder_ = localAudioCoder_;
102            remoteVideoCoder_ = localVideoCoder_;
103    
104            dtmf_mode_ = DTMF_RFC2833;
105            rfc2833_payload_type_ = 101;  /* may be changed by sdp processing */
106    
107          /* Number of steps in the initialisation sequence, decremented by event          /* Number of steps in the initialisation sequence, decremented by event
108           * handlers. When zero, state is changed to IDLE.           * handlers. When zero, state is changed to IDLE.
109           *           *
# Line 83  Line 129 
129   */   */
130  void IpmDevice::processPendingCommand()  void IpmDevice::processPendingCommand()
131  {  {
132          if ( !pending_.empty() )          while ( !busy_ && !pending_.empty() )
133          {          {
134                    LOGDEBUG("IpmDevice::processPendingCommand()");
135                  switch( pending_.front().cmd )                  switch( pending_.front().cmd )
136                  {                  {
137                          case IpmCommand::START:                          case IpmCommand::START:
# Line 118  Line 165 
165   */   */
166  bool IpmDevice::open()  bool IpmDevice::open()
167  {  {
168          LOGDEBUG("IpmDevice::open() device: " << devName_);          LOGDEBUG("IpmDevice::open() device: " << getDeviceName());
169    
170          devHandle_ = ipm_Open(devName_.c_str(), NULL, EV_ASYNC);          devHandle_ = ipm_Open(getDeviceName().c_str(), NULL, EV_ASYNC);
171          if ( devHandle_ < 0 )          if ( devHandle_ < 0 )
172          {          {
173                  LOGERROR("ipm_Open() failed");                  LOGERROR("ipm_Open() failed");
# Line 136  Line 183 
183   */   */
184  bool IpmDevice::close()  bool IpmDevice::close()
185  {  {
186          LOGDEBUG("IpmDevice::close() device: " << devName_);          LOGDEBUG("IpmDevice::close() device: " << getDeviceName());
187    
188          if ( devHandle_ > 0 )          if ( devHandle_ > 0 )
189          {          {
# Line 162  Line 209 
209                  return true;                  return true;
210          }          }
211    
212          if ( listening_ != other )          if ( other_ != other )
213          {          {
214                  LOGDEBUG("IpmDevice::listen() device: " << devName_ <<                  LOGDEBUG("IpmDevice::listen() device: " << getDeviceName() <<
215                           " other: " << other->getDeviceName());                           " other: " << other->getDeviceName());
216    
217                  SC_TSINFO tsinfo;                  SC_TSINFO tsinfo;
# Line 173  Line 220 
220    
221                  if ( ipm_Listen(devHandle_, &tsinfo, EV_ASYNC) == -1 )                  if ( ipm_Listen(devHandle_, &tsinfo, EV_ASYNC) == -1 )
222                  {                  {
223                          LOGERROR("ipm_Listen() failed on device: " << devName_ <<                          LOGERROR("ipm_Listen() failed on device: " << getDeviceName() <<
224                                   " " << ATDV_ERRMSGP(devHandle_));                                   " " << ATDV_ERRMSGP(devHandle_));
225                          return false;                          return false;
226                  }                  }
227                    other_ = other;
                 listening_ = other;  
228                  busy_ = true;                  busy_ = true;
229          }          }
230          return true;          return true;
# Line 196  Line 242 
242                  return true;                  return true;
243          }          }
244    
245          if ( listening_ )          if ( other_ )
246          {          {
247                  LOGDEBUG("IpmDevice::unListen() device: " << devName_);                  LOGDEBUG("IpmDevice::unListen() device: " << getDeviceName());
248    
249                  if ( ipm_UnListen(devHandle_, EV_ASYNC) == -1)                  if ( ipm_UnListen(devHandle_, EV_ASYNC) == -1)
250                  {                  {
251                          LOGERROR("ipm_UnListen() failed on device: " << devName_ <<                          LOGERROR("ipm_UnListen() failed on device: " << getDeviceName() <<
252                                           " " << ATDV_ERRMSGP(devHandle_));                                           " " << ATDV_ERRMSGP(devHandle_));
253                          return false;                          return false;
254                  }                  }
255                    other_ = 0;
                 listening_ = 0;  
256                  busy_ = true;                  busy_ = true;
257          }          }
258          return true;          return true;
# Line 225  Line 270 
270                  return true;                  return true;
271          }          }
272    
273          if ( listening_ != other )          if ( !other_ )
274          {          {
275                  LOGDEBUG("IpmDevice::connect() device: " << devName_ <<                  LOGDEBUG("IpmDevice::connect() device: " << getDeviceName() <<
276                           " to: " << other->getDeviceName());                           " to: " << other->getDeviceName());
277    
278                  DM_PORT_CONNECT_INFO_LIST portConnectInfoList;                  DM_PORT_CONNECT_INFO_LIST portConnectInfoList;
# Line 246  Line 291 
291                  portConnectInfoList.port_connect_info[count].port_info_tx = getVideoTxPortInfo();                  portConnectInfoList.port_connect_info[count].port_info_tx = getVideoTxPortInfo();
292                  portConnectInfoList.port_connect_info[count].port_info_rx = other->getVideoRxPortInfo();                  portConnectInfoList.port_connect_info[count].port_info_rx = other->getVideoRxPortInfo();
293                  count++;                  count++;
294  /*  
                 printPortInfo(&portConnectInfoList.port_connect_info[0].port_info_tx);  
                 printPortInfo(&portConnectInfoList.port_connect_info[0].port_info_rx);  
                 printPortInfo(&portConnectInfoList.port_connect_info[1].port_info_tx);  
                 printPortInfo(&portConnectInfoList.port_connect_info[1].port_info_rx);  
 */  
295                  portConnectInfoList.unCount = count;                  portConnectInfoList.unCount = count;
296                  if ( dev_PortConnect(devHandle_, &portConnectInfoList, NULL) != DEV_SUCCESS )                  if ( dev_PortConnect(devHandle_, &portConnectInfoList, NULL) != DEV_SUCCESS )
297                  {                  {
298                          LOGERROR("IpmDevice::connect() dev_PortConnect() failed on device: " << devName_ <<                          LOGERROR("IpmDevice::connect() dev_PortConnect() failed on device: " << getDeviceName() <<
299                                   " " << ATDV_ERRMSGP(devHandle_));                                   " " << ATDV_ERRMSGP(devHandle_));
300                          return false;                          return false;
301                  }                  }
302    
303                  listening_ = other;                  other_ = other;
304                  busy_ = true;                  busy_ = true;
305          }          }
306          else          else
307          {          {
308                  LOGWARN("IpmDevice::connect() " << devName_ <<                  if ( other_ != other )
309                      " already connected to device: "  << listening_->getDeviceName() <<                  {
310                      " trying to connect to device: " << other->getDeviceName());                          LOGERROR("IpmDevice::connect() " << getDeviceName() <<
311                                     " unable to connect to device: " << other->getDeviceName() <<
312                                     " already connected to device: "  << other_->getDeviceName());
313                    }
314          }          }
315          return true;          return true;
316  }  }
# Line 284  Line 327 
327                  return true;                  return true;
328          }          }
329    
330          if ( listening_ )          if ( other_ )
331          {          {
332                  LOGDEBUG("IpmDevice::disconnect() device: " << devName_ <<                  LOGDEBUG("IpmDevice::disconnect() device: " << getDeviceName() <<
333                           " from: " << listening_->getDeviceName());                           " from: " << other_->getDeviceName());
334    
335                  DM_PORT_CONNECT_INFO_LIST portConnectInfoList;                  DM_PORT_CONNECT_INFO_LIST portConnectInfoList;
336                  memset(&portConnectInfoList, 0, sizeof(portConnectInfoList));                  memset(&portConnectInfoList, 0, sizeof(portConnectInfoList));
# Line 296  Line 339 
339    
340                  INIT_DM_PORT_CONNECT_INFO(&portConnectInfoList.port_connect_info[count]);                  INIT_DM_PORT_CONNECT_INFO(&portConnectInfoList.port_connect_info[count]);
341                  portConnectInfoList.port_connect_info[count].port_info_tx = getAudioTxPortInfo();                  portConnectInfoList.port_connect_info[count].port_info_tx = getAudioTxPortInfo();
342                  portConnectInfoList.port_connect_info[count].port_info_rx = listening_->getAudioRxPortInfo(); //XXX                  portConnectInfoList.port_connect_info[count].port_info_rx = other_->getAudioRxPortInfo();
343                  count++;                  count++;
344    
345                  INIT_DM_PORT_CONNECT_INFO(&portConnectInfoList.port_connect_info[count]);                  INIT_DM_PORT_CONNECT_INFO(&portConnectInfoList.port_connect_info[count]);
346                  portConnectInfoList.port_connect_info[count].port_info_tx = getVideoTxPortInfo();                  portConnectInfoList.port_connect_info[count].port_info_tx = getVideoTxPortInfo();
347                  portConnectInfoList.port_connect_info[count].port_info_rx = listening_->getVideoRxPortInfo(); //XXX                  portConnectInfoList.port_connect_info[count].port_info_rx = other_->getVideoRxPortInfo();
348                  count++;                  count++;
349    
350                  portConnectInfoList.unCount = count;                  portConnectInfoList.unCount = count;
 /*  
                 printPortInfo(&portConnectInfoList.port_connect_info[0].port_info_tx);  
                 printPortInfo(&portConnectInfoList.port_connect_info[0].port_info_rx);  
                 printPortInfo(&portConnectInfoList.port_connect_info[1].port_info_tx);  
                 printPortInfo(&portConnectInfoList.port_connect_info[1].port_info_rx);  
 */  
351                  if ( dev_PortDisconnect(devHandle_, &portConnectInfoList, NULL) != DEV_SUCCESS )                  if ( dev_PortDisconnect(devHandle_, &portConnectInfoList, NULL) != DEV_SUCCESS )
352                  {                  {
353                          LOGERROR("IpmDevice::disconnect() dev_PortDisconnect() failed on device: " << devName_ <<                          LOGERROR("IpmDevice::disconnect() dev_PortDisconnect() failed on device: " << getDeviceName() <<
354                                   " " << ATDV_ERRMSGP(devHandle_));                                   " " << ATDV_ERRMSGP(devHandle_));
355                          return false;                          return false;
356                  }                  }
357    
358                  listening_ = 0;                  other_ = 0;
359                  busy_ = true;                  busy_ = true;
360          }          }
         else  
         {  
                 LOGWARN("IpmDevice::disconnect() device: " << devName_ << " not connected");  
         }  
361          return true;          return true;
362  }  }
363    
# Line 361  Line 394 
394    
395    
396  /*  /*
397   * Save the remote params.   * Save the remote params, the RTCP port is assumed to be media + 1.
398   */   */
399  void IpmDevice::setRemoteMediaInfo( eIPM_MEDIA_TYPE type,  void IpmDevice::setRemoteMediaInfo( eIPM_MEDIA_TYPE type,
400                                      const IpInfo& rtp_info )                                      const IpInfo& rtp_info )
# Line 372  Line 405 
405                  remoteRtcpAudio_ = rtp_info;                  remoteRtcpAudio_ = rtp_info;
406                  remoteRtcpAudio_.setPort(remoteRtpAudio_.getPort() + 1);                  remoteRtcpAudio_.setPort(remoteRtpAudio_.getPort() + 1);
407    
408                  LOGDEBUG("IpmDevice::setRemoteMediaInfo() device: " << devName_ <<                  LOGDEBUG("IpmDevice::setRemoteMediaInfo() device: " << getDeviceName() <<
409                           " a=" << remoteRtpAudio_);                           " a=" << remoteRtpAudio_);
410          }          }
411          if ( type == MEDIATYPE_VIDEO_REMOTE_RTP_INFO )          if ( type == MEDIATYPE_VIDEO_REMOTE_RTP_INFO )
# Line 380  Line 413 
413                  remoteRtpVideo_ = rtp_info;                  remoteRtpVideo_ = rtp_info;
414                  remoteRtcpVideo_ = rtp_info;                  remoteRtcpVideo_ = rtp_info;
415                  remoteRtcpVideo_.setPort(remoteRtpVideo_.getPort() + 1);                  remoteRtcpVideo_.setPort(remoteRtpVideo_.getPort() + 1);
416                  LOGDEBUG("IpmDevice::setRemoteMediaInfo() device: " << devName_ <<                  LOGDEBUG("IpmDevice::setRemoteMediaInfo() device: " << getDeviceName() <<
417                           " v=" << remoteRtpVideo_);                           " v=" << remoteRtpVideo_);
418          }          }
419  }  }
# Line 404  Line 437 
437    
438          if ( ipm_Stop(devHandle_, operation, EV_ASYNC) == -1 )          if ( ipm_Stop(devHandle_, operation, EV_ASYNC) == -1 )
439          {          {
440                  LOGERROR("ipm_Stop() on device: " << devName_ << " failed: " <<                  LOGERROR("ipm_Stop() on device: " << getDeviceName() << " failed: " <<
441                           ATDV_LASTERR(devHandle_));                           ATDV_LASTERR(devHandle_));
442                  return false;                  return false;
443          }          }
444    
445          LOGDEBUG("IpmDevice::stopMedia() stopping RTP streaming on device: " <<          LOGDEBUG("IpmDevice::stopMedia() stopping RTP streaming on device: " <<
446                   devName_);                   getDeviceName());
447    
448          state_ = IPM_STOPPING;          state_ = IPM_STOPPING;
449          busy_ = true;          busy_ = true;
# Line 420  Line 453 
453    
454    
455  /*  /*
456   * Start RTP streaming to peer.   * Start RTP streaming to peer using the current settings.
457   */   */
458  bool IpmDevice::startMedia()  bool IpmDevice::startMedia()
459  {  {
# Line 432  Line 465 
465    
466    
467  /*  /*
468   * Start RTP streaming using G.711ulaw and local/remote port information.   * Start RTP streaming: audio and possibly video.
  * XXX codecs from config  
469   */   */
470  bool IpmDevice::startMedia( const IpInfo& remote_rtp_audio,  bool IpmDevice::startMedia( const IpInfo& remote_rtp_audio,
471                              const IpInfo& remote_rtcp_audio,                              const IpInfo& remote_rtcp_audio,
# Line 450  Line 482 
482          {          {
483                   /* already started, ignore */                   /* already started, ignore */
484                  LOGDEBUG("IpmDevice::startMedia() already streaming on device: " <<                  LOGDEBUG("IpmDevice::startMedia() already streaming on device: " <<
485                           devName_);                           getDeviceName());
486                  return true;                  return true;
487          }          }
488    
489          setDtmfMode(DTMF_RFC2833);          if ( !remote_rtp_audio.isValid() && !remote_rtp_video.isValid() )
490            {
491                    LOGERROR("IpmDevice::startMedia() no remote rtp media for device: " <<
492                             getDeviceName());
493                    return false;
494            }
495    
496            setDtmfMode(dtmf_mode_);
497    
498          IPM_MEDIA_INFO mediaInfo;          IPM_MEDIA_INFO mediaInfo;
499          memset(&mediaInfo, 0, sizeof(IPM_MEDIA_INFO));          memset(&mediaInfo, 0, sizeof(IPM_MEDIA_INFO));
500    
501          int mediaCnt = 0; /* limit MAX_MEDIA_INFO */          int mediaCnt = 0; /* limit MAX_MEDIA_INFO */
502    
503          /* remote audio          /* local audio.
504           */           */
505          mediaInfo.MediaData[mediaCnt].eMediaType = MEDIATYPE_AUDIO_REMOTE_CODER_INFO;          mediaInfo.MediaData[mediaCnt].eMediaType = MEDIATYPE_AUDIO_LOCAL_CODER_INFO;
506          mediaInfo.MediaData[mediaCnt].mediaInfo.CoderInfo.eCoderType = CODER_TYPE_G711ULAW64K;          mediaInfo.MediaData[mediaCnt].mediaInfo.CoderInfo.eCoderType = remoteAudioCoder_.coderType;
507          mediaInfo.MediaData[mediaCnt].mediaInfo.CoderInfo.eFrameSize = CODER_FRAMESIZE_20;          mediaInfo.MediaData[mediaCnt].mediaInfo.CoderInfo.eFrameSize = remoteAudioCoder_.coderFramesize;
508          mediaInfo.MediaData[mediaCnt].mediaInfo.CoderInfo.unFramesPerPkt = 1;          mediaInfo.MediaData[mediaCnt].mediaInfo.CoderInfo.unFramesPerPkt = remoteAudioCoder_.framesPerPkt;
509          mediaInfo.MediaData[mediaCnt].mediaInfo.CoderInfo.eVadEnable = CODER_VAD_ENABLE;          mediaInfo.MediaData[mediaCnt].mediaInfo.CoderInfo.eVadEnable = remoteAudioCoder_.vadEnable;
510          mediaInfo.MediaData[mediaCnt].mediaInfo.CoderInfo.unCoderPayloadType = 0;          mediaInfo.MediaData[mediaCnt].mediaInfo.CoderInfo.unCoderPayloadType = remoteAudioCoder_.coderPayloadType;
511          mediaInfo.MediaData[mediaCnt].mediaInfo.CoderInfo.unRedPayloadType = 0;          mediaInfo.MediaData[mediaCnt].mediaInfo.CoderInfo.unRedPayloadType = remoteAudioCoder_.redPayloadType;
512          mediaCnt++;          mediaCnt++;
513    
514          /* local audio          /* remote audio.
515           */           */
516          mediaInfo.MediaData[mediaCnt].eMediaType = MEDIATYPE_AUDIO_LOCAL_CODER_INFO;          mediaInfo.MediaData[mediaCnt].eMediaType = MEDIATYPE_AUDIO_REMOTE_CODER_INFO;
517          mediaInfo.MediaData[mediaCnt].mediaInfo.CoderInfo.eCoderType = CODER_TYPE_G711ULAW64K;          mediaInfo.MediaData[mediaCnt].mediaInfo.CoderInfo.eCoderType = remoteAudioCoder_.coderType;
518          mediaInfo.MediaData[mediaCnt].mediaInfo.CoderInfo.eFrameSize = CODER_FRAMESIZE_20;          mediaInfo.MediaData[mediaCnt].mediaInfo.CoderInfo.eFrameSize = remoteAudioCoder_.coderFramesize;
519          mediaInfo.MediaData[mediaCnt].mediaInfo.CoderInfo.unFramesPerPkt = 1;          mediaInfo.MediaData[mediaCnt].mediaInfo.CoderInfo.unFramesPerPkt = remoteAudioCoder_.framesPerPkt;
520          mediaInfo.MediaData[mediaCnt].mediaInfo.CoderInfo.eVadEnable = CODER_VAD_ENABLE;          mediaInfo.MediaData[mediaCnt].mediaInfo.CoderInfo.eVadEnable = remoteAudioCoder_.vadEnable;
521          mediaInfo.MediaData[mediaCnt].mediaInfo.CoderInfo.unCoderPayloadType = 0;          mediaInfo.MediaData[mediaCnt].mediaInfo.CoderInfo.unCoderPayloadType = remoteAudioCoder_.coderPayloadType;
522          mediaInfo.MediaData[mediaCnt].mediaInfo.CoderInfo.unRedPayloadType = 0;          mediaInfo.MediaData[mediaCnt].mediaInfo.CoderInfo.unRedPayloadType = remoteAudioCoder_.redPayloadType;
523          mediaCnt++;          mediaCnt++;
524    
525          /* remote audio ports and IP addresses          /* remote audio ports and IP addresses.
526           */           */
527          mediaInfo.MediaData[mediaCnt].eMediaType = MEDIATYPE_AUDIO_REMOTE_RTP_INFO;          mediaInfo.MediaData[mediaCnt].eMediaType = MEDIATYPE_AUDIO_REMOTE_RTP_INFO;
528          copy_string_to_c_array(remote_rtp_audio.getAddress(),          copy_string_to_c_array(remote_rtp_audio.getAddress(),
# Line 499  Line 538 
538          mediaInfo.MediaData[mediaCnt].mediaInfo.PortInfo.unPortId = remote_rtcp_audio.getPort();          mediaInfo.MediaData[mediaCnt].mediaInfo.PortInfo.unPortId = remote_rtcp_audio.getPort();
539          mediaCnt++;          mediaCnt++;
540    
541          /* remote video          if ( remote_rtp_video.isValid() )
542           */          {
543          mediaInfo.MediaData[mediaCnt].eMediaType = MEDIATYPE_VIDEO_REMOTE_CODER_INFO;                  /* local video.
         INIT_IPM_VIDEO_CODER_INFO(&mediaInfo.MediaData[mediaCnt].mediaInfo.VideoCoderInfo);  
         mediaInfo.MediaData[mediaCnt].mediaInfo.CoderInfo.eCoderType = CODER_TYPE_H263;  
         mediaInfo.MediaData[mediaCnt].mediaInfo.CoderInfo.unCoderPayloadType = 34;  
   
         IPM_VIDEO_CODER_INFO_EX remoteVideoCoderInfoEx;  
         INIT_IPM_VIDEO_CODER_INFO_EX(&remoteVideoCoderInfoEx);  
         remoteVideoCoderInfoEx.eProfile = VIDEO_PROFILE_0_H263;  
         remoteVideoCoderInfoEx.eLevel = VIDEO_LEVEL_10_H263;  
         remoteVideoCoderInfoEx.eImageWidth = VIDEO_IMAGE_WIDTH_352; //176;  
         remoteVideoCoderInfoEx.eImageHeight = VIDEO_IMAGE_HEIGHT_288; //144;  
         remoteVideoCoderInfoEx.eFramesPerSec = VIDEO_FRAMESPERSEC_15;  
         remoteVideoCoderInfoEx.unBitRate = 90000;  
         remoteVideoCoderInfoEx.eSamplingRate = VIDEO_SAMPLING_RATE_DEFAULT;  
         remoteVideoCoderInfoEx.unVisualConfigSize = 0;  
         remoteVideoCoderInfoEx.szVisualConfiguration = NULL;  
         mediaInfo.MediaData[mediaCnt].mediaInfo.VideoCoderInfo.pExtraCoderInfo = &remoteVideoCoderInfoEx;  
         mediaCnt++;  
   
         /* local video  
544           */           */
545          mediaInfo.MediaData[mediaCnt].eMediaType = MEDIATYPE_VIDEO_LOCAL_CODER_INFO;          mediaInfo.MediaData[mediaCnt].eMediaType = MEDIATYPE_VIDEO_LOCAL_CODER_INFO;
546          INIT_IPM_VIDEO_CODER_INFO(&mediaInfo.MediaData[mediaCnt].mediaInfo.VideoCoderInfo);          INIT_IPM_VIDEO_CODER_INFO(&mediaInfo.MediaData[mediaCnt].mediaInfo.VideoCoderInfo);
547          mediaInfo.MediaData[mediaCnt].mediaInfo.CoderInfo.eCoderType = CODER_TYPE_H263;                  mediaInfo.MediaData[mediaCnt].mediaInfo.VideoCoderInfo.eCoderType = remoteVideoCoder_.coderType;
548          mediaInfo.MediaData[mediaCnt].mediaInfo.CoderInfo.unCoderPayloadType = 34;                  mediaInfo.MediaData[mediaCnt].mediaInfo.VideoCoderInfo.unCoderPayloadType = remoteVideoCoder_.coderPayloadType;
549    
550          IPM_VIDEO_CODER_INFO_EX localVideoCoderInfoEx;          IPM_VIDEO_CODER_INFO_EX localVideoCoderInfoEx;
551          INIT_IPM_VIDEO_CODER_INFO_EX(&localVideoCoderInfoEx);          INIT_IPM_VIDEO_CODER_INFO_EX(&localVideoCoderInfoEx);
552          localVideoCoderInfoEx.eProfile = VIDEO_PROFILE_0_H263;                  localVideoCoderInfoEx.eProfile = remoteVideoCoder_.profile;
553          localVideoCoderInfoEx.eLevel = VIDEO_LEVEL_10_H263;                  localVideoCoderInfoEx.eLevel = remoteVideoCoder_.level;
554          localVideoCoderInfoEx.eImageWidth = VIDEO_IMAGE_WIDTH_352; //176;                  localVideoCoderInfoEx.eImageWidth = remoteVideoCoder_.active_fmt.imageWidth;
555          localVideoCoderInfoEx.eImageHeight = VIDEO_IMAGE_HEIGHT_288; //144;                  localVideoCoderInfoEx.eImageHeight = remoteVideoCoder_.active_fmt.imageHeight;
556          localVideoCoderInfoEx.eFramesPerSec = VIDEO_FRAMESPERSEC_15;                  localVideoCoderInfoEx.eFramesPerSec = remoteVideoCoder_.active_fmt.framesPerSec;
557          localVideoCoderInfoEx.unBitRate = 90000;                  localVideoCoderInfoEx.unBitRate = remoteVideoCoder_.bitRate;
558          localVideoCoderInfoEx.eSamplingRate = VIDEO_SAMPLING_RATE_DEFAULT;                  localVideoCoderInfoEx.eSamplingRate = remoteVideoCoder_.samplingRate;
559          localVideoCoderInfoEx.unVisualConfigSize = 0;          localVideoCoderInfoEx.unVisualConfigSize = 0;
560          localVideoCoderInfoEx.szVisualConfiguration = NULL;          localVideoCoderInfoEx.szVisualConfiguration = NULL;
561          mediaInfo.MediaData[mediaCnt].mediaInfo.VideoCoderInfo.pExtraCoderInfo = &localVideoCoderInfoEx;          mediaInfo.MediaData[mediaCnt].mediaInfo.VideoCoderInfo.pExtraCoderInfo = &localVideoCoderInfoEx;
562                    //LOGINFO("IpmDevice::startMedia() Local VideoCoderInfo: " << std::endl << mediaInfo.MediaData[mediaCnt].mediaInfo.VideoCoderInfo);
563                    mediaCnt++;
564    
565                    /* remote video.
566                     */
567                    mediaInfo.MediaData[mediaCnt].eMediaType = MEDIATYPE_VIDEO_REMOTE_CODER_INFO;
568                    INIT_IPM_VIDEO_CODER_INFO(&mediaInfo.MediaData[mediaCnt].mediaInfo.VideoCoderInfo);
569                    mediaInfo.MediaData[mediaCnt].mediaInfo.VideoCoderInfo.eCoderType = remoteVideoCoder_.coderType;
570                    mediaInfo.MediaData[mediaCnt].mediaInfo.VideoCoderInfo.unCoderPayloadType = remoteVideoCoder_.coderPayloadType;
571    
572                    IPM_VIDEO_CODER_INFO_EX remoteVideoCoderInfoEx;
573                    INIT_IPM_VIDEO_CODER_INFO_EX(&remoteVideoCoderInfoEx);
574                    remoteVideoCoderInfoEx.eProfile = remoteVideoCoder_.profile;
575                    remoteVideoCoderInfoEx.eLevel = remoteVideoCoder_.level;
576                    remoteVideoCoderInfoEx.eImageWidth = remoteVideoCoder_.active_fmt.imageWidth;
577                    remoteVideoCoderInfoEx.eImageHeight = remoteVideoCoder_.active_fmt.imageHeight;
578                    remoteVideoCoderInfoEx.eFramesPerSec = remoteVideoCoder_.active_fmt.framesPerSec;
579                    remoteVideoCoderInfoEx.unBitRate = remoteVideoCoder_.bitRate;
580                    remoteVideoCoderInfoEx.eSamplingRate = remoteVideoCoder_.samplingRate;
581                    remoteVideoCoderInfoEx.unVisualConfigSize = 0;
582                    remoteVideoCoderInfoEx.szVisualConfiguration = NULL;
583                    mediaInfo.MediaData[mediaCnt].mediaInfo.VideoCoderInfo.pExtraCoderInfo = &remoteVideoCoderInfoEx;
584                    //LOGINFO("IpmDevice::startMedia() Remote VideoCoderInfo: " << std::endl << mediaInfo.MediaData[mediaCnt].mediaInfo.VideoCoderInfo);
585          mediaCnt++;          mediaCnt++;
586    
587          /* remote video ports and IP addresses                  /* remote video ports and IP addresses.
588           */           */
589          mediaInfo.MediaData[mediaCnt].eMediaType = MEDIATYPE_VIDEO_REMOTE_RTP_INFO;          mediaInfo.MediaData[mediaCnt].eMediaType = MEDIATYPE_VIDEO_REMOTE_RTP_INFO;
590          copy_string_to_c_array(remote_rtp_video.getAddress(),          copy_string_to_c_array(remote_rtp_video.getAddress(),
# Line 556  Line 599 
599                                 IP_ADDR_SIZE);                                 IP_ADDR_SIZE);
600          mediaInfo.MediaData[mediaCnt].mediaInfo.PortInfo.unPortId = remote_rtcp_video.getPort();          mediaInfo.MediaData[mediaCnt].mediaInfo.PortInfo.unPortId = remote_rtcp_video.getPort();
601          mediaCnt++;          mediaCnt++;
602            }
603    
604          /* done          /* done.
605           */           */
606          mediaInfo.unCount = mediaCnt;          mediaInfo.unCount = mediaCnt;
607    
608          LOGDEBUG("IpmDevice::startMedia() starting RTP streaming on device: " <<          LOGDEBUG("IpmDevice::startMedia() starting audio on device: " <<
609                   devName_ <<                   getDeviceName() <<
610                   " remote_rtp_audio: " << remote_rtp_audio <<                   " remote_rtp: " << remote_rtp_audio <<
611                   " remote_rtcp_audio: " << remote_rtcp_audio <<                   " remote_rtcp: " << remote_rtcp_audio);
612                   " remote_rtp_video: " << remote_rtp_video <<  
613                   " remote_rtcp_video: " << remote_rtcp_video);          if ( remote_rtp_video.isValid() )
614            {
615                    LOGDEBUG("IpmDevice::startMedia() starting video on device: " <<
616                             getDeviceName() <<
617                             " remote_rtp: " << remote_rtp_video <<
618                             " remote_rtcp: " << remote_rtcp_video);
619            }
620    
621          if ( ipm_StartMedia(devHandle_, &mediaInfo, DATA_IP_TDM_BIDIRECTIONAL, EV_ASYNC) == -1 )          if ( ipm_StartMedia(devHandle_, &mediaInfo, DATA_IP_TDM_BIDIRECTIONAL, EV_ASYNC) == -1 )
622          {          {
623                  LOGERROR("ipm_StartMedia failed for device: " << devName_ <<                  LOGERROR("ipm_StartMedia failed for device: " << getDeviceName() <<
624                           " with error: " << ATDV_ERRMSGP(devHandle_));                           " with error: " << ATDV_ERRMSGP(devHandle_));
625                  return false;                  return false;
626          }          }
# Line 654  Line 704 
704                          break;                          break;
705    
706                  case DMEV_PORT_DISCONNECT_FAIL:                  case DMEV_PORT_DISCONNECT_FAIL:
707                          LOGERROR("IpmDevice::onPortDisconnectFail() device: " << devName_);                          LOGERROR("IpmDevice::onPortDisconnectFail() device: " << getDeviceName());
708                          break;                          break;
709    
710                  default:                  default:
711                          LOGWARN("IpmDevice::processEvent() unhandled event: 0x" <<                          LOGWARN("IpmDevice::processEvent() unhandled event: 0x" <<
712                                  std::hex << metaevent.evttype << " for device: " << devName_);                                  std::hex << metaevent.evttype << " for device: " << getDeviceName());
713                          return false;                          return false;
714          }          }
715          return true;          return true;
# Line 671  Line 721 
721   */   */
722  void IpmDevice::onOpen()  void IpmDevice::onOpen()
723  {  {
724          LOGINFO("IpmDevice::onOpen() device: " << devName_);          LOGINFO("IpmDevice::onOpen() device: " << getDeviceName());
725    
726          listening_ = 0;          other_ = 0;
727    
728          /* Get and save the transmit timeslot on CTBus          /* Get and save the transmit timeslot on CTBus.
729           */           */
730          SC_TSINFO tsinfo;          SC_TSINFO tsinfo;
731          tsinfo.sc_numts = 1;          tsinfo.sc_numts = 1;
# Line 693  Line 743 
743                  LOGERROR("ipm_EnableEvent() failed on device:" << devHandle_);                  LOGERROR("ipm_EnableEvent() failed on device:" << devHandle_);
744          }          }
745    
746          /* Request port info          /* Request port info.
747           */           */
748          if ( dev_GetTransmitPortInfo(devHandle_, this) == -1 )          if ( dev_GetTransmitPortInfo(devHandle_, this) == -1 )
749          {          {
# Line 715  Line 765 
765          if ( ipm_GetLocalMediaInfo(devHandle_, &media_info, EV_ASYNC) == -1 )          if ( ipm_GetLocalMediaInfo(devHandle_, &media_info, EV_ASYNC) == -1 )
766          {          {
767                  LOGERROR("ipm_GetLocalMediaInfo() failed for device: " <<                  LOGERROR("ipm_GetLocalMediaInfo() failed for device: " <<
768                           devName_ << " with error: " << ATDV_LASTERR(devHandle_));                           getDeviceName() << " with error: " << ATDV_LASTERR(devHandle_));
769          }          }
770    
771          /* update init state          /* update init state.
772           */           */
773          state_ = IPM_INITIALIZATION_START;          state_ = IPM_INITIALIZATION_START;
774          initStepsRemaining_--;          initStepsRemaining_--;
# Line 734  Line 784 
784   */   */
785  void IpmDevice::onGetTxPortInfo( DM_PORT_INFO_LIST* portInfoList )  void IpmDevice::onGetTxPortInfo( DM_PORT_INFO_LIST* portInfoList )
786  {  {
787          LOGINFO("IpmDevice::onGetTxPortInfo() device: " << devName_);          LOGINFO("IpmDevice::onGetTxPortInfo() device: " << getDeviceName());
788    
789          txPortInfoList_ = *portInfoList;          txPortInfoList_ = *portInfoList;
790          printPortInfoList(&txPortInfoList_);          LOGDEBUG(std::endl << txPortInfoList_);
791    
792          for ( unsigned int i = 0; i < txPortInfoList_.unCount; i++ )          for ( unsigned int i = 0; i < txPortInfoList_.unCount; i++ )
793          {          {
794                  switch ( txPortInfoList_.port_info[i].port_media_type )                  switch ( txPortInfoList_.port_info[i].port_media_type )
795                  {                  {
796                          case DM_PORT_MEDIA_TYPE_AUDIO:                          case DM_PORT_MEDIA_TYPE_AUDIO:
                                 //memcpy(&audioPortTxInfo_, &txPortInfoList_.port_info[i], sizeof(DM_PORT_INFO));  
797                                  audioPortTxInfo_ = txPortInfoList_.port_info[i];                                  audioPortTxInfo_ = txPortInfoList_.port_info[i];
798                                  break;                                  break;
799    
800                          case DM_PORT_MEDIA_TYPE_VIDEO:                          case DM_PORT_MEDIA_TYPE_VIDEO:
                                 //memcpy(&videoPortTxInfo_, &txPortInfoList_.port_info[i], sizeof(DM_PORT_INFO));  
801                                  videoPortTxInfo_ = txPortInfoList_.port_info[i];                                  videoPortTxInfo_ = txPortInfoList_.port_info[i];
802                                  break;                                  break;
803    
# Line 771  Line 819 
819   */   */
820  void IpmDevice::onGetRxPortInfo( DM_PORT_INFO_LIST* portInfoList )  void IpmDevice::onGetRxPortInfo( DM_PORT_INFO_LIST* portInfoList )
821  {  {
822          LOGINFO("IpmDevice::onGetRxPortInfo() device: " << devName_);          LOGINFO("IpmDevice::onGetRxPortInfo() device: " << getDeviceName());
823    
824          rxPortInfoList_ = *portInfoList;          rxPortInfoList_ = *portInfoList;
825          printPortInfoList(&rxPortInfoList_);          LOGDEBUG(std::endl << rxPortInfoList_);
826    
827          for ( unsigned int i = 0; i < rxPortInfoList_.unCount; i++ )          for ( unsigned int i = 0; i < rxPortInfoList_.unCount; i++ )
828          {          {
829                  switch ( rxPortInfoList_.port_info[i].port_media_type )                  switch ( rxPortInfoList_.port_info[i].port_media_type )
830                  {                  {
831                          case DM_PORT_MEDIA_TYPE_AUDIO:                          case DM_PORT_MEDIA_TYPE_AUDIO:
                                 //memcpy(&audioPortRxInfo_, &rxPortInfoList_.port_info[i], sizeof(DM_PORT_INFO));  
832                                  audioPortRxInfo_ = rxPortInfoList_.port_info[i];                                  audioPortRxInfo_ = rxPortInfoList_.port_info[i];
833                                  break;                                  break;
834    
835                          case DM_PORT_MEDIA_TYPE_VIDEO:                          case DM_PORT_MEDIA_TYPE_VIDEO:
                                 //memcpy(&videoPortRxInfo_, &rxPortInfoList_.port_info[i], sizeof(DM_PORT_INFO));  
836                                  videoPortRxInfo_ =  rxPortInfoList_.port_info[i];                                  videoPortRxInfo_ =  rxPortInfoList_.port_info[i];
837                                  break;                                  break;
838    
# Line 809  Line 855 
855   */   */
856  void IpmDevice::onPortGetFail()  void IpmDevice::onPortGetFail()
857  {  {
858          LOGINFO("IpmDevice::onPortGetFail() device: " << devName_);          LOGINFO("IpmDevice::onPortGetFail() device: " << getDeviceName());
859    
860          state_ = IPM_INVALID;          state_ = IPM_INVALID;
861  }  }
# Line 820  Line 866 
866   */   */
867  void IpmDevice::onError()  void IpmDevice::onError()
868  {  {
869          LOGERROR("IpmDevice::onError() device: " << devName_ <<          LOGERROR("IpmDevice::onError() device: " << getDeviceName() <<
870                   " error: " << ATDV_ERRMSGP(devHandle_));                   " error: " << ATDV_ERRMSGP(devHandle_));
871    
872          state_ = IPM_INVALID;          state_ = IPM_INVALID;
# Line 832  Line 878 
878   */   */
879  void IpmDevice::onTelephonyEvent( IPM_TELEPHONY_INFO* info )  void IpmDevice::onTelephonyEvent( IPM_TELEPHONY_INFO* info )
880  {  {
881          LOGINFO("IpmDevice::processEvent() IPMEV_TELEPHONY_EVENT device: " << devName_ );          LOGINFO("IpmDevice::processEvent() IPMEV_TELEPHONY_EVENT device: " << getDeviceName() );
882          const std::string dtmf = "0123456789*#";          const std::string dtmf = "0123456789*#";
883    
884          switch ( info->eTelInfoType )          switch ( info->eTelInfoType )
# Line 843  Line 889 
889                          LOGDEBUG("TelephonyEventID: 0x" << std::hex << event_id);                          LOGDEBUG("TelephonyEventID: 0x" << std::hex << event_id);
890                          if ( event_id >= 0 && event_id <= 11 )                          if ( event_id >= 0 && event_id <= 11 )
891                          {                          {
892                                  channelMgr_.onDtmf(ipt_, dtmf.substr(event_id, 1), 100); /* fake duration */                                  channelMgr_.onDtmf(ipt_, dtmf[event_id], 100); /* fake duration */
893                          }                          }
894                          break;                          break;
895                  }                  }
# Line 860  Line 906 
906   */   */
907  void IpmDevice::onLocalMediaInfo( IPM_MEDIA_INFO* mediaInfo )  void IpmDevice::onLocalMediaInfo( IPM_MEDIA_INFO* mediaInfo )
908  {  {
909          LOGINFO("IpmDevice::onLocalMediaInfo() device: " << devName_);          LOGINFO("IpmDevice::onLocalMediaInfo() device: " << getDeviceName());
910          printMediaInfo(mediaInfo);          LOGDEBUG(std::endl << *mediaInfo);
911    
912          for( unsigned int i = 0; i < mediaInfo->unCount; i++ )          for( unsigned int i = 0; i < mediaInfo->unCount; i++ )
913          {          {
# Line 895  Line 941 
941    
942    
943  /*  /*
944   * Handler for IPMEV_EVENT_ENABLED events   * Handler for IPMEV_EVENT_ENABLED events.
945   */   */
946  void IpmDevice::onEventEnabled()  void IpmDevice::onEventEnabled()
947  {  {
948          LOGINFO("IpmDevice::onEventEnabled() device: " << devName_);          LOGINFO("IpmDevice::onEventEnabled() device: " << getDeviceName());
949    
950          initStepsRemaining_--;          initStepsRemaining_--;
951          if ( initStepsRemaining_ == 0 )          if ( initStepsRemaining_ == 0 )
# Line 914  Line 960 
960   */   */
961  void IpmDevice::onStartMedia()  void IpmDevice::onStartMedia()
962  {  {
963          LOGINFO("IpmDevice::onStartMedia() device: " << devName_);          LOGINFO("IpmDevice::onStartMedia() device: " << getDeviceName());
964          state_ = IPM_STREAMING;          state_ = IPM_STREAMING;
965          busy_ = false;          busy_ = false;
966          processPendingCommand();          processPendingCommand();
# Line 926  Line 972 
972   */   */
973  void IpmDevice::onStopped()  void IpmDevice::onStopped()
974  {  {
975          LOGINFO("IpmDevice::onStopped() device: " << devName_);          LOGINFO("IpmDevice::onStopped() device: " << getDeviceName());
976          state_ = IPM_IDLE;          state_ = IPM_IDLE;
977          busy_ = false;          busy_ = false;
978          processPendingCommand();          processPendingCommand();
# Line 938  Line 984 
984   */   */
985  void IpmDevice::onListen()  void IpmDevice::onListen()
986  {  {
987          LOGINFO("IpmDevice::onListen() device: " << devName_);          LOGINFO("IpmDevice::onListen() device: " << getDeviceName());
988          busy_ = false;          busy_ = false;
989          processPendingCommand();          processPendingCommand();
990  }  }
# Line 949  Line 995 
995   */   */
996  void IpmDevice::onUnListen()  void IpmDevice::onUnListen()
997  {  {
998          LOGINFO("IpmDevice::onUnListen() device: " << devName_);          LOGINFO("IpmDevice::onUnListen() device: " << getDeviceName());
999          busy_ = false;          busy_ = false;
1000          processPendingCommand();          processPendingCommand();
1001  }  }
# Line 960  Line 1006 
1006   */   */
1007  void IpmDevice::onPortConnect()  void IpmDevice::onPortConnect()
1008  {  {
1009          LOGINFO("IpmDevice::onPortConnect() device: " << devName_);          LOGINFO("IpmDevice::onPortConnect() device: " << getDeviceName());
1010          busy_ = false;          busy_ = false;
1011          processPendingCommand();          processPendingCommand();
1012  }  }
# Line 970  Line 1016 
1016   */   */
1017  void IpmDevice::onPortConnectFail()  void IpmDevice::onPortConnectFail()
1018  {  {
1019          LOGERROR("IpmDevice::onPortConnectFail() device: " << devName_);          LOGERROR("IpmDevice::onPortConnectFail() device: " << getDeviceName());
1020          busy_ = false;          busy_ = false;
1021          processPendingCommand();          processPendingCommand();
1022  }  }
# Line 980  Line 1026 
1026   */   */
1027  void IpmDevice::onPortDisconnect()  void IpmDevice::onPortDisconnect()
1028  {  {
1029          LOGINFO("IpmDevice::onPortDisconnect() device: " << devName_);          LOGINFO("IpmDevice::onPortDisconnect() device: " << getDeviceName());
1030          busy_ = false;          busy_ = false;
1031          processPendingCommand();          processPendingCommand();
1032  }  }
1033    
1034    
1035  /*  /*
1036   * print all structs in the list   * Set the dtmf signalling mode.
1037     * XXX add support for SIP INFO (need to process message body ourselves).
1038   */   */
1039  void IpmDevice::printPortInfoList( DM_PORT_INFO_LIST* portInfoList ) const  void IpmDevice::setDtmfMode( DtmfMode dtmf_mode )
1040    {
1041            IPM_PARM_INFO parmInfo;
1042    
1043            switch ( dtmf_mode )
1044  {  {
1045          for ( unsigned int i = 0; i < portInfoList->unCount; i++ )                  case DTMF_RFC2833:
1046          {          {
1047                  printPortInfo(&portInfoList->port_info[i]);                                  eIPM_DTMFXFERMODE value = DTMFXFERMODE_RFC2833;
1048          }                                  parmInfo.eParm = PARMCH_DTMFXFERMODE;
1049                                    parmInfo.pvParmValue = &value;
1050                                    LOGINFO("IpmDevice::setDtmfMode() using RFC2833");
1051                                    if ( ipm_SetParm(devHandle_, &parmInfo, EV_SYNC) < 0 )
1052                                    {
1053                                            LOGERROR("ipm_SetParm() DTMFXFERMODE_RFC2833");
1054  }  }
1055    
1056  /*                                  parmInfo.eParm = PARMCH_RFC2833EVT_TX_PLT;
1057   * print the struct                                  parmInfo.pvParmValue = &rfc2833_payload_type_;
1058   */                                  if ( ipm_SetParm(devHandle_, &parmInfo, EV_SYNC) < 0 )
 void IpmDevice::printPortInfo( DM_PORT_INFO* portInfo ) const  
1059  {  {
1060          std::stringstream ss;                                          LOGERROR("ipm_SetParm() PARMCH_RFC2833EVT_TX_PLT " << rfc2833_payload_type_);
1061                                    }
1062    
1063          ss << "MediaType: " << portInfo->port_media_type << " ";                                  parmInfo.eParm = PARMCH_RFC2833EVT_RX_PLT;
1064          if ( portInfo->port_media_type == DM_PORT_MEDIA_TYPE_AUDIO )                                  parmInfo.pvParmValue = &rfc2833_payload_type_;
1065                                    if ( ipm_SetParm(devHandle_, &parmInfo, EV_SYNC) < 0 )
1066          {          {
1067                  ss << "Audio";                                          LOGERROR("ipm_SetParm() PARMCH_RFC2833EVT_RX_PLT " << rfc2833_payload_type_);
1068          }          }
         else if ( portInfo->port_media_type == DM_PORT_MEDIA_TYPE_VIDEO )  
         {  
                 ss << "Video";  
1069          }          }
1070          else if ( portInfo->port_media_type == DM_PORT_MEDIA_TYPE_NBUP )                          break;
1071    
1072                    case DTMF_INBAND:
1073          {          {
1074                  ss << "NBUP";                                  eIPM_DTMFXFERMODE value = DTMFXFERMODE_INBAND;
1075          }                                  parmInfo.eParm = PARMCH_DTMFXFERMODE;
1076          else                                  parmInfo.pvParmValue = &value;
1077    
1078                                    LOGINFO("IpmDevice::setDtmfMode() using inband audio");
1079                                    if ( ipm_SetParm(devHandle_, &parmInfo, EV_SYNC) < 0 )
1080          {          {
1081                  ss << portInfo->port_media_type;                                          LOGERROR("ipm_SetParm() DTMFXFERMODE_INBAND");
1082          }          }
         ss << " DeviceID: ";  
         for ( size_t i = 0; i < sizeof(portInfo->device_ID); i++ )  
         {  
                 ss << std::setw(2) << std::setfill('0') << std::hex << (unsigned int)portInfo->device_ID[i];  
1083          }          }
1084          ss << " PortID: ";                          break;
         for ( size_t i = 0; i < sizeof(portInfo->port_ID); i++ )  
         {  
                 ss << std::setw(2) << std::setfill('0') << std::hex << (unsigned int) portInfo->port_ID[i];  
1085          }          }
         LOGDEBUG(ss.str());  
1086  }  }
1087    
1088    
1089  /*  /*
1090   * Debug aid   * Convert a minimum-picture-interval to frames-per-second.
1091     * RFC4629: fps = 30 / (1.001 * the specified value).
1092   */   */
1093  void IpmDevice::printMediaInfo( IPM_MEDIA_INFO* mediaInfo ) const  int IpmDevice::mpi2fps( int mpi )
 {  
         std::stringstream ss;  
         for ( unsigned int i = 0; i < mediaInfo->unCount; i++ )  
1094          {          {
1095                  ss << "MediaType = ";          int fps;
1096                  switch ( mediaInfo->MediaData[i].eMediaType )          switch ( mpi )
1097                  {                  {
1098                          case MEDIATYPE_VIDEO_LOCAL_RTP_INFO:                  case 1:
1099                                  ss << "MEDIATYPE_VIDEO_LOCAL_RTP_INFO";                          fps = VIDEO_FRAMESPERSEC_2997;
                                 break;  
   
                         case MEDIATYPE_VIDEO_LOCAL_RTCP_INFO:  
                                 ss << "MEDIATYPE_VIDEO_LOCAL_RTCP_INFO";  
1100                                  break;                                  break;
1101    
1102                          case MEDIATYPE_AUDIO_LOCAL_RTP_INFO:                  case 2:
1103                                  ss << "MEDIATYPE_AUDIO_LOCAL_RTP_INFO";                          fps = VIDEO_FRAMESPERSEC_15;
1104                                  break;                                  break;
1105    
1106                          case MEDIATYPE_AUDIO_LOCAL_RTCP_INFO:                  case 3:
1107                                  ss << "MEDIATYPE_AUDIO_LOCAL_RTCP_INFO";                          fps = VIDEO_FRAMESPERSEC_10;
1108                                  break;                                  break;
1109    
1110                          case MEDIATYPE_NBUP_LOCAL_RTP_INFO:                  case 5:
1111                                  ss << "MEDIATYPE_NBUP_LOCAL_RTP_INFO";                          fps = VIDEO_FRAMESPERSEC_6;
1112                                  break;                                  break;
1113    
1114                          default:                          default:
1115                                  ss << "MEDIATYPE_??? " << mediaInfo->MediaData[i].eMediaType;                          fps = VIDEO_FRAMESPERSEC_DEFAULT;
1116                                  break;                                  break;
1117                  }                  }
1118                  ss << " IP = " << mediaInfo->MediaData[i].mediaInfo.PortInfo.cIPAddress;          return fps;
1119                  ss << " Port = " << mediaInfo->MediaData[i].mediaInfo.PortInfo.unPortId;  }
1120                  ss << std::endl;  
1121    
1122    /*
1123     * Convert frames-per-second to a minimum-picture-interval.
1124     * RFC4629: fps = 30 / (1.001 * the specified value).
1125     */
1126    int IpmDevice::fps2mpi( eVIDEO_FRAMESPERSEC fps )
1127    {
1128            int mpi;
1129            switch ( fps )
1130            {
1131                    case VIDEO_FRAMESPERSEC_6:
1132                            mpi = 5;
1133                            break;
1134    
1135                    case  VIDEO_FRAMESPERSEC_10:
1136                            mpi = 3;
1137                            break;
1138    
1139                    case VIDEO_FRAMESPERSEC_2997:
1140                    case VIDEO_FRAMESPERSEC_30:
1141                            mpi = 1;
1142                            break;
1143    
1144                    default:  /* 15 fps */
1145                            mpi = 2;
1146                            break;
1147          }          }
1148          LOGDEBUG(ss.str());          return mpi;
1149  }  }
1150    
1151    
1152  /*  /*
1153   * load local information into the sdp   * offer sdpS contain all available codecs.
  * XXX 'response' sdpS should return all 'm' (media) headers that were 'offered'  
  * with unused/unsupported ones having their port set to 0.  
1154   */   */
1155  void IpmDevice::buildLocalSdp( sdpSessionDescription& sdp ) const  void IpmDevice::buildOfferSdp( SdpSessionDescription& sdp )
1156  {  {
1157          /* get here so it can be used for the origin address */          /* get here so it can be used for the origin address */
1158          IpInfo audio_media;          IpInfo local_audio_rtp;
1159          getLocalMediaInfo(MEDIATYPE_AUDIO_LOCAL_RTP_INFO, audio_media);          getLocalMediaInfo(MEDIATYPE_AUDIO_LOCAL_RTP_INFO, local_audio_rtp);
1160    
1161          sdp.version()->setVersion("0");          sdp.version()->setVersion("0");
1162    
1163          sdp.origin()->setUserName("DiaStarServer");          sdp.origin()->setUserName("DiaStarServer");
1164          sdp.origin()->setNetworkType("IN");          sdp.origin()->setNetworkType("IN");
1165          sdp.origin()->setAddressType("IP4");          sdp.origin()->setAddressType("IP4");
1166          sdp.origin()->setAddress(audio_media.getAddress().c_str());          sdp.origin()->setAddress(local_audio_rtp.getAddress().c_str());
1167    
1168            /* use a common c= for all media */
1169            sdp.connection()->setNetworkType("IN");
1170            sdp.connection()->setAddressType("IP4");
1171            sdp.connection()->setAddress(local_audio_rtp.getAddress().c_str());
1172    
1173          time_t t;          time_t t;
1174          time(&t);          time(&t);
# Line 1105  Line 1179 
1179    
1180          sdp.sessionName()->setName("DiaStarServer");          sdp.sessionName()->setName("DiaStarServer");
1181    
1182          sdpTimeDescription* timeDescription = sdp.timeDescriptionList()->addItem();          SdpTimeDescription* timeDescription = sdp.timeDescriptionList()->addItem();
1183          timeDescription->time()->setStart(0);          timeDescription->time()->setStart(0);
1184          timeDescription->time()->setStop(0);          timeDescription->time()->setStop(0);
1185    
1186          /* media          /* media
1187           */           */
1188          sdpMediaDescriptionList* mdList = sdp.mediaDescriptionList();          SdpMediaDescriptionList* mdList = sdp.mediaDescriptionList();
1189          mdList->clear();          mdList->clear();
1190    
1191          /* audio          /* m=audio
1192           */           */
1193          sdpMediaDescription* audioMD = mdList->addItem();          const Coders::audio_coders_t&  audioCoders = channelMgr_.getAudioCoders();
1194          audioMD->connection()->setNetworkType("IN");          if ( audioCoders.size() > 0 )
1195          audioMD->connection()->setAddressType("IP4");          {
1196          audioMD->connection()->setAddress(audio_media.getAddress().c_str());                  SdpMediaDescription* audioMD = mdList->addItem();
1197                    SdpMedia* audioMedia = audioMD->media();
         sdpMedia* audioMedia = audioMD->media();  
1198          audioMedia->setMedia("audio");          audioMedia->setMedia("audio");
1199          audioMedia->setPort(audio_media.getPort());                  audioMedia->setPort(local_audio_rtp.getPort());
1200          audioMedia->setTransport("RTP/AVP");          audioMedia->setTransport("RTP/AVP");
1201          audioMedia->setNumPorts(1);          audioMedia->setNumPorts(1);
         audioMedia->addFormat("0");      /* PCMU/8000 */  
         audioMedia->addFormat("101");    /* telephone-event/8000 */  
1202    
1203          sdpAttributeList* audioAttrList = audioMD->attributeList();                  SdpAttributeList* audioAttrList = audioMD->attributeList();
1204          sdpAttribute* audioAttribute = audioAttrList->addItem();                  SdpAttribute* audioAttribute;
1205    
1206                    Coders::audio_coders_t::const_iterator i;
1207                    for ( i = audioCoders.begin(); i != audioCoders.end(); ++i )
1208                    {
1209                            const AudioCoderInfo& audio_coder_info = *i;
1210    
1211                            if ( audio_coder_info.coderType == CODER_TYPE_G711ULAW64K )
1212                            {
1213                                    audioMedia->addFormat("0");
1214                                    audioAttribute = audioAttrList->addItem();
1215          audioAttribute->setProperty("rtpmap");          audioAttribute->setProperty("rtpmap");
1216          audioAttribute->setPropertyValue("0 PCMU/8000");          audioAttribute->setPropertyValue("0 PCMU/8000");
1217                            }
1218                            else if ( audio_coder_info.coderType == CODER_TYPE_G711ALAW64K )
1219                            {
1220                                    audioMedia->addFormat("8");
1221                                    audioAttribute = audioAttrList->addItem();
1222                                    audioAttribute->setProperty("rtpmap");
1223                                    audioAttribute->setPropertyValue("8 PCMA/8000");
1224                            }
1225                            else
1226                            {
1227                                    /* more */
1228                            }
1229                    }
1230                    if ( dtmf_mode_ == DTMF_RFC2833 )
1231                    {
1232                            rfc2833_payload_type_ = 101;
1233    
1234                            std::stringstream payload;
1235                            payload << rfc2833_payload_type_;
1236                            audioMedia->addFormat(payload.str().c_str());
1237    
1238          audioAttribute = audioAttrList->addItem();          audioAttribute = audioAttrList->addItem();
1239          audioAttribute->setProperty("rtpmap");          audioAttribute->setProperty("rtpmap");
1240          audioAttribute->setPropertyValue("101 telephone-event/8000");                          std::string rtpmap = payload.str() + " telephone-event/8000";
1241                            audioAttribute->setPropertyValue(rtpmap.c_str());
1242                    }
1243    
1244          audioAttribute = audioAttrList->addItem();          audioAttribute = audioAttrList->addItem();
1245          audioAttribute->setProperty("sendrecv");          audioAttribute->setProperty("sendrecv");
1246          audioAttribute->setPropertyValue("");          audioAttribute->setPropertyValue("");
1247            }
1248    
1249            /* m=video
1250             */
1251            const Coders::video_coders_t& videoCoders = channelMgr_.getVideoCoders();
1252            if ( videoCoders.size() > 0 )
1253            {
1254                    IpInfo local_video_rtp;
1255                    if ( getLocalMediaInfo(MEDIATYPE_VIDEO_LOCAL_RTP_INFO, local_video_rtp) )
1256                    {
1257                            SdpMediaDescription* videoMD = mdList->addItem();
1258                            SdpMedia* videoMedia = videoMD->media();
1259                            videoMedia->setMedia("video");
1260                            videoMedia->setPort(local_video_rtp.getPort());
1261                            videoMedia->setTransport("RTP/AVP");
1262                            videoMedia->setNumPorts(1);
1263    
1264                            SdpAttributeList* videoAttrList = videoMD->attributeList();
1265                            SdpAttribute* videoAttribute = videoAttrList->addItem();
1266    
1267                            Coders::video_coders_t::const_iterator j;
1268                            for ( j = videoCoders.begin(); j != videoCoders.end(); ++j )
1269                            {
1270                                    const VideoCoderInfo& video_coder_info  = *j;
1271    
1272                                    if ( (video_coder_info.coderType == CODER_TYPE_H263 ) ||
1273                                         (video_coder_info.coderType == CODER_TYPE_H263_1998) )
1274                                    {
1275                                            std::stringstream payload;
1276                                            payload.str("");
1277                                            payload << video_coder_info.coderPayloadType;
1278                                            videoMedia->addFormat(payload.str().c_str());
1279    
1280                                            std::stringstream rtpmap;
1281                                            rtpmap.str("");
1282                                            rtpmap << video_coder_info.coderPayloadType << " ";
1283                                            rtpmap << video_coder_info.encoding << '/' << 90000;
1284                                            videoAttribute->setProperty("rtpmap");
1285                                            videoAttribute->setPropertyValue(rtpmap.str().c_str());
1286    
1287                                            videoAttribute = videoAttrList->addItem();
1288                                            videoAttribute->setProperty("fmtp");
1289                                            std::stringstream fmtp;
1290                                            fmtp.str("");
1291                                            fmtp << video_coder_info.coderPayloadType << " ";
1292                                            std::vector<VideoCoderInfo::Fmt>::const_iterator k = video_coder_info.available_fmts.begin();
1293                                            while ( k != video_coder_info.available_fmts.end() )
1294                                            {
1295                                                    if ( ((*k).imageWidth == VIDEO_IMAGE_WIDTH_352) &&
1296                                                         ((*k).imageHeight == VIDEO_IMAGE_HEIGHT_288) )
1297                                                    {
1298                                                            fmtp << "CIF=";
1299                                                    }
1300                                                    else if ( ((*k).imageWidth == VIDEO_IMAGE_WIDTH_176) &&
1301                                                              ((*k).imageHeight == VIDEO_IMAGE_HEIGHT_144) )
1302                                                    {
1303                                                            fmtp << "QCIF=";
1304                                                    }
1305                                                    else
1306                                                    {
1307                                                            ;
1308                                                    }
1309                                                    fmtp << fps2mpi((*k).framesPerSec);
1310                                                    if ( ++k != video_coder_info.available_fmts.end() )
1311                                                    {
1312                                                            fmtp << ';';
1313                                                    }
1314                                            }
1315                                            videoAttribute->setPropertyValue(fmtp.str().c_str());
1316                                    }
1317                                    videoAttribute = videoAttrList->addItem();
1318                                    videoAttribute->setProperty("sendrecv");
1319                                    videoAttribute->setPropertyValue("");
1320    
1321                                    std::stringstream bandwidth;
1322                                    bandwidth << 384;
1323                                    videoMD->bandwidth()->setModifier("AS");
1324                                    videoMD->bandwidth()->setBandwidthValue(bandwidth.str().c_str());
1325                            }
1326                    }
1327            }
1328    }
1329    
1330    
1331    /*
1332     * Answer sdpS return all 'm' (media) headers that were 'offered'.
1333     * Unused/unsupported ones have their port set to 0.
1334     */
1335    void IpmDevice::buildAnswerSdp( SdpSessionDescription& sdp )
1336    {
1337            /* get here so it can be used for the origin address */
1338            IpInfo local_audio_rtp;
1339            getLocalMediaInfo(MEDIATYPE_AUDIO_LOCAL_RTP_INFO, local_audio_rtp);
1340    
1341            sdp.version()->setVersion("0");
1342    
1343            sdp.origin()->setUserName("DiaStarServer");
1344            sdp.origin()->setNetworkType("IN");
1345            sdp.origin()->setAddressType("IP4");
1346            sdp.origin()->setAddress(local_audio_rtp.getAddress().c_str());
1347    
1348            /* use a common c= for all media */
1349            sdp.connection()->setNetworkType("IN");
1350            sdp.connection()->setAddressType("IP4");
1351            sdp.connection()->setAddress(local_audio_rtp.getAddress().c_str());
1352    
1353            time_t t;
1354            time(&t);
1355            std::stringstream sessionIdandVersion;
1356            sessionIdandVersion << t;
1357            sdp.origin()->setSessionId(sessionIdandVersion.str().c_str());
1358            sdp.origin()->setVersion(sessionIdandVersion.str().c_str());
1359    
1360            sdp.sessionName()->setName("DiaStarServer");
1361    
1362            SdpTimeDescription* timeDescription = sdp.timeDescriptionList()->addItem();
1363            timeDescription->time()->setStart(0);
1364            timeDescription->time()->setStop(0);
1365    
1366            /*
1367             * media
1368             */
1369            SdpMediaDescriptionList* mdList = sdp.mediaDescriptionList();
1370            mdList->clear();
1371    
1372            /* m=audio
1373             */
1374            SdpMediaDescription* audioMD = mdList->addItem();
1375            SdpMedia* audioMedia = audioMD->media();
1376            audioMedia->setMedia("audio");
1377            audioMedia->setPort(local_audio_rtp.getPort());
1378            audioMedia->setTransport("RTP/AVP");
1379            audioMedia->setNumPorts(1);
1380    
1381            unsigned int accepted = 0;
1382            RemoteMedia::audio_t::const_iterator i;
1383            for ( i = offered_media_.audio.begin(); i != offered_media_.audio.end(); ++i )
1384            {
1385                    /* chosen codec.
1386                     */
1387                    if ( (*i).coder == remoteAudioCoder_ )
1388                    {
1389                            SdpAttributeList* audioAttrList = audioMD->attributeList();
1390                            SdpAttribute* audioAttribute = audioAttrList->addItem();
1391                            audioAttribute->setProperty("rtpmap");
1392    
1393                            if ( remoteAudioCoder_.coderType == CODER_TYPE_G711ULAW64K )
1394                            {
1395                                    audioMedia->addFormat("0");
1396                                    audioAttribute->setPropertyValue("0 PCMU/8000");
1397                            }
1398                            else if ( remoteAudioCoder_.coderType == CODER_TYPE_G711ALAW64K )
1399                            {
1400                                    audioMedia->addFormat("8");
1401                                    audioAttribute->setPropertyValue("8 PCMA/8000");
1402                            }
1403                            else
1404                            {
1405                                    ;
1406                            }
1407                            audioAttribute = audioAttrList->addItem();
1408                            audioAttribute->setProperty((*i).direction.c_str());
1409                            audioAttribute->setPropertyValue("");
1410    
1411                            accepted++;
1412                    }
1413    
1414                    if ( (*i).rfc2833 && (dtmf_mode_ == DTMF_RFC2833) )
1415                    {
1416                            /* save the offered payload type as it may differ from the local default. */
1417                            rfc2833_payload_type_ = (*i).coder.coderPayloadType;
1418    
1419                            std::stringstream payload;
1420                            payload << rfc2833_payload_type_;
1421                            audioMedia->addFormat(payload.str().c_str());
1422    
1423                            SdpAttributeList* audioAttrList = audioMD->attributeList();
1424                            SdpAttribute* audioAttribute = audioAttrList->addItem();
1425                            audioAttribute->setProperty("rtpmap");
1426                            std::string rtpmap = payload.str() + " telephone-event/8000";
1427                            audioAttribute->setPropertyValue(rtpmap.c_str());
1428    
1429          /* video                          accepted++;
1430                    }
1431            }
1432    
1433            /* rejected media, send m= with port set to zero.
1434           */           */
1435          IpInfo video_media;          if  ( (i == offered_media_.audio.end()) || (offered_media_.audio.size() > accepted) )
1436          if ( getLocalMediaInfo(MEDIATYPE_VIDEO_LOCAL_RTP_INFO, video_media) )          {
1437                    SdpMediaDescription* audioMD = mdList->addItem();
1438                    SdpMedia* audioMedia = audioMD->media();
1439                    audioMedia->setMedia("audio");
1440                    audioMedia->setPort(0);               /* important! */
1441                    audioMedia->setTransport("RTP/AVP");
1442                    audioMedia->setNumPorts(1);
1443    
1444                    for ( i = offered_media_.audio.begin(); i != offered_media_.audio.end(); ++i )
1445          {          {
1446                  sdpMediaDescription* videoMD = mdList->addItem();                          if ( ((*i).coder != remoteAudioCoder_ ) &&
1447                  videoMD->connection()->setNetworkType("IN");                               !((*i).rfc2833 && (dtmf_mode_ == DTMF_RFC2833)) )
1448                  videoMD->connection()->setAddressType("IP4");                          {
1449                  videoMD->connection()->setAddress(video_media.getAddress().c_str());                                  std::stringstream payload;
1450                                    payload << (*i).coder.coderPayloadType;
1451                                    audioMedia->addFormat(payload.str().c_str());
1452                                    payload.str("");
1453                            }
1454                    }
1455            }
1456    
1457                  sdpMedia* videoMedia = videoMD->media();          /* m=video
1458             */
1459            IpInfo local_video_rtp;
1460            getLocalMediaInfo(MEDIATYPE_VIDEO_LOCAL_RTP_INFO, local_video_rtp);
1461    
1462            RemoteMedia::video_t::const_iterator j;
1463            for ( j = offered_media_.video.begin(); j != offered_media_.video.end(); ++j )
1464            {
1465                    /* chosen codec.
1466                     */
1467                    if ( (*j).coder == remoteVideoCoder_ )
1468                    {
1469                            SdpMediaDescription* videoMD = mdList->addItem();
1470                            SdpMedia* videoMedia = videoMD->media();
1471                  videoMedia->setMedia("video");                  videoMedia->setMedia("video");
1472                  videoMedia->setPort(video_media.getPort());                          videoMedia->setPort(local_video_rtp.getPort());
1473                  videoMedia->setTransport("RTP/AVP");                  videoMedia->setTransport("RTP/AVP");
1474                  videoMedia->setNumPorts(1);                  videoMedia->setNumPorts(1);
                 videoMedia->addFormat("34");      /* H263/90000 */  
1475    
1476                  sdpAttributeList* videoAttrList = videoMD->attributeList();                          if ( (remoteVideoCoder_.coderType == CODER_TYPE_H263 ) ||
1477                  sdpAttribute* videoAttribute = videoAttrList->addItem();                                   (remoteVideoCoder_.coderType == CODER_TYPE_H263_1998) )
1478                            {
1479                                    std::stringstream payload;
1480                                    payload << remoteVideoCoder_.coderPayloadType;
1481                                    videoMedia->addFormat(payload.str().c_str());
1482    
1483                                    std::stringstream rtpmap;
1484                                    rtpmap << remoteVideoCoder_.coderPayloadType << " ";
1485                                    rtpmap << remoteVideoCoder_.encoding << '/' << 90000;
1486                                    SdpAttributeList* videoAttrList = videoMD->attributeList();
1487                                    SdpAttribute* videoAttribute = videoAttrList->addItem();
1488                  videoAttribute->setProperty("rtpmap");                  videoAttribute->setProperty("rtpmap");
1489                  videoAttribute->setPropertyValue("34 H263/90000");                                  videoAttribute->setPropertyValue(rtpmap.str().c_str());
1490    
1491                  videoAttribute = videoAttrList->addItem();                  videoAttribute = videoAttrList->addItem();
1492                  videoAttribute->setProperty("fmtp");                  videoAttribute->setProperty("fmtp");
1493                  videoAttribute->setPropertyValue("34 CIF=2");                                  std::stringstream fmtp;
1494                                    if ( (remoteVideoCoder_.active_fmt.imageWidth == VIDEO_IMAGE_WIDTH_352) &&
1495                                         (remoteVideoCoder_.active_fmt.imageHeight == VIDEO_IMAGE_HEIGHT_288) )
1496                                    {
1497                                            fmtp << remoteVideoCoder_.coderPayloadType << " CIF=";
1498                                    }
1499                                    else if ( (remoteVideoCoder_.active_fmt.imageWidth == VIDEO_IMAGE_WIDTH_176) &&
1500                                              (remoteVideoCoder_.active_fmt.imageHeight == VIDEO_IMAGE_HEIGHT_144) )
1501                                    {
1502                                            fmtp << remoteVideoCoder_.coderPayloadType << " QCIF=";
1503                                    }
1504                                    else
1505                                    {
1506                                            ;
1507                                    }
1508                                    fmtp << fps2mpi(remoteVideoCoder_.active_fmt.framesPerSec);
1509                                    videoAttribute->setPropertyValue(fmtp.str().c_str());
1510    
1511                  videoAttribute = videoAttrList->addItem();                  videoAttribute = videoAttrList->addItem();
1512                  videoAttribute->setProperty("sendrecv");                                  videoAttribute->setProperty((*j).direction.c_str());
1513                                    videoAttribute->setPropertyValue("");
1514    
1515                                    std::stringstream bandwidth;
1516                                    bandwidth << 384;
1517                                    videoMD->bandwidth()->setModifier("AS");
1518                                    videoMD->bandwidth()->setBandwidthValue(bandwidth.str().c_str());
1519                            }
1520                            else if ( remoteVideoCoder_.coderType == CODER_TYPE_MP4V_ES )
1521                            {
1522                                    std::stringstream payload;
1523                                    payload << remoteVideoCoder_.coderPayloadType;
1524                                    videoMedia->addFormat(payload.str().c_str());
1525    
1526                                    std::stringstream rtpmap;
1527                                    rtpmap << remoteVideoCoder_.coderPayloadType << " ";
1528                                    rtpmap << remoteVideoCoder_.encoding << '/' << 90000;
1529                                    SdpAttributeList* videoAttrList = videoMD->attributeList();
1530                                    SdpAttribute* videoAttribute = videoAttrList->addItem();
1531                                    videoAttribute->setProperty("rtpmap");
1532                                    videoAttribute->setPropertyValue(rtpmap.str().c_str());
1533    
1534                                    videoAttribute = videoAttrList->addItem();
1535                                    videoAttribute->setProperty("fmtp");
1536                                    std::stringstream fmtp;
1537                                    fmtp << remoteVideoCoder_.coderPayloadType << " profile-level-id=";
1538    
1539                                    if ( remoteVideoCoder_.profile == VIDEO_PROFILE_LEVEL_SP0_MPEG4 )
1540                                    {
1541                                            fmtp << "0";
1542                                    }
1543                                    else if ( remoteVideoCoder_.profile == VIDEO_PROFILE_LEVEL_SP1_MPEG4 )
1544                                    {
1545                                            fmtp << "1";
1546                                    }
1547                                    else if ( remoteVideoCoder_.profile == VIDEO_PROFILE_LEVEL_SP2_MPEG4 )
1548                                    {
1549                                            fmtp << "2";
1550                                    }
1551                                    else if ( remoteVideoCoder_.profile == VIDEO_PROFILE_LEVEL_SP3_MPEG4 )
1552                                    {
1553                                            fmtp << "3";
1554                                    }
1555                                    videoAttribute->setPropertyValue(fmtp.str().c_str());
1556    
1557                                    videoAttribute = videoAttrList->addItem();
1558                                    videoAttribute->setProperty((*j).direction.c_str());
1559                  videoAttribute->setPropertyValue("");                  videoAttribute->setPropertyValue("");
1560    
1561                                    std::stringstream bandwidth;
1562                                    bandwidth << 384;
1563                  videoMD->bandwidth()->setModifier("AS");                  videoMD->bandwidth()->setModifier("AS");
1564                  videoMD->bandwidth()->setBandwidthValue("90");                                  videoMD->bandwidth()->setBandwidthValue(bandwidth.str().c_str());
1565                            }
1566                            else
1567                            {
1568                                    /* more coders */
1569                            }
1570                            break;
1571                    }
1572            }
1573            /* rejected media, send m= with port set to zero.
1574             */
1575            if  ( (j == offered_media_.video.end()) || (offered_media_.video.size() > 1) )
1576            {
1577                    SdpMediaDescription* videoMD = mdList->addItem();
1578                    SdpMedia* videoMedia = videoMD->media();
1579                    videoMedia->setMedia("video");
1580                    videoMedia->setPort(0);               /* important! */
1581                    videoMedia->setTransport("RTP/AVP");
1582                    videoMedia->setNumPorts(1);
1583    
1584                    for ( j = offered_media_.video.begin(); j != offered_media_.video.end(); ++j )
1585                    {
1586                            if ( (*j).coder != remoteVideoCoder_ )
1587                            {
1588                                    std::stringstream payload;
1589                                    payload << (*j).coder.coderPayloadType;
1590                                    videoMedia->addFormat(payload.str().c_str());
1591                                    payload.str("");
1592                            }
1593                    }
1594          }          }
1595  }  }
1596    
1597    
1598  /*  /*
1599   * Set the dtmf signalling mode.   * Extract the media details from the sdp and choose a coder from those offered.
1600   */   */
1601  void IpmDevice::setDtmfMode( DtmfMode dtmf_mode )  void IpmDevice::onSdp( SdpSessionDescription& sdp )
1602  {  {
1603          IPM_PARM_INFO parmInfo;          parseSdp(sdp);  /* parses the sdp into offered_media_ */
1604    
1605          switch ( dtmf_mode )          setRemoteMediaInfo(MEDIATYPE_AUDIO_REMOTE_RTP_INFO, IpInfo());  /* clear */
1606    
1607            const Coders::audio_coders_t&  audioCoders = channelMgr_.getAudioCoders();
1608            Coders::audio_coders_t::const_iterator i;
1609            for ( i = audioCoders.begin(); i != audioCoders.end(); ++i )
1610          {          {
1611                  case DTMF_RFC2833:                  RemoteMedia::audio_t::const_iterator j;
1612                    for ( j = offered_media_.audio.begin(); j != offered_media_.audio.end(); ++j )
1613                          {                          {
1614                                  eIPM_DTMFXFERMODE value = DTMFXFERMODE_RFC2833;                          if ( *i == (*j).coder )
1615                                  parmInfo.eParm = PARMCH_DTMFXFERMODE;                          {
1616                                  parmInfo.pvParmValue = &value;                                  LOGINFO("IpmDevice::onSdp() chose: \"" << (*i).encoding << "\" for audio");
1617                                  LOGINFO("IpmDevice::setDtmfMode() using RFC2833");                                  remoteAudioCoder_ = (*j).coder;
1618                                  if ( ipm_SetParm(devHandle_, &parmInfo, EV_SYNC) < 0 )                                  setRemoteMediaInfo(MEDIATYPE_AUDIO_REMOTE_RTP_INFO, (*j).rtp);
1619                                    break;
1620                            }
1621                    }
1622                    if ( j != offered_media_.audio.end() )
1623                                  {                                  {
1624                                          LOGERROR("Error in ipm_SetParm()\n");                          break;
1625                    }
1626                                  }                                  }
1627    
1628                                  int rfc2833PayloadType = 101;          setRemoteMediaInfo(MEDIATYPE_VIDEO_REMOTE_RTP_INFO, IpInfo());  /* clear */
1629    
1630                                  parmInfo.eParm = PARMCH_RFC2833EVT_TX_PLT;          const Coders::video_coders_t&  videoCoders = channelMgr_.getVideoCoders();
1631                                  parmInfo.pvParmValue = &rfc2833PayloadType;          Coders::video_coders_t::const_iterator k;
1632                                  if ( ipm_SetParm(devHandle_, &parmInfo, EV_SYNC) < 0 )          for ( k = videoCoders.begin(); k != videoCoders.end(); ++k )
1633            {
1634                    RemoteMedia::video_t::const_iterator l;
1635                    for ( l = offered_media_.video.begin(); l != offered_media_.video.end(); ++l )
1636                    {
1637                            if ( *k == (*l).coder )
1638                                  {                                  {
1639                                          LOGERROR("Error in ipm_SetParm()\n");                                  LOGINFO("IpmDevice::onSdp() chose: \"" << (*k).encoding << "\" for video");
1640                                    remoteVideoCoder_ = (*l).coder;
1641                                    /* use the first fmt offered, there is always at least one */
1642                                    remoteVideoCoder_.active_fmt = (*l).coder.available_fmts[0];
1643                                    setRemoteMediaInfo(MEDIATYPE_VIDEO_REMOTE_RTP_INFO, (*l).rtp);
1644                                    break;
1645                            }
1646                    }
1647                    if ( l != offered_media_.video.end() )
1648                    {
1649                            break;
1650                    }
1651            }
1652                                  }                                  }
1653    
1654                                  parmInfo.eParm = PARMCH_RFC2833EVT_RX_PLT;  
1655                                  parmInfo.pvParmValue = &rfc2833PayloadType;  /*
1656                                  if ( ipm_SetParm(devHandle_, &parmInfo, EV_SYNC) < 0 )   * Extract media details from an sdp.
1657     */
1658    void IpmDevice::parseSdp( SdpSessionDescription& sdp )
1659    {
1660            offered_media_.audio.clear();
1661            offered_media_.video.clear();
1662    
1663            std::string addr(sdp.connection()->getAddress());
1664    /*
1665            int bandwidth = atoi(sdp.bandwidth()->getBandwidthValue());
1666            std::string modifier = sdp.bandwidth()->getModifier();
1667    */
1668            std::string direction = "sendrecv";
1669            SdpAttributeList* attributeList = sdp.attributeList();
1670            int nAttribute = attributeList->numItem();
1671            for ( int n = 0; n < nAttribute; n++ )
1672            {
1673                    SdpAttribute* attribute = attributeList->getItem(n);
1674    
1675                    if ( !strcmp(attribute->getProperty(), "sendonly") )
1676                    {
1677                            direction = "sendonly";
1678                    }
1679                    if ( !strcmp(attribute->getProperty(), "recvonly") )
1680                    {
1681                            direction = "recvonly";
1682                    }
1683                    if ( !strcmp(attribute->getProperty(), "sendrecv") )
1684                    {
1685                            direction = "sendrecv";
1686                    }
1687                    if ( !strcmp(attribute->getProperty(), "inactive") )
1688                    {
1689                            direction = "inactive";
1690                    }
1691            }
1692            // TODO add direction check inside each media description
1693    
1694            int num_media = sdp.mediaDescriptionList()->numItem();
1695            for ( int i = 0; i < num_media; i++ )
1696            {
1697                    SdpMediaDescription* md = sdp.mediaDescriptionList()->getItem(i);
1698    
1699                    /* m=audio
1700                     */
1701                    SdpMedia* media = md->media();
1702                    if ( !strcmp(media->getMedia(), "audio") &&
1703                         !strcmp(media->getTransport(), "RTP/AVP") &&
1704                         (media->getPort() != 0) )
1705                    {
1706                            IpInfo rtp(addr, media->getPort());
1707    
1708                            int num_format = media->getNumFormat();
1709                            for ( int j = 0; j < num_format; j++ )
1710                            {
1711                                    RemoteMedia::Audio audio_media;
1712                                    audio_media.rtp = rtp;
1713    
1714                                    audio_media.coder.coderPayloadType = atoi(media->getFormat(j));
1715                                    audio_media.coder.coderType = CODER_TYPE_NONSTANDARD;
1716    
1717                                    /* set defaults for fixed formats, these may be overridden by
1718                                     * an fmtp attribute.
1719                                     */
1720                                    if ( audio_media.coder.coderPayloadType == 0 )  /* PCMU */
1721                                    {
1722                                            audio_media.coder.encoding = "PCMU";
1723                                            audio_media.coder.coderType = CODER_TYPE_G711ULAW64K;
1724                                            audio_media.coder.coderFramesize = CODER_FRAMESIZE_20;
1725                                            audio_media.coder.framesPerPkt = 1;
1726                                            audio_media.coder.vadEnable = CODER_VAD_ENABLE;
1727                                            audio_media.coder.redPayloadType = 0;
1728                                    }
1729                                    else if ( audio_media.coder.coderPayloadType == 8 )  /* PCMA */
1730                                    {
1731                                            audio_media.coder.encoding = "PCMA";
1732                                            audio_media.coder.coderType = CODER_TYPE_G711ALAW64K;
1733                                            audio_media.coder.coderFramesize = CODER_FRAMESIZE_20;
1734                                            audio_media.coder.framesPerPkt = 1;
1735                                            audio_media.coder.vadEnable = CODER_VAD_ENABLE;
1736                                            audio_media.coder.redPayloadType = 0;
1737                                    }
1738                                    else
1739                                    {
1740                                            /* more payload types go here. */
1741                                    }
1742                                    audio_media.direction = direction;
1743                                    audio_media.rfc2833  = false;
1744                                    offered_media_.audio.push_back(audio_media);
1745                            }
1746    
1747                            SdpAttributeList* attributeList = md->attributeList();
1748                            int nAttribute = attributeList->numItem();
1749                            for ( int k = 0; k < nAttribute; k++ )
1750                            {
1751                                    SdpAttribute* attribute = attributeList->getItem(k);
1752    
1753                                    if ( strcmp(attribute->getProperty(), "rtpmap") == 0 )
1754                                  {                                  {
1755                                          LOGERROR("Error in ipm_SetParm()\n");                                          StringTokeniser rtpmap(attribute->getPropertyValue());
1756    
1757                                            int payload = atoi(rtpmap.token(' ').c_str());
1758                                            std::string encoding = rtpmap.token('/');
1759                                            int clockrate = atoi(rtpmap.token().c_str());
1760                                            if ( clockrate != 8000 )
1761                                            {
1762                                                    LOGWARN("IpmDevice::parseSdp() payload: " << payload <<
1763                                                            " has an unsupported clockrate: " << clockrate);
1764                                            }
1765                                            RemoteMedia::audio_t::iterator i;
1766                                            for ( i = offered_media_.audio.begin(); i != offered_media_.audio.end(); ++i )
1767                                            {
1768                                                    if ( (*i).coder.coderPayloadType == payload )
1769                                                    {
1770                                                            (*i).coder.encoding = encoding;
1771    
1772                                                            if ( strcasecmp((*i).coder.encoding.c_str(), "PCMU") == 0 )
1773                                                            {
1774                                                                    (*i).coder.coderType = CODER_TYPE_G711ULAW64K;
1775                                                            }
1776                                                            else if ( strcasecmp((*i).coder.encoding.c_str(), "PCMA") == 0 )
1777                                                            {
1778                                                                    (*i).coder.coderType = CODER_TYPE_G711ALAW64K;
1779                                                            }
1780                                                            else if ( strcasecmp((*i).coder.encoding.c_str(), "telephone-event") == 0 )
1781                                                            {
1782                                                                    /* not really a codec. */
1783                                                                    (*i).coder.coderType = CODER_TYPE_NONSTANDARD;
1784                                                                    (*i).rfc2833 = true;
1785                                  }                                  }
1786                                                            else
1787                                                            {
1788                          }                          }
1789                          break;                          break;
1790                                                    }
1791                                            }
1792                                    }
1793                                    else if ( strcmp(attribute->getProperty(), "fmtp") == 0 )
1794                                    {
1795                                            StringTokeniser fmtp(attribute->getPropertyValue());
1796    
1797                  case DTMF_INBAND:                                          int format = atoi(fmtp.token(' ').c_str());
1798    
1799                                            RemoteMedia::audio_t::iterator i;
1800                                            for ( i = offered_media_.audio.begin(); i != offered_media_.audio.end(); ++i )
1801                          {                          {
1802                                  eIPM_DTMFXFERMODE value = DTMFXFERMODE_INBAND;                                                  if ( (*i).coder.coderPayloadType == format )
1803                                  parmInfo.eParm = PARMCH_DTMFXFERMODE;                                                  {
1804                                  parmInfo.pvParmValue = &value;                                                          if ( ((*i).coder.coderType == CODER_TYPE_NONSTANDARD) && ((*i).rfc2833) )
1805                                                            {
1806                                                                    /* TODO use this */
1807                                                            }
1808                                                            else
1809                                                            {
1810                                                                    /* more payload types */
1811                                                            }
1812                                                            break;
1813                                                    }
1814                                            }
1815                                    }
1816                                    else
1817                                    {
1818                                            /* more attributes */
1819                                    }
1820                            }
1821                    }
1822    
1823                                  LOGINFO("IpmDevice::setDtmfMode() using inband audio");                  /* m=video
1824                                  if ( ipm_SetParm(devHandle_, &parmInfo, EV_SYNC) < 0 )                   */
1825                    if ( !strcmp(media->getMedia(), "video") &&
1826                         !strcmp(media->getTransport(), "RTP/AVP") &&
1827                         (media->getPort() != 0) )
1828                    {
1829                            IpInfo rtp(addr, media->getPort());
1830    
1831                            int num_format = media->getNumFormat();
1832                            for ( int j = 0; j < num_format; j++ )
1833                            {
1834                                    RemoteMedia::Video video_media;
1835                                    video_media.rtp = rtp;
1836    
1837                                    video_media.coder.coderPayloadType = atoi(media->getFormat(j));
1838    
1839                                    /* set defaults for fixed formats, these may be overridden by
1840                                     * an fmtp attribute.
1841                                     */
1842                                    if ( video_media.coder.coderPayloadType == 34 )   /* H.263 */
1843                                    {
1844                                            video_media.coder.encoding = "H263";
1845                                            video_media.coder.coderType = CODER_TYPE_H263;
1846                                            video_media.coder.profile = VIDEO_PROFILE_0_H263;
1847                                            video_media.coder.level = VIDEO_LEVEL_10_H263;
1848                                            video_media.coder.samplingRate = VIDEO_SAMPLING_RATE_DEFAULT;
1849                                            video_media.coder.bitRate = VIDEO_BITRATE_384K;
1850    
1851                                            /* set default fmt, this will be removed if an
1852                                             * fmtp attribute is found.
1853                                             */
1854                                            VideoCoderInfo::Fmt fmt;
1855                                            fmt.imageWidth = VIDEO_IMAGE_WIDTH_176;
1856                                            fmt.imageHeight = VIDEO_IMAGE_HEIGHT_144;
1857                                            fmt.framesPerSec = VIDEO_FRAMESPERSEC_15;
1858                                            video_media.coder.available_fmts.push_back(fmt);
1859                                    }
1860                                    else
1861                                    {
1862                                            /* more *known* payload types */
1863                                    }
1864                                    video_media.direction = direction;
1865                                    offered_media_.video.push_back(video_media);
1866                            }
1867    
1868                            SdpAttributeList* attributeList = md->attributeList();
1869                            int nAttribute = attributeList->numItem();
1870                            for ( int k = 0; k < nAttribute; k++ )
1871                            {
1872                                    SdpAttribute* attribute = attributeList->getItem(k);
1873    
1874                                    if ( strcmp(attribute->getProperty(), "rtpmap") == 0 )
1875                                    {
1876                                            StringTokeniser rtpmap(attribute->getPropertyValue());
1877    
1878                                            int payload = atoi(rtpmap.token(' ').c_str());
1879                                            std::string encoding = rtpmap.token('/');
1880                                            int clockrate = atoi(rtpmap.token().c_str());
1881                                            if ( clockrate != 90000 )
1882                                            {
1883                                                    LOGWARN("IpmDevice::parseSdp() payload: " << payload <<
1884                                                            " has an unsupported clockrate: " << clockrate);
1885                                            }
1886                                            RemoteMedia::video_t::iterator i;
1887                                            for ( i = offered_media_.video.begin(); i != offered_media_.video.end(); ++i )
1888                                            {
1889                                                    if ( (*i).coder.coderPayloadType == payload )
1890                                                    {
1891                                                            (*i).coder.encoding = encoding;
1892    
1893                                                            if ( strcasecmp((*i).coder.encoding.c_str(), "H263") == 0 )
1894                                  {                                  {
1895                                          LOGERROR("Error in ipm_SetParm()\n");                                                                  /* static payload type; defaults already set */
1896                                                                    (*i).coder.coderType = CODER_TYPE_H263;
1897                                  }                                  }
1898                                                            else if ( strcasecmp((*i).coder.encoding.c_str(), "H263-1998") == 0 )
1899                                                            {
1900                                                                    (*i).coder.coderType = CODER_TYPE_H263_1998;
1901                                                                    (*i).coder.profile = VIDEO_PROFILE_0_H263;
1902                                                                    (*i).coder.level = VIDEO_LEVEL_10_H263;
1903                                                                    (*i).coder.samplingRate = VIDEO_SAMPLING_RATE_DEFAULT;
1904                                                                    (*i).coder.bitRate = VIDEO_BITRATE_384K;
1905    
1906                                                                    /* set default fmt, this will be removed if an
1907                                                                     * fmtp attribute is found.
1908                                                                     */
1909                                                                    VideoCoderInfo::Fmt fmt;
1910                                                                    fmt.imageWidth = VIDEO_IMAGE_WIDTH_176;
1911                                                                    fmt.imageHeight = VIDEO_IMAGE_HEIGHT_144;
1912                                                                    fmt.framesPerSec = VIDEO_FRAMESPERSEC_15;
1913                                                                    (*i).coder.available_fmts.push_back(fmt);
1914                                                            }
1915                                                            else if ( strcasecmp((*i).coder.encoding.c_str(), "MP4V-ES") == 0 )
1916                                                            {
1917                                                                    (*i).coder.coderType = CODER_TYPE_MP4V_ES;
1918                                                                    (*i).coder.profile = VIDEO_PROFILE_LEVEL_SP0_MPEG4;
1919                                                                    (*i).coder.level = VIDEO_LEVEL_DEFAULT;
1920                                                                    (*i).coder.samplingRate = VIDEO_SAMPLING_RATE_DEFAULT;
1921                                                                    (*i).coder.bitRate = VIDEO_BITRATE_384K;
1922    
1923                                                                    /* set default fmt, this will be removed if an
1924                                                                     * fmtp attribute is found.
1925                                                                     */
1926                                                                    VideoCoderInfo::Fmt fmt;
1927                                                                    fmt.imageWidth = VIDEO_IMAGE_WIDTH_176;
1928                                                                    fmt.imageHeight = VIDEO_IMAGE_HEIGHT_144;
1929                                                                    fmt.framesPerSec = VIDEO_FRAMESPERSEC_15;
1930                                                                    (*i).coder.available_fmts.push_back(fmt);
1931                                                            }
1932                                                            else
1933                                                            {
1934                                                                    /* more encodings */
1935                          }                          }
1936                          break;                          break;
1937          }          }
1938  }  }
1939                                    }
1940                                    else if ( strcmp(attribute->getProperty(), "fmtp") == 0 )
1941                                    {
1942                                            StringTokeniser fmtp(attribute->getPropertyValue());
1943    
1944                                            int format = atoi(fmtp.token(' ').c_str());
1945    
1946                                            RemoteMedia::video_t::iterator i;
1947                                            for ( i = offered_media_.video.begin(); i != offered_media_.video.end(); ++i )
1948                                            {
1949                                                    if ( (*i).coder.coderPayloadType == format )
1950                                                    {
1951                                                            if ( ((*i).coder.coderType == CODER_TYPE_H263) ||
1952                                                                 ((*i).coder.coderType == CODER_TYPE_H263_1998) )
1953                                                            {
1954                                                                    /* e.g. fmtp:34 CIF=2;QCIF=1 */
1955    
1956                                                                    VideoCoderInfo::Fmt fmt;
1957                                                                    bool done = false;
1958                                                                    while ( !done )
1959                                                                    {
1960                                                                            std::string size = fmtp.token('=');
1961                                                                            trim(size);
1962                                                                            if ( size.empty() )
1963                                                                            {
1964                                                                                    break;
1965                                                                            }
1966                                                                            std::string mpi = fmtp.token(';');
1967                                                                            trim(mpi);
1968                                                                            if ( mpi.empty() )
1969                                                                            {
1970                                                                                    mpi = fmtp.token();
1971                                                                                    done = true;
1972                                                                            }
1973                                                                            if ( size == "CIF" )
1974                                                                            {
1975                                                                                    fmt.imageWidth = VIDEO_IMAGE_WIDTH_352;
1976                                                                                    fmt.imageHeight = VIDEO_IMAGE_HEIGHT_288;
1977                                                                            }
1978                                                                            else if ( size == "QCIF" )
1979                                                                            {
1980                                                                                    fmt.imageWidth = VIDEO_IMAGE_WIDTH_176;
1981                                                                                    fmt.imageHeight = VIDEO_IMAGE_HEIGHT_144;
1982                                                                            }
1983                                                                            else if ( size == "profile" )
1984                                                                            {
1985                                                                                    continue; // XXX use
1986                                                                            }
1987                                                                            else if ( size == "level" )
1988                                                                            {
1989                                                                                    continue; // XXX use
1990                                                                            }
1991                                                                            else
1992                                                                            {
1993                                                                                    continue; /* ignore unsupported params. */
1994                                                                            }
1995                                                                            int fps = mpi2fps(atoi(mpi.c_str()));
1996                                                                            if ( fps > VIDEO_FRAMESPERSEC_30 )
1997                                                                            {
1998                                                                                    fmt.framesPerSec = VIDEO_FRAMESPERSEC_30;
1999                                                                            }
2000                                                                            else
2001                                                                            {
2002                                                                                    fmt.framesPerSec = (eVIDEO_FRAMESPERSEC)fps;
2003                                                                            }
2004                                                                            (*i).coder.available_fmts.push_back(fmt);
2005                                                                    }
2006                                                                    /* remove the default fmt, no longer needed. */
2007                                                                    if ( (*i).coder.available_fmts.size() > 1 )
2008                                                                    {
2009                                                                            (*i).coder.available_fmts.erase((*i).coder.available_fmts.begin());
2010                                                                    }
2011                                                            }
2012                                                            else if ( (*i).coder.coderType == CODER_TYPE_MP4V_ES )
2013                                                            {
2014                                                                    std::string param = fmtp.token('=');
2015                                                                    trim(param);
2016                                                                    std::string value = fmtp.token(';');
2017                                                                    trim(value);
2018                                                                    if ( value.empty() )
2019                                                                    {
2020                                                                            value = fmtp.token();
2021                                                                    }
2022                                                                    if ( param == "profile-level-id" )
2023                                                                    {
2024                                                                            if ( value == "0" )
2025                                                                            {
2026                                                                                    (*i).coder.profile = VIDEO_PROFILE_LEVEL_SP0_MPEG4;
2027                                                                                    VideoCoderInfo::Fmt fmt;
2028                                                                                    fmt.imageWidth = VIDEO_IMAGE_WIDTH_176;
2029                                                                                    fmt.imageHeight = VIDEO_IMAGE_HEIGHT_144;
2030                                                                                    fmt.framesPerSec = VIDEO_FRAMESPERSEC_15;
2031    
2032                                                                                    (*i).coder.available_fmts.push_back(fmt);
2033                                                                            }
2034                                                                            else if ( value == "1" )
2035                                                                            {
2036                                                                                    (*i).coder.profile = VIDEO_PROFILE_LEVEL_SP1_MPEG4;
2037                                                                                    VideoCoderInfo::Fmt fmt;
2038                                                                                    fmt.imageWidth = VIDEO_IMAGE_WIDTH_176;
2039                                                                                    fmt.imageHeight = VIDEO_IMAGE_HEIGHT_144;
2040                                                                                    fmt.framesPerSec = VIDEO_FRAMESPERSEC_15;
2041    
2042                                                                                    (*i).coder.available_fmts.push_back(fmt);
2043                                                                            }
2044                                                                            else if ( value == "2" )
2045                                                                            {
2046                                                                                    (*i).coder.profile = VIDEO_PROFILE_LEVEL_SP2_MPEG4;
2047                                                                                    VideoCoderInfo::Fmt fmt;
2048                                                                                    fmt.imageWidth = VIDEO_IMAGE_WIDTH_176;
2049                                                                                    fmt.imageHeight = VIDEO_IMAGE_HEIGHT_144;
2050                                                                                    fmt.framesPerSec = VIDEO_FRAMESPERSEC_30;
2051    
2052                                                                                    (*i).coder.available_fmts.push_back(fmt);
2053                                                                            }
2054                                                                            else if ( value == "3" )
2055                                                                            {
2056                                                                                    (*i).coder.profile = VIDEO_PROFILE_LEVEL_SP3_MPEG4;
2057                                                                                    VideoCoderInfo::Fmt fmt;
2058                                                                                    fmt.imageWidth = VIDEO_IMAGE_WIDTH_352;
2059                                                                                    fmt.imageHeight = VIDEO_IMAGE_HEIGHT_288;
2060                                                                                    fmt.framesPerSec = VIDEO_FRAMESPERSEC_30;
2061    
2062                                                                                    (*i).coder.available_fmts.push_back(fmt);
2063                                                                            }
2064                                                                    }
2065                                                                    /* remove the default fmt, no longer needed. */
2066                                                                    if ( (*i).coder.available_fmts.size() > 1 )
2067                                                                    {
2068                                                                            (*i).coder.available_fmts.erase((*i).coder.available_fmts.begin());
2069                                                                    }
2070                                                            }
2071                                                            else
2072                                                            {
2073                                                                    /* more payload types */
2074                                                            }
2075                                                            break;
2076                                                    }
2077                                            }
2078                                    }
2079                                    else
2080                                    {
2081                                            /* more attributes */
2082                                    }
2083                            }
2084                    }
2085            }
2086    }
2087    
2088    
2089    
2090  /* vim:ts=4:set nu:  /* vim:ts=4:set nu:

Legend:
Removed from v.413  
changed lines
  Added in v.524

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