📄 video.cxx
字号:
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);
}
////////////////////////////////////////////////////////////////////////////////////
BOOL VideoDelay::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
} else if (error <= -frameTime) {
PThread::Current()->Sleep(frameTime);
previousTime = PTime();
error = 0;
}
return error <= -frameTime;
}
BOOL Conference::DetectNoise(const void * buffer, PINDEX amount)
{
short *start = (short *)buffer;
short *end = start + (amount/2);
int sum;
sum=0;
while (start != end)
if(*start<0)
sum -= *start++;
else
sum += *start++;
return (sum/amount) > 50;
}
BOOL Conference::WriteVideo(const PString & thisToken,
const void * buffer,
PINDEX amount,
const PString & roomID)
{
PWaitAndSignal mutex(roomListMutex);
// Check that the room still exists
if (videoBufferDict.Contains(roomID) == FALSE) {
cout << "ROOM HAS BEEN REMOVED (WriteVideo)" << endl;
return FALSE;
}
VideoBuffer & videoBuffer = videoBufferDict[roomID];
if (singleStream) {
videoBuffer.WriteAll((BYTE *)buffer, amount);
}
else {
// The last four elements of spokenList indicate the last
// four connections from which audio was received.
PINDEX keyIndex = FindTokensVideoPosn(thisToken,roomID);
if (keyIndex != P_MAX_INDEX)
videoBuffer.Write((BYTE *)buffer, amount, keyIndex);
}
return TRUE;
}
BOOL MyH323EndPoint::ReadVideo(const PString & /*thisToken*/,
void * buffer,
PINDEX amount,
const PString & roomID)
{
PWaitAndSignal mutex(roomListMutex);
// Check that the room still exists
if (videoBufferDict.Contains(roomID) == FALSE) {
cout << "ROOM HAS BEEN REMOVED (ReadVideo)" << endl;
return FALSE;
}
VideoBuffer & videoBuffer = videoBufferDict[roomID];
videoBuffer.Read((BYTE *)buffer,amount);
return TRUE;
}
IncomingVideo::IncomingVideo(MyH323EndPoint & _ep, OpenMCUH323Connection & _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(H323EndPoint & _ep, OpenMCUH323Connection & _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;
}
#endif //NO_MCU_VIDEO
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -