?? main.cxx
字號:
return FALSE;
}
#endif
BOOL MyH323EndPoint::WriteAudio(const PString & thisToken, const void * buffer, PINDEX amount, PString roomID)
{
PWaitAndSignal mutex(memberMutex);
// Check that the room still exists
if (memberListDict.Contains(roomID) == FALSE) {
cout << "ROOM HAS BEEN REMOVED (WriteAudio)" << endl;
return FALSE;
}
//The spokenList construct is required to determine who were the last
//to speak, which is needed for determining which four videoimages are displayed.
//spokenList contains a sorted list of when the last packet was received from
//which connection. Thus, when an audio packet is received from a connection,
//the name of the connection is moved to the end of the list.
// If someone new comes along, everyone moves down.
#ifndef NO_VIDEO
if ( DetectNoise(buffer,amount) ) {
PStringList & spokenList = spokenListDict[roomID];
PINDEX keyIndex = spokenList.GetStringsIndex(thisToken);
if (keyIndex != P_MAX_INDEX)
spokenList.RemoveAt(keyIndex);
spokenList.AppendString(thisToken);
if (FindTokensVideoPosn(thisToken,roomID) != P_MAX_INDEX)
goto processAudio;
if (AddVideoPosnToken(thisToken,roomID))
goto processAudio;
keyIndex = spokenList.GetSize() - 1;
PStringList & videoPosnList = videoPosnDict[roomID];
if (keyIndex >= videoPosnList.GetSize()) {
PString tokenToWipe = spokenList[keyIndex-videoPosnList.GetSize()];
keyIndex = FindTokensVideoPosn(tokenToWipe,roomID);
}
if(keyIndex != P_MAX_INDEX)
videoPosnList[keyIndex] = thisToken;
}
processAudio:
#endif
PStringList & memberList = memberListDict[roomID];
PINDEX i;
for (i = 0; i < memberList.GetSize(); i++) {
PString token = memberList[i];
if (token != thisToken) {
MyH323Connection * conn = (MyH323Connection *)FindConnectionWithLock(token);
if (conn != NULL) {
conn->WriteAudio(thisToken, buffer, amount);
conn->Unlock();
}
} else {
// Do not lock as we are looking for our own connection.
// This should only happen in audio loopback mode as we do not
// normally want to add our own voice to the audio we hear from the MCU.
MyH323Connection * conn = (MyH323Connection *)FindConnectionWithoutLocks(thisToken);
if (conn != NULL) {
conn->WriteAudio(thisToken, buffer, amount);
}
}
}
return TRUE;
}
BOOL MyH323EndPoint::ReadAudio(const PString & thisToken, void * buffer, PINDEX amount, PString roomID)
{
PWaitAndSignal mutex(memberMutex);
// Check that the room still exists
if (memberListDict.Contains(roomID) == FALSE) {
cout << "ROOM HAS BEEN REMOVED (ReadAudio)" << endl;
return FALSE;
}
PStringList & memberList = memberListDict[roomID];
PINDEX i;
for (i = 0; i < memberList.GetSize(); i++) {
PString token = memberList[i];
if (token == thisToken) {
MyH323Connection * conn = (MyH323Connection *)FindConnectionWithLock(token);
if (conn != NULL) {
conn->ReadAudio(thisToken, buffer, amount);
conn->Unlock();
}
}
}
return TRUE;
}
#ifndef NO_VIDEO
BOOL MyH323EndPoint::DetectNoise(const void * buffer, PINDEX amount)
{
short *start = (short *)buffer;
short *end = start + (amount/2);
int sum;
sum=0;
while (start != end)
if(*start<0)
sum -= *start++;
else
sum += *start++;
return (sum/amount) > 50;
}
BOOL MyH323EndPoint::WriteVideo(const PString & thisToken, const void * buffer, PINDEX amount, PString roomID)
{
PWaitAndSignal mutex(memberMutex);
// Check that the room still exists
if (videoBufferDict.Contains(roomID) == FALSE) {
cout << "ROOM HAS BEEN REMOVED (WriteVideo)" << endl;
return FALSE;
}
VideoBuffer & videoBuffer = videoBufferDict[roomID];
// The last four elements of spokenList indicate the last
// four connections from which audio was received.
PINDEX keyIndex = FindTokensVideoPosn(thisToken,roomID);
if (keyIndex != P_MAX_INDEX)
videoBuffer.Write((BYTE *)buffer, amount, keyIndex);
return TRUE;
}
BOOL MyH323EndPoint::ReadVideo(const PString & /*thisToken*/, void * buffer, PINDEX amount, PString roomID)
{
PWaitAndSignal mutex(memberMutex);
// Check that the room still exists
if (videoBufferDict.Contains(roomID) == FALSE) {
cout << "ROOM HAS BEEN REMOVED (ReadVideo)" << endl;
return FALSE;
}
VideoBuffer & videoBuffer = videoBufferDict[roomID];
videoBuffer.Read((BYTE *)buffer,amount);
return TRUE;
}
#endif
///////////////////////////////////////////////////////////////
MyH323Connection::MyH323Connection(MyH323EndPoint & _ep, unsigned callReference)
: H323Connection(_ep, callReference), ep(_ep), connected(FALSE)
{
incomingAudio = NULL;
outgoingAudio = NULL;
audioReceiveCodecName = audioTransmitCodecName = "none";
#ifndef NO_VIDEO
incomingVideo = NULL;
outgoingVideo = NULL;
videoReceiveCodecName = videoTransmitCodecName = "none";
#endif
aborted = FALSE;
cout << "Opening connection" << endl;
}
MyH323Connection::~MyH323Connection()
{
cout << "Closing connection" << endl;
#ifdef LOGGING
LogCall(*this);
#endif
delete incomingAudio;
delete outgoingAudio;
#ifndef NO_VIDEO
delete incomingVideo;
delete outgoingVideo;
#endif
}
void MyH323Connection::CleanUpOnCallEnd()
{
if (incomingAudio)
incomingAudio->Close();
if (outgoingAudio)
outgoingAudio->Close();
#ifndef NO_VIDEO
if (incomingVideo)
incomingVideo->Close();
if (outgoingVideo)
outgoingVideo->Close();
#endif
if (!aborted && connected)
ep.RemoveMember(this);
H323Connection::CleanUpOnCallEnd();
}
H323Connection::AnswerCallResponse
MyH323Connection::OnAnswerCall(const PString & caller,
const H323SignalPDU & setupPDU,
H323SignalPDU & /*connectPDU*/)
{
if (!setupPDU.GetQ931().GetCalledPartyNumber(roomID)) {
const H225_Setup_UUIE & setup = setupPDU.m_h323_uu_pdu.m_h323_message_body;
PINDEX i;
for (i = 0; i < setup.m_destinationAddress.GetSize(); i++) {
roomID = H323GetAliasAddressString(setup.m_destinationAddress[i]);
if (!roomID)
break;
}
// If a room was not specified in the connection then use the default
// room name.
PString defaultRoomName = ep.GetDefaultRoomName();
if ((roomID.IsEmpty()) && (defaultRoomName.IsEmpty()) ) {
cout << "Incoming H.323 call from " << caller << " has not selected a room." << endl;
cout << "No default room specified." << endl;
#ifdef LOGGING
LogCall(*this, FALSE);
#endif
aborted = TRUE;
return AnswerCallDenied;
}
if ((roomID.IsEmpty()) && (!defaultRoomName.IsEmpty()) ) {
cout << "Incoming H.323 call from " << caller << " has not selected a room." << endl;
cout << "Using room " << defaultRoomName << " as the default." << endl;
roomID = defaultRoomName;
}
}
PString product = "Unknown";
const H225_Setup_UUIE & setup = setupPDU.m_h323_uu_pdu.m_h323_message_body;
const H225_EndpointType & epInfo = setup.m_sourceInfo;
if (epInfo.HasOptionalField(H225_EndpointType::e_vendor)) {
const H225_VendorIdentifier & vendorInfo = epInfo.m_vendor;
if (vendorInfo.HasOptionalField(H225_VendorIdentifier::e_productId))
product = vendorInfo.m_productId.AsString();
if (vendorInfo.HasOptionalField(H225_VendorIdentifier::e_versionId))
product = product + "/" + vendorInfo.m_versionId.AsString();
}
cout << "Accepting call from " << caller << " using " << product << " with room id " << roomID << endl;
connected = TRUE;
ep.AddMember(this);
return AnswerCallNow;
}
BOOL
MyH323Connection::OnSendSignalSetup( H323SignalPDU & callProceedingPDU )
{
// We are making a connection to a remote EP so add this connection to
// the list of rooms and members.
// We will add them to the default room as we have no method of
// specifying which room our connection should join.
connected = TRUE;
roomID = ep.GetDefaultRoomName();
cout << "Adding connection to room " << roomID << endl;
ep.AddMember(this);
return H323Connection::OnSendSignalSetup( callProceedingPDU );
}
BOOL MyH323Connection::OpenAudioChannel(BOOL isEncoding, unsigned /* bufferSize */, H323AudioCodec & codec)
{
PStringStream codecName;
codecName << codec;
codec.SetSilenceDetectionMode( H323AudioCodec::NoSilenceDetection );
// if (!codec.IsDescendant(H323_GSM0610Codec::Class()) &&
// - need to add MS-GSM here along with any other codecs
// !codec.IsDescendant(H323_muLawCodec::Class())) {
// cerr << "Unknown codec \"" << codecName << endl;
// return FALSE;
// }
PWaitAndSignal mutex(audioMutex);
if (incomingAudio == NULL) {
incomingAudio = new IncomingAudio(ep, *this);
}
if (outgoingAudio == NULL) {
outgoingAudio = new OutgoingAudio(ep, *this);
}
if (isEncoding) {
audioTransmitCodecName = codecName;
codec.AttachChannel(outgoingAudio, FALSE);
} else {
audioReceiveCodecName = codecName;
codec.AttachChannel(incomingAudio, FALSE);
}
return TRUE;
}
#ifndef NO_VIDEO
BOOL MyH323Connection::OpenVideoChannel(BOOL isEncoding,
H323VideoCodec & codec)
{
PStringStream codecName;
codecName << codec;
PWaitAndSignal mutex(videoMutex);
if (isEncoding) {
if (outgoingVideo == NULL) {
outgoingVideo = new OutgoingVideo(ep, *this, ep.videoFramesPS, ep.videoLarge);
codec.AttachChannel(outgoingVideo,FALSE);
// outgoingVideo->SetFrameSize(352>>1,288>>1);
}
/*At last. Modularity. The video codec is told the parameters of video compresion/decompression.
The only thing the video codec knows about the ouside world is how to acquire/render data, which
is via the video channel, provided by the OutgoingVideo class.
The codec does provide a second interface, through which ethernet packets enter (or leave) */
codec.SetTxQualityLevel(ep.videoTxQuality);
codec.SetBackgroundFill(ep.videoFill);
videoTransmitCodecName = codecName;
} else {
if (incomingVideo == NULL)
incomingVideo = new IncomingVideo(ep, *this);
codec.AttachChannel(incomingVideo,FALSE);
videoReceiveCodecName = codecName;
}
return TRUE;
}
#endif
BOOL MyH323Connection::OnStartLogicalChannel(H323Channel & channel)
{
if (!H323Connection::OnStartLogicalChannel(channel))
return FALSE;
cout << "Started logical channel: ";
switch (channel.GetDirection()) {
case H323Channel::IsTransmitter :
cout << "sending ";
break;
case H323Channel::IsReceiver :
cout << "receiving ";
break;
default :
break;
}
cout << channel.GetCapability() << endl;
return TRUE;
}
BOOL MyH323Connection::OnOutgoingAudio(void * buffer, PINDEX amount)
{
return ep.ReadAudio(GetCallToken(), buffer, amount, roomID);
}
BOOL MyH323Connection::OnIncomingAudio(const void * buffer, PINDEX amount)
{
return ep.WriteAudio(GetCallToken(), buffer, amount, roomID);
}
#ifndef NO_VIDEO
BOOL MyH323Connection::OnOutgoingVideo(void * buffer, PINDEX & amount)
{
return ep.ReadVideo(GetCallToken(), buffer, amount, roomID);
}
BOOL MyH323Connection::OnIncomingVideo(const void * buffer, PINDEX amount)
{
return ep.WriteVideo(GetCallToken(), buffer, amount, roomID);
}
#endif
void MyH323Connection::AddMember(const PString & token)
{
audioMutex.Wait();
cout << "Adding audio buffer for " << token
<< " to connection " << GetCallToken() << endl;
// Create a new audio buffer to hold audio between the connection
// called 'token' and this connection.
audioBuffers.SetAt(token, new AudioBuffer);
audioMutex.Signal();
}
void MyH323Connection::RemoveMember(const PString & token)
{
PWaitAndSignal mutex(audioMutex);
cout << "Removing audio buffer for " << token
<< " from connection " << GetCallToken() << endl;
audioBuffers.RemoveAt(token);
}
BOOL MyH323Connection::WriteAudio(const PString & token, const void * buffer, PINDEX amount)
{
PWaitAndSignal mutex(audioMutex);
AudioBuffer * audioBuffer = audioBuffers.GetAt(token);
if (audioBuffer != NULL)
audioBuffer->Write((BYTE *)buffer, amount);
return TRUE;
}
BOOL MyH323Connection::ReadAudio(const PString & /*token*/, void * buffer, PINDEX amount)
{
PWaitAndSignal mutex(audioMutex);
// First, set the buffer to empty.
memset(buffer, 0, amount);
// get number of channels to mix
PINDEX numChannels = audioBuffers.GetSize();
if (numChannels== 0)
return TRUE;
// scan through the audio buffers and mix the signals
PINDEX i;
for (i = 0; i < numChannels; i++) {
PString key = audioBuffers.GetKeyAt(i);
audioBuffers[key].ReadAndMix((BYTE *)buffer, amount, numChannels);
}
return TRUE;
}
///////////////////////////////////////////////////////////////
OutgoingAudio::OutgoingAudio(MyH323EndPoint & _ep, MyH323Connection & _conn)
: ep(_ep), conn(_conn)
{
os_handle = 0;
}
void OutgoingAudio::CreateSilence(void * buffer, PINDEX amount)
{
memset(buffer, 0, amount);
lastReadCount = amount;
}
BOOL OutgoingAudio::Read(void * buffer, PINDEX amount)
{
PWaitAndSignal mutexR(audioChanMutex);
if (!IsOpen())
return FALSE;
if (!delay.Delay(amount / 16)) {
// do the read call here, by calling conn.OnOutgoingAudio():
BOOL doSilence = !conn.OnOutgoingAudio(buffer, amount);
if (doSilence)
CreateSilence(buffer, amount);
}
lastReadCount = amount;
return TRUE;
}
BOOL OutgoingAudio::Close()
{
if (!IsOpen())
return FALSE;
PWaitAndSignal mutexC(audioChanMutex);
os_handle = -1;
return TRUE;
}
///////////////////////////////////////////////////////////////////////////
IncomingAudio::IncomingAudio(MyH323EndPoint & _ep, MyH323Connection & _conn)
: ep(_ep), conn(_conn)
{
os_handle = 0;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -