⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 video.cxx

📁 openmcu 是开源的H.323会议服务器,需要pwlib 和 openh323的编译库文件支持。
💻 CXX
📖 第 1 页 / 共 2 页
字号:
      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 + -