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

📄 h263codec.cxx

📁 sloedgy open sip stack source code
💻 CXX
📖 第 1 页 / 共 3 页
字号:
					     unsigned _cif4MPI,
					     unsigned _cif16MPI,
					     unsigned _maxBitRate,
					     BOOL _unrestrictedVector,
					     BOOL _arithmeticCoding,
					     BOOL _advancedPrediction,
					     BOOL _pbFrames,
					     BOOL _temporalSpatialTradeOff,
					     unsigned _hrd_B,
					     unsigned _bppMaxKb,
					     unsigned _slowSqcifMPI,
					     unsigned _slowQcifMPI,
					     unsigned _slowCifMPI,
					     unsigned _slowCif4MPI,
					     unsigned _slowCif16MPI,
					     BOOL _errorCompensation)
{
  sqcifMPI = (_sqcifMPI>0?_sqcifMPI:-(signed)_slowSqcifMPI);
  qcifMPI = (_qcifMPI>0?_qcifMPI:-(signed)_slowQcifMPI);
  cifMPI = (_cifMPI>0?_cifMPI:-(signed)_slowCifMPI);
  cif4MPI = (_cif4MPI>0?_cif4MPI:-(signed)_slowCif4MPI);
  cif16MPI = (_cif16MPI>0?_cif16MPI:-(signed)_slowCif16MPI);

  maxBitRate = _maxBitRate;

  unrestrictedVector = _unrestrictedVector;
  arithmeticCoding = _arithmeticCoding;
  advancedPrediction = _advancedPrediction;
  pbFrames = _pbFrames;

  temporalSpatialTradeOff = _temporalSpatialTradeOff;

  hrd_B = _hrd_B;
  bppMaxKb = _bppMaxKb;

  errorCompensation = _errorCompensation;
}

PObject * H323_H263Capability::Clone() const
{
  return new H323_H263Capability(*this);
}

PObject::Comparison H323_H263Capability::Compare(const PObject & obj) const
{
  if (!PIsDescendant(&obj, H323_H263Capability))
    return LessThan;

  Comparison result = H323Capability::Compare(obj);
  if (result != EqualTo) 
    return result;

  const H323_H263Capability & other = (const H323_H263Capability &)obj;

  if ((sqcifMPI && other.sqcifMPI) ||
      (qcifMPI && other.qcifMPI) ||
      (cifMPI && other.cifMPI) ||
      (cif4MPI && other.cif4MPI) ||
      (cif16MPI && other.cif16MPI))
    return EqualTo;

  if ((!cif16MPI && other.cif16MPI) ||
      (!cif4MPI && other.cif4MPI) ||
      (!cifMPI && other.cifMPI) ||
      (!qcifMPI && other.qcifMPI))
    return LessThan;

  return GreaterThan;
}

PString H323_H263Capability::GetFormatName() const
{
  PString ret = OpalH263;

  if (sqcifMPI)
    ret += "-SQCIF";

  if (qcifMPI)
    ret += "-QCIF";

  if (cifMPI)
    ret += "-CIF";

  if (cif4MPI)
    ret += "-4CIF";

  if (cif16MPI)
    ret += "-16CIF";

  return ret;
}

unsigned H323_H263Capability::GetSubType() const
{
  return H245_VideoCapability::e_h263VideoCapability;
}

BOOL H323_H263Capability::OnSendingPDU(H245_VideoCapability & cap) const
{
  cap.SetTag(H245_VideoCapability::e_h263VideoCapability);

  H245_H263VideoCapability & h263 = cap;
  if (sqcifMPI > 0) {
    h263.IncludeOptionalField(H245_H263VideoCapability::e_sqcifMPI);
    h263.m_sqcifMPI = sqcifMPI;
  }
  if (qcifMPI > 0) {
    h263.IncludeOptionalField(H245_H263VideoCapability::e_qcifMPI);
    h263.m_qcifMPI = qcifMPI;
  }
  if (cifMPI > 0) {
    h263.IncludeOptionalField(H245_H263VideoCapability::e_cifMPI);
    h263.m_cifMPI = cifMPI;
  }
  if (cif4MPI > 0) {
    h263.IncludeOptionalField(H245_H263VideoCapability::e_cif4MPI);
    h263.m_cif4MPI = cif4MPI;
  }
  if (cif16MPI > 0) {
    h263.IncludeOptionalField(H245_H263VideoCapability::e_cif16MPI);
    h263.m_cif16MPI = cif16MPI;
  }
  h263.m_temporalSpatialTradeOffCapability = temporalSpatialTradeOff;
  h263.m_maxBitRate = maxBitRate;
  if (sqcifMPI < 0) {
    h263.IncludeOptionalField(H245_H263VideoCapability::e_slowSqcifMPI);
    h263.m_slowSqcifMPI = -sqcifMPI;
  }
  if (qcifMPI < 0) {
    h263.IncludeOptionalField(H245_H263VideoCapability::e_slowQcifMPI);
    h263.m_slowQcifMPI = -qcifMPI;
  }
  if (cifMPI < 0) {
    h263.IncludeOptionalField(H245_H263VideoCapability::e_slowCifMPI);
    h263.m_slowCifMPI = -cifMPI;
  }
  if (cif4MPI < 0) {
    h263.IncludeOptionalField(H245_H263VideoCapability::e_slowCif4MPI);
    h263.m_slowCif4MPI = -cif4MPI;
  }
  if (cif16MPI < 0) {
    h263.IncludeOptionalField(H245_H263VideoCapability::e_slowCif16MPI);
    h263.m_slowCif16MPI = -cif16MPI;
  }

  return TRUE;
}

