mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-05-29 18:11:33 +00:00
changes to put freeswitch in control of lifecycle of some critical objects, -sigh
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@11899 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
d47662fc64
commit
e39a63d820
@ -47,6 +47,9 @@ static FSProcess *opal_process = NULL;
|
|||||||
static const char ModuleName[] = "opal";
|
static const char ModuleName[] = "opal";
|
||||||
|
|
||||||
|
|
||||||
|
static switch_status_t on_hangup(switch_core_session_t *session);
|
||||||
|
|
||||||
|
|
||||||
static switch_io_routines_t opalfs_io_routines = {
|
static switch_io_routines_t opalfs_io_routines = {
|
||||||
/*.outgoing_channel */ create_outgoing_channel,
|
/*.outgoing_channel */ create_outgoing_channel,
|
||||||
/*.read_frame */ FSConnection::read_audio_frame,
|
/*.read_frame */ FSConnection::read_audio_frame,
|
||||||
@ -64,7 +67,7 @@ static switch_state_handler_table_t opalfs_event_handlers = {
|
|||||||
/*.on_init */ FSConnection::on_init,
|
/*.on_init */ FSConnection::on_init,
|
||||||
/*.on_routing */ FSConnection::on_routing,
|
/*.on_routing */ FSConnection::on_routing,
|
||||||
/*.on_execute */ FSConnection::on_execute,
|
/*.on_execute */ FSConnection::on_execute,
|
||||||
/*.on_hangup */ FSConnection::on_hangup,
|
/*.on_hangup */ on_hangup,
|
||||||
/*.on_loopback */ FSConnection::on_loopback,
|
/*.on_loopback */ FSConnection::on_loopback,
|
||||||
/*.on_transmit */ FSConnection::on_transmit
|
/*.on_transmit */ FSConnection::on_transmit
|
||||||
};
|
};
|
||||||
@ -486,14 +489,19 @@ OpalLocalConnection *FSEndPoint::CreateConnection(OpalCall & call, void *userDat
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
FSConnection::FSConnection(OpalCall & call, FSEndPoint & endpoint)
|
FSConnection::FSConnection(OpalCall & call, FSEndPoint & endpoint)
|
||||||
: OpalLocalConnection(call, endpoint, NULL)
|
: OpalLocalConnection(call, endpoint, NULL)
|
||||||
, m_endpoint(endpoint)
|
, m_endpoint(endpoint)
|
||||||
{
|
{
|
||||||
|
opal_private_t *tech_pvt;
|
||||||
FSManager & mgr = (FSManager &) endpoint.GetManager();
|
FSManager & mgr = (FSManager &) endpoint.GetManager();
|
||||||
m_fsSession = switch_core_session_request(mgr.GetSwitchInterface(), NULL);
|
m_fsSession = switch_core_session_request(mgr.GetSwitchInterface(), NULL);
|
||||||
m_fsChannel = switch_core_session_get_channel(m_fsSession);
|
m_fsChannel = switch_core_session_get_channel(m_fsSession);
|
||||||
switch_core_session_set_private(m_fsSession, this);
|
|
||||||
|
tech_pvt = (opal_private_t *) switch_core_session_alloc(m_fsSession, sizeof(*tech_pvt));
|
||||||
|
tech_pvt->me = this;
|
||||||
|
switch_core_session_set_private(m_fsSession, tech_pvt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -568,11 +576,16 @@ bool FSConnection::OnIncoming()
|
|||||||
|
|
||||||
void FSConnection::OnReleased()
|
void FSConnection::OnReleased()
|
||||||
{
|
{
|
||||||
|
opal_private_t *tech_pvt = (opal_private_t *) switch_core_session_get_private(m_fsSession);
|
||||||
|
|
||||||
|
/* so FS on_hangup will not try to deref a landmine */
|
||||||
|
tech_pvt->me = NULL;
|
||||||
|
|
||||||
m_rxAudioOpened.Signal(); // Just in case
|
m_rxAudioOpened.Signal(); // Just in case
|
||||||
m_txAudioOpened.Signal();
|
m_txAudioOpened.Signal();
|
||||||
H225_ReleaseCompleteReason dummy;
|
H225_ReleaseCompleteReason dummy;
|
||||||
switch_channel_hangup(switch_core_session_get_channel(m_fsSession),
|
switch_channel_hangup(switch_core_session_get_channel(m_fsSession),
|
||||||
(switch_call_cause_t)H323TranslateFromCallEndReason(GetCallEndReason(), dummy));
|
(switch_call_cause_t)H323TranslateFromCallEndReason(GetCallEndReason(), dummy));
|
||||||
OpalLocalConnection::OnReleased();
|
OpalLocalConnection::OnReleased();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -752,16 +765,49 @@ switch_status_t FSConnection::on_execute()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
switch_status_t FSConnection::on_hangup()
|
/* this function has to be called with the original session beause the FSConnection might already be destroyed and we
|
||||||
|
will can't have it be a method of a dead object
|
||||||
|
*/
|
||||||
|
static switch_status_t on_hangup(switch_core_session_t *session)
|
||||||
{
|
{
|
||||||
switch_channel_t *channel = switch_core_session_get_channel(m_fsSession);
|
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||||
if (channel == NULL) {
|
opal_private_t *tech_pvt = (opal_private_t *) switch_core_session_get_private(session);
|
||||||
return SWITCH_STATUS_FALSE;
|
|
||||||
|
/* if this is still here it was our idea to hangup not opal's */
|
||||||
|
if (tech_pvt->me) {
|
||||||
|
Q931::CauseValues cause = (Q931::CauseValues)switch_channel_get_cause_q850(channel);
|
||||||
|
tech_pvt->me->SetQ931Cause(cause);
|
||||||
|
tech_pvt->me->ClearCallSynchronous(NULL, H323TranslateToCallEndReason(cause, UINT_MAX));
|
||||||
|
tech_pvt->me = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tech_pvt->read_codec.implementation) {
|
||||||
|
switch_core_codec_destroy(&tech_pvt->read_codec);
|
||||||
}
|
}
|
||||||
|
|
||||||
Q931::CauseValues cause = (Q931::CauseValues)switch_channel_get_cause_q850(channel);
|
if (tech_pvt->write_codec.implementation) {
|
||||||
SetQ931Cause(cause);
|
switch_core_codec_destroy(&tech_pvt->write_codec);
|
||||||
ClearCallSynchronous(NULL, H323TranslateToCallEndReason(cause, UINT_MAX));
|
}
|
||||||
|
|
||||||
|
if (tech_pvt->vid_read_codec.implementation) {
|
||||||
|
switch_core_codec_destroy(&tech_pvt->vid_read_codec);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tech_pvt->vid_write_codec.implementation) {
|
||||||
|
switch_core_codec_destroy(&tech_pvt->vid_write_codec);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tech_pvt->read_timer.timer_interface) {
|
||||||
|
switch_core_timer_destroy(&tech_pvt->read_timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tech_pvt->vid_read_timer.timer_interface) {
|
||||||
|
switch_core_timer_destroy(&tech_pvt->vid_read_timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_core_session_unset_read_codec(session);
|
||||||
|
switch_core_session_unset_write_codec(session);
|
||||||
|
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -808,8 +854,7 @@ switch_status_t FSConnection::send_dtmf(const switch_dtmf_t *dtmf)
|
|||||||
|
|
||||||
switch_status_t FSConnection::receive_message(switch_core_session_message_t *msg)
|
switch_status_t FSConnection::receive_message(switch_core_session_message_t *msg)
|
||||||
{
|
{
|
||||||
switch_core_session_t *session = GetSession();
|
switch_channel_t *channel = switch_core_session_get_channel(m_fsSession);
|
||||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -969,13 +1014,15 @@ FSMediaStream::FSMediaStream(FSConnection & conn, const OpalMediaFormat & mediaF
|
|||||||
, m_callOnStart(true)
|
, m_callOnStart(true)
|
||||||
{
|
{
|
||||||
memset(&m_readFrame, 0, sizeof(m_readFrame));
|
memset(&m_readFrame, 0, sizeof(m_readFrame));
|
||||||
m_readFrame.codec = &m_switchCodec;
|
m_readFrame.codec = m_switchCodec;
|
||||||
m_readFrame.flags = SFF_RAW_RTP;
|
m_readFrame.flags = SFF_RAW_RTP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PBoolean FSMediaStream::Open()
|
PBoolean FSMediaStream::Open()
|
||||||
{
|
{
|
||||||
|
opal_private_t *tech_pvt = (opal_private_t *) switch_core_session_get_private(m_fsSession);
|
||||||
|
|
||||||
if (IsOpen()) {
|
if (IsOpen()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -993,13 +1040,21 @@ PBoolean FSMediaStream::Open()
|
|||||||
|
|
||||||
int ptime = mediaFormat.GetOptionInteger(OpalAudioFormat::TxFramesPerPacketOption()) * mediaFormat.GetFrameTime() / mediaFormat.GetTimeUnits();
|
int ptime = mediaFormat.GetOptionInteger(OpalAudioFormat::TxFramesPerPacketOption()) * mediaFormat.GetFrameTime() / mediaFormat.GetTimeUnits();
|
||||||
|
|
||||||
|
|
||||||
|
if (IsSink()) {
|
||||||
|
m_switchCodec = isAudio ? &tech_pvt->read_codec : &tech_pvt->vid_read_codec;
|
||||||
|
m_switchTimer = isAudio ? &tech_pvt->read_timer : &tech_pvt->vid_read_timer;
|
||||||
|
} else {
|
||||||
|
m_switchCodec = isAudio ? &tech_pvt->write_codec : &tech_pvt->vid_write_codec;
|
||||||
|
}
|
||||||
|
|
||||||
// The following is performed on two different instances of this object.
|
// The following is performed on two different instances of this object.
|
||||||
if (switch_core_codec_init(&m_switchCodec, mediaFormat.GetEncodingName(), NULL, // FMTP
|
if (switch_core_codec_init(m_switchCodec, mediaFormat.GetEncodingName(), NULL, // FMTP
|
||||||
mediaFormat.GetClockRate(), ptime, 1, // Channels
|
mediaFormat.GetClockRate(), ptime, 1, // Channels
|
||||||
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, // Settings
|
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, // Settings
|
||||||
switch_core_session_get_pool(m_fsSession)) != SWITCH_STATUS_SUCCESS) {
|
switch_core_session_get_pool(m_fsSession)) != SWITCH_STATUS_SUCCESS) {
|
||||||
// Could not select a codecs using negotiated frames/packet, so try using default.
|
// Could not select a codecs using negotiated frames/packet, so try using default.
|
||||||
if (switch_core_codec_init(&m_switchCodec, mediaFormat.GetEncodingName(), NULL, // FMTP
|
if (switch_core_codec_init(m_switchCodec, mediaFormat.GetEncodingName(), NULL, // FMTP
|
||||||
mediaFormat.GetClockRate(), 0, 1, // Channels
|
mediaFormat.GetClockRate(), 0, 1, // Channels
|
||||||
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, // Settings
|
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, // Settings
|
||||||
switch_core_session_get_pool(m_fsSession)) != SWITCH_STATUS_SUCCESS) {
|
switch_core_session_get_pool(m_fsSession)) != SWITCH_STATUS_SUCCESS) {
|
||||||
@ -1020,24 +1075,25 @@ PBoolean FSMediaStream::Open()
|
|||||||
m_readFrame.rate = mediaFormat.GetClockRate();
|
m_readFrame.rate = mediaFormat.GetClockRate();
|
||||||
|
|
||||||
if (isAudio) {
|
if (isAudio) {
|
||||||
switch_core_session_set_read_codec(m_fsSession, &m_switchCodec);
|
switch_core_session_set_read_codec(m_fsSession, m_switchCodec);
|
||||||
if (switch_core_timer_init(&m_switchTimer,
|
if (switch_core_timer_init(m_switchTimer,
|
||||||
"soft",
|
"soft",
|
||||||
m_switchCodec.implementation->microseconds_per_packet / 1000,
|
m_switchCodec->implementation->microseconds_per_packet / 1000,
|
||||||
m_switchCodec.implementation->samples_per_packet,
|
m_switchCodec->implementation->samples_per_packet,
|
||||||
switch_core_session_get_pool(m_fsSession)) != SWITCH_STATUS_SUCCESS) {
|
switch_core_session_get_pool(m_fsSession)) != SWITCH_STATUS_SUCCESS) {
|
||||||
switch_core_codec_destroy(&m_switchCodec);
|
switch_core_codec_destroy(m_switchCodec);
|
||||||
|
m_switchCodec = NULL;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
switch_core_session_set_video_read_codec(m_fsSession, &m_switchCodec);
|
switch_core_session_set_video_read_codec(m_fsSession, m_switchCodec);
|
||||||
switch_channel_set_flag(m_fsChannel, CF_VIDEO);
|
switch_channel_set_flag(m_fsChannel, CF_VIDEO);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (isAudio) {
|
if (isAudio) {
|
||||||
switch_core_session_set_write_codec(m_fsSession, &m_switchCodec);
|
switch_core_session_set_write_codec(m_fsSession, m_switchCodec);
|
||||||
} else {
|
} else {
|
||||||
switch_core_session_set_video_write_codec(m_fsSession, &m_switchCodec);
|
switch_core_session_set_video_write_codec(m_fsSession, m_switchCodec);
|
||||||
switch_channel_set_flag(m_fsChannel, CF_VIDEO);
|
switch_channel_set_flag(m_fsChannel, CF_VIDEO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1053,36 +1109,11 @@ PBoolean FSMediaStream::Close()
|
|||||||
{
|
{
|
||||||
if (!IsOpen())
|
if (!IsOpen())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
/* forget these FS will properly destroy them for us */
|
||||||
|
|
||||||
bool isAudio;
|
m_switchTimer = NULL;
|
||||||
|
m_switchCodec = NULL;
|
||||||
if (mediaFormat.GetMediaType() == OpalMediaType::Audio()) {
|
|
||||||
isAudio = true;
|
|
||||||
} else if (mediaFormat.GetMediaType() == OpalMediaType::Video()) {
|
|
||||||
isAudio = false;
|
|
||||||
} else {
|
|
||||||
return OpalMediaStream::Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsSink()) {
|
|
||||||
if (isAudio) {
|
|
||||||
switch_core_session_unset_read_codec(m_fsSession);
|
|
||||||
switch_core_timer_destroy(&m_switchTimer);
|
|
||||||
} else {
|
|
||||||
switch_core_session_set_video_read_codec(m_fsSession, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch_core_codec_destroy(&m_switchCodec);
|
|
||||||
} else {
|
|
||||||
if (isAudio)
|
|
||||||
switch_core_session_unset_write_codec(m_fsSession);
|
|
||||||
else
|
|
||||||
switch_core_session_set_video_write_codec(m_fsSession, NULL);
|
|
||||||
switch_core_codec_destroy(&m_switchCodec);
|
|
||||||
}
|
|
||||||
|
|
||||||
PTRACE(3, "mod_opal\tReset & destroyed " << (IsSink()? "read" : "write")
|
|
||||||
<< ' ' << mediaFormat.GetMediaType() << " codec for connection " << *this);
|
|
||||||
|
|
||||||
return OpalMediaStream::Close();
|
return OpalMediaStream::Close();
|
||||||
}
|
}
|
||||||
@ -1102,6 +1133,11 @@ PBoolean FSMediaStream::RequiresPatchThread(OpalMediaStream *) const
|
|||||||
|
|
||||||
switch_status_t FSMediaStream::read_frame(switch_frame_t **frame, switch_io_flag_t flags)
|
switch_status_t FSMediaStream::read_frame(switch_frame_t **frame, switch_io_flag_t flags)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if (!m_switchCodec) {
|
||||||
|
return SWITCH_STATUS_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_callOnStart) {
|
if (m_callOnStart) {
|
||||||
/*
|
/*
|
||||||
There is a race here... sometimes we make it here and GetPatch() is NULL
|
There is a race here... sometimes we make it here and GetPatch() is NULL
|
||||||
@ -1148,11 +1184,11 @@ switch_status_t FSMediaStream::read_frame(switch_frame_t **frame, switch_io_flag
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (!GetPatch()->GetSource().ReadPacket(m_readRTP)) {
|
if (!m_switchTimer || !GetPatch()->GetSource().ReadPacket(m_readRTP)) {
|
||||||
return SWITCH_STATUS_FALSE;
|
return SWITCH_STATUS_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch_core_timer_next(&m_switchTimer);
|
switch_core_timer_next(m_switchTimer);
|
||||||
|
|
||||||
if (!(m_readFrame.datalen = m_readRTP.GetPayloadSize())) {
|
if (!(m_readFrame.datalen = m_readRTP.GetPayloadSize())) {
|
||||||
m_readFrame.flags = SFF_CNG;
|
m_readFrame.flags = SFF_CNG;
|
||||||
@ -1174,6 +1210,7 @@ switch_status_t FSMediaStream::read_frame(switch_frame_t **frame, switch_io_flag
|
|||||||
m_readFrame.m = (switch_bool_t) m_readRTP.GetMarker();
|
m_readFrame.m = (switch_bool_t) m_readRTP.GetMarker();
|
||||||
m_readFrame.seq = m_readRTP.GetSequenceNumber();
|
m_readFrame.seq = m_readRTP.GetSequenceNumber();
|
||||||
m_readFrame.ssrc = m_readRTP.GetSyncSource();
|
m_readFrame.ssrc = m_readRTP.GetSyncSource();
|
||||||
|
m_readFrame.codec = m_switchCodec;
|
||||||
*frame = &m_readFrame;
|
*frame = &m_readFrame;
|
||||||
|
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
@ -106,6 +106,18 @@ class FSManager : public OpalManager {
|
|||||||
list < FSListener > m_listeners;
|
list < FSListener > m_listeners;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class FSConnection;
|
||||||
|
typedef struct {
|
||||||
|
switch_timer_t read_timer;
|
||||||
|
switch_codec_t read_codec;
|
||||||
|
switch_codec_t write_codec;
|
||||||
|
|
||||||
|
switch_timer_t vid_read_timer;
|
||||||
|
switch_codec_t vid_read_codec;
|
||||||
|
switch_codec_t vid_write_codec;
|
||||||
|
FSConnection *me;
|
||||||
|
} opal_private_t;
|
||||||
|
|
||||||
|
|
||||||
class FSEndPoint:public OpalLocalEndPoint {
|
class FSEndPoint:public OpalLocalEndPoint {
|
||||||
PCLASSINFO(FSEndPoint, OpalLocalEndPoint);
|
PCLASSINFO(FSEndPoint, OpalLocalEndPoint);
|
||||||
@ -117,23 +129,25 @@ class FSEndPoint:public OpalLocalEndPoint {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#define DECLARE_CALLBACK0(name) \
|
#define DECLARE_CALLBACK0(name) \
|
||||||
static switch_status_t name(switch_core_session_t *session) { \
|
static switch_status_t name(switch_core_session_t *session) { \
|
||||||
FSConnection * conn = (FSConnection *)switch_core_session_get_private(session); \
|
opal_private_t *tech_pvt = (opal_private_t *) switch_core_session_get_private(session); \
|
||||||
return conn != NULL ? conn->name() : SWITCH_STATUS_FALSE; } \
|
return tech_pvt && tech_pvt->me != NULL ? tech_pvt->me->name() : SWITCH_STATUS_FALSE; } \
|
||||||
switch_status_t name()
|
switch_status_t name()
|
||||||
|
|
||||||
#define DECLARE_CALLBACK1(name, type1, name1) \
|
#define DECLARE_CALLBACK1(name, type1, name1) \
|
||||||
static switch_status_t name(switch_core_session_t *session, type1 name1) { \
|
static switch_status_t name(switch_core_session_t *session, type1 name1) { \
|
||||||
FSConnection * conn = (FSConnection *)switch_core_session_get_private(session); \
|
opal_private_t *tech_pvt = (opal_private_t *) switch_core_session_get_private(session); \
|
||||||
return conn != NULL ? conn->name(name1) : SWITCH_STATUS_FALSE; } \
|
return tech_pvt && tech_pvt->me != NULL ? tech_pvt->me->name(name1) : SWITCH_STATUS_FALSE; } \
|
||||||
switch_status_t name(type1 name1)
|
switch_status_t name(type1 name1)
|
||||||
|
|
||||||
#define DECLARE_CALLBACK3(name, type1, name1, type2, name2, type3, name3) \
|
#define DECLARE_CALLBACK3(name, type1, name1, type2, name2, type3, name3) \
|
||||||
static switch_status_t name(switch_core_session_t *session, type1 name1, type2 name2, type3 name3) { \
|
static switch_status_t name(switch_core_session_t *session, type1 name1, type2 name2, type3 name3) { \
|
||||||
FSConnection * conn = (FSConnection *)switch_core_session_get_private(session); \
|
opal_private_t *tech_pvt = (opal_private_t *) switch_core_session_get_private(session); \
|
||||||
return conn != NULL ? conn->name(name1, name2, name3) : SWITCH_STATUS_FALSE; } \
|
return tech_pvt && tech_pvt->me != NULL ? tech_pvt->me->name(name1, name2, name3) : SWITCH_STATUS_FALSE; } \
|
||||||
switch_status_t name(type1 name1, type2 name2, type3 name3)
|
switch_status_t name(type1 name1, type2 name2, type3 name3)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class FSConnection:public OpalLocalConnection {
|
class FSConnection:public OpalLocalConnection {
|
||||||
@ -156,7 +170,8 @@ class FSConnection:public OpalLocalConnection {
|
|||||||
DECLARE_CALLBACK0(on_init);
|
DECLARE_CALLBACK0(on_init);
|
||||||
DECLARE_CALLBACK0(on_routing);
|
DECLARE_CALLBACK0(on_routing);
|
||||||
DECLARE_CALLBACK0(on_execute);
|
DECLARE_CALLBACK0(on_execute);
|
||||||
DECLARE_CALLBACK0(on_hangup);
|
//DECLARE_CALLBACK0(on_hangup);
|
||||||
|
|
||||||
DECLARE_CALLBACK0(on_loopback);
|
DECLARE_CALLBACK0(on_loopback);
|
||||||
DECLARE_CALLBACK0(on_transmit);
|
DECLARE_CALLBACK0(on_transmit);
|
||||||
|
|
||||||
@ -206,8 +221,8 @@ class FSMediaStream:public OpalMediaStream {
|
|||||||
private:
|
private:
|
||||||
switch_core_session_t *m_fsSession;
|
switch_core_session_t *m_fsSession;
|
||||||
switch_channel_t *m_fsChannel;
|
switch_channel_t *m_fsChannel;
|
||||||
switch_timer_t m_switchTimer;
|
switch_timer_t *m_switchTimer;
|
||||||
switch_codec_t m_switchCodec;
|
switch_codec_t *m_switchCodec;
|
||||||
switch_frame_t m_readFrame;
|
switch_frame_t m_readFrame;
|
||||||
RTP_DataFrame m_readRTP;
|
RTP_DataFrame m_readRTP;
|
||||||
bool m_callOnStart;
|
bool m_callOnStart;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user