Hello,

o Ovidiu Sas [03/25/09 23:42]:

Also it will have to handle multiple end events, as my source sends it
three times.
that is the reason it waits for some time before it passes the DTMF as key
press to the session. It may indeed be not possible to tell with 100%
certainity whether the RTP events belong to the same key press; there is no
ID or the like in the events.

The timestamp for two different events should be different and this
can act as an event ID.  This should be an indication that a packet
belongs to a new event (even if the event is identical to the previous
one) and it should reliably detect a new event.
thats true. I have attached a patch that does use this. Its not yet optimal though - in the case of RTP event detect timeout it can still not distinguish the two keys.

Stefan



Regards,
Ovidiu Sas

--
Stefan Sayer
VoIP Services

[email protected]
www.iptego.com

IPTEGO GmbH
Wittenbergplatz 1
10789 Berlin
Germany

Amtsgericht Charlottenburg, HRB 101010
Geschaeftsfuehrer: Alexander Hoffmann
Index: AmDtmfDetector.cpp
===================================================================
--- AmDtmfDetector.cpp  (revision 1319)
+++ AmDtmfDetector.cpp  (working copy)
@@ -135,13 +135,14 @@
 //
 // AmRtpDtmfEvent methods
 //
-AmRtpDtmfEvent::AmRtpDtmfEvent(const dtmf_payload_t *payload, int sample_rate)
+AmRtpDtmfEvent::AmRtpDtmfEvent(const dtmf_payload_t *payload, int sample_rate, 
unsigned int ts)
   : AmDtmfEvent(Dtmf::SOURCE_RTP)
 {
   m_duration_msec = ntohs(payload->duration) * 1000 / sample_rate;
   m_e = payload->e;
   m_volume = payload->volume;
   m_event = payload->event;
+  m_ts = ts;
   // RFC 2833:
   // R: This field is reserved for future use. The sender MUST set it
   // to zero, the receiver MUST ignore it.
@@ -180,7 +181,8 @@
     m_sipDetector(this),
     m_eventPending(false), m_sipEventReceived(false),
     m_inbandEventReceived(false), m_rtpEventReceived(false),
-    m_inband_type(Dtmf::SEMSInternal)
+    m_inband_type(Dtmf::SEMSInternal),
+    m_currentEvent(-1)
 {
 #ifndef USE_SPANDSP
   setInbandDetector(Dtmf::SEMSInternal);
@@ -237,11 +239,12 @@
 
 void AmDtmfDetector::registerKeyReleased(int event, Dtmf::EventSource source,
                                          const struct timeval& start,
-                                         const struct timeval& stop)
+                                         const struct timeval& stop,
+                                        bool flush)
 {
   // Old event has not been sent yet
   // push out it now
-  if (m_eventPending && m_currentEvent != event)
+  if (flush || (m_eventPending && m_currentEvent != event))
     {
       reportEvent();
     }
@@ -333,7 +336,7 @@
 
 // AmRtpDtmfDetector methods
 AmRtpDtmfDetector::AmRtpDtmfDetector(AmKeyPressSink *keysink)
-  : m_keysink(keysink), m_eventPending(false), m_packetCount(0)
+  : m_keysink(keysink), m_eventPending(false), m_packetCount(0), 
m_currentTS(0), m_currentTS_i(false)
 {
 }
 
@@ -350,39 +353,37 @@
          gettimeofday(&m_startTime, NULL);
          m_eventPending = true;
          m_currentEvent = evt->event();
+         m_currentTS = evt->ts();
+         m_currentTS_i = true;
         }
-
-      if (m_eventPending)
+      else
         {
-         if (evt->event() != m_currentEvent)
+         if ((evt->event() != m_currentEvent) || 
+             (m_currentTS_i && (evt->ts() != m_currentTS)))
             {
              // Previous event does not end correctly so send out it now...
-             sendPending();
+             sendPending(true);
              // ... and reinitialize to process current event
              gettimeofday(&m_startTime, NULL);
              m_eventPending = true;
              m_currentEvent = evt->event();
+             m_currentTS = evt->ts();
+             m_currentTS_i = true;
             }
-         if (evt->e())
-            {
-             sendPending();
-            }
         }
-      if (m_eventPending)
-        {
-         m_keysink->registerKeyPressed(m_currentEvent, Dtmf::SOURCE_RTP);
-        }
+      m_keysink->registerKeyPressed(m_currentEvent, Dtmf::SOURCE_RTP);    
     }
 }
 
