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

📄 video.cxx

📁 openmcu 是开源的H.323会议服务器,需要pwlib 和 openh323的编译库文件支持。
💻 CXX
📖 第 1 页 / 共 2 页
字号:
/*
 * video.cxx
 *
 * Video 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: video.cxx,v $
 * Revision 2.2  2004/03/23 11:40:06  csoutheren
 * Fixed problem where deleting map element in-place causes crash at end of call
 * Fixed problem where referencing map by iterator rather than ID
 * Fixed code formatting problems
 *
 * 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
 *
 */


#include <ptlib.h>

#ifdef _WIN32
#pragma warning(disable:4786)
#endif

#include "main.h"

#ifndef NO_MCU_VIDEO


VideoBuffer::VideoBuffer()
  : xSize(176), ySize(144)
{
  buffer = NULL;
  SetSize( xSize, ySize );
}

VideoBuffer::~VideoBuffer()
{
  delete[] buffer;
}


void VideoBuffer::WriteAll(BYTE * data, PINDEX amount)
{
  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);

  ySecond = yFirst + (xSize < srcXSize ?
           xSize :
    	     xSize << 1);    // 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 == srcXSize ) {
    // just copy the whole buffer
    memcpy(buffer, data, amount);
  } else if ( xSize == 176 && srcXSize == 352 ) {
     // Copy 1 pixel out of 2
     int src_step   = 3 * srcXSize;
     int step       = xSize;
     int srcuv_step = (srcXSize >> 1);
     int uv_step    = 0;

     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;
     }
  } else {
     // Copy 2 pixels from 1
     int src_step   = srcXSize;
     int step       = 3 * xSize;
     int srcuv_step = 0;
     int uv_step    = (xSize >> 1);

     for(int i=0; i<srcYSize; i+=2) {
        for(int j=0; j<srcXSize; j++) {
           *yFirst = *srcYFirst;
           *(yFirst + xSize)  = *srcYFirst;
           yFirst++;
           *yFirst = *srcYFirst;
           *(yFirst + xSize)  = *(srcYFirst++);
           yFirst++;

           *ySecond = *srcYSecond;
           *(ySecond + xSize)  = *srcYSecond;
           ySecond++;
           *ySecond = *srcYSecond;
           *(ySecond + xSize)  = *(srcYSecond++);
           ySecond++;

           *u = *srcU;
           *(u + (xSize >> 1)) = *srcU;
           u++;
           if (j%2) srcU++;

           *v = *srcV;
           *(v + (xSize >> 1)) = *srcV;
           v++;
           if (j%2) srcV++;
        }
        srcYFirst  += src_step;
        srcYSecond += src_step;
        yFirst     += step;
        ySecond    += step;
        srcU += srcuv_step;
        srcV += srcuv_step;
        u    += uv_step;
        v    += uv_step;
     }
  }

  return;
}


//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 if ( xSize == 176 && srcXSize == 352 ) {
      // Copy 1 pixel out of 4
      int src_step   = 7 * srcXSize;
      int step       = xSize + (xSize >> 1);
      int srcuv_step = (srcXSize >> 1);
      int uv_step    = (xSize >> 2);

      for(int i=0; i<srcYSize; i+=8) {
         for(int j=0; j<srcXSize; j+=8) {
            *(yFirst++) = *srcYFirst;
            srcYFirst += 4;
            *(yFirst++) = *srcYFirst;
            srcYFirst += 4;
            *(ySecond++)= *srcYSecond;
            srcYSecond += 4;
            *(ySecond++) = *srcYSecond;
            srcYSecond += 4;
            *(u++) = *srcU;
            *(v++) = *srcV;
            srcU += 4;
            srcV += 4;
         }
         srcYFirst  += src_step;
         srcYSecond += src_step;
         yFirst     += step;
         ySecond    += step;
         srcU += srcuv_step;
         srcV += srcuv_step;
         u    += uv_step;
         v    += uv_step;
      }
   } else {
      // This code handles the other 2 cases in a generic fashion
      // Copy 1 pixel out of 2
      int src_step   = 3 * srcXSize;
      int step       = xSize + (xSize >> 1);
      int srcuv_step = (srcXSize >> 1);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -