Google
  Web www.spinics.net

Re: OPAL and H323_ExternalRTPChannel

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]


Ok, Thanks for your answer Martin. It has been very detailed.

On 10/17/06, Martin Acevedo <acevedoma@xxxxxxxxxxx> wrote:
Hi

>I'm new to OPAL and I've a little application written using OpenH323 that
>uses H323_ExternalRTPChannel to play a prerrecorded file.Now, I want to
>test
>OPAL, and I have a few questions:
>
>1. Can I use H323_ExternalRTPChannel the same way as in OpenH323? Any docs
>describing required changes?
>2. Is there an equivalent class for SIP? Is it possible to do the same in
>SIP? Any docs or samples?
>
>I've been looking at code samples (simple and openphone), but they both use
>OpalPCSSEndpoint, which I think I should not use to do what I want (use
>H323_ExternalRTPChannel, or SIP equivalent, to play a prerrecorded file).

I don´t know if external rtp exists in opal, but, you can use your own
endpoint/connection/mediastream derived classes in order to make a wav file
player/recorder application,  similar to the PCSSEndpoint or IVREndPoint
available in opal. Instead of a soundcard/vxmlsession you can use a PWAVFile
as a source/destintation of the mediastreams....

The you should add your new endpoint to the routes in your opalmanager class

AddRouteEntry("h323:.* = wav:<da>");

"wav" is the name of the prefix used for the endpoint ( const char * prefix
= "wav")

you can use code similar to this

///WavPlayer.h

#ifndef __OPAL_WAV_H
#define __OPAL_WAV_H

#include <opal/endpoint.h>
#include <ptclib/pwavfile.h>
#include <ptclib/delaychan.h>
class WavConnection;

class WavEndPoint : public OpalEndPoint
{
       PCLASSINFO(WavEndPoint, OpalEndPoint);
public:
       WavEndPoint(OpalManager & manager, const char * prefix = "wav" );
       ~WavEndPoint();

       virtual BOOL MakeConnection(OpalCall & call, const PString & party,  void *
userData = NULL);
       virtual OpalMediaFormatList GetMediaFormats() const;
       virtual WavConnection * CreateConnection(OpalCall & call, const PString &
token,   void * userData);
       virtual PString CreateConnectionToken();
       PSafePtr<WavConnection> GetIVRConnectionWithLock(const PString & token,
PSafetyMode mode = PSafeReadWrite)
       { return PSafePtrCast<OpalConnection,
WavConnection>(GetConnectionWithLock(token, mode)); }



       void SetDefaultMediaFormats(const OpalMediaFormatList & formats);
protected:
       unsigned            nextTokenNumber;
       OpalMediaFormatList defaultMediaFormats;
};


class WavConnection : public OpalConnection
{
       PCLASSINFO(WavConnection, OpalConnection);
public:
       WavConnection(OpalCall & call, WavEndPoint & endpoint,  const PString &
token,  void * userData );
       ~WavConnection();
       virtual BOOL SetUpConnection();
       virtual BOOL SetAlerting(const PString & calleeName,  BOOL withMedia);
       virtual BOOL SetConnected();
       virtual OpalMediaFormatList GetMediaFormats() const;
       virtual OpalMediaStream * CreateMediaStream(const OpalMediaFormat &
mediaFormat, unsigned sessionID, BOOL isSource);
       virtual BOOL SendUserInputString(const PString & value);
       virtual void InitiateCall();


protected:
       WavEndPoint   & endpoint;
};


class WavMediaStream : public OpalRawMediaStream
{
       PCLASSINFO(WavMediaStream, OpalRawMediaStream);
public:
       WavMediaStream(const OpalMediaFormat & mediaFormat,  unsigned sessionID,
BOOL isSource);
       virtual BOOL Open();
       virtual BOOL IsSynchronous() const;
       virtual BOOL ReadData(BYTE* data,PINDEX size,PINDEX& length);
       virtual BOOL WriteData(const BYTE* data,PINDEX length, PINDEX& written);

       int packetSize;
       int packetDuration ;
protected:
       PWAVFile* file;
       PAdaptiveDelay channelDelay;
};