-void AmRtpDtmfDetector::sendPending()
+void AmRtpDtmfDetector::sendPending(bool flush)
 {
   if (m_eventPending)
     {
       struct timeval end_time;
       gettimeofday(&end_time, NULL);
-      m_keysink->registerKeyReleased(m_currentEvent, Dtmf::SOURCE_RTP, 
m_startTime, end_time);
+      m_keysink->registerKeyReleased(m_currentEvent, Dtmf::SOURCE_RTP, 
m_startTime, end_time, flush);
       m_eventPending = false;
+      m_currentTS_i = false;
     }
 }
 
Index: AmDtmfDetector.h
===================================================================
--- AmDtmfDetector.h    (revision 1319)
+++ AmDtmfDetector.h    (working copy)
@@ -129,9 +129,10 @@
    * @param source which detector posted this event
    * @param start time when key was pressed
    * @param stop time when key was released
+   * @param flush whether key should be registered as own keypress immediately
    */
   virtual void registerKeyReleased(int event, Dtmf::EventSource source,
-                                  const struct timeval& start, const struct 
timeval& stop) = 0;
+                                  const struct timeval& start, const struct 
timeval& stop, bool flush=false) = 0;
   /**
    * Through this method the AmDtmfDetector receives events that was
    * detected by specific detectors.
@@ -156,13 +157,18 @@
    */
   int m_volume;
 
+  /** 
+   * RTP timestamp 
+   */
+  unsigned int m_ts;
+
  public:
   /**
    * Constructor
    * @param payload data from rtp packet of payload type telephone-event
    * @param sample_rate sampling rate (from SDP payload description)
    */
-  AmRtpDtmfEvent(const dtmf_payload_t *payload, int sample_rate);
+  AmRtpDtmfEvent(const dtmf_payload_t *payload, int sample_rate, unsigned int 
ts);
 
   /**
    * Volume value from RTP packet
@@ -172,6 +178,8 @@
    * E flag from RTP packet
    */
   int e() { return m_e; }
+
+  unsigned int ts() { return m_ts; }
 };
 
 /**
@@ -328,9 +336,11 @@
    */
   bool m_eventPending;
   int m_currentEvent;
+  unsigned int m_currentTS;
+  bool m_currentTS_i;
   int m_packetCount;
 
-  static const int MAX_PACKET_WAIT = 3;
+  static const int MAX_PACKET_WAIT = 4;
   /**
    * Time when first packet for current event was received
    */
@@ -339,7 +349,7 @@
   /**
    * Send out pending event
    */
-  void sendPending();
+  void sendPending(bool flush=false);
 
  public:
   /**
@@ -404,9 +414,11 @@
    * @param source which detector posted this event
    * @param start time when key was pressed
    * @param stop time when key was released
+   * @param flush whether key should be registered as own keypress immediately
    */
   void registerKeyReleased(int event, Dtmf::EventSource source,
-                          const struct timeval& start, const struct timeval& 
stop);
+                          const struct timeval& start, const struct timeval& 
stop,
+                          bool flush=false);
   /**
    * Through this method the AmDtmfDetector receives events that was
    * detected by specific detectors.
Index: AmRtpStream.cpp
===================================================================
--- AmRtpStream.cpp     (revision 1319)
+++ AmRtpStream.cpp     (working copy)
@@ -319,9 +319,9 @@
     {
       dtmf_payload_t* dpl = (dtmf_payload_t*)rp->getData();
 
-      DBG("DTMF: event=%i; e=%i; r=%i; volume=%i; duration=%i\n",
-         dpl->event,dpl->e,dpl->r,dpl->volume,ntohs(dpl->duration));
-      session->postDtmfEvent(new AmRtpDtmfEvent(dpl, getTelephoneEventRate()));
+      DBG("DTMF: event=%i; e=%i; r=%i; volume=%i; duration=%i; ts=%u\n",
+         
dpl->event,dpl->e,dpl->r,dpl->volume,ntohs(dpl->duration),rp->timestamp);
+      session->postDtmfEvent(new AmRtpDtmfEvent(dpl, getTelephoneEventRate(), 
rp->timestamp));
       mem.freePacket(rp);
       return RTP_DTMF;
     }
_______________________________________________
Semsdev mailing list
[email protected]
http://lists.iptel.org/mailman/listinfo/semsdev

Reply via email to