/*
* conference.h
*
* Conferencing functions for a simple MCU
*
* Copyright (c) 2000 Equivalence Pty. Ltd.
* Copyright (c) 2004 Post Increment
*
* 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 of this code were written by Post Increment (http://www.postincrement.com)
* with the assistance of funding from Citron Networks (http://www.citron.com.tw)
*
* Portions are Copyright (C) 1993 Free Software Foundation, Inc.
* All Rights Reserved.
*
* Contributor(s): Derek J Smithies (derek@indranet.co.nz)
* ------------------------------
*
* $Log: conference.h,v $
* Revision 2.5 2005/06/21 12:45:21 rjongbloed
* Disabled video so will compile - for now.
*
* Revision 2.4 2005/03/11 00:25:24 csoutheren
* Fixed problems with flags
*
* Revision 2.3 2004/05/26 06:54:31 csoutheren
* Changed to be a PHTTPServiceProcess
* Added ability to play WAV files on member entry and exit
* Added additional documentation on all classes
* Preparation for re-introducing video
*
* Revision 2.2 2004/03/31 03:36:38 csoutheren
* Fixed problem with user indication messages
* Fixed problems with room listener and unlisten
*
* Revision 2.1 2004/03/11 20:49:44 csoutheren
* Removed warnings
*
* Revision 2.0 2004/03/08 02:06:24 csoutheren
* Totally rewritten to use new connection locking mecahnism
* Added ability to monitor conferences
* Added initial support for H.323 MCU messages
* Thanks to Citron Networks for supporting this work
*
*/
#ifndef _OpenMCU_CONFERENCE_H
#define _OpenMCU_CONFERENCE_H
#ifdef _WIN32
#pragma warning(disable:4786)
#pragma warning(disable:4100)
#endif
#include <set>
#include <map>
#include <h323.h>
#include <h323pdu.h>
class OpenMCUH323Connection;
#define NO_MCU_VIDEO
////////////////////////////////////////////////////
#ifndef NO_MCU_VIDEO
class VideoBuffer : public PObject
{
PCLASSINFO(VideoBuffer, PObject);
public:
VideoBuffer();
~VideoBuffer();
void WriteAll( BYTE * ptr, PINDEX amount); //For single stream option
void Write( BYTE * ptr, PINDEX amount, PINDEX posn);
void Read(BYTE * ptr, PINDEX amount);
void Clear(PINDEX posn); //Reset the buffer at the specified position
void SetSize(int x, int y); // Set the vidbuffer size
protected:
BYTE * buffer;
PINDEX videoBufferSize; ///Total number of bytes in buffer. Never gets changed.
PMutex videoBufferMutex;
int bufferFrameSize;
int xSize, ySize;
};
typedef map<PString, VideoBuffer *> VideoBufferDict;
#endif
////////////////////////////////////////////////////
class AudioDelay : public PObject
{
PCLASSINFO(AudioDelay, PObject);
public:
AudioDelay();
virtual BOOL Delay(int time);
virtual void Restart();
protected:
PTime previousTime;
BOOL firstTime;
int error;
};
class VideoDelay : public AudioDelay
{
PCLASSINFO(VideoDelay, AudioDelay);
public:
BOOL Delay(int time);
};
////////////////////////////////////////////////////
class MCULock : public PObject
{
PCLASSINFO(MCULock, PObject);
public:
MCULock();
BOOL Wait(BOOL hard = FALSE);
void Signal(BOOL hard = FALSE);
void WaitForClose();
protected:
PMutex mutex;
BOOL closing;
int count;
PSyncPoint closeSync;
};
////////////////////////////////////////////////////
class Conference;
/**
* this class describes a connection between a conference member and a conference
* each conference member has one instance of class for every other member of the conference
*/
class ConferenceConnection : public PObject {
PCLASSINFO(ConferenceConnection, PObject);
public:
ConferenceConnection(void * _id);
~ConferenceConnection();
void * GetID() const
{ return id; }
#ifdef _WIN32
#pragma warning(push)
#pragma warning(disable:4311)
#endif
virtual PString GetName() const
{ return PString(PString::Unsigned, (unsigned)id); }
#ifdef _WIN32
#pragma warning(pop)
#endif
virtual void OnUserInputIndication(const PString &)
{ }
void WriteAudio(void * source, const void * buffer, PINDEX amount);
void Write(const BYTE * ptr, PINDEX amount);
void ReadAudio(BYTE * ptr, PINDEX amount);
void ReadAndMixAudio(BYTE * ptr, PINDEX amount, PINDEX channels);
protected:
Conference * conference;
void * id;
void Mix(BYTE * dst, const BYTE * src, PINDEX count, PINDEX channels);
BYTE * buffer;
PINDEX bufferLen; ///Number of bytes unread in the buffer.
PINDEX bufferStart; ///Current position in the buffer.
PINDEX bufferSize; ///Total number of bytes in buffer. Never gets changed.
PMutex audioBufferMutex;
#ifndef NO_MCU_VIDEO
BOOL hasVideo;
IncomingVideo * incomingVideo;
OutgoingVideo * outgoingVideo;
#endif
};
////////////////////////////////////////////////////
/**
* this class describes a member of a conference
*/
class ConferenceManager;
class ConferenceMember : public PObject
{
PCLASSINFO(ConferenceMember, PObject);
public:
/**
* create a new conference member. The single parameter is an "id" (usually a pointer)
* that can used to identify this member unambiguously
*/
ConferenceMember(void * id);
/**
* used to add a conference member to a conference. This is not done in the constructor
* as some conference members have non-trivial startup requirements
*/
virtual BOOL AddToConference(Conference * conference);
/**
* used to remove a conference member from a conference. This is not done in the destructor
* as some conference members have non-trivial shutdown requirements
*/
virtual void RemoveFromConference();
/**
* If this returns TRUE, the conference member will be visible in all publically displayed
* conference lists. It will always be visible in the console displays
*/
virtual BOOL Visible() const
{ return TRUE; }
/**
* return the conference member ID
*/
void * GetID() const
{ return id; }
#ifdef _WIN32
#pragma warning(push)
#pragma warning(disable:4311)
#endif
/**
* return the name of the the conference member
*/
virtual PString GetName() const
{ return PString(PString::Unsigned, (unsigned)id); }
#ifdef _WIN32
#pragma warning(pop)
#endif
/**
* return the conference this member belongs to
*/
Conference * GetConference()
{ return conference; }
/**
* add a new connection for the specified member to this member to the internal list of connections
*/
virtual void AddConnection(ConferenceMember * newMember);
/**
* remove any connections belong to the specified ID from the internal list of connections
*/
virtual void RemoveConnection(void * id);
/**
* This is called when the conference member want to send a user input indication to the the conference.
* By default, this routines calls OnReceivedUserInputIndication for all of the other conference members
*/
virtual void SendUserInputIndication(const PString & str);
/**
* this virtual function is called when the conference sends a user input indication to the endpoint
* the conference
*/
virtual void OnReceivedUserInputIndication(const PString & str)
{ }
/**
* Called when the conference member want to send audio data to the cofnerence
*/
virtual void WriteAudio(const void * buffer, PINDEX amount);
/**
* Called when the conference member wants to read a block of audio from the conference
*/
virtual void ReadAudio(void * buffer, PINDEX amount);
/**
* Called when another conference member wants to send audio to the endpoint
* By default, the audio is added to the queue for the specified member
* so it can be retreived by a later call to OnIncomingAudio
*/
virtual void OnExternalAudio(void * id, const void * buffer, PINDEX amount);
/*
* Used to create a conference connection for this member
*/
virtual ConferenceConnection * CreateConnection() = 0;
void WaitForClose()
{ lock.WaitForClose(); }
protected:
typedef std::map<void *, ConferenceConnection *> ConnectionList;
typedef std::map<void *, ConferenceMember *> MemberList;
Conference * conference;
void * id;
MCULock lock;
ConnectionList connectionList;
MemberList memberList;
};
////////////////////////////////////////////////////
/**
* this class describes a conference or "room"
*/
class Conference : public PObject
{
PCLASSINFO(Conference, PObject);
public:
typedef std::map<void *, ConferenceMember *> MemberList;
Conference(ConferenceManager & manager,
const OpalGloballyUniqueID & _guid,
const PString & _number,
const PString & _name);
~Conference();
PMutex & GetMutex()
{ return memberListMutex; }
ConferenceManager & GetManager()
{ return manager; }
/**
* add the specified member to the conference
*/
void AddMember(ConferenceMember * member);
/**
* remove the specifed member from the conference.
* Note that this function does not actually delete the conference member
* as sometimes a conference member needs to remove itself from a conference
*
* @return if TRUE, the conference is now empty
*/
BOOL RemoveMember(ConferenceMember * member);
MemberList & GetMemberList()
{ return memberList; }
virtual PString GetName() const
{ return name; }
virtual PString GetNumber() const
{ return number; }
OpalGloballyUniqueID GetID() const
{ return guid; }
virtual BOOL IsVisible() const
{ return TRUE; }
virtual void OnMemberJoining(ConferenceMember *);
virtual void OnMemberLeaving(ConferenceMember *);
protected:
ConferenceManager & manager;
PMutex memberListMutex;
MemberList memberList;
OpalGloballyUniqueID guid;
PString number;
PString name;
};
////////////////////////////////////////////////////
typedef std::map<OpalGloballyUniqueID, Conference *> ConferenceList;
class ConferenceManager : public PObject
{
PCLASSINFO(ConferenceManager, PObject);
public:
ConferenceManager();
/**
* Make a new conference with the specified conference ID, number and name
*/
Conference * MakeConference(
const OpalGloballyUniqueID & conferenceID,
const PString & number,
const PString & name
);
/**
* Make a new conference with the specified number and name, and use a new conference ID
*/
Conference * MakeConference(
const PString & number,
const PString & name
);
/**
* return true if a conference with the specified ID exists
*/
BOOL HasConference(
const OpalGloballyUniqueID & conferenceID
);
/**
* return true if a conference with the specified number exists
*/
BOOL HasConference(
const PString & number
);
/**
* Remove and delete the specified conference
*/
void RemoveConference(const OpalGloballyUniqueID & confId);
/**
* Remove the specified member from the specified conference.
* The member will will deleted, and if the conference is empty after the removal,
* it is deleted too
*/
void RemoveMember(const OpalGloballyUniqueID & confId, ConferenceMember * toRemove);
PMutex & GetConferenceListMutex()
{ return conferenceListMutex; }
ConferenceList & GetConferenceList()
{ return conferenceList; }
virtual void OnCreateConference(Conference *)
{ }
virtual void OnDestroyConference(Conference *)
{ }
virtual void OnMemberJoining(Conference *, ConferenceMember *)
{ }
virtual void OnMemberLeaving(Conference *, ConferenceMember *)
{ }
protected:
virtual Conference * CreateConference(const OpalGloballyUniqueID & _guid,
const PString & _number,
const PString & _name);
PMutex conferenceListMutex;
ConferenceList conferenceList;
};
#ifndef NO_MCU_VIDEO
////////////////////////////////////////////////////
/** OutGoingVideo describes the data leaving the computer,
and then sent by TCP/IP methods to the remote computer.
OutGoingVideo is the connection/channel which connects the
codec and the connection class, for the transport of data.
*/
class OutgoingVideo : public PVideoChannel
{
PCLASSINFO(OutgoingVideo, PVideoChannel);
public:
OutgoingVideo(H323EndPoint & ep, OpenMCUH323Connection & conn, int framesPerSec, BOOL videoLarge);
~OutgoingVideo();
BOOL Close();
/** uses over ride of Read function in the PChannel class.
*/
BOOL Read(void * buffer, PINDEX amount);
void SetRenderFrameSize(int /*_width*/, int /*_height*/)
{PTRACE(3,"OutgoingVideo Set size");}
BOOL Redraw(const BYTE * /*frame*/)
{ return TRUE; }
BOOL IsOpen() const
{ return !closed; }
BOOL IsGrabberOpen()
{ return TRUE; }
PINDEX GetGrabWidth()
{ return (videoLarge ? 352 : 176); }
/**Return the height of the currently selected grabbing device.
*/
PINDEX GetGrabHeight()
{ return (videoLarge ? 288 : 144 ); }
protected:
H323EndPoint & ep;
OpenMCUH323Connection & conn;
PMutex videoChanMutex;
BOOL videoLarge;
VideoDelay delay;
int msBetweenFrames;
BOOL closed;
};
////////////////////////////////////////////////////
/** IncomingVideo describes the data entering the computer,
which is placed in the video buffer.
*/
class IncomingVideo : public PVideoChannel
{
PCLASSINFO(IncomingVideo, PVideoChannel);
public:
IncomingVideo(MyH323EndPoint & ep, OpenMCUH323Connection & conn);
~IncomingVideo();
BOOL Write(const void * buffer, PINDEX amount);
BOOL Close();
void SetRenderFrameSize(int _width, int _height);
BOOL Redraw(const BYTE * frame)
{ return Write(frame,0); }
BOOL IsOpen() const
{ return !closed; }
PINDEX GetGrabWidth()
{ PTRACE(3,"incomingvideo get grab width"); return width; }
/**Return the height of the currently selected grabbing device.
*/
PINDEX GetGrabHeight()
{ return height; }
protected:
MyH323EndPoint & ep;
OpenMCUH323Connection & conn;
PMutex videoChanMutex;
PINDEX width;
PINDEX height;
PINDEX frameSize;
VideoDelay delay;
BOOL closed;
};
#endif
#endif
syntax highlighted by Code2HTML, v. 0.9.1