📄 main.cxx
字号:
}
H323Connection * MyH323EndPoint::CreateConnection(unsigned callReference)
{
unsigned options = 0;
options |= H323Connection::H245TunnelingOptionDisable;
// options |= H323Connection::FastStartOptionDisable;
// options |= H323Connection::H245inSetupOptionDisable;
return new MyH323Connection(*this, callReference, options);
}
BOOL MyH323EndPoint::Initialise(PConfigArgs & args)
{
// format for record files, raw or wav
if (args.HasOption("recordraw"))
SetRecordWav(FALSE);
else
SetRecordWav(TRUE);
// get G723.1 OGM
if (args.HasOption("g7231message"))
g7231Ogm = args.GetOptionString("g7231message");
else if (args.HasOption('m')) {
if (PFile::Exists(args.GetOptionString('m') + "_g7231" + WAVExt)) {
g7231Ogm = args.GetOptionString('m') + "_g7231" + WAVExt;
}
else if (PFile::Exists(args.GetOptionString('m') + PCMExt)) {
g7231Ogm = args.GetOptionString('m') + G7231Ext;
}
}
if (!g7231Ogm.IsEmpty()) {
// check if the file exists. (do not check if filename contains %s)
if ((g7231Ogm.Find("%s") == P_MAX_INDEX) && !PFile::Exists(g7231Ogm)) {
cout << "warning: cannot open G723.1 OGM file \"" << g7231Ogm << "\"" << endl;
g7231Ogm = "";
}
}
if (g7231Ogm.IsEmpty())
cout << "No G.723.1 outgoing message set\n";
else {
cout << "Using \"" << g7231Ogm << "\" as G.723.1 outgoing message\n";
}
// Get the OGM message for the 'PCM' codecs
// Check if the file specified exists. If it does, use it.
// If it does not exist, try with .wav and .sw extensions.
if (args.HasOption("pcmmessage")) {
pcmOgm = args.GetOptionString("pcmmessage");
}
else if (args.HasOption('m')) {
if (PFile::Exists(args.GetOptionString('m'))) {
pcmOgm = args.GetOptionString('m');
}
else if (PFile::Exists(args.GetOptionString('m') + WAVExt)) {
pcmOgm = args.GetOptionString('m') + WAVExt;
}
else if (PFile::Exists(args.GetOptionString('m') + PCMExt)) {
pcmOgm = args.GetOptionString('m') + PCMExt;
}
}
if (args.HasOption("loop"))
SetLoopMessage(TRUE);
else
SetLoopMessage(FALSE);
// By default, use the pcmOgm for all the PCM codecs, but allow the user
// to override them.
gsmOgm = pcmOgm;
g711Ogm = pcmOgm;
lpc10Ogm = pcmOgm;
speexOgm = pcmOgm;
ilbcOgm = pcmOgm;
// We can set the filename for specific codecs.
if (args.HasOption("gsmmessage"))
gsmOgm = args.GetOptionString("gsmmessage");
if (args.HasOption("g711message"))
g711Ogm = args.GetOptionString("g711message");
if (args.HasOption("lpc10message"))
lpc10Ogm = args.GetOptionString("lpc10message");
if (args.HasOption("speexmessage"))
speexOgm = args.GetOptionString("speexmessage");
if (args.HasOption("ilbcmessage"))
ilbcOgm = args.GetOptionString("ilbcmessage");
if (args.HasOption("ilbcmessage"))
ilbcOgm = args.GetOptionString("ilbcmessage");
// Check GSM OGM message
if (!gsmOgm.IsEmpty()) {
if ((gsmOgm.Find("%s") == P_MAX_INDEX) && !PFile::Exists(gsmOgm)) {
cout << "warning: cannot open GSM OGM file \"" << gsmOgm << "\"" << endl;
gsmOgm = "";
}
}
if (gsmOgm.IsEmpty())
cout << "No GSM outgoing message set\n";
else {
cout << "Using \"" << gsmOgm << "\" as GSM outgoing message\n";
}
// Check G.711 OGM message
if (!g711Ogm.IsEmpty()) {
if ((g711Ogm.Find("%s") == P_MAX_INDEX) && !PFile::Exists(g711Ogm)) {
cout << "warning: cannot open G711 OGM file \"" << g711Ogm << "\"" << endl;
g711Ogm = "";
}
}
if (g711Ogm.IsEmpty())
cout << "No G711 outgoing message set\n";
else {
cout << "Using \"" << g711Ogm << "\" as G.711 outgoing message\n";
}
// Check LPC10 OGM message
if (!lpc10Ogm.IsEmpty()) {
if ((lpc10Ogm.Find("%s") == P_MAX_INDEX) && !PFile::Exists(lpc10Ogm)) {
cout << "warning: cannot open LPC10 OGM file \"" << lpc10Ogm << "\"" << endl;
lpc10Ogm = "";
}
}
if (lpc10Ogm.IsEmpty())
cout << "No LPC10 outgoing message set\n";
else {
cout << "Using \"" << lpc10Ogm << "\" as LPC10 outgoing message\n";
}
// Check Speex OGM message
if (!speexOgm.IsEmpty()) {
// check if the file exists. (do not check if filename contains %s)
if ((speexOgm.Find("%s") == P_MAX_INDEX) && !PFile::Exists(speexOgm)) {
cout << "warning: cannot open Speex OGM file \"" << speexOgm << "\"" << endl;
speexOgm = "";
}
}
if (speexOgm.IsEmpty())
cout << "No Speex outgoing message set\n";
else {
cout << "Using \"" << speexOgm << "\" as Speex outgoing message\n";
}
// Check iLBC OGM message
if (!ilbcOgm.IsEmpty()) {
// check if the file exists. (do not check if filename contains %s)
if ((ilbcOgm.Find("%s") == P_MAX_INDEX) && !PFile::Exists(ilbcOgm)) {
cout << "warning: cannot open iLBC OGM file \"" << ilbcOgm << "\"" << endl;
ilbcOgm = "";
}
}
if (ilbcOgm.IsEmpty())
cout << "No iLBC outgoing message set\n";
else {
cout << "Using \"" << ilbcOgm << "\" as iLBC outgoing message\n";
}
#if OPENAM_VIDEO
// Check for video message
videoOgm = args.GetOptionString("videomessage");
#endif
if (g7231Ogm.IsEmpty() && gsmOgm.IsEmpty() && g711Ogm.IsEmpty()
&& lpc10Ogm.IsEmpty() && speexOgm.IsEmpty()
&& videoOgm.IsEmpty()
) {
cerr << "Must specify at least one outgoing message" << endl;
return FALSE;
}
AddAllCapabilities(0, 0, "*");
#if OPENAM_VIDEO
if (!videoOgm.IsEmpty()) {
autoStartTransmitVideo = TRUE;
cout << "Using \"" << videoOgm << "\" as video outgoing message\n";
OpalMediaFormat::List mediaFormats = H323PluginCodecManager::GetMediaFormats();
// int videoBitRate = 0; //disable setting videoBitRate.
// if (args.HasOption("videobitrate")) {
// videoBitRate = args.GetOptionString("videobitrate").AsInteger();
// videoBitRate = 1024 * PMAX(16, PMIN(2048, videoBitRate));
// }
videoSize = (PString(DEFAULT_VIDEO_SIZE) *= "qcif") ? 0 : 1;
if (args.GetOptionString("videosize") *= "cif")
videoSize = 1;
videoIsPal = PString(DEFAULT_VIDEO_FORMAT) *= "pal";
if (args.HasOption("videoformat"))
videoIsPal = args.GetOptionString("videoformat") *= "pal";
cout << "Video size is " << (videoIsPal ? "pal" : "ntsc") << " " << (videoSize == 0 ? "qcif" : "cif") << endl;
frameRate = DEFAULT_VIDEO_FRAME_RATE;
if (args.HasOption("videorate"))
frameRate = args.GetOptionString("videorate").AsInteger();
cout << "Video frame rate is " << frameRate << endl;
videoChannel = DEFAULT_VIDEO_MODE;
{
PString str = args.GetOptionString("videomode");
if (!str.IsEmpty()) {
PINDEX i;
for (i = 0; VideoModes[i] != NULL; ++i)
if (str *= VideoModes[i])
break;
if (VideoModes[i] == NULL) {
PError << "error: cannot set video mode " << str << endl;
return FALSE;
}
videoChannel = i;
}
}
cout << "Video play mode is " << VideoModes[videoChannel] << endl;
}
#endif // OPENAM_VIDEO
PString removeString;
if (gsmOgm.IsEmpty())
removeString = removeString & OpalGSM0610 & "MS-GSM";
if (speexOgm.IsEmpty())
removeString = removeString & "Speex";
if (g711Ogm.IsEmpty())
removeString = removeString & "711";
if (lpc10Ogm.IsEmpty())
removeString = removeString & "LPC-10";
if (ilbcOgm.IsEmpty())
removeString = removeString & "iLBC";
if (!g7231Ogm.IsEmpty())
SetCapability(0, 0, new G7231_File_Capability);
capabilities.Remove(args.GetOptionString('D').Lines());
if (!removeString.IsEmpty())
capabilities.Remove(removeString.Tokenise(' '));
capabilities.Reorder(args.GetOptionString('P').Lines());
cout << "Codecs (in preference order):\n" << setprecision(2) << capabilities << endl;
return TRUE;
}
///////////////////////////////////////////////////////////////
PCM_RecordFile::PCM_RecordFile(MyH323Connection & _conn, const PFilePath & _fn, unsigned _callLimit)
: conn(_conn), fn(_fn), callLimit(_callLimit)
{
recordStarted = FALSE;
timeLimitExceeded = FALSE;
closed = FALSE;
dataWritten = FALSE;
// If the file name ends in .wav then open the output as a WAV file.
// Otherwise open it as a raw file.
if ((_fn.Right(4)).ToLower() == ".wav")
fileclass = new PWAVFile(_fn, PFile::WriteOnly,
PFile::ModeDefault,PWAVFile::PCM_WavFile);
else
fileclass = new PFile(_fn, PFile::WriteOnly);
}
void PCM_RecordFile::StartRecording()
{
PWaitAndSignal mutex(pcmrecordMutex);
if (recordStarted)
return;
PTRACE(1, "Starting recording to " << fn);
PTime now;
recordStarted = TRUE;
finishTime = now + (callLimit * 1000);
}
BOOL PCM_RecordFile::Close()
{
PWaitAndSignal mutex(pcmrecordMutex);
closed = TRUE;
return fileclass->Close();
}
BOOL PCM_RecordFile::Write(const void * buf, PINDEX len)
{
// Wait for the mutex, and Signal it at the end of this function
PWaitAndSignal mutex(pcmrecordMutex);
// If the record file has been closed, or if the time limit has
// been exceeded, then return immediatly.
if (closed || timeLimitExceeded)
return FALSE;
if (!recordStarted) {
DelayFrame(len);
return TRUE;
}
PTime now;
if ((callLimit != 0) && (now >= finishTime)) {
PTRACE(1, "Terminating call due to timeout");
conn.ClearCall();
timeLimitExceeded = TRUE;
return TRUE;
}
DelayFrame(len);
dataWritten = TRUE;
return WriteFrame(buf, len);
}
BOOL PCM_RecordFile::WriteFrame(const void * buf, PINDEX len)
{
//cerr << "Writing PCM " << len << endl;
return fileclass->Write(buf, len);
}
void PCM_RecordFile::DelayFrame(PINDEX len)
{
delay.Delay(len/16);
}
PCM_RecordFile::~PCM_RecordFile()
{
PWaitAndSignal mutex(pcmrecordMutex);
if (!dataWritten) {
PTRACE(1, "Deleting " << fn << " as no data recorded");
fileclass->Remove(fn);
}
delete fileclass;
}
///////////////////////////////////////////////////////////////
// Override some of the PCM_RecordFile functions to write
// G723.1 data instead of PCM data.
G7231_RecordFile::G7231_RecordFile(MyH323Connection & _conn, const PFilePath & _fn, unsigned _callLimit)
: PCM_RecordFile(_conn, _fn, _callLimit)
{
// If the record file is a .wav file, we need to close the file
// that PCM_RecordFile will have opened, and reopen it as a G.723.1 Wav file.
if ((_fn.Right(4)).ToLower() == ".wav") {
fileclass->Remove(_fn);
delete fileclass;
fileclass = new PWAVFile(_fn, PFile::WriteOnly,
PFile::ModeDefault,PWAVFile::G7231_WavFile);
}
}
BOOL G7231_RecordFile::WriteFrame(const void * buf, PINDEX /*len*/)
{
int frameLen = G7231_File_Codec::GetFrameLen(*(BYTE *)buf);
// cerr << "Writing G7231 " << frameLen << endl;
return fileclass->Write(buf, frameLen);
}
void G7231_RecordFile::DelayFrame(PINDEX /*len*/)
{
// Ignore the len parameter as that is the compressed size.
// We must delay by the actual sample time.
delay.Delay((G7231_SAMPLES_PER_BLOCK*2)/16);
}
///////////////////////////////////////////////////////////////
static BOOL MatchString(const PString & str1, const PString str2)
{
if (str1.GetLength() != str2.GetLength())
return FALSE;
PINDEX len = str1.GetLength();
PINDEX i;
for (i = 0; i < len; i++)
if ((str1[i] != '?') && (str2[i] != '?') && (str1[i] != str2[i]))
return FALSE;
return TRUE;
}
static PINDEX FindMatch(const PStringList & list, const PString & key)
{
PINDEX maxKeyLen = 0;
PINDEX i;
PINDEX keyLen = key.GetLength();
PINDEX listLen = list.GetSize();
for (i = 0; i < listLen; i++)
maxKeyLen = PMAX(maxKeyLen, list[i].GetLength());
if (keyLen == 0 || maxKeyLen == 0)
return P_MAX_INDEX;
if (keyLen > maxKeyLen)
return P_MAX_INDEX;
PINDEX len = 1;
while (len <= keyLen) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -