?? main.cxx
字號:
/*
* main.cxx
*
* A simple H.323 MCU
*
* Copyright (c) 2000 Equivalence Pty. Ltd.
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
* the License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Portable Windows Library.
*
* The Initial Developer of the Original Code is Equivalence Pty. Ltd.
*
* Portions are Copyright (C) 1993 Free Software Foundation, Inc.
* All Rights Reserved.
*
* Contributor(s): Derek J Smithies (derek@indranet.co.nz)
* ------------------------------
*
* $Log: main.cxx,v $
* Revision 1.62 2003/02/10 09:29:15 rogerh
* Check that a room still exists when reading/writing audio and video.
* This fixes a problem where the video compression thread was reading
* from a room which had been deleted.
*
* Revision 1.61 2003/02/06 22:29:09 robertj
* Fixed MSVC warning.
*
* Revision 1.60 2003/02/06 02:43:49 rogerh
* There is now a video buffer for each 'room', which stops people in
* different rooms from seeing each other. Bug pointed out by Damien Sandras.
* Will need for fix leaks and delete the video buffer when a room empties.
*
* Revision 1.59 2002/12/16 08:57:12 robertj
* Fixed problem with spoken list crashing with video, thanks Bob Lindell
*
* Revision 1.58 2002/11/21 07:58:32 robertj
* Fixed stupid mistake in removing make call function.
*
* Revision 1.57 2002/11/21 07:54:52 robertj
* Removed redundent and incorrect function for making outgoing call.
*
* Revision 1.56 2002/11/13 10:23:57 rogerh
* Enable Speex codec by default, now it is part of OpenH323.
*
* Revision 1.55 2002/11/10 08:12:42 robertj
* Moved constants for "well known" ports to better place (OPAL change).
*
* Revision 1.54 2002/10/31 00:55:42 robertj
* Enhanced jitter buffer system so operates dynamically between minimum and
* maximum values. Altered API to assure app writers note the change!
*
* Revision 1.53 2002/10/16 10:01:28 rogerh
* Add Speex 8k and 15k codecs.
*
* Revision 1.52 2002/06/14 08:05:08 dereks
* Added tweak to support operation behind a NAT that forwards ports
* This will use TranslateTCPAddress to change the address reported
* to connections that occur from outside the 192. subnet. Thanks Sahai.
*
*
* Revision 1.51 2002/04/18 10:54:34 rogerh
* Fix bug in audio mixing reportde by Bob Lindell <lindell@isi.edu>
* AudioBuffer::Read() had been optimised to do reading and mixing and
* contained memset()'s which were incorrect. Clean up the code with
* a proper Read() method and an optimised ReadAndMix() method.
*
* Revision 1.50 2002/04/06 00:54:43 rogerh
* Clean up the videoBufferSize code
*
* Revision 1.49 2002/04/06 00:15:14 rogerh
* Fix bugs in the Clear() method.
*
* Revision 1.48 2002/02/17 08:46:20 rogerh
* Add simple wildcard of "*" for --audio-loopback to enable loopback
* in all rooms
*
* Revision 1.47 2002/02/17 08:30:17 rogerh
* The new openh323 library checks for getLastReadCount
*
* Revision 1.46 2002/02/07 12:19:15 rogerh
* add --listenport option. Requested by Damien
*
* Revision 1.45 2002/01/16 10:19:45 rogerh
* Tidy code and screen alignment
*
* Revision 1.44 2001/12/02 08:28:39 rogerh
* Update help for audio-loopback
*
* Revision 1.43 2001/12/02 08:17:57 rogerh
* Change --audio-loopback to take a room name. Only connections to the
* specified room will have audio loopback applied. The remainder of the rooms
* in OpenMCU will work as normal.
* Submitted by Malcolm Caldwell <malcolm.caldwell@ntu.edu.au>
* I hard coded room "loopback" as a loopback room regardless of
* the --audio-loopback parameter.
*
* Revision 1.42 2001/11/27 12:33:56 rogerh
* Fix bug in statictics which caused a core dump
*
* Revision 1.41 2001/11/22 13:06:38 rogerh
* Add --audio-loopback. Users of OpenMCU can hear their own voice echoed back
* which is very handy for testing purposes.
*
* Revision 1.40 2001/08/27 03:47:39 robertj
* Changed if statement with constant expression to be #ifdef.
*
* Revision 1.39 2001/08/24 13:48:01 rogerh
* Delete the listener thread if StartListener() fails.
*
* Revision 1.38 2001/08/23 07:54:09 rogerh
* Add code which allows a user to hear their own audio echo back from the MCU
* This needs to be enabled at compile time with the HEAR_OWN_AUDIO define.
*
* Revision 1.37 2001/07/23 03:55:13 rogerh
* Seperate out codec names for audio and video
*
* Revision 1.36 2001/07/23 03:28:03 rogerh
* Display the codec name in the statistics page
*
* Revision 1.35 2001/07/17 11:49:38 rogerh
* Change title, Mcu -> MCU
*
* Revision 1.34 2001/07/17 10:57:45 rogerh
* Add LPC-10 codec support, from Santiago Garcia Mantinan <openh323@manty.net>
*
* Revision 1.33 2001/07/12 06:18:27 rogerh
* Add G711 A-Law codec
*
* Revision 1.32 2001/06/28 06:08:17 rogerh
* Fix compilation warning
*
* Revision 1.31 2001/06/13 06:01:35 rogerh
* Add some comments
*
* Revision 1.30 2001/06/13 05:47:19 rogerh
* Fix the Make Call menu option which was broken when multiple rooms were
* added. Calls made from OpenMCU are added to the default room name.
* Add the Microsoft GSM codec to the codecs list.
*
* Revision 1.29 2001/05/31 17:01:52 rogerh
* Fixes from Dan Johansson <djn98006@student.mdh.se> to make video work.
* Go back to using 'closed' for the Video Classes. This is needed as
* the the video classes come from PVideoChannel which does not use os_handle
* in its IsOpen() method. Instead, we must define our own IsOpen() method.
* Also, back out the size of the image change.
* Finally, add a new feature. For the first 4 connections, video from an
* endpoint is displayed immediatly rather than waiting until that ep sends
* some audio. (handy for endpoints with video only and with no talking)
*
* Revision 1.28 2001/05/31 14:29:29 rogerh
* Add --disable-menu to OpenMCU
*
* Revision 1.27 2001/05/17 22:07:51 dereks
* fixed calculation of the number of bytes in the image.
*
* Revision 1.26 2001/05/08 13:43:11 rogerh
* Connections without a room name will now join the default room (room101)
* Handy for NetMeeting users who cannot specify the room to OpenMCU.
* Add --defaultroom to change the default room name. Add --no-defaultroom to
* prevent use of the default room and to reject calls without a room name.
*
* Revision 1.25 2001/05/08 11:30:39 rogerh
* clean up display
*
* Revision 1.24 2001/05/08 10:47:07 rogerh
* Handle the removal of members correctly.
*
* Revision 1.23 2001/05/04 08:07:49 rogerh
* Improve stats when there are no connections and fix nested mutex bug
*
* Revision 1.22 2001/03/20 23:34:33 robertj
* Added creating of room member lists on first use of room.
* Used the new PTrace::Initialise function for starting trace code.
*
* Revision 1.21 2001/03/18 07:40:45 robertj
* Fixed MSVC compatibility.
*
* Revision 1.20 2001/03/18 06:50:20 robertj
* More changes for multiple conferences from Patrick Koorevaar.
*
* Revision 1.19 2001/03/06 04:32:50 robertj
* Fixed another error in previous update, variable declared twice.
*
* Revision 1.18 2001/03/05 22:36:22 robertj
* Changes for logging and multiple conferences from Patrick Koorevaar.
*
* Revision 1.17 2001/02/19 05:04:18 robertj
* Added more fixes on shutdown, thanks Paul E. Zaremba.
*
* Revision 1.16 2001/02/09 06:09:42 robertj
* Added fix for crashing on exit problem, thanks Dhomin.
*
* Revision 1.15 2001/02/08 07:06:37 robertj
* Added 'm' command to make call, thanks Paul Zaremba.
* Added ability to send CIF size images, thanks again Paul Zaremba.
*
* Revision 1.14 2001/01/04 01:35:43 dereks
* Add user interface thread to openmcu.
* tidy up the exiting process, but it is still in need of work.
*
* Revision 1.13 2001/01/03 03:59:26 dereks
* Adjusted algorithm for selecting which corners contain which video stream.
* Add gsmframes and g711frames option. Add documentation describing data flows.
*
* Revision 1.12 2000/12/22 08:28:23 dereks
* Optimise video handling, and reduce load on mcu computer
* Include noise detection routine, to determine which images are displayed when > 4 connections.
*
* Revision 1.11 2000/12/19 22:41:44 dereks
* Add video conferencing - limited to 5 connected nodes.
* Use the video channel facility now in openh323 and pwlib modules
* Add simple interface to handle commands entered at the keyboard.
*
* Revision 1.10 2000/11/08 04:27:33 robertj
* Fixed MSVC warnings.
*
* Revision 1.9 2000/11/03 06:38:07 craigs
* Added conditional for windows until we decide what to do
*
* Revision 1.8 2000/11/02 03:33:41 craigs
* Changed to provide some sort of software timeing loop
*
* Revision 1.7 2000/06/20 02:38:32 robertj
* Changed H323TransportAddress to default to IP.
*
* Revision 1.6 2000/05/25 13:26:18 robertj
* Fixed incorrect "save" parameter specification.
*
* Revision 1.5 2000/05/25 12:06:20 robertj
* Added PConfigArgs class so can save program arguments to config files.
*
* Revision 1.4 2000/05/11 11:47:11 robertj
* Fixed alpha linux GNU compiler problems.
*
* Revision 1.3 2000/05/11 09:54:02 robertj
* Win32 compilation
*
* Revision 1.2 2000/05/10 08:11:57 craigs
* Fixed copyrights and names
*
* Revision 1.1 2000/05/10 05:54:06 craigs
* Initial version
*
*/
#include <ptlib.h>
#include <ptlib/pipechan.h>
#include "version.h"
#include "mscodecs.h"
#include "lpc10codec.h"
#include "speexcodec.h"
#ifndef NO_VIDEO
#include "h261codec.h"
#include "videoio.h"
#endif
#include "main.h"
//#include "acmencr.h"
PCREATE_PROCESS(OpenMcu);
#define new PNEW
// size of a PCM data packet, in samples
#define PCM_PACKET_LEN 240
// size of a PCM data buffer, in bytes
#define PCM_BUFFER_LEN (PCM_PACKET_LEN * 2)
// number of PCM buffers to keep
#define PCM_BUFFER_COUNT 2
#define PCM_BUFFER_SIZE (PCM_BUFFER_LEN * PCM_BUFFER_COUNT)
///////////////////////////////////////////////////////////////
#ifdef LOGGING
static PString DEFAULT_CALL_LOG = "c:\\mcu_log.txt";
static PMutex logMutex;
static PTextFile logFile;
static PFilePath logFilename = DEFAULT_CALL_LOG;
static void LogMessage(const PString & str)
{
PTime now;
PString msg = now.AsString("dd/MM/yyyy") & str;
logMutex.Wait();
if (!logFile.IsOpen()) {
logFile.Open(logFilename, PFile::ReadWrite);
logFile.SetPosition(0, PFile::End);
}
logFile.WriteLine(msg);
logFile.Close();
logMutex.Signal();
}
static void LogCall(MyH323Connection& connection,
const BOOL accepted = TRUE)
{
H323TransportAddress address = connection.GetControlChannel().GetRemoteAddress();
PIPSocket::Address ip;
WORD port;
PStringStream stringStream, timeStream;
address.GetIpAndPort(ip, port);
timeStream << connection.GetConnectionStartTime().AsString("hh:mm:ss");
stringStream << ' ' << "caller-ip:" << ip << ':' << port << ' '
<< connection.GetRemotePartyName()
<< " room:" << connection.GetRoomID();
if (accepted) {
PStringStream connectionDuration;
connectionDuration << setprecision(0) << setw(5) << (PTime() - connection.GetConnectionStartTime());
LogMessage(timeStream + stringStream + " connection duration:" + connectionDuration);
}
else
LogMessage(timeStream + " Call denied:" + stringStream);
}
#endif
///////////////////////////////////////////////////////////////
OpenMcu::OpenMcu()
: PProcess("OpenH323 Project", "OpenMCU",
MAJOR_VERSION, MINOR_VERSION, BUILD_TYPE, BUILD_NUMBER)
{
}
OpenMcu::~OpenMcu()
{
}
void OpenMcu::Main()
{
cout << GetName()
<< " Version " << GetVersion(TRUE)
<< " by " << GetManufacturer()
<< " on " << GetOSClass() << ' ' << GetOSName()
<< " (" << GetOSVersion() << '-' << GetOSHardware() << ")\n";
//PArgList & args = GetArguments();
PConfigArgs args(GetArguments());
args.Parse(
"g-gatekeeper:" "n-no-gatekeeper."
"-require-gatekeeper." "-no-require-gatekeeper."
"q-translate:"
"h-help."
"i-interface:" "-no-interface."
"-save."
"j-jitter:"
"-listenport:"
"-gsmframes:" "-no-gsmframes."
"-g711frames:" "-no-g711frames."
#if PTRACING
"t-trace."
"o-output:"
#endif
"-defaultroom:" "-no-defaultroom."
"u-username:" "-no-username."
#ifndef NO_VIDEO
"v-video." "-no-video."
"-videolarge."
"-videotxquality:" "-no-videotxquality."
"-videofill:" "-no-videofill."
"-videotxfps:" "-no-videotxfps."
"-disable-menu."
"-audio-loopback:"
#endif
, FALSE);
#if PTRACING
PTrace::Initialise(args.GetOptionCount('t'),
args.HasOption('o') ? (const char *)args.GetOptionString('o') : NULL);
#endif
if (args.HasOption('h')) {
cout << "Usage : " << GetName() << " [options]\n"
"Options:\n"
" -u --username str : Set the local endpoint name to str\n"
" -g --gatekeeper host: Specify gatekeeper host.\n"
" -n --no-gatekeeper : Disable gatekeeper discovery.\n"
" --require-gatekeeper: Exit if gatekeeper discovery fails.\n"
" -q --translate ip : Set external IP address to ip if masQueraded \n"
" -i --interface ip : Bind to a specific interface\n"
" -j --jitter [min-]max : Set minimum (optional) and maximum jitter buffer (in milliseconds).\n"
" --listenport n : Port to listen on for incoming connections(default 1720)\n"
" --g711frames count : Set the number G.711 frames in capabilities (default 30)\n"
" --gsmframes count : Set the number GSM frames in capabilities (default 4)\n"
#if PTRACING
" -t --trace : Enable trace, use multiple times for more detail\n"
" -o --output : File for trace output, default is stderr\n"
#endif
" --save : Save arguments in configuration file\n"
#ifndef NO_VIDEO
" -v --video : Enable H261 video handling\n"
" --videolarge : Set the video size from normal (176x144) to large (352x288).\n"
" --videotxquality n : Select sent video quality,(def 9). 1(good)<=n<=31\n"
" --videofill n : Select number of updated background blocks per frame 1<=n<=99 (2 def)\n"
" --videotxfps n : Maximum number of transmitted video frames per sec 1<10(def)<30\n\n"
#endif
" --defaultroom name : Connections without a room name will join this room\n"
" (Default room is room101)\n"
" --no-defaultroom : Reject connections with no room specified\n"
" --disable-menu : Disable the command line menu\n"
" --audio-loopback name : Let a user hear their own voice echo'ed back in this room\n"
" -h --help : Display this help message\n";
return;
}
args.Save("save");
MyH323EndPoint endpoint;
PString userName = "OpenH323 MCU v" + GetVersion();
if (args.HasOption('u'))
userName = args.GetOptionString('u');
endpoint.SetLocalUserName(userName);
int g711Frames = 30;
if (args.HasOption("g711frames")) {
g711Frames = args.GetOptionString("g711frames").AsInteger();
if (g711Frames <= 10 || g711Frames > 240) {
cerr << "error: G.711 frame size must be in range 10 to 240" << endl;
g711Frames = 30;
}
}
int gsmFrames = 4;
if (args.HasOption("gsmframes")) {
gsmFrames = args.GetOptionString("gsmframes").AsInteger();
if (gsmFrames < 1 || gsmFrames > 7) {
cerr << "error: GSM frame size must be in range 1 to 7" << endl;
gsmFrames = 4;
}
}
H323Capability * gsm = new H323_GSM0610Capability;
H323Capability * msgsm = new MicrosoftGSMAudioCapability;
H323Capability * ulaw64 = new H323_G711Capability(H323_G711Capability::muLaw, H323_G711Capability::At64k);
H323Capability * alaw64 = new H323_G711Capability(H323_G711Capability::ALaw, H323_G711Capability::At64k);
H323Capability * lpc10 = new H323_LPC10Capability(endpoint);
H323Capability * speex3 = new SpeexNarrow3AudioCapability(); // 8k
H323Capability * speex5 = new SpeexNarrow5AudioCapability(); // 15k
endpoint.SetCapability(0, 0, speex3);
endpoint.SetCapability(0, 0, speex5);
endpoint.SetCapability(0, 0, gsm);
gsm->SetTxFramesInPacket(gsmFrames);
endpoint.SetCapability(0, 0, msgsm);
msgsm->SetTxFramesInPacket(gsmFrames);
endpoint.SetCapability(0, 0, ulaw64);
ulaw64->SetTxFramesInPacket(g711Frames);
endpoint.SetCapability(0, 0, alaw64);
alaw64->SetTxFramesInPacket(g711Frames);
endpoint.SetCapability(0, 0, lpc10);
if (args.HasOption('j')) {
unsigned minJitter;
unsigned maxJitter;
PStringArray delays = args.GetOptionString('j').Tokenise(",-");
if (delays.GetSize() == 1) {
minJitter = delays[0].AsUnsigned();
maxJitter = delays[1].AsUnsigned();
}
else {
maxJitter = delays[0].AsUnsigned();
minJitter = PMIN(endpoint.GetMinAudioJitterDelay(), maxJitter);
}
if (minJitter >= 20 && minJitter <= maxJitter && maxJitter <= 1000)
endpoint.SetAudioJitterDelay(minJitter, maxJitter);
else {
cerr << "Jitter should be between 20 and 1000 milliseconds." << endl;
return;
}
}
// start the H.323 listener
H323ListenerTCP * listener;
WORD listenPort = H323EndPoint::DefaultTcpPort;
if (args.HasOption("listenport"))
listenPort = (WORD)args.GetOptionString("listenport").AsInteger();
if (args.GetOptionString('i').IsEmpty()) {
PIPSocket::Address interfaceAddress(INADDR_ANY);
listener = new H323ListenerTCP(endpoint, interfaceAddress, listenPort);
} else {
PIPSocket::Address interfaceAddress(args.GetOptionString('i'));
listener = new H323ListenerTCP(endpoint, interfaceAddress, listenPort);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -