📄 h323.cxx
字号:
PTRACE(3,"Failed to set format to yuv420p");
return FALSE;
}
if (ep.GetVideoFrameRate() != 0) {
if (!grabber->SetFrameRate(ep.GetVideoFrameRate())) {
PTRACE(3, "Failed to set framerate to " << ep.GetVideoFrameRate());
return FALSE;
}
}
if (!grabber->SetFrameSizeConverter(newFrameWidth,newFrameHeight,FALSE)) {
PTRACE(3, "Failed to set frame size to " << newFrameWidth << "x" << newFrameHeight);
return FALSE;
}
return TRUE;
}
#endif
void OpenMCUH323Connection::OnUserInputString(const PString & str)
{
PWaitAndSignal m(connMutex);
if (conferenceMember != NULL)
conferenceMember->SendUserInputIndication(str);
}
BOOL OpenMCUH323Connection::OnIncomingAudio(const void * buffer, PINDEX amount)
{
PWaitAndSignal m(connMutex);
// If record file is open, write data to it
if (recordFile.IsOpen()) {
recordFile.Write(buffer, amount);
recordDuration += amount / 2;
if (recordDuration > recordLimit) {
recordFile.Close();
OnFinishRecording();
}
else {
const WORD * samples = (const WORD *)buffer;
PINDEX sampleCount = amount / 2;
BOOL silence = TRUE;
while (sampleCount-- > 0 && silence) {
if (*samples > 100 || *samples < -100)
silence = FALSE;
++samples;
}
if (!silence)
recordSilenceCount = 0;
else {
recordSilenceCount += amount / 2;
if ((recordSilenceThreshold > 0) && (recordSilenceCount >= recordSilenceThreshold)) {
recordFile.Close();
OnFinishRecording();
}
}
}
}
else if (conferenceMember != NULL)
conferenceMember->WriteAudio(buffer, amount);
return TRUE;
}
void OpenMCUH323Connection::StartRecording(const PFilePath & filename, unsigned limit, unsigned threshold)
{
if (!recordFile.Open(filename, PFile::ReadWrite, PFile::Create | PFile::Truncate))
return;
recordSilenceCount = 0;
recordDuration = 0;
recordSilenceThreshold = threshold * 8000;
recordLimit = limit * 8000;
}
void OpenMCUH323Connection::OnFinishRecording()
{
}
BOOL OpenMCUH323Connection::OnOutgoingAudio(void * buffer, PINDEX amount)
{
// When the prodedure begins, play the welcome file
if (welcomeState == NotStartedYet) {
ChangeWelcomeState(PlayingWelcome);
}
for (;;) {
// Do actions that are not triggered by events
OnWelcomeProcessing();
// If a wave is not playing, we may continue now
if (!playFile.IsOpen())
break;
// Wait for wave file completion
if (playFile.Read(buffer, amount)) {
int len = playFile.GetLastReadCount();
if (len < amount) {
memset(((BYTE *)buffer)+len, 0, amount-len);
}
//playDelay.Delay(amount/16);
// Exit now since the buffer is ready
return TRUE;
}
PTRACE(4, "MCU\tFinished playing file");
playFile.Close();
// Wave completed, if no event should be fired
// then we may continue now
if(!wavePlayingInSameState)
break;
// Fire wave completion event
OnWelcomeWaveEnded();
// We should repeat the loop now because the callback
// above might have started a new wave file
}
PWaitAndSignal m(connMutex);
// If a we are connected to a conference and no wave
// is playing, read data from the conference
if (conferenceMember != NULL) {
conferenceMember->ReadAudio(buffer, amount);
return TRUE;
}
// Generate silence
return FALSE;
}
///////////////////////////////////////////////////////////////////////////////////////
void OpenMCUH323Connection::ChangeWelcomeState(int newState)
{
PWaitAndSignal m(connMutex);
if(welcomeState != newState)
{
PTRACE(4, "MCU\tEntering welcome state " << newState);
welcomeState = newState;
wavePlayingInSameState = FALSE;
OnWelcomeStateChanged();
}
}
void OpenMCUH323Connection::PlayWelcomeFile(BOOL useTheFile, PFilePath & fileToPlay)
{
playFile.Close();
wavePlayingInSameState = TRUE;
if(useTheFile) {
if(playFile.Open(fileToPlay, PFile::ReadOnly))
{
PTRACE(4, "MCU\tPlaying welcome procedure file " << fileToPlay);
return;
}
else
PTRACE(3, "MCU\tFailed to play welcome procedure file " << fileToPlay);
}
// File not played, call the wave end callback anyway
OnWelcomeWaveEnded();
}
void OpenMCUH323Connection::OnWelcomeStateChanged()
{
PFilePath fn;
OpenMCU & mcu = OpenMCU::Current();
switch(welcomeState) {
case PlayingWelcome:
// Welcome file not implemented yet
PlayWelcomeFile(FALSE, fn);
break;
case PlayingConnecting:
PlayWelcomeFile(mcu.GetConnectingWAVFile(fn), fn);
break;
case CompleteConnection:
JoinConference(requestedRoom);
break;
case JoinFailed:
case ConferenceEnded:
// Goodbye file not implemented yet
PlayWelcomeFile(FALSE, fn);
break;
default:
// Do nothing
break;
}
}
void OpenMCUH323Connection::OnWelcomeProcessing()
{
}
void OpenMCUH323Connection::OnWelcomeWaveEnded()
{
switch(welcomeState) {
case PlayingWelcome:
ChangeWelcomeState(PlayingConnecting);
break;
case PlayingConnecting:
ChangeWelcomeState(CompleteConnection);
break;
case JoinFailed:
case ConferenceEnded:
ClearCall();
break;
default:
// Do nothing
break;
}
}
///////////////////////////////////////////////////////////////////////////////////////
#if OPENMCU_VIDEO
//
// this function is called whenever a connection needs a frame of video for output
//
BOOL OpenMCUH323Connection::OnOutgoingVideo(void * buffer, int width, int height, PINDEX & amount)
{
PWaitAndSignal m(connMutex);
if (conferenceMember != NULL)
conferenceMember->ReadVideo(buffer, width, height, amount);
else if (!GetPreMediaFrame(buffer, width, height, amount)) {
if ((width == CIF_WIDTH) && (height == CIF_HEIGHT))
MCUVideoMixer::FillCIFYUVFrame(buffer, 0, 0, 0);
else if ((width == QCIF_WIDTH) && (height == QCIF_HEIGHT))
MCUVideoMixer::FillQCIFYUVFrame(buffer, 0, 0, 0);
}
return TRUE;
}
BOOL OpenMCUH323Connection::GetPreMediaFrame(void * buffer, int width, int height, PINDEX & amount)
{
return OpenMCU::Current().GetPreMediaFrame(buffer, width, height, amount);
}
//
// this function is called whenever a connection receives a frame of video
//
BOOL OpenMCUH323Connection::OnIncomingVideo(const void * buffer, int width, int height, PINDEX amount)
{
if (conferenceMember != NULL)
conferenceMember->WriteVideo(buffer, width, height, amount);
return TRUE;
}
#endif // OPENMCU_VIDEO
///////////////////////////////////////////////////////////////
H323Connection_ConferenceMember::H323Connection_ConferenceMember(Conference * _conference, OpenMCUH323EndPoint & _ep, const PString & _h323Token, ConferenceMemberId _id, BOOL _isMCU)
: ConferenceMember(_conference, _id, _isMCU), ep(_ep), h323Token(_h323Token)
{
conference->AddMember(this);
}
H323Connection_ConferenceMember::~H323Connection_ConferenceMember()
{
PTRACE(4, "H323Connection_ConferenceMember deleted");
}
void H323Connection_ConferenceMember::Close()
{
OpenMCUH323Connection * conn = (OpenMCUH323Connection *)ep.FindConnectionWithLock(h323Token);
if (conn != NULL) {
conn->LeaveConference();
conn->Unlock();
}
}
PString H323Connection_ConferenceMember::GetTitle() const
{
PString output;
OpenMCUH323Connection * conn = (OpenMCUH323Connection *)ep.FindConnectionWithLock(h323Token);
if (conn != NULL) {
output = conn->GetRemoteName();
conn->Unlock();
}
return output;
}
PString H323Connection_ConferenceMember::GetMonitorInfo(const PString & hdr)
{
PStringStream output;
OpenMCUH323Connection * conn = (OpenMCUH323Connection *)ep.FindConnectionWithLock(h323Token);
if (conn != NULL) {
output << hdr << "Remote Address: " << conn->GetRemotePartyAddress() << "\n"
<< hdr << "AudioCodecs: " << conn->GetAudioTransmitCodecName() << '/' << conn->GetAudioReceiveCodecName() << "\n"
#if OPENMCU_VIDEO
<< hdr << "VideoCodecs: " << conn->GetVideoTransmitCodecName() << '/' << conn->GetVideoReceiveCodecName() << "\n"
#endif
;
conn->Unlock();
}
return output;
}
///////////////////////////////////////////////////////////////
void OpenMCUH323Connection::LogCall(const BOOL accepted)
{
H323TransportAddress address = GetControlChannel().GetRemoteAddress();
PIPSocket::Address ip;
WORD port;
PStringStream stringStream, timeStream;
address.GetIpAndPort(ip, port);
timeStream << GetConnectionStartTime().AsString("hh:mm:ss");
stringStream << ' ' << "caller-ip:" << ip << ':' << port << ' '
<< GetRemotePartyName()
<< " room:" << ((conference != NULL) ? conference->GetNumber() : PString());
if (accepted) {
PStringStream connectionDuration;
connectionDuration << setprecision(0) << setw(5) << (PTime() - GetConnectionStartTime());
OpenMCU::Current().LogMessage(timeStream + stringStream + " connection duration:" + connectionDuration);
}
else
OpenMCU::Current().LogMessage(timeStream + " Call denied:" + stringStream);
}
///////////////////////////////////////////////////////////////
OutgoingAudio::OutgoingAudio(H323EndPoint & _ep, OpenMCUH323Connection & _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;
// do the read call here, by calling conn.OnOutgoingAudio():
if (!conn.OnOutgoingAudio(buffer, amount))
CreateSilence(buffer, amount);
delay.Delay(amount / 16);
lastReadCount = amount;
return TRUE;
}
BOOL OutgoingAudio::Close()
{
if (!IsOpen())
return FALSE;
PWaitAndSignal mutexC(audioChanMutex);
os_handle = -1;
return TRUE;
}
///////////////////////////////////////////////////////////////////////////
IncomingAudio::IncomingAudio(H323EndPoint & _ep, OpenMCUH323Connection & _conn)
: ep(_ep), conn(_conn)
{
os_handle = 0;
}
BOOL IncomingAudio::Write(const void * buffer, PINDEX amount)
{
PWaitAndSignal mutexW(audioChanMutex);
if (!IsOpen())
return FALSE;
conn.OnIncomingAudio(buffer, amount);
delay.Delay(amount / 16);
return TRUE;
}
BOOL IncomingAudio::Close()
{
if (!IsOpen())
return FALSE;
PWaitAndSignal mutexA(audioChanMutex);
os_handle = -1;
return TRUE;
}
///////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -