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

📄 h261codec.cxx

📁 mgcp协议源代码。支持多种编码:g711
💻 CXX
字号:
/* * h261codec.cxx * * H.323 protocol handler * * Open H323 Library *     * Copyright (c) 1998-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 Open H323 Library. * * The Initial Developer of the Original Code is Equivalence Pty. Ltd. * * Contributor(s): Michele Piccini (michele@piccini.com) *                 Derek Smithies (derek@indranet.co.nz) * * $Log: h261codec.cxx,v $ * Revision 1.20  2000/07/13 12:31:31  robertj * Fixed format name output for in band switching H.261 * * Revision 1.19  2000/07/04 13:00:36  craigs * Fixed problem with selecting large and small video sizes * * Revision 1.18  2000/06/10 09:21:36  rogerh * Make GetFormatName return H.261 QCIF or H.261 CIF * * Revision 1.17  2000/05/10 04:05:34  robertj * Changed capabilities so has a function to get name of codec, instead of relying on PrintOn. * * Revision 1.16  2000/05/02 04:32:26  robertj * Fixed copyright notice comment. * * Revision 1.15  2000/04/29 03:01:48  robertj * Fixed bug in receive of H261 capability, setting cif & qcif variables correctly. * * Revision 1.14  2000/03/24 01:23:49  robertj * Directory reorganisation. * * Revision 1.13  2000/03/21 03:06:49  robertj * Changes to make RTP TX of exact numbers of frames in some codecs. * * Revision 1.12  2000/02/10 03:08:02  craigs * Added ability to specify NTSC or PAL video format * * Revision 1.11  2000/02/04 05:11:19  craigs * Updated for new Makefiles and for new video transmission code * * Revision 1.10  2000/01/13 04:03:45  robertj * Added video transmission * * Revision 1.9  1999/12/23 23:02:35  robertj * File reorganision for separating RTP from H.323 and creation of LID for VPB support. * * Revision 1.8  1999/11/29 08:20:47  craigs * Updated for new codec interface * * Revision 1.7  1999/11/01 00:52:00  robertj * Fixed various problems in video, especially ability to pass error return value. * * Revision 1.6  1999/10/08 09:59:03  robertj * Rewrite of capability for sending multiple audio frames * * Revision 1.5  1999/10/08 04:58:38  robertj * Added capability for sending multiple audio frames in single RTP packet * * Revision 1.4  1999/09/21 14:13:53  robertj * Windows MSVC compatibility. * * Revision 1.3  1999/09/21 08:10:03  craigs * Added support for video devices and H261 codec * * Revision 1.2  1999/09/18 13:24:38  craigs * Added ability to disable jitter buffer * Added ability to access entire RTP packet in codec Write * * Revision 1.1  1999/09/08 04:05:49  robertj * Added support for video capabilities & codec, still needs the actual codec itself! * */#pragma implementation "h261codec.h"#include <ptlib.h>#include "h261codec.h"#include "videoio.h"#include "h245.h"#include "rtp.h"#include "vic/p64.h"#include "vic/p64encoder.h"#define new PNEWH323_H261Capability::H323_H261Capability(unsigned _qcifMPI,                                         unsigned _cifMPI,                                         BOOL _temporalSpatialTradeOffCapability,                                         BOOL _stillImageTransmission,                                         unsigned _maxBitRate){  qcifMPI = _qcifMPI;  cifMPI = _cifMPI;  temporalSpatialTradeOffCapability = _temporalSpatialTradeOffCapability;  maxBitRate = _maxBitRate;  stillImageTransmission = _stillImageTransmission;}PObject * H323_H261Capability::Clone() const{  return new H323_H261Capability(qcifMPI,                                 cifMPI,                                 temporalSpatialTradeOffCapability,                                 stillImageTransmission,                                 maxBitRate);}PObject::Comparison H323_H261Capability::Compare(const PObject & obj) const{  Comparison result = H323Capability::Compare(obj);  if (result != EqualTo)    return result;  PAssert(obj.IsDescendant(H323_H261Capability::Class()), PInvalidCast);  const H323_H261Capability & other = (const H323_H261Capability &)obj;  if (((qcifMPI > 0) && (other.qcifMPI > 0)) ||      ((cifMPI  > 0) && (other.cifMPI > 0)))    return EqualTo;  if (qcifMPI > 0)    return LessThan;  return GreaterThan;}PString H323_H261Capability::GetFormatName() const{  if (qcifMPI > 0 && cifMPI > 0)    return "H.261-(Q)CIF";  if (qcifMPI > 0)    return "H.261-QCIF";  if (cifMPI > 0)    return "H.261-CIF";  return "H.261";}unsigned H323_H261Capability::GetSubType() const{  return H245_VideoCapability::e_h261VideoCapability;}BOOL H323_H261Capability::OnSendingPDU(H245_VideoCapability & cap) const{  cap.SetTag(H245_VideoCapability::e_h261VideoCapability);  H245_H261VideoCapability & h261 = cap;  if (qcifMPI > 0) {    h261.IncludeOptionalField(H245_H261VideoCapability::e_qcifMPI);    h261.m_qcifMPI = qcifMPI;  }  if (cifMPI > 0) {    h261.IncludeOptionalField(H245_H261VideoCapability::e_cifMPI);    h261.m_cifMPI = cifMPI;  }  h261.m_temporalSpatialTradeOffCapability = temporalSpatialTradeOffCapability;  h261.m_maxBitRate = maxBitRate;  h261.m_stillImageTransmission = stillImageTransmission;  return TRUE;}BOOL H323_H261Capability::OnReceivedPDU(const H245_VideoCapability & cap){  if (cap.GetTag() != H245_VideoCapability::e_h261VideoCapability)    return FALSE;  const H245_H261VideoCapability & h261 = cap;  if (h261.HasOptionalField(H245_H261VideoCapability::e_qcifMPI))    qcifMPI = h261.m_qcifMPI;  else    qcifMPI = 0;  if (h261.HasOptionalField(H245_H261VideoCapability::e_cifMPI))    cifMPI = h261.m_cifMPI;  else    cifMPI = 0;  temporalSpatialTradeOffCapability = h261.m_temporalSpatialTradeOffCapability;  maxBitRate = h261.m_maxBitRate;  stillImageTransmission = h261.m_stillImageTransmission;  return TRUE;}unsigned H323_H261Capability::GetMaxFrameSize() const{  return 2000; // Need to know what correct value is for this.}H323Codec * H323_H261Capability::CreateCodec(H323Codec::Direction direction) const{  return new H323_H261Codec(direction, qcifMPI > 0);}//////////////////////////////////////////////////////////////////////////////H323_H261Codec::H323_H261Codec(Direction dir, BOOL isqCIF)  : H323VideoCodec(dir){  rtpPayloadType = RTP_DataFrame::H261;  //h261 = h261_create();  PTRACE(3, "Codec\tH261 " << (dir == Encoder ? "en" : "de") << "coder created");  // no video decoder until we receive a packet  videoDecoder = NULL;  // no video encoder until we receive a packet  videoEncoder = NULL;  // other stuff  now = 1;  rvts = NULL;  nblk = ndblk = 0;  // initial size of the window is CIF  packetReceived = dir == Encoder;  if (dir == Encoder) {    width  = isqCIF ? QCIF_WIDTH  : CIF_WIDTH;    height = isqCIF ? QCIF_HEIGHT : CIF_HEIGHT;  } else {    width=0;    height=0;  }}H323_H261Codec::~H323_H261Codec(){  delete videoDecoder;  delete videoEncoder;  delete rvts;}//This function grabs, displays, and compresses a video frame into//into H261 packets.//Get another frame if all packets of previous frame have been sent.//Get next packet on list and send that one.//Render the current frame if all of its packets have been sent.BOOL H323_H261Codec::Read(BYTE * buffer,                          unsigned & length,                          RTP_DataFrame & frame){  if (videoEncoder == NULL)     videoEncoder = new P64Encoder(videoInput, videoIsPal);  if(rawDevice){    if(!rawDevice->Width()){      PTRACE(2,"H261\t Display width is zero, so no video transmission");      length=0;      return FALSE;    }    videoEncoder->SetSize(rawDevice->Width(),rawDevice->Height());   }  if(!videoEncoder->PacketsOutStanding()) {    videoEncoder->GrabOneFrame();             RenderFrame();                          //use data from grab process.      videoEncoder->ProcessOneFrame();        //Generate H261 packets.  }  videoEncoder->ReadOnePacket(buffer,length); //get next packet on list  if(videoEncoder->PacketsOutStanding())       frame.SetMarker(FALSE);                     else       frame.SetMarker(TRUE);  return TRUE;}BOOL H323_H261Codec::Write(const BYTE * buffer,                           unsigned length,                           const RTP_DataFrame & frame,                           unsigned & written){  // always indicate we have written the entire packet  written = length;  // assume buffer is start of H.261 header  const BYTE * header  = buffer;  // see if any contributing source  PINDEX cnt = frame.GetContribSrcCount();  if (cnt > 0) {    header += cnt * 4;    length -= cnt * 4;  }  // rh = RTP header -> header  // bp = payload  // cc = payload length  // determine video codec type  if (videoDecoder == NULL) {    if ( (*(buffer+1)) & 2)      videoDecoder = new IntraP64Decoder();    else      videoDecoder = new FullP64Decoder();    videoDecoder->marks(rvts);  }  // decode values from the RTP H261 header  u_int v = ntohl(*(u_int*)header);  int sbit  = (v >> 29) & 0x07;  int ebit  = (v >> 26) & 0x07;  int gob   = (v >> 20) & 0xf;  int mba   = (v >> 15) & 0x1f;  int quant = (v >> 10) & 0x1f;  int mvdh  = (v >>  5) & 0x1f;  int mvdv  =  v & 0x1f;  //if (gob > 12) {  //  h261_rtp_bug_ = 1;  //  mba = (v >> 19) & 0x1f;  //  gob = (v >> 15) & 0xf; // }  if (gob > 12) {    //count(STAT_BAD_HEADER);    return FALSE;  }  // leave 4 bytes for H.261 header  const BYTE * payload = header + 4;  length = length - 4;  videoDecoder->mark(now);  (void)videoDecoder->decode(payload, length, sbit, ebit, mba, gob, quant, mvdh, mvdv);  BOOL ok = TRUE;  // If the stream changes format, issue a resize.  if (videoDecoder->width() != width) {    ok = Resize(videoDecoder->width(), videoDecoder->height());    videoDecoder->marks(rvts);  }  if (ok && frame.GetMarker()) {    videoDecoder->sync();    ndblk = videoDecoder->ndblk();    if (!packetReceived) {      packetReceived = TRUE;      ok = Resize(videoDecoder->width(), videoDecoder->height());    } else       ok = RenderFrame();     videoDecoder->resetndblk();  }  return ok;}/**Resize is relevant to the decoder only*/BOOL H323_H261Codec::Resize(int _width, int _height){  width  = _width;  height = _height;  nblk = (width * height) / 64;  delete rvts;  rvts = new BYTE[nblk];  memset(rvts, 0, nblk);  // only pass on the resize if we have actually received any data  if (packetReceived&&rawDevice) {    rawDevice->SetSize(width, height);    PTRACE(1, "Size of video frame set to " << width << "x" << height);  }  return Redraw();}BOOL H323_H261Codec::Redraw(){  now = 1;  memset(rvts, 1, nblk);//  if (rawDevice != NULL)//    rawDevice->SetNow(0);  return RenderFrame();}BOOL H323_H261Codec::RenderFrame(){  int wraptime = now ^ 0x80;  BYTE * ts = rvts;  int k;  for (k = nblk; --k >= 0; ++ts) {    if (*ts == wraptime)      *ts = (BYTE)now;  }  BOOL ok = TRUE;  if ((rawDevice != NULL) && packetReceived)    if (direction == Encoder)      ok = rawDevice->Redraw(videoEncoder->Frame());    else      ok = rawDevice->Redraw(videoDecoder->Frame());  now = (now + 1) & 0xff;  return ok;}unsigned H323_H261Codec::GetFrameRate() const{  return 3003;  // Number of 90kHz units in a video frame at 29.97Hz}unsigned H323_H261Codec::GetBandwidth() const{  return 2400;  // Number of 100 bits/sec units used by codec}/////////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

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