📄 main.cxx
字号:
BOOL IncomingAudio::Write(const void * buffer, PINDEX amount)
{
PWaitAndSignal mutexW(audioChanMutex);
if (!IsOpen())
return FALSE;
if (!delay.Delay(amount / 16))
conn.OnIncomingAudio(buffer, amount);
return TRUE;
}
BOOL IncomingAudio::Close()
{
if (!IsOpen())
return FALSE;
PWaitAndSignal mutexA(audioChanMutex);
os_handle = -1;
return TRUE;
}
///////////////////////////////////////////////////////////////////////////
AudioBuffer::AudioBuffer()
: bufferSize(PCM_BUFFER_SIZE)
{
buffer = new BYTE[bufferSize];
bufferStart = bufferLen = 0;
}
AudioBuffer::~AudioBuffer()
{
delete[] buffer;
}
void AudioBuffer::Read(BYTE * data, PINDEX amount)
{
if (amount == 0)
return;
PWaitAndSignal mutex(audioBufferMutex);
if (bufferLen == 0) {
memset(data, 0, amount); // nothing in the buffer. return silence
return;
}
// fill output data block with silence if audiobuffer is
// almost empty.
if (amount > bufferLen)
memset(data + bufferLen, 0, amount - bufferLen);
// only copy up to the amount of data remaining
PINDEX copyLeft = PMIN(amount, bufferLen);
// if buffer is wrapping, get first part
if ((bufferStart + copyLeft) > bufferSize) {
PINDEX toCopy = bufferSize - bufferStart;
memcpy(data, buffer + bufferStart, toCopy);
data += toCopy;
bufferLen -= toCopy;
copyLeft -= toCopy;
bufferStart = 0;
}
// get the remainder of the buffer
if (copyLeft > 0) {
memcpy(data, buffer + bufferStart, copyLeft);
bufferLen -= copyLeft;
bufferStart = (bufferStart + copyLeft) % bufferSize;
}
}
void AudioBuffer::ReadAndMix(BYTE * data, PINDEX amount, PINDEX channels)
{
if (amount == 0)
return;
PWaitAndSignal mutex(audioBufferMutex);
if (bufferLen == 0) {
// nothing in the buffer to mix.
return;
}
// only mix up to the amount of data remaining
PINDEX copyLeft = PMIN(amount, bufferLen);
// if buffer is wrapping, get first part
if ((bufferStart + copyLeft) > bufferSize) {
PINDEX toCopy = bufferSize - bufferStart;
Mix(data, buffer + bufferStart, toCopy, channels);
data += toCopy;
bufferLen -= toCopy;
copyLeft -= toCopy;
bufferStart = 0;
}
// get the remainder of the buffer
if (copyLeft > 0) {
Mix(data, buffer + bufferStart, copyLeft, channels);
bufferLen -= copyLeft;
bufferStart = (bufferStart + copyLeft) % bufferSize;
}
}
void AudioBuffer::Mix(BYTE * dst, const BYTE * src, PINDEX count, PINDEX /*channels*/)
{
#if 0
memcpy(dst, src, count);
#else
PINDEX i;
for (i = 0; i < count; i += 2) {
int srcVal = *(short *)src;
int dstVal = *(short *)dst;
int newVal = dstVal;
#if 1 //The loudest person gains the channel.
#define mix_abs(x) ((x) >= 0 ? (x) : -(x))
if (mix_abs(newVal) > mix_abs(srcVal))
dstVal = newVal;
else
dstVal = srcVal;
#else //Just add up all the channels.
if ((newVal + srcVal) > 0x7fff)
dstVal = 0x7fff;
else
dstVal += srcVal;
#endif
*(short *)dst = (short)dstVal;
dst += 2;
src += 2;
}
#endif
}
void AudioBuffer::Write(const BYTE * data, PINDEX amount)
{
if (amount == 0)
return;
PWaitAndSignal mutex(audioBufferMutex);
// if there is not enough room for the new data, make room
PINDEX newLen = bufferLen + amount;
if (newLen > bufferSize) {
PINDEX toRemove = newLen - bufferSize;
bufferStart = (bufferStart + toRemove) % bufferSize;
bufferLen -= toRemove;
}
// copy data to the end of the new data, up to the end of the buffer
PINDEX copyStart = (bufferStart + bufferLen) % bufferSize;
if ((copyStart + amount) > bufferSize) {
PINDEX toCopy = bufferSize - copyStart;
memcpy(buffer + copyStart, data, toCopy);
copyStart = 0;
data += toCopy;
amount -= toCopy;
bufferLen += toCopy;
}
// copy the rest of the data
if (amount > 0) {
memcpy(buffer + copyStart, data, amount);
bufferLen += amount;
}
}
///////////////////////////////////////////////////////////////////////////
#ifndef NO_VIDEO
IncomingVideo::IncomingVideo(MyH323EndPoint & _ep, MyH323Connection & _conn)
: ep(_ep), conn(_conn), width(0), height(0), frameSize(0)
{
closed = FALSE;
}
IncomingVideo::~IncomingVideo()
{
IncomingVideo::Close();
PVideoChannel::Close();
}
BOOL IncomingVideo::Write(const void * buffer, PINDEX amount)
{
amount = (frameSize*3) >> 1; // frameSize==width*height
PWaitAndSignal mutex( videoChanMutex );
if (closed){
return FALSE;
}
conn.OnIncomingVideo(buffer, amount);
return TRUE;
}
void IncomingVideo::SetRenderFrameSize(int _width, int _height)
{
PTRACE(3,"IncomingVideo Set size");
width = _width;
height = _height;
frameSize = width * height;
}
BOOL IncomingVideo::Close()
{
PWaitAndSignal mutex(videoChanMutex);
closed = TRUE;
return TRUE;
}
///////////////////////////////////////////////////////////////////////////
OutgoingVideo::OutgoingVideo(MyH323EndPoint & _ep, MyH323Connection & _conn, int framesPerSec, BOOL _videoLarge)
: ep(_ep), conn(_conn), videoLarge(_videoLarge)
{
closed = FALSE;
if ( ( framesPerSec>0 ) && ( framesPerSec < 31 ) ) {
msBetweenFrames= 1000/framesPerSec;
} else {
cerr << "Invalid video transmit frame rate. Frame rate should be between 1 and 30 frames per second"<<endl;
msBetweenFrames = 100;
}
}
OutgoingVideo::~OutgoingVideo()
{
OutgoingVideo::Close();
}
BOOL OutgoingVideo::Read(void *buffer, PINDEX amount)
{
PWaitAndSignal mutex1(videoChanMutex);
amount = (( videoLarge ? 352*288*3 : 176*144*3 ) >> 1);
if (!delay.Delay(msBetweenFrames))
conn.OnOutgoingVideo(buffer, amount);
return TRUE;
}
BOOL OutgoingVideo::Close()
{
// PWaitAndSignal mutex(videoChanMutex);
closed = TRUE;
return TRUE;
}
///////////////////////////////////////////////////////////////////////////
VideoBuffer::VideoBuffer()
: xSize(176), ySize(144)
{
buffer = NULL;
SetSize( xSize, ySize );
}
VideoBuffer::~VideoBuffer()
{
delete[] buffer;
}
//Writes data into the specified posn of the buffer.
//0 == top left, 1 == top right
//2 == bot left, 3 == bot right
void VideoBuffer::Write(BYTE * data, PINDEX amount, PINDEX posn)
{
// It appears that a full frame is always written.
// We can determine the size of the frame by how much
// is written.
if (amount == 0)
return;
PWaitAndSignal mutex(videoBufferMutex);
BYTE *yFirst, *ySecond, *u, *v, *srcYFirst, *srcYSecond, *srcU, *srcV;
int srcFrameSize = (amount<<1)/3;
int srcXSize = (srcFrameSize == (176 * 144) ? 176 : 352 );
int srcYSize = (srcFrameSize == (176 * 144) ? 144 : 288 );
yFirst = buffer;
u= buffer + bufferFrameSize;
v= buffer + bufferFrameSize + (bufferFrameSize >> 2);
srcYFirst = data;
srcYSecond = srcYFirst + (xSize == srcXSize ?
srcXSize << 1 :
srcXSize);
srcU = data + srcFrameSize;
srcV = data + srcFrameSize + (srcFrameSize >> 2);
switch (posn) {
case 0:
break;
case 1:
yFirst +=(xSize >> 1);
u +=(xSize >> 2);
v +=(xSize >> 2);
break;
case 2:
yFirst += (bufferFrameSize >> 1);
u += (bufferFrameSize >> 3);
v += (bufferFrameSize >> 3);
break;
case 3:
yFirst += (bufferFrameSize >> 1) + (xSize >> 1);
u += (bufferFrameSize >> 3) + (xSize >> 2);
v += (bufferFrameSize >> 3) + (xSize >> 2);
break;
default:
return;
}
ySecond = yFirst + xSize; // added down here so that any changes to
// yFirst are taken into account - pez
// Special case, can fit 'in' images perfectly inside 'out' images
if ( xSize == 352 && srcXSize == 176 ) {
for(int i=0; i < 144; i+=2) {
memcpy(yFirst, srcYFirst, 176);
memcpy(ySecond, srcYSecond, 176);
memcpy(u, srcU, 88 );
memcpy(v, srcV, 88 );
srcYFirst += 352;
srcYSecond += 352;
yFirst += 704;
ySecond += 704;
srcU += 88;
srcV += 88;
u += 176;
v += 176;
}
} else {
// This code handles the other 2 cases in a generic fashion
int src_step = 3 * srcXSize;
int step = xSize + (xSize >> 1);
int srcuv_step = (srcXSize >> 1);
int uv_step = (xSize >> 2);
for(int i=0; i<srcYSize; i+=4) {
for(int j=0; j<srcXSize; j+=4) {
*yFirst++ = *srcYFirst;
srcYFirst += 2;
*yFirst++ = *srcYFirst;
srcYFirst += 2;
*ySecond++ = *srcYSecond;
srcYSecond += 2;
*ySecond++ = *srcYSecond;
srcYSecond += 2;
*u++ = *srcU;
*v++ = *srcV;
srcU+= 2;
srcV+= 2;
}
srcYFirst += src_step;
srcYSecond += src_step;
yFirst += step;
ySecond += step;
srcU += srcuv_step;
srcV += srcuv_step;
u += uv_step;
v += uv_step;
}
}
return;
}
void VideoBuffer::Clear(PINDEX posn)
{
PWaitAndSignal mutex(videoBufferMutex);
BYTE *yFirst, *ySecond, *u, *v;
yFirst = buffer;
u= buffer + bufferFrameSize;
v= buffer + bufferFrameSize + (bufferFrameSize/4);
switch (posn) {
case 0:
break;
case 1:
yFirst += (xSize >> 1);
u += (xSize >> 2);
v += (xSize >> 2);
break;
case 2:
yFirst += (bufferFrameSize >> 1);
u += (bufferFrameSize >> 3);
v += (bufferFrameSize >> 3);
break;
case 3:
yFirst += (bufferFrameSize >>1) + (xSize >> 1);
u += (bufferFrameSize >> 3) + (xSize >> 2);
v += (bufferFrameSize >> 3) + (xSize >> 2);
break;
default:
return;
}
ySecond = yFirst + xSize;
for(int y=0; y < (ySize>>1); y+=2) {
memset(yFirst, 0x80, xSize >> 1); // Mid Grey
memset(ySecond, 0x80, xSize >> 1); // Mid Grey
memset(u, 0x80, xSize >> 2);
memset(v, 0x80, xSize >> 2);
yFirst += xSize * 2;
ySecond += xSize * 2;
u += (xSize >> 1);
v += (xSize >> 1);
}
return;
}
void VideoBuffer::SetSize(int x, int y)
{
PWaitAndSignal mutex(videoBufferMutex);
if ( buffer != NULL )
delete[] buffer;
xSize = x;
ySize = y;
bufferFrameSize = xSize * ySize;
videoBufferSize = bufferFrameSize
+ (bufferFrameSize >> 2 )
+ (bufferFrameSize >> 2); // Y + U + V;
buffer = new BYTE[ videoBufferSize ];
memset( buffer, 0x80, videoBufferSize); // Set Y, U and V to 0x80 - Mid Grey.
}
void VideoBuffer::Read(BYTE * data, PINDEX amount)
{
if (amount == 0)
return;
PWaitAndSignal mutex(videoBufferMutex);
memcpy(data,buffer,amount);
}
#endif //NO_VIDEO
///////////////////////////////////////////////////////////////////////////
#define MIN_HEADROOM 30
#define MAX_HEADROOM 60
AudioDelay::AudioDelay()
{
firstTime = TRUE;
error = 0;
}
void AudioDelay::Restart()
{
firstTime = TRUE;
}
BOOL AudioDelay::Delay(int frameTime)
{
if (firstTime) {
firstTime = FALSE;
previousTime = PTime();
return TRUE;
}
error += frameTime;
PTime now;
PTimeInterval delay = now - previousTime;
error -= (int)delay.GetMilliSeconds();
previousTime = now;
if (error > 0)
#ifdef P_LINUX
usleep(error * 1000);
#else
PThread::Current()->Sleep(error);
#endif
return error <= -frameTime;
//if (headRoom > MAX_HEADROOM)
// PThread::Current()->Sleep(headRoom - MIN_HEADROOM);
}
// End of File ///////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -