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

📄 main.cxx

📁 mcu for video conference test
💻 CXX
📖 第 1 页 / 共 4 页
字号:
  }
  if (!endpoint.StartListener(listener)) {
    cout <<  "Could not open H.323 listener port on "
         << listener->GetListenerPort() << endl;
    delete listener;
    return;
  }

  cout << "Listening on port " << listener->GetListenerPort() << endl;


  if (args.GetOptionString('q').IsEmpty()) {
    endpoint.behind_masq = FALSE;
  } else {
    endpoint.masqAddressPtr = new PIPSocket::Address(args.GetOptionString('q'));
    endpoint.behind_masq = TRUE;
    cout << "Masquerading as address " << *(endpoint.masqAddressPtr) << endl;
  }

#ifndef NO_VIDEO
  // If videoLarge was specified
  if (args.HasOption("videolarge")) {
    endpoint.videoLarge = TRUE;
  } else {
    endpoint.videoLarge = FALSE;
  }
         
  if (args.HasOption('v')) {
    //Add capability to allow the reception of video.

    // this is the only way I know of at present to transmit
    // CIF size video - pez
    // Do not allow CIF video if size is medium
    if ( endpoint.videoLarge )
      endpoint.SetCapability(0, 1, new H323_H261Capability(0, 4, FALSE, FALSE, 6217)); // CIF
      endpoint.SetCapability(0, 1, new H323_H261Capability(2, 0, FALSE, FALSE, 6217)); // QCIF
  } 

  endpoint.EnableVideoReception(args.HasOption('v'));

  int videoTxQual = 10;
  if (args.HasOption("videotxquality")) 
      videoTxQual = args.GetOptionString("videotxquality").AsInteger();
  endpoint.videoTxQuality = PMAX(1, PMIN(31, videoTxQual));

  int videoF = 2;
  if (args.HasOption("videofill")) 
    videoF = args.GetOptionString("videofill").AsInteger();
  endpoint.videoFill = PMAX(1, PMIN(99, videoF));

  int videoFPS = 10;
  if (args.HasOption("videotxfps")) 
    videoFPS = args.GetOptionString("videotxfps").AsInteger();
  endpoint.videoFramesPS = PMAX(1,PMIN(30,videoFPS));
#endif

  if (args.HasOption('g')) {
    PString gkName = args.GetOptionString('g');
    if (endpoint.SetGatekeeper(gkName, new H323TransportUDP(endpoint)))
      cout << "Gatekeeper set: " << *endpoint.GetGatekeeper() << endl;
    else {
      cout << "Error registering with gatekeeper at \"" << gkName << '"' << endl;
      return;
    }
  }
  else if (!args.HasOption('n')) {
    cout << "Searching for gatekeeper..." << flush;
    if (endpoint.DiscoverGatekeeper(new H323TransportUDP(endpoint)))
      cout << "\nGatekeeper found: " << *endpoint.GetGatekeeper() << endl;
    else {
      cout << "\nNo gatekeeper found." << endl;
      if (args.HasOption("require-gatekeeper"))
        return;
    }
  }  

  PString roomName = "room101";
  if (args.HasOption("defaultroom")) {
    roomName = args.GetOptionString("defaultroom");
  }
  if (args.HasOption("no-defaultroom")) {
    roomName = "";
  }
  endpoint.SetDefaultRoomName(roomName);


  if (args.HasOption("disable-menu")) {
    endpoint.hasMenu = FALSE;
  } else {
    endpoint.hasMenu = TRUE;
  }


  if (args.HasOption("audio-loopback")) {
    endpoint.audioLoopbackRoom = args.GetOptionString("audio-loopback");
  } else {
    endpoint.audioLoopbackRoom = "";
  }


  cout <<  "Codecs (in preference order):\n" << setprecision(2) << endpoint.GetCapabilities() << endl << endl;

  endpoint.ListenForIncomingCalls();
  endpoint.AwaitTermination();
  cout << "GoodBye. " << endl;

  PThread::Current()->Sleep(2000);
  cout << "Finished 2 sec sleep" <<endl;
  
#if 0 //PTRACING
  if (output != NULL) 
    delete output;
#endif
}


