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

📄 vconvert.cxx

📁 opal的ptlib c++源程序 可以从官方网站上下载
💻 CXX
📖 第 1 页 / 共 5 页
字号:
/*
 * vconvert.cxx
 *
 * Classes to support streaming video input (grabbing) and output.
 *
 * Portable Windows Library
 *
 * Copyright (c) 1993-2000 Equivalence Pty. Ltd.
 *
 * 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.
 *
 * Contributor(s): Derek Smithies (derek@indranet.co.nz)
 *   Thorsten Westheider (thorsten.westheider@teleos-web.de)
 *   Mark Cooke (mpc@star.sr.bham.ac.uk)
 *
 * $Revision: 19008 $
 * $Author: rjongbloed $
 * $Date: 2007-11-29 09:17:41 +0000 (Thu, 29 Nov 2007) $
 */

#include <ptlib.h>

#if P_VIDEO

#include <ptlib/video.h>

#ifdef __GNUC__
#pragma implementation "vconvert.h"
#endif

#include <ptlib/vconvert.h>

#if  defined(__GNUC__) || defined(__sun) 
#include "tinyjpeg.h"
#endif


#ifdef _MSC_VER
#pragma warning(disable : 4244)
#endif


#ifdef P_MEDIALIB
#include <mlib.h>
#endif

static PColourConverterRegistration * RegisteredColourConvertersListHead = NULL;

PSYNONYM_COLOUR_CONVERTER(SBGGR8, SBGGR8);
PSYNONYM_COLOUR_CONVERTER(Grey,   Grey);
PSYNONYM_COLOUR_CONVERTER(RGB24,  RGB24);
PSYNONYM_COLOUR_CONVERTER(BGR24,  BGR24);
PSYNONYM_COLOUR_CONVERTER(RGB32,  RGB32);
PSYNONYM_COLOUR_CONVERTER(BGR32,  BGR32);
PSYNONYM_COLOUR_CONVERTER(UYVY422,UYVY422);
PSYNONYM_COLOUR_CONVERTER(YUV411P,YUV411P);
PSYNONYM_COLOUR_CONVERTER(YUV420P,IYUV);
PSYNONYM_COLOUR_CONVERTER(IYUV,   YUV420P);
PSYNONYM_COLOUR_CONVERTER(YUV420P,I420);
PSYNONYM_COLOUR_CONVERTER(I420,   YUV420P);


class PStandardColourConverter : public PColourConverter
{
  PCLASSINFO(PStandardColourConverter, PColourConverter);

  protected:
    PStandardColourConverter(
      const PVideoFrameInfo & src,
      const PVideoFrameInfo & dst
    ) : PColourConverter(src, dst) { }

    PBoolean SBGGR8toYUV420P(
     const BYTE * srgb,
      BYTE * rgb,
      PINDEX * bytesReturned
    ) const;
    PBoolean SBGGR8toRGB(
      const BYTE * srgb,
      BYTE * rgb,
      PINDEX * bytesReturned
    ) const;
    void GreytoYUV420PSameSize(
      const BYTE * rgb,
      BYTE * yuv
    ) const;
    void GreytoYUV420PWithResize(
      const BYTE * rgb,
      BYTE * yuv
    ) const;
    PBoolean GreytoYUV420P(
      const BYTE * rgb,
      BYTE * yuv,
      PINDEX * bytesReturned
    ) const;
    void RGBtoYUV420PSameSize(
      const BYTE * rgb,
      BYTE * yuv,
      unsigned rgbIncrement,
      unsigned redOffset,
      unsigned blueOffset
    ) const;
    void RGBtoYUV420PWithResize(
      const BYTE * rgb,
      BYTE * yuv,
      unsigned rgbIncrement,
      unsigned redOffset,
      unsigned blueOffset
    ) const;
    PBoolean RGBtoYUV420P(
      const BYTE * rgb,
      BYTE * yuv,
      PINDEX * bytesReturned,
      unsigned rgbIncrement,
      unsigned redOffset,
      unsigned blueOffset
    ) const;
    PBoolean YUV420PtoRGB(
      const BYTE * yuv,
      BYTE * rgb,
      PINDEX * bytesReturned,
      unsigned rgbIncrement,
      unsigned redOffset,
      unsigned blueOffset
    ) const;
    PBoolean SwapRedAndBlue(
      const BYTE * src,
      BYTE * dst,
      PINDEX * bytesReturned,
      unsigned srcIncrement,
      unsigned dstIncrement
    ) const;
    void ResizeUYVY422(
      const BYTE *src_uyvy,
      BYTE *dst_uyvy
    ) const;
    void ResizeYUV422(
      const BYTE * src,
      BYTE * dest
    ) const;
    void ResizeYUV420P(
      const BYTE * src,
      BYTE * dest
    ) const;
    void UYVY422toYUV420PSameSize(
      const BYTE *uyvy,
      BYTE *yuv420p
    ) const;
    void UYVY422toYUV420PWithResize(
      const BYTE *uyvy,
      BYTE *yuv420p
    ) const;
    void YUY2toYUV420PSameSize(
      const BYTE *yuy2,
      BYTE *yuv420p
    ) const;
    void YUY2toYUV420PWithResize(
      const BYTE *yuy2,
      BYTE *yuv420p
    ) const;
    bool MJPEGtoYUV420PSameSize(
      const BYTE *yuy2,
      BYTE *yuv420p
    );
#if defined (__GNUC__) || defined (__sun)
    bool MJPEGtoXXX(
      const BYTE *mjpeg,
	    BYTE *output_data,
	    PINDEX *bytesReturned,
	    int format
    );
    bool MJPEGtoYUV420P(
      const BYTE *mjpeg,
      BYTE *yuv420p,
      PINDEX *bytesReturned
    );
    bool MJPEGtoXXXSameSize(
      const BYTE *yuy2,
      BYTE *rgb,
      int format
    );
#endif
};


#define PSTANDARD_COLOUR_CONVERTER(from,to) \
  PCOLOUR_CONVERTER2(P_##from##_##to,PStandardColourConverter,#from,#to)


#define new PNEW


///////////////////////////////////////////////////////////////////////////////
// PColourConverter

PColourConverterRegistration::PColourConverterRegistration(const PString & srcColourFormat,
                                                           const PString & destColourFormat)
  : PCaselessString(srcColourFormat+'\t'+destColourFormat)
{
  PColourConverterRegistration * test = RegisteredColourConvertersListHead;
  while (test != NULL) {
    if (*test == *this)
      return;
    test = test->link;
  }

  link = RegisteredColourConvertersListHead;
  RegisteredColourConvertersListHead = this;
}


PColourConverter * PColourConverter::Create(const PVideoFrameInfo & src,
                                            const PVideoFrameInfo & dst)
{
  PString converterName = src.GetColourFormat() + '\t' + dst.GetColourFormat();

  PColourConverterRegistration * find = RegisteredColourConvertersListHead;
  while (find != NULL) {
    if (*find == converterName) {
      return find->Create(src, dst);
    }
    find = find->link;
  }

  PTRACE(2,"PColCnv\tCreate error. Did not find " << src.GetColourFormat() << "->" << dst.GetColourFormat());
  return NULL;
}

PColourConverter * PColourConverter::Create(const PString & srcColourFormat,
                                            const PString & destColourFormat,
                                            unsigned width,
                                            unsigned height)
{
  PVideoFrameInfo src;
  src.SetColourFormat(srcColourFormat);
  src.SetFrameSize(width, height);

  PVideoFrameInfo dst;
  dst.SetColourFormat(destColourFormat);

  return Create(src, dst);
}


PColourConverter::PColourConverter(
      const PString & _srcColourFormat,  ///< Name of source colour format
      const PString & _dstColourFormat,  ///< Name of destination colour format
      unsigned width,   ///< Width of frame
      unsigned height   ///< Height of frame
)
  : verticalFlip(PFalse)
#ifndef P_MACOSX
  , jdec(NULL)
#endif
{
  PVideoFrameInfo src;
  src.SetColourFormat(_srcColourFormat);
  src.SetFrameSize(width, height);

  PVideoFrameInfo dst;
  dst.SetColourFormat(_dstColourFormat);

  srcColourFormat = src.GetColourFormat();
  dstColourFormat = dst.GetColourFormat();
  resizeMode = dst.GetResizeMode();

  src.GetFrameSize(srcFrameWidth, srcFrameHeight);
  srcFrameBytes = src.CalculateFrameBytes();
  dst.GetFrameSize(dstFrameWidth, dstFrameHeight);
  dstFrameBytes = dst.CalculateFrameBytes();
  PTRACE(6,"PColCnv\tPColourConverter constructed: " << srcColourFormat << ' ' << srcFrameWidth << 'x'<< srcFrameHeight
                                           << " -> " << dstColourFormat << ' ' << dstFrameWidth << 'x'<< dstFrameHeight);
}

PColourConverter::PColourConverter(const PVideoFrameInfo & src,
                                   const PVideoFrameInfo & dst)
  : srcColourFormat(src.GetColourFormat())
  , dstColourFormat(dst.GetColourFormat())
  , resizeMode(dst.GetResizeMode())
  , verticalFlip(PFalse)
#ifndef P_MACOSX
  , jdec(NULL)
#endif
{
  src.GetFrameSize(srcFrameWidth, srcFrameHeight);
  srcFrameBytes = src.CalculateFrameBytes();
  dst.GetFrameSize(dstFrameWidth, dstFrameHeight);
  dstFrameBytes = dst.CalculateFrameBytes();
  PTRACE(6,"PColCnv\tPColourConverter constructed: " << srcColourFormat << ' ' << srcFrameWidth << 'x'<< srcFrameHeight
                                           << " -> " << dstColourFormat << ' ' << dstFrameWidth << 'x'<< dstFrameHeight);
}


PBoolean PColourConverter::SetFrameSize(unsigned width, unsigned height)
{
  PBoolean ok1 = SetSrcFrameSize(width, height);
  PBoolean ok2 = SetDstFrameSize(width, height);
  PTRACE(2,"PColCnv\tSetFrameSize: " << width << 'x' << height
         << (ok1 && ok2 ? " OK" : " Failed"));
  return ok1 && ok2;
}


PBoolean PColourConverter::SetSrcFrameInfo(const PVideoFrameInfo & info)
{
  if (info.GetColourFormat() != GetSrcColourFormat())
    return PFalse;

  unsigned w, h;
  return info.GetFrameSize(w, h) && SetSrcFrameSize(w, h);
}


PBoolean PColourConverter::SetDstFrameInfo(const PVideoFrameInfo & info)
{
  if (info.GetColourFormat() != GetDstColourFormat())
    return PFalse;

  SetResizeMode(info.GetResizeMode());

  unsigned w, h;
  return info.GetFrameSize(w, h) && SetDstFrameSize(w, h);
}


void PColourConverter::GetSrcFrameInfo(PVideoFrameInfo & info)
{
  info.SetColourFormat(GetSrcColourFormat());
  info.SetFrameSize(srcFrameWidth, srcFrameHeight);
}


void PColourConverter::GetDstFrameInfo(PVideoFrameInfo & info)
{
  info.SetColourFormat(GetDstColourFormat());
  info.SetFrameSize(dstFrameWidth, dstFrameHeight);
}


PBoolean PColourConverter::SetSrcFrameSize(unsigned width, unsigned height)
{
  if (srcFrameWidth == width && srcFrameHeight == height)
    return PTrue;

  srcFrameWidth = width;
  srcFrameHeight = height;
  srcFrameBytes = PVideoDevice::CalculateFrameBytes(srcFrameWidth, srcFrameHeight, srcColourFormat);
  PTRACE(srcFrameBytes != 0 ? 6 : 2, "PColCnv\tSetSrcFrameSize "
         << ((srcFrameBytes != 0) ? "Succeed": "Fail") << "ed, "
         << srcColourFormat << ' ' << srcFrameWidth << 'x' << srcFrameHeight
         << ", " << srcFrameBytes << " bytes.");

  return srcFrameBytes != 0;
}


PBoolean PColourConverter::SetDstFrameSize(unsigned width, unsigned height)
{
  dstFrameWidth  = width;
  dstFrameHeight = height;

  dstFrameBytes = PVideoDevice::CalculateFrameBytes(dstFrameWidth, dstFrameHeight, dstColourFormat);

  PTRACE(dstFrameBytes != 0 ? 6 : 2, "PColCnv\tSetDstFrameSize "
         << ((dstFrameBytes != 0) ? "Succeed": "Fail") << "ed, "
         << dstColourFormat << ' ' << dstFrameWidth << 'x' << dstFrameHeight
         << ", " << dstFrameBytes << " bytes.");

  return dstFrameBytes != 0;
}

PBoolean PColourConverter::SetDstFrameSize(
      unsigned width, 
      unsigned height,
      PBoolean bScale
)
{
  if (!SetDstFrameSize(width, height))
    return PFalse;

  if (bScale)
    SetResizeMode(PVideoFrameInfo::eScale);
  else
    SetResizeMode(PVideoFrameInfo::eCropCentre);

  return PTrue;
}

PBoolean PColourConverter::GetSrcFrameSize(unsigned &width, unsigned &height) const
{
  width = srcFrameWidth;
  height = srcFrameHeight;
  return PTrue;
}


PBoolean PColourConverter::GetDstFrameSize(unsigned &width, unsigned &height) const
{
  width = dstFrameWidth;
  height = dstFrameHeight;
  return PTrue;
}


PBoolean PColourConverter::ConvertInPlace(BYTE * frameBuffer,
                                      PINDEX * bytesReturned,
                                      PBoolean noIntermediateFrame)
{
  if (Convert(frameBuffer, frameBuffer, bytesReturned))
    return PTrue;

  if (noIntermediateFrame) {
    PTRACE(2,"PColCnv\tError in ConvertInPlace, no intermediate frame available.");
    return PFalse;
  }

  BYTE * intermediate = intermediateFrameStore.GetPointer(dstFrameBytes);
  PINDEX bytes;
  if (!Convert(frameBuffer, intermediate, &bytes))
    return PFalse;

  memcpy(frameBuffer, intermediate, bytes);
  if (bytesReturned != NULL)
    *bytesReturned = bytes;
  return PTrue;
}


///////////////////////////////////////////////////////////////////////////////

PSynonymColourRegistration::PSynonymColourRegistration(const char * srcFmt,
                                                       const char * dstFmt)
  : PColourConverterRegistration(srcFmt,dstFmt)
{

⌨️ 快捷键说明

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