#endif



///WavPlayer.cpp


#include < ptlib.h>

#include "WavPlayer.h"

#include <opal/call.h>

/////////////////////////////////////////////////////////////////////////////

WavEndPoint::WavEndPoint(OpalManager & mgr, const char * prefix)
: OpalEndPoint(mgr, prefix, CanTerminateCall)
{
       nextTokenNumber = 1;

       defaultMediaFormats += OpalPCM16;


       PTRACE(3, "WavPlayer\tCreated endpoint.");
}


WavEndPoint::~WavEndPoint()
{
       PTRACE(3, "WavPlayer\tDeleted endpoint.");
}


BOOL WavEndPoint::MakeConnection(OpalCall & call,
                                                                const PString & remoteParty,
                                                                void * userData)
{
       // First strip of the prefix if present
       PINDEX prefixLength = 0;
       if (remoteParty.Find(GetPrefixName()+":") == 0)
               prefixLength = GetPrefixName().GetLength()+1;


       WavConnection * connection = CreateConnection(call,
CreateConnectionToken(), userData);
       if (connection == NULL)
               return FALSE;

       connectionsActive.SetAt(connection->GetToken(), connection);

       // If we are the A-party then need to initiate a call now in this thread
and
       // go through the routing engine via OnIncomingConnection. If we are the
       // B-Party then SetUpConnection() gets called in the context of the A-party
       // thread.
       if (call.GetConnection(0, PSafeReference) == connection)
               connection->InitiateCall();

       return TRUE;
}


OpalMediaFormatList WavEndPoint::GetMediaFormats() const
{
       PWaitAndSignal mutex(inUseFlag);
       return defaultMediaFormats;
}


WavConnection * WavEndPoint::CreateConnection(OpalCall & call, const PString
& token,  void * userData)
{
       WavConnection * conn = new WavConnection(call, *this, token, userData);
       if (conn != NULL)
               OnNewConnection(call, *conn);
       return conn;
}


PString WavEndPoint::CreateConnectionToken()
{
       inUseFlag.Wait();
       unsigned tokenNumber = nextTokenNumber++;
       inUseFlag.Signal();
       return psprintf("Wav/%u", tokenNumber);
}





void WavEndPoint::SetDefaultMediaFormats(const OpalMediaFormatList &
formats)
{
       inUseFlag.Wait();
       defaultMediaFormats = formats;
       inUseFlag.Signal();
}


/////////////////////////////////////////////////////////////////////////////

WavConnection::WavConnection(OpalCall & call,
                                                        WavEndPoint & ep,
                                                        const PString & token,
                                                        void * /*userData*/
                                                        )
                                                        : OpalConnection(call, ep, token),
                                                        endpoint(ep)
{
       phase = SetUpPhase;

       PTRACE(3, "Wav\tInitiateCall ctor.");
}


WavConnection::~WavConnection()
{
       PTRACE(3, "Wav\t~InitiateCall.");
}


BOOL WavConnection::SetUpConnection()
{
       remotePartyName =
ownerCall.GetOtherPartyConnection (*this)->GetRemotePartyName();

       PTRACE(3, "Wav\tSetUpConnection(" << remotePartyName << ')');


       phase = AlertingPhase;
       OnAlerting();

       phase = ConnectedPhase;
       OnConnected();


       if (!mediaStreams.IsEmpty()) {
               phase = EstablishedPhase;
               OnEstablished();
       }

       return TRUE;
}


BOOL WavConnection::SetAlerting(const PString & calleeName, BOOL)
{
       PTRACE(3, "WAV\tSetAlerting(" << calleeName << ')');

       if (!LockReadWrite())
               return FALSE;

       phase = AlertingPhase;
       remotePartyName = calleeName;
       UnlockReadWrite();

       return TRUE;
}


BOOL WavConnection::SetConnected()
{
       PTRACE(3, "WAV\tSetConnected()");

       {
               PSafeLockReadWrite safeLock(*this);
               if (!safeLock.IsLocked())
                       return FALSE;

               phase = ConnectedPhase;

               if (mediaStreams.IsEmpty())
                       return TRUE;

               phase = EstablishedPhase;
       }

       OnEstablished();

       return TRUE;
}


OpalMediaFormatList WavConnection::GetMediaFormats() const
{
       return this-> endpoint.GetMediaFormats();
}


OpalMediaStream * WavConnection::CreateMediaStream(const OpalMediaFormat &
mediaFormat,
                                                                                                  unsigned sessionID,
                                                                                                  BOOL isSource)
{
       return new WavMediaStream(mediaFormat, sessionID, isSource);
}


BOOL WavConnection::SendUserInputString(const PString & value)
{
       PTRACE(3, "WAV\tSendUserInputString(" << value << ')');


       return TRUE;
}


void WavConnection::InitiateCall()
{
       PTRACE(3, "WAV\tInitiateCall");
       phase = SetUpPhase;
       if (!OnIncomingConnection())
               Release(EndedByCallerAbort);
       else {
               PTRACE(2, "WAV\tOutgoing call routed to " << ownerCall.GetPartyB () << "
for " << *this);
               if (!ownerCall.OnSetUp(*this))
                       Release(EndedByNoAccept);
       }
}


/////////////////////////////////////////////////////////////////////////////

WavMediaStream::WavMediaStream(const OpalMediaFormat & mediaFormat,
                                                          unsigned sessionID,
                                                          BOOL isSourceStream
                                                          )
                                                          : OpalRawMediaStream(mediaFormat, sessionID, isSourceStream, NULL,
FALSE)

{
       file = new PWAVFile(PWAVFile::fmt_PCM);
       this->channel = file ;
       OpalMediaStream::defaultDataSize = 480;
       packetSize = 80;
       packetDuration = 5;

       if (isSource)
       {
               file->SetFilePath("C:\\wav\\Play.wav");
               isOpen = file->Open(PWAVFile::ReadOnly);
       }
       else
       {
               file->SetFilePath("C:\\wav\\Record.wav");
               isOpen = file->Open(PWAVFile::WriteOnly);
       }
       PTRACE(3, "WAV\tWavMediaStream sessionID = " << sessionID << ",
isSourceStream = " << isSourceStream);
}


BOOL WavMediaStream::Open()
{
       PTRACE(3, "WAV\tOpen");
       return OpalMediaStream::Open();
}


BOOL WavMediaStream::IsSynchronous() const
{
       return TRUE;
}

BOOL WavMediaStream::ReadData(BYTE* data,PINDEX size,PINDEX& length)
{
       int count = size / packetSize;

       BOOL rslt = OpalRawMediaStream::ReadData(data,size,length);
       channelDelay.Delay(packetDuration * count);

       return rslt;
}
BOOL WavMediaStream::WriteData(const BYTE* data, PINDEX length, PINDEX&
written)
{
       int count = length / packetSize;
       written = length;
       BOOL rslt = TRUE;
       if (count > 0)
       {
               rslt = OpalRawMediaStream::WriteData(data,length,written);
               channelDelay.Delay(packetDuration * count );
       }
       return rslt;

}


------------------------------------------------------------------------
Check the FAQ before asking! - http://www.openh323.org/~openh323/fom.cgi
The OpenH323 Project mailing list, using Mailman. To unsubscribe or
change your subscription options, goto
http://www.openh323.org/mailman/listinfo/openh323
Maintained by Quicknet Technologies, Inc - http://www.quicknet.net
------------------------------------------------------------------------



--

"Los más indicados para dar consejos son aquellos que nunca los siguen"

-----------------------------------------------------
Pablo Miguel Ríos Montaño

  ("`-''-/").___..--''"`-._
   `6_ 6  )   `-.  (     ).`-.__.`)
   (_Y_.)'  ._   )  `._ `. ``-..-'
    _..`--'_..-_/  /--'_.' ,'
(il),-''  (li),'  ((!.-'

-----------------------------------------------------

[Open H.323]     [IETF SIP]     [Gnu Gatekeeper]     [Asterisk PBX]     [Fedora Linux]     [Gimp]     [Yosemite News]     [Yosemite Photos]     [Yosemite Campsites]     [ISDN Cause Codes]

Add to Google Powered by Linux