⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.cxx

📁 mcu for video conference test
💻 CXX
📖 第 1 页 / 共 4 页
字号:
  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 + -