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

📄 qcelpaudiortpsource.cpp

📁 流媒体传输协议的实现代码,非常有用.可以支持rtsp mms等流媒体传输协议
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/**********This library is free software; you can redistribute it and/or modify it underthe terms of the GNU Lesser General Public License as published by theFree Software Foundation; either version 2.1 of the License, or (at youroption) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)This library is distributed in the hope that it will be useful, but WITHOUTANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESSFOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License formore details.You should have received a copy of the GNU Lesser General Public Licensealong with this library; if not, write to the Free Software Foundation, Inc.,59 Temple Place, Suite 330, Boston, MA  02111-1307  USA**********/// "liveMedia"// Copyright (c) 1996-2004 Live Networks, Inc.  All rights reserved.// Qualcomm "PureVoice" (aka. "QCELP") Audio RTP Sources// Implementation#include "QCELPAudioRTPSource.hh"#include "MultiFramedRTPSource.hh"#include "FramedFilter.hh"#include <string.h>#include <stdlib.h>// This source is implemented internally by two separate sources:// (i) a RTP source for the raw (interleaved) QCELP frames, and// (ii) a deinterleaving filter that reads from this.// Define these two new classes here:class RawQCELPRTPSource: public MultiFramedRTPSource {public:  static RawQCELPRTPSource* createNew(UsageEnvironment& env,				      Groupsock* RTPgs,				      unsigned char rtpPayloadFormat,				      unsigned rtpTimestampFrequency);  unsigned char interleaveL() const { return fInterleaveL; }  unsigned char interleaveN() const { return fInterleaveN; }  unsigned char& frameIndex() { return fFrameIndex; } // index within pktprivate:  RawQCELPRTPSource(UsageEnvironment& env, Groupsock* RTPgs,		    unsigned char rtpPayloadFormat,		    unsigned rtpTimestampFrequency);      // called only by createNew()  virtual ~RawQCELPRTPSource();private:  // redefined virtual functions:  virtual Boolean processSpecialHeader(BufferedPacket* packet,                                       unsigned& resultSpecialHeaderSize);  virtual char const* MIMEtype() const;   virtual Boolean hasBeenSynchronizedUsingRTCP();private:  unsigned char fInterleaveL, fInterleaveN, fFrameIndex;  unsigned fNumSuccessiveSyncedPackets;};class QCELPDeinterleaver: public FramedFilter {public:  static QCELPDeinterleaver* createNew(UsageEnvironment& env,				       RawQCELPRTPSource* inputSource);private:  QCELPDeinterleaver(UsageEnvironment& env,		     RawQCELPRTPSource* inputSource);      // called only by "createNew()"   virtual ~QCELPDeinterleaver();  static void afterGettingFrame(void* clientData, unsigned frameSize,				unsigned numTruncatedBytes,                                struct timeval presentationTime,				unsigned durationInMicroseconds);  void afterGettingFrame1(unsigned frameSize, struct timeval presentationTime); private:  // Redefined virtual functions:  void doGetNextFrame();private:  class QCELPDeinterleavingBuffer* fDeinterleavingBuffer;  Boolean fNeedAFrame;};////////// QCELPAudioRTPSource implementation //////////FramedSource*QCELPAudioRTPSource::createNew(UsageEnvironment& env,			       Groupsock* RTPgs,			       RTPSource*& resultRTPSource,			       unsigned char rtpPayloadFormat,			       unsigned rtpTimestampFrequency) {  RawQCELPRTPSource* rawRTPSource;  resultRTPSource = rawRTPSource    = RawQCELPRTPSource::createNew(env, RTPgs, rtpPayloadFormat,				   rtpTimestampFrequency);  if (resultRTPSource == NULL) return NULL;  QCELPDeinterleaver* deinterleaver    = QCELPDeinterleaver::createNew(env, rawRTPSource);  if (deinterleaver == NULL) {    Medium::close(resultRTPSource);    resultRTPSource = NULL;  }  return deinterleaver;}////////// QCELPBufferedPacket and QCELPBufferedPacketFactory //////////// A subclass of BufferedPacket, used to separate out QCELP frames.class QCELPBufferedPacket: public BufferedPacket {public:  QCELPBufferedPacket(RawQCELPRTPSource& ourSource);  virtual ~QCELPBufferedPacket();private: // redefined virtual functions  virtual unsigned nextEnclosedFrameSize(unsigned char*& framePtr,					 unsigned dataSize);private:  RawQCELPRTPSource& fOurSource;};class QCELPBufferedPacketFactory: public BufferedPacketFactory {private: // redefined virtual functions  virtual BufferedPacket* createNewPacket(MultiFramedRTPSource* ourSource);};///////// RawQCELPRTPSource implementation ////////RawQCELPRTPSource*RawQCELPRTPSource::createNew(UsageEnvironment& env, Groupsock* RTPgs,			     unsigned char rtpPayloadFormat,			     unsigned rtpTimestampFrequency) {  return new RawQCELPRTPSource(env, RTPgs, rtpPayloadFormat,			       rtpTimestampFrequency);}RawQCELPRTPSource::RawQCELPRTPSource(UsageEnvironment& env,				     Groupsock* RTPgs,				     unsigned char rtpPayloadFormat,				     unsigned rtpTimestampFrequency)  : MultiFramedRTPSource(env, RTPgs, rtpPayloadFormat,			 rtpTimestampFrequency,                         new QCELPBufferedPacketFactory),  fInterleaveL(0), fInterleaveN(0), fFrameIndex(0),  fNumSuccessiveSyncedPackets(0) {}RawQCELPRTPSource::~RawQCELPRTPSource() {}Boolean RawQCELPRTPSource::processSpecialHeader(BufferedPacket* packet,		       unsigned& resultSpecialHeaderSize) {  unsigned char* headerStart = packet->data();  unsigned packetSize = packet->dataSize();  // First, check whether this packet's RTP timestamp is synchronized:  if (RTPSource::hasBeenSynchronizedUsingRTCP()) {    ++fNumSuccessiveSyncedPackets;  } else {    fNumSuccessiveSyncedPackets = 0;  }  // There's a 1-byte header indicating the interleave parameters  if (packetSize < 1) return False;  // Get the interleaving parameters from the 1-byte header,  // and check them for validity:  unsigned char const firstByte = headerStart[0];  unsigned char const interleaveL = (firstByte&0x38)>>3;  unsigned char const interleaveN = firstByte&0x07;#ifdef DEBUG  fprintf(stderr, "packetSize: %d, interleaveL: %d, interleaveN: %d\n", packetSize, interleaveL, interleaveN);#endif  if (interleaveL > 5 || interleaveN > interleaveL) return False; //invalid  fInterleaveL = interleaveL;  fInterleaveN = interleaveN;  fFrameIndex = 0; // initially  resultSpecialHeaderSize = 1;  return True;} char const* RawQCELPRTPSource::MIMEtype() const {  return "audio/QCELP";}Boolean RawQCELPRTPSource::hasBeenSynchronizedUsingRTCP() {  // Don't report ourselves as being synchronized until we've received  // at least a complete interleave cycle of synchronized packets.  // This ensures that the receiver is currently getting a frame from  // a packet that was synchronized.  if (fNumSuccessiveSyncedPackets > (unsigned)(fInterleaveL+1)) {    fNumSuccessiveSyncedPackets = fInterleaveL+2; // prevents overflow    return True;  }  return False;}///// QCELPBufferedPacket and QCELPBufferedPacketFactory implementationQCELPBufferedPacket::QCELPBufferedPacket(RawQCELPRTPSource& ourSource)  : fOurSource(ourSource) {}QCELPBufferedPacket::~QCELPBufferedPacket() {}unsigned QCELPBufferedPacket::  nextEnclosedFrameSize(unsigned char*& framePtr, unsigned dataSize) {  // The size of the QCELP frame is determined by the first byte:  if (dataSize == 0) return 0; // sanity check  unsigned char const firstByte = framePtr[0];  unsigned frameSize;  switch (firstByte) {  case 0: { frameSize = 1; break; }  case 1: { frameSize = 4; break; }  case 2: { frameSize = 8; break; }  case 3: { frameSize = 17; break; }  case 4: { frameSize = 35; break; }  default: { frameSize = 0; break; }  }#ifdef DEBUG  fprintf(stderr, "QCELPBufferedPacket::nextEnclosedFrameSize(): frameSize: %d, dataSize: %d\n", frameSize, dataSize);#endif  if (dataSize < frameSize) return 0;  ++fOurSource.frameIndex();  return frameSize;}BufferedPacket* QCELPBufferedPacketFactory::createNewPacket(MultiFramedRTPSource* ourSource) {  return new QCELPBufferedPacket((RawQCELPRTPSource&)(*ourSource));

⌨️ 快捷键说明

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