BOOL H323_H263Capability::OnSendingPDU(H245_VideoMode & pdu) const
{
  pdu.SetTag(H245_VideoMode::e_h263VideoMode);
  H245_H263VideoMode & mode = pdu;
  mode.m_resolution.SetTag(cif16MPI ? H245_H263VideoMode_resolution::e_cif16
			  :(cif4MPI ? H245_H263VideoMode_resolution::e_cif4
			   :(cifMPI ? H245_H263VideoMode_resolution::e_cif
			    :(qcifMPI ? H245_H263VideoMode_resolution::e_qcif
			     : H245_H263VideoMode_resolution::e_sqcif))));
  mode.m_bitRate = maxBitRate;
  mode.m_unrestrictedVector = unrestrictedVector;
  mode.m_arithmeticCoding = arithmeticCoding;
  mode.m_advancedPrediction = advancedPrediction;
  mode.m_pbFrames = pbFrames;
  mode.m_errorCompensation = errorCompensation;

  return TRUE;
}

BOOL H323_H263Capability::OnReceivedPDU(const H245_VideoCapability & cap)
{
  if (cap.GetTag() != H245_VideoCapability::e_h263VideoCapability)
    return FALSE;

  const H245_H263VideoCapability & h263 = cap;
  if (h263.HasOptionalField(H245_H263VideoCapability::e_sqcifMPI))
    sqcifMPI = h263.m_sqcifMPI;
  else if (h263.HasOptionalField(H245_H263VideoCapability::e_slowSqcifMPI))
    sqcifMPI = -(signed)h263.m_slowSqcifMPI;
  else
    sqcifMPI = 0;
  if (h263.HasOptionalField(H245_H263VideoCapability::e_qcifMPI))
    qcifMPI = h263.m_qcifMPI;
  else if (h263.HasOptionalField(H245_H263VideoCapability::e_slowQcifMPI))
    qcifMPI = -(signed)h263.m_slowQcifMPI;
  else
    qcifMPI = 0;
  if (h263.HasOptionalField(H245_H263VideoCapability::e_cifMPI))
    cifMPI = h263.m_cifMPI;
  else if (h263.HasOptionalField(H245_H263VideoCapability::e_slowCifMPI))
    cifMPI = -(signed)h263.m_slowCifMPI;
  else
    cifMPI = 0;
  if (h263.HasOptionalField(H245_H263VideoCapability::e_cif4MPI))
    cif4MPI = h263.m_cif4MPI;
  else if (h263.HasOptionalField(H245_H263VideoCapability::e_slowCif4MPI))
    cif4MPI = -(signed)h263.m_slowCif4MPI;
  else
    cif4MPI = 0;
  if (h263.HasOptionalField(H245_H263VideoCapability::e_cif16MPI))
    cif16MPI = h263.m_cif16MPI;
  else if (h263.HasOptionalField(H245_H263VideoCapability::e_slowCif16MPI))
    cif16MPI = -(signed)h263.m_slowCif16MPI;
  else
    cif16MPI = 0;
  maxBitRate = h263.m_maxBitRate;
  unrestrictedVector = h263.m_unrestrictedVector;
  arithmeticCoding = h263.m_arithmeticCoding;
  advancedPrediction = h263.m_advancedPrediction;
  pbFrames = h263.m_pbFrames;
  temporalSpatialTradeOff = h263.m_temporalSpatialTradeOffCapability;
  hrd_B = h263.m_hrd_B;
  bppMaxKb = h263.m_bppMaxKb;
  errorCompensation = h263.m_errorCompensation;

  return TRUE;
}

#endif // NO_H323

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

void H263Packet::Store(void *_data, int _data_size, void *_hdr, int _hdr_size)
{
  data = _data;
  data_size = _data_size;
  hdr = _hdr;
  hdr_size = _hdr_size;
}

BOOL H263Packet::Read(unsigned & length, RTP_DataFrame & frame)
{
  length = (unsigned) (hdr_size + data_size);
  if (!frame.SetPayloadSize(length)) {
    PTRACE(1, "H263Pck\tNot enough memory for packet of " << length << " bytes");
    length = 0;
    return FALSE;
  }
  memcpy(frame.GetPayloadPtr(), hdr, hdr_size);
  memcpy(frame.GetPayloadPtr() + hdr_size, data, data_size);
  return TRUE;
}

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

Opal_H263_YUV420P::Opal_H263_YUV420P()
  : OpalVideoTranscoder(OpalH263, OpalYUV420P)
{
  if (!ff.IsLoaded())
    return;

  if ((codec = ff.AvcodecFindDecoder(CODEC_ID_H263)) == NULL) {
    PTRACE(1, "H263\tCodec not found for decoder");
    return;
  }

  frameWidth = 352;
  frameHeight = 288;

  context = ff.AvcodecAllocContext();
  if (context == NULL) {
    PTRACE(1, "H263\tFailed to allocate context for decoder");
    return;
  }

  picture = ff.AvcodecAllocFrame();
  if (picture == NULL) {
    PTRACE(1, "H263\tFailed to allocate frame for decoder");
    return;
  }

  if (!OpenCodec()) { // decoder will re-initialise context with correct frame size
    PTRACE(1, "H263\tFailed to open codec for decoder");
    return;
  }

  frameNum = 0;

  PTRACE(3, "Codec\tH263 decoder created");
}

Opal_H263_YUV420P::~Opal_H263_YUV420P()
{
  if (ff.IsLoaded()) {
    CloseCodec();

    ff.AvcodecFree(context);
    ff.AvcodecFree(picture);
  }
}

BOOL Opal_H263_YUV420P::OpenCodec()
{
  // avoid copying input/output
  context->flags |= CODEC_FLAG_INPUT_PRESERVED; // we guarantee to preserve input for max_b_frames+1 frames
  context->flags |= CODEC_FLAG_EMU_EDGE; // don't draw edges

  context->width  = frameWidth;
  context->height = frameHeight;

  context->workaround_bugs = 0; // no workaround for buggy H.263 implementations
  context->error_concealment = FF_EC_GUESS_MVS | FF_EC_DEBLOCK;
  context->error_resilience = FF_ER_CAREFULL;

  if (ff.AvcodecOpen(context, codec) < 0) {
    PTRACE(1, "H263\tFailed to open H.263 decoder");
    return FALSE;
  }

  return TRUE;
}

void Opal_H263_YUV420P::CloseCodec()
{
  if (context != NULL) {
    if (context->codec != NULL) {
      ff.AvcodecClose(context);
      PTRACE(5, "H263\tClosed H.263 decoder" );
    }
  }
}

PINDEX Opal_H263_YUV420P::GetOptimalDataFrameSize(BOOL input) const
{
  return input ? maxOutputSize : ((frameWidth * frameHeight * 12) / 8);
}

BOOL Opal_H263_YUV420P::ConvertFrames(const RTP_DataFrame & src, RTP_DataFrameList & dst)
{
  if (!ff.IsLoaded())
    return FALSE;

  PWaitAndSignal mutex(updateMutex);

  dst.RemoveAll();

  int payload_size = src.GetPayloadSize();
  unsigned char * payload;

  // get payload and ensure correct padding
  if (src.GetHeaderSize() + payload_size + FF_INPUT_BUFFER_PADDING_SIZE > src.GetSize()) {
    payload = (unsigned char *) encFrameBuffer.GetPointer(payload_size + FF_INPUT_BUFFER_PADDING_SIZE);
    memcpy(payload, src.GetPayloadPtr(), payload_size);
  }
  else
    payload = (unsigned char *) src.GetPayloadPtr();

  // some decoders might overread/segfault if the first 23 bits of padding are not 0
  unsigned char * padding = payload + payload_size;
  padding[0] = 0;
  padding[1] = 0;

⌨️ 快捷键说明

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