///////////////////////////////////////////////////////////////

MyH323EndPoint::MyH323EndPoint()
{
	terminalType = e_MCUWithAudioMP;
#ifndef NO_VIDEO
	terminalType = e_MCUWithAVMP;
#endif
}

H323Connection * MyH323EndPoint::CreateConnection(unsigned callReference)
{
  return new MyH323Connection(*this, callReference);
}


void MyH323EndPoint::TranslateTCPAddress(PIPSocket::Address &localAddr, const PIPSocket::Address &remoteAddr) 
{

  if (this->behind_masq && 
      (remoteAddr.Byte1() != 192)) {
    localAddr = *(this->masqAddressPtr);
  }
  return;
}

void MyH323EndPoint::ListenForIncomingCalls()
{
  cout << "Waiting for incoming calls for \"" << GetLocalUserName() << '"' << endl;
}


void MyH323EndPoint::AwaitTermination()
{
  PThread * userInterfaceThread = NULL;
  if (hasMenu)
    userInterfaceThread = new UserInterfaceThread(*this);

  // poll the handset every 100ms looking for state changes
  while (!exitFlag.Wait(100)) {

    // lock the user interface state whilst we change it
  }

  if (userInterfaceThread != NULL) {
    userInterfaceThread->Terminate();
    userInterfaceThread->WaitForTermination();
    delete userInterfaceThread;

    cout << "User Interface thread has terminated successfully."<<endl;  
  }

}


void MyH323EndPoint::HandleUserInterface()
{
  PConsoleChannel console(PConsoleChannel::StandardInput);
  PString user;
  PString str; 
  PINDEX idx;
 
  PTRACE(2, "OpenMCU\tUser interface thread started.");

  PStringStream help;
  help << "Select:\n"
          " ? : Print this help message\n"
#ifndef NO_VIDEO
          " v : report  connections are at which video corner\n"
#endif
					" m : make a call\n"
          " x : Exit immediately\n"
	        " s : Report statistics\n"
          " z : Put message in log file (for debugging)\n"
    ;
  
  for (;;) {
    // display the prompt
    cout << "Command ? " << flush;

    
    //terminate the menu loop if console finished
     char ch = (char)console.peek();
     if (console.eof()) {
        cerr << "\nConsole gone - menu disabled" << endl;
        cerr << "Finishing program"<<endl;        
        ch = 'x';
      } else
        console >> ch;

    switch (tolower(ch)) {
      case '?' :
        cout << help << endl;
        break;
      case 'm' :
      	console >> user;
        if (!MakeCall(user, str))
          cerr << "Error making call to \"" << user << '"' << endl;
        break;
      case 's' :
        {
        memberMutex.Wait();

        PINDEX rooms = memberListDict.GetSize();

        if (rooms == 0) {
          cout << "No statistics available" << endl;
        } else {

          for (idx = 0; idx < rooms; idx++) {
            PStringList & memberList = memberListDict.GetDataAt(idx);
            PString roomID = memberListDict.GetKeyAt(idx);
          
            cout << "Statistics for " << memberList.GetSize() << " connected parties in room "
                 << (idx+1) << " of "<< rooms << " with room id " 
                 << roomID << endl;

            for (PINDEX i = 0; i < memberList.GetSize(); i++) {
              PString token = memberList[i];
              MyH323Connection * conn = (MyH323Connection *)FindConnectionWithLock(token);
              if (conn != NULL) {
                PTime now;
                PTime callStart = conn->GetConnectionStartTime();
                cout << "Connected to : " << conn->GetRemotePartyName() << " for " 
                     << setw(5) << setprecision(0) << (now - callStart) << " mins " <<endl;

                RTP_Session * session = conn->GetSession(RTP_Session::DefaultAudioSessionID);
                if (session == NULL) {
		  cout << "             : "
		       << "Sending audio with "
		       << conn->GetAudioTransmitCodecName()
		       << endl; 
		  cout << "             : "
		       << "Receiving audio with "
		       << conn->GetAudioReceiveCodecName()
		       << endl;
                } else {
                  cout << "             : "
                       << session->GetPacketsSent() << '/'
                       << session->GetOctetsSent() 
                       << " audio packets/bytes sent ("
		       << conn->GetAudioTransmitCodecName()
		       << ")" << endl;
                  cout << "             : "
                       << session->GetPacketsReceived() << '/'
                       << session->GetOctetsReceived()
                       << " audio packets/bytes received ("
		       << conn->GetAudioReceiveCodecName()
		       << ")" << endl;
		}
#ifndef NO_VIDEO
		cout << "             : "
		     << "Sending video with "
		     << conn->GetVideoTransmitCodecName()
		     << endl; 
		cout << "             : "
		     << "Receiving video with "
		     << conn->GetVideoReceiveCodecName()
		     << endl;
#endif
                conn->Unlock();
              }
            }
            PStringList & videoPosnList = videoPosnDict[roomID];
            for(PINDEX j = 0; j < videoPosnList.GetSize(); j++) {
              str = videoPosnList[j];
              str.Delete(0,3);
              cout << "   video for position " << j << " is \""
                   << str.Left(str.Find(':')) << '"' << endl;
            }
          }
        }
        memberMutex.Signal();
        }
        break;
#ifndef NO_VIDEO
    case 'v' : 
      cout << " video information now available with option s" << endl;
      break;
#endif    
    case 'z' : 
      console >> str;
      PTRACE(0,"Log message=" << str);
      break;

    case 'q' :
    case 'x' :
      cout << "Exiting." << endl;
      memberMutex.Wait(); //Stops flow of data into/out of audio buffers.
			
			ClearAllCalls(H323Connection::EndedByLocalUser, FALSE);
      /*for (i = 0; i < memberList.GetSize(); i++) {
        PString token = memberList[i];
        MyH323Connection * conn = (MyH323Connection *)FindConnectionWithLock(token);
        if (conn != NULL)           
          conn->ClearCall();
      }*/
      
      cout << "All calls cleared"<<endl;      
      exitFlag.Signal();
      console.ignore(INT_MAX, '\n');
      memberMutex.Signal();
      
      return;

    default :
      cout << "The input character \""<<ch<<"\" is not defined"<<endl;
		}
  }
}

void MyH323EndPoint::SetDefaultRoomName(PString roomName)
{
  defaultRoomName = roomName;
}

PString MyH323EndPoint::GetDefaultRoomName(void)
{
  return defaultRoomName;
}

void MyH323EndPoint::AddMember(MyH323Connection * newMember)
{
  PWaitAndSignal mutex(memberMutex);
  PString newToken = newMember->GetCallToken();
  PString newRoomID = newMember->GetRoomID();
  BOOL create_new_room = FALSE;

  // is this is the first connection to a room?
  if (!memberListDict.Contains(newRoomID)) {
    create_new_room = TRUE;
  }

  // if this is the first connection to a room, create the memberList
  if (create_new_room) {
    memberListDict.SetAt(newRoomID, new PStringList);
  }

  // add this connection to the member list
  PStringList & memberList = memberListDict[newRoomID];
  memberList.AppendString(newToken);

#ifndef NO_VIDEO

  // if this is the first connection to a room, create the video buffer.
  if (create_new_room) {
    //cout << "CREATING VIDEO BUFFER FOR "<<newRoomID<<endl;
    videoBufferDict.SetAt(newRoomID, new VideoBuffer);

    VideoBuffer & videoBuffer = videoBufferDict[newRoomID];
    if (videoLarge)
      videoBuffer.SetSize(352,288);


    // create the spoken list.
    spokenListDict.SetAt(newRoomID, new PStringList);


    // create the position list.
    videoPosnDict.SetAt(newRoomID, new PStringList);
  
    PStringList & videoPosnList = videoPosnDict[newRoomID];
    PINDEX i;
    for(i=0;i<4;i++)  // hard coded to support 4 images
      videoPosnList.AppendString("");
  }


  // Normally we display the video for the "active" users, ie
  // people who are currently speaking (based on noise detection)
  //
  // If there are currently less than 4 members then we can display
  // the video right from the start, before they begin talking.
  // This is also handy for connections with video, but no audio.
  //
  // Problem is finding out whether or not an ep sends video.
  // That is for a coming version.
 
  AddVideoPosnToken(newToken,newRoomID);

#endif

  // add the new member to every other member,
  // and add every other member to the new member.
  PINDEX i;
  for (i = 0; i < memberList.GetSize(); i++) {
    PString token = memberList[i];
    if (token != newToken) {      
      cout << "Adding member " << newToken << " to list of " << token << endl;
      MyH323Connection * conn = (MyH323Connection *)FindConnectionWithLock(token);
      if (conn != NULL) {
        conn->AddMember(newToken);
        newMember->AddMember(token);
        conn->Unlock();
      }
    } else {
      if ((newRoomID == audioLoopbackRoom) || (newRoomID == "loopback")
       || (audioLoopbackRoom == "*") // basic wildcard
      ) {
        cout << "Member " << newToken << " will hear their own voice" << endl;
        newMember->AddMember(newToken);
      } else {
        cout << "Member " << newToken << " will not hear their own voice" << endl;
      }
    }
  }

}

void MyH323EndPoint::RemoveMember(MyH323Connection * oldConn)
{
  PWaitAndSignal mutex(memberMutex);
  PString oldToken = oldConn->GetCallToken();
  PString oldRoomID = oldConn->GetRoomID();
  BOOL delete_this_room = FALSE;
 
  // get the list of members of this room 
  PStringList & memberList = memberListDict[oldRoomID];

  PINDEX i;

#ifndef NO_VIDEO
  PStringList & spokenList = spokenListDict[oldRoomID];

  //remove the connection from the spokenList
  PINDEX keyIndex = spokenList.GetStringsIndex(oldToken);
  if (keyIndex != P_MAX_INDEX)
    spokenList.RemoveAt(keyIndex);

  //Clear the corner of the video window that the connection just
  //vacated.
  VideoBuffer & videoBuffer = videoBufferDict[oldRoomID];
  PStringList & videoPosn   = videoPosnDict[oldRoomID];
  i = FindTokensVideoPosn(oldToken,oldRoomID);
  if (i != P_MAX_INDEX) {    
    videoBuffer.Clear(i);
    videoPosn[i] = "";  
  }
#endif

  // remove this member from the audio buffer lists
  for (i = 0; i < memberList.GetSize(); i++) {
    PString token = memberList[i];
    if (token != oldToken) {
      MyH323Connection * conn = (MyH323Connection *)FindConnectionWithLock(token);
      if (conn != NULL) {
	conn->RemoveMember(oldToken);
	oldConn->RemoveMember(token);
        conn->Unlock();
      }
    }
  }

  // remove this connection from the member list
  memberList.RemoveAt(memberList.GetStringsIndex(oldToken));

  // is the room empty now?
  if (memberList.GetSize() == 0) {
    delete_this_room = TRUE;
  }


  // if there are no more members in this room, clean up
  if (delete_this_room == TRUE) {
    cout << "Room " << oldRoomID << " is now empty" << endl;
    memberListDict.RemoveAt(oldRoomID); // Note: memberList is now invalid
#ifndef NO_VIDEO
    spokenListDict.RemoveAt(oldRoomID);
    videoBufferDict.RemoveAt(oldRoomID);
    videoPosnDict.RemoveAt(oldRoomID);
#endif
  }
}

#ifndef NO_VIDEO
PINDEX MyH323EndPoint::FindTokensVideoPosn(const PString & thisToken, PString roomID)
{
  PStringList & videoPosnList = videoPosnDict[roomID];
  PINDEX keyIndex;
  for (keyIndex = 0; keyIndex<videoPosnList.GetSize(); keyIndex++)
    if (thisToken == videoPosnList[keyIndex] )
      return keyIndex;
  
  return P_MAX_INDEX;
}

BOOL MyH323EndPoint::AddVideoPosnToken(const PString & thisToken, PString roomID)
{
  PStringList & videoPosnList = videoPosnDict[roomID];
  PINDEX keyIndex;
  for (keyIndex = 0; keyIndex<videoPosnList.GetSize(); keyIndex++)
    if (videoPosnList[keyIndex] == "" ) {
      videoPosnList[keyIndex] = thisToken;
      return TRUE;
    }
  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -