📄 patch.cxx
字号:
/*
* patch.cxx
*
* Media stream patch thread.
*
* Open Phone Abstraction Library (OPAL)
* Formally known as the Open H323 project.
*
* Copyright (c) 2001 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 Open Phone Abstraction Library.
*
* The Initial Developer of the Original Code is Equivalence Pty. Ltd.
*
* Contributor(s): ______________________________________.
*
* $Log: patch.cxx,v $
* Revision 1.1 2006/06/26 03:03:23 joegenbaclor
* I have decided to include the latest development realease of OPAL tagged Deimos Devel 1 (June 8 2006) as inegrated classes to opensipstack to avoid future version conflicts due to the fast pace in OPAL development. This move is also aimed to reduce the size of projects using OPAL componets such as the soon to be relased OpenSIPPhone.
*
* Revision 2.25 2006/06/03 12:42:36 shorne
* Fix compile error on MSVC6
*
* Revision 2.24 2006/05/07 15:33:54 dsandras
* Reverted the last part of the patch.
*
* Revision 2.23 2006/05/07 14:03:04 dsandras
* Reverted patch 2.21 which could cause some deadlocks with H.323.
*
* Revision 2.22 2006/04/09 12:12:54 rjongbloed
* Changed the media format option merging to include the transcoder formats.
*
* Revision 2.21 2006/03/20 10:37:47 csoutheren
* Applied patch #1453753 - added locking on media stream manipulation
* Thanks to Dinis Rosario
*
* Revision 2.20 2006/02/02 07:02:58 csoutheren
* Added RTP payload map to transcoders and connections to allow remote SIP endpoints
* to change the payload type used for outgoing RTP.
*
* Revision 2.19 2005/12/30 14:33:12 dsandras
* Added support for Packet Loss Concealment frames for framed codecs supporting it similarly to what was done for OpenH323.
*
* Revision 2.18 2005/12/21 20:39:15 dsandras
* Prevent recursion when executing a command on a stream.
*
* Revision 2.17 2005/11/25 21:02:19 dsandras
* Remove the filters when closing the OpalMediaPatch.
*
* Revision 2.16 2005/10/20 20:28:18 dsandras
* Avoid the thread to keep the priority for a too long time.
*
* Revision 2.15 2005/09/06 12:44:49 rjongbloed
* Many fixes to finalise the video processing: merging remote media
*
* Revision 2.14 2005/09/04 06:23:39 rjongbloed
* Added OpalMediaCommand mechanism (via PNotifier) for media streams
* and media transcoders to send commands back to remote.
*
* Revision 2.13 2005/08/31 13:19:25 rjongbloed
* Added mechanism for controlling media (especially codecs) including
* changing the OpalMediaFormat option list (eg bit rate) and a completely
* new OpalMediaCommand abstraction for things like video fast update.
*
* Revision 2.12 2005/07/24 07:42:29 rjongbloed
* Fixed various video media stream issues.
*
* Revision 2.11 2004/08/16 09:53:48 rjongbloed
* Fixed possible deadlock in PTRACE output of media patch.
*
* Revision 2.10 2004/08/15 10:10:28 rjongbloed
* Fixed possible deadlock when closing media patch
*
* Revision 2.9 2004/08/14 07:56:43 rjongbloed
* Major revision to utilise the PSafeCollection classes for the connections and calls.
*
* Revision 2.8 2004/05/17 13:24:18 rjongbloed
* Added silence suppression.
*
* Revision 2.7 2004/04/25 02:53:29 rjongbloed
* Fixed GNU 3.4 warnings
*
* Revision 2.6 2004/02/15 04:34:08 rjongbloed
* Fixed correct setting of write data size on sick stream. Important for current
* output of silence frames and adjustment of sound card buffers.
* Fixed correct propagation of timestamp values from source to sink media
* stream and back from sink to source stream.
*
* Revision 2.5 2004/01/18 15:35:21 rjongbloed
* More work on video support
*
* Revision 2.4 2003/03/17 10:27:00 robertj
* Added video support.
*
* Revision 2.3 2002/03/07 02:25:52 craigs
* Patch threads now take notice of failed writes by removing the offending sink from the list
*
* Revision 2.2 2002/01/22 05:13:15 robertj
* Added filter functions to media patch.
*
* Revision 2.1 2002/01/14 02:19:03 robertj
* Added ability to turn jitter buffer off in media stream to allow for patches
* that do not require it.
*
* Revision 2.0 2001/07/27 15:48:25 robertj
* Conversion of OpenH323 to Open Phone Abstraction Library (OPAL)
*
*/
#include <ptlib.h>
#ifdef __GNUC__
#pragma implementation "patch.h"
#endif
#include <opal/patch.h>
#include <opal/mediastrm.h>
#include <opal/transcoders.h>
#define new PNEW
/////////////////////////////////////////////////////////////////////////////
OpalMediaPatch::OpalMediaPatch(OpalMediaStream & src)
: PThread(10000,
NoAutoDeleteThread,
HighestPriority,
"Media Patch:%x"),
source(src)
{
src.SetPatch(this);
}
OpalMediaPatch::~OpalMediaPatch()
{
PTRACE(3, "Patch\tMedia patch thread " << *this << " destroyed.");
}
void OpalMediaPatch::PrintOn(ostream & strm) const
{
strm << "Patch " << source;
// Have timed mutex so avoid deadlocks in PTRACE(), it is nice to
// get all the sinks in the PrintOn, we don't HAVE to have it.
if (inUse.Wait(20)) {
if (sinks.GetSize() > 0) {
strm << " -> ";
if (sinks.GetSize() == 1)
strm << *sinks[0].stream;
else {
for (PINDEX i = 0; i < sinks.GetSize(); i++) {
if (i > 0)
strm << ", ";
strm << "sink[" << i << "]=" << *sinks[i].stream;
}
}
}
inUse.Signal();
}
}
void OpalMediaPatch::Main()
{
PTRACE(3, "Patch\tThread started for " << *this);
PINDEX i;
inUse.Wait();
if (!source.IsSynchronous()) {
for (i = 0; i < sinks.GetSize(); i++) {
if (sinks[i].stream->IsSynchronous()) {
source.EnableJitterBuffer();
break;
}
}
}
inUse.Signal();
RTP_DataFrame sourceFrame(source.GetDataSize());
while (source.ReadPacket(sourceFrame)) {
inUse.Wait();
FilterFrame(sourceFrame, source.GetMediaFormat());
for (i = 0; i < sinks.GetSize(); i++)
sinks[i].WriteFrame(sourceFrame); // Got write error, remove from sink list
PINDEX len = sinks.GetSize();
inUse.Signal();
Sleep(5); // Permit to another thread to take the mutex
if (len == 0)
break;
}
PTRACE(3, "Patch\tThread ended for " << *this);
}
void OpalMediaPatch::Close()
{
PTRACE(3, "Patch\tClosing media patch " << *this);
filters.RemoveAll();
source.Close();
inUse.Wait();
// This relies on the channel close doing a RemoveSink() call
while (sinks.GetSize() > 0) {
OpalMediaStream * stream = sinks[0].stream;
inUse.Signal();
stream->Close();
inUse.Wait();
}
inUse.Signal();
PTRACE(3, "Patch\tWaiting for media patch thread to stop " << *this);
PAssert(WaitForTermination(10000), "Media patch thread not terminated.");
}
BOOL OpalMediaPatch::AddSink(OpalMediaStream * stream, const RTP_DataFrame::PayloadMapType & rtpMap)
{
if (PAssertNULL(stream) == NULL)
return FALSE;
PAssert(stream->IsSink(), "Attempt to set source stream as sink!");
PWaitAndSignal mutex(inUse);
Sink * sink = new Sink(*this, stream);
sinks.Append(sink);
stream->SetPatch(this);
// Find the media formats than can be used to get from source to sink
OpalMediaFormat sourceFormat = source.GetMediaFormat();
OpalMediaFormat destinationFormat = stream->GetMediaFormat();
#if PTRACING
ostream & traceStream = PTrace::Begin(4, __FILE__, __LINE__);
traceStream << "Patch\tAdded sink\n from " << sourceFormat << '\n';
for (PINDEX i = 0; i < sourceFormat.GetOptionCount(); i++) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -