[Freeswitch-svn] [commit] r11899 - freeswitch/trunk/src/mod/endpoints/mod_opal
FreeSWITCH SVN
anthm at freeswitch.org
Wed Feb 11 16:26:04 PST 2009
Author: anthm
Date: Wed Feb 11 18:26:04 2009
New Revision: 11899
Log:
changes to put freeswitch in control of lifecycle of some critical objects, -sigh
Modified:
freeswitch/trunk/src/mod/endpoints/mod_opal/mod_opal.cpp
freeswitch/trunk/src/mod/endpoints/mod_opal/mod_opal.h
Modified: freeswitch/trunk/src/mod/endpoints/mod_opal/mod_opal.cpp
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_opal/mod_opal.cpp (original)
+++ freeswitch/trunk/src/mod/endpoints/mod_opal/mod_opal.cpp Wed Feb 11 18:26:04 2009
@@ -47,6 +47,9 @@
static const char ModuleName[] = "opal";
+static switch_status_t on_hangup(switch_core_session_t *session);
+
+
static switch_io_routines_t opalfs_io_routines = {
/*.outgoing_channel */ create_outgoing_channel,
/*.read_frame */ FSConnection::read_audio_frame,
@@ -64,7 +67,7 @@
/*.on_init */ FSConnection::on_init,
/*.on_routing */ FSConnection::on_routing,
/*.on_execute */ FSConnection::on_execute,
- /*.on_hangup */ FSConnection::on_hangup,
+ /*.on_hangup */ on_hangup,
/*.on_loopback */ FSConnection::on_loopback,
/*.on_transmit */ FSConnection::on_transmit
};
@@ -486,14 +489,19 @@
///////////////////////////////////////////////////////////////////////
+
FSConnection::FSConnection(OpalCall & call, FSEndPoint & endpoint)
: OpalLocalConnection(call, endpoint, NULL)
, m_endpoint(endpoint)
{
+ opal_private_t *tech_pvt;
FSManager & mgr = (FSManager &) endpoint.GetManager();
m_fsSession = switch_core_session_request(mgr.GetSwitchInterface(), NULL);
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 @@
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_txAudioOpened.Signal();
H225_ReleaseCompleteReason dummy;
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();
}
@@ -752,16 +765,49 @@
}
-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);
- if (channel == NULL) {
- return SWITCH_STATUS_FALSE;
+ switch_channel_t *channel = switch_core_session_get_channel(session);
+ opal_private_t *tech_pvt = (opal_private_t *) switch_core_session_get_private(session);
+
+ /* 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);
- SetQ931Cause(cause);
- ClearCallSynchronous(NULL, H323TranslateToCallEndReason(cause, UINT_MAX));
+ if (tech_pvt->write_codec.implementation) {
+ switch_core_codec_destroy(&tech_pvt->write_codec);
+ }
+
+ 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;
}
@@ -808,8 +854,7 @@
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(session);
+ switch_channel_t *channel = switch_core_session_get_channel(m_fsSession);
/*
@@ -969,13 +1014,15 @@
, m_callOnStart(true)
{
memset(&m_readFrame, 0, sizeof(m_readFrame));
- m_readFrame.codec = &m_switchCodec;
+ m_readFrame.codec = m_switchCodec;
m_readFrame.flags = SFF_RAW_RTP;
}
PBoolean FSMediaStream::Open()
{
+ opal_private_t *tech_pvt = (opal_private_t *) switch_core_session_get_private(m_fsSession);
+
if (IsOpen()) {
return true;
}
@@ -993,13 +1040,21 @@
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.
- 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
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, // Settings
switch_core_session_get_pool(m_fsSession)) != SWITCH_STATUS_SUCCESS) {
// 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
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, // Settings
switch_core_session_get_pool(m_fsSession)) != SWITCH_STATUS_SUCCESS) {
@@ -1020,24 +1075,25 @@
m_readFrame.rate = mediaFormat.GetClockRate();
if (isAudio) {
- switch_core_session_set_read_codec(m_fsSession, &m_switchCodec);
- if (switch_core_timer_init(&m_switchTimer,
+ switch_core_session_set_read_codec(m_fsSession, m_switchCodec);
+ if (switch_core_timer_init(m_switchTimer,
"soft",
- m_switchCodec.implementation->microseconds_per_packet / 1000,
- m_switchCodec.implementation->samples_per_packet,
+ m_switchCodec->implementation->microseconds_per_packet / 1000,
+ m_switchCodec->implementation->samples_per_packet,
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;
}
} 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);
}
} else {
if (isAudio) {
- switch_core_session_set_write_codec(m_fsSession, &m_switchCodec);
+ switch_core_session_set_write_codec(m_fsSession, m_switchCodec);
} 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);
}
}
@@ -1053,36 +1109,11 @@
{
if (!IsOpen())
return false;
+
+ /* forget these FS will properly destroy them for us */
- bool isAudio;
-
- 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);
+ m_switchTimer = NULL;
+ m_switchCodec = NULL;
return OpalMediaStream::Close();
}
@@ -1102,6 +1133,11 @@
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) {
/*
There is a race here... sometimes we make it here and GetPatch() is NULL
@@ -1148,11 +1184,11 @@
}
} else {
- if (!GetPatch()->GetSource().ReadPacket(m_readRTP)) {
+ if (!m_switchTimer || !GetPatch()->GetSource().ReadPacket(m_readRTP)) {
return SWITCH_STATUS_FALSE;
}
- switch_core_timer_next(&m_switchTimer);
+ switch_core_timer_next(m_switchTimer);
if (!(m_readFrame.datalen = m_readRTP.GetPayloadSize())) {
m_readFrame.flags = SFF_CNG;
@@ -1174,6 +1210,7 @@
m_readFrame.m = (switch_bool_t) m_readRTP.GetMarker();
m_readFrame.seq = m_readRTP.GetSequenceNumber();
m_readFrame.ssrc = m_readRTP.GetSyncSource();
+ m_readFrame.codec = m_switchCodec;
*frame = &m_readFrame;
return SWITCH_STATUS_SUCCESS;
Modified: freeswitch/trunk/src/mod/endpoints/mod_opal/mod_opal.h
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_opal/mod_opal.h (original)
+++ freeswitch/trunk/src/mod/endpoints/mod_opal/mod_opal.h Wed Feb 11 18:26:04 2009
@@ -106,6 +106,18 @@
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 {
PCLASSINFO(FSEndPoint, OpalLocalEndPoint);
@@ -117,23 +129,25 @@
};
-#define DECLARE_CALLBACK0(name) \
+#define DECLARE_CALLBACK0(name) \
static switch_status_t name(switch_core_session_t *session) { \
- FSConnection * conn = (FSConnection *)switch_core_session_get_private(session); \
- return conn != NULL ? conn->name() : SWITCH_STATUS_FALSE; } \
+ opal_private_t *tech_pvt = (opal_private_t *) switch_core_session_get_private(session); \
+ return tech_pvt && tech_pvt->me != NULL ? tech_pvt->me->name() : SWITCH_STATUS_FALSE; } \
switch_status_t name()
#define DECLARE_CALLBACK1(name, type1, name1) \
static switch_status_t name(switch_core_session_t *session, type1 name1) { \
- FSConnection * conn = (FSConnection *)switch_core_session_get_private(session); \
- return conn != NULL ? conn->name(name1) : SWITCH_STATUS_FALSE; } \
- switch_status_t name(type1 name1)
+ opal_private_t *tech_pvt = (opal_private_t *) switch_core_session_get_private(session); \
+ return tech_pvt && tech_pvt->me != NULL ? tech_pvt->me->name(name1) : SWITCH_STATUS_FALSE; } \
+switch_status_t name(type1 name1)
#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) { \
- FSConnection * conn = (FSConnection *)switch_core_session_get_private(session); \
- return conn != NULL ? conn->name(name1, name2, name3) : SWITCH_STATUS_FALSE; } \
- switch_status_t name(type1 name1, type2 name2, type3 name3)
+ opal_private_t *tech_pvt = (opal_private_t *) switch_core_session_get_private(session); \
+ 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)
+
+
class FSConnection:public OpalLocalConnection {
@@ -156,7 +170,8 @@
DECLARE_CALLBACK0(on_init);
DECLARE_CALLBACK0(on_routing);
DECLARE_CALLBACK0(on_execute);
- DECLARE_CALLBACK0(on_hangup);
+ //DECLARE_CALLBACK0(on_hangup);
+
DECLARE_CALLBACK0(on_loopback);
DECLARE_CALLBACK0(on_transmit);
@@ -206,8 +221,8 @@
private:
switch_core_session_t *m_fsSession;
switch_channel_t *m_fsChannel;
- switch_timer_t m_switchTimer;
- switch_codec_t m_switchCodec;
+ switch_timer_t *m_switchTimer;
+ switch_codec_t *m_switchCodec;
switch_frame_t m_readFrame;
RTP_DataFrame m_readRTP;
bool m_callOnStart;
More information about the Freeswitch-svn
mailing list