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

📄 mp3aduinterleaving.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.// Interleaving of MP3 ADUs// Implementation#include "MP3ADUinterleaving.hh"#include "MP3ADUdescriptor.hh"#include <string.h>#ifdef TEST_LOSS#include "GroupsockHelper.hh"#endif////////// Interleaving //////////Interleaving::Interleaving(unsigned cycleSize,			   unsigned char const* cycleArray)  : fCycleSize(cycleSize) {  for (unsigned i = 0; i < fCycleSize; ++i) {    fInverseCycle[cycleArray[i]] = i;  }}Interleaving::~Interleaving() {}////////// MP3ADUinterleaverBase //////////MP3ADUinterleaverBase::MP3ADUinterleaverBase(UsageEnvironment& env,					     FramedSource* inputSource)  : FramedFilter(env, inputSource) {}MP3ADUinterleaverBase::~MP3ADUinterleaverBase() {}FramedSource* MP3ADUinterleaverBase::getInputSource(UsageEnvironment& env,						    char const* inputSourceName) {  FramedSource* inputSource;  if (!FramedSource::lookupByName(env, inputSourceName, inputSource))    return NULL;    if (strcmp(inputSource->MIMEtype(), "audio/MPA-ROBUST") != 0) {    env.setResultMsg(inputSourceName, " is not an MP3 ADU source");    return NULL;  }    return inputSource;}void MP3ADUinterleaverBase::afterGettingFrame(void* clientData,					      unsigned numBytesRead,					      unsigned /*numTruncatedBytes*/,					      struct timeval presentationTime,					      unsigned durationInMicroseconds) {  MP3ADUinterleaverBase* interleaverBase = (MP3ADUinterleaverBase*)clientData;  // Finish up after reading:  interleaverBase->afterGettingFrame(numBytesRead,				     presentationTime, durationInMicroseconds);  // Then, continue to deliver an outgoing frame:  interleaverBase->doGetNextFrame();}////////// InterleavingFrames (definition) //////////class InterleavingFrames {public:  InterleavingFrames(unsigned maxCycleSize);  virtual ~InterleavingFrames();  Boolean haveReleaseableFrame();  void getIncomingFrameParams(unsigned char index,			      unsigned char*& dataPtr,			      unsigned& bytesAvailable);  void getReleasingFrameParams(unsigned char index,			       unsigned char*& dataPtr,			       unsigned& bytesInUse,			       struct timeval& presentationTime,			       unsigned& durationInMicroseconds);  void setFrameParams(unsigned char index,		      unsigned char icc, unsigned char ii,		      unsigned frameSize, struct timeval presentationTime,		      unsigned durationInMicroseconds);  unsigned nextIndexToRelease() {return fNextIndexToRelease;}  void releaseNext();private:  unsigned fMaxCycleSize;  unsigned fNextIndexToRelease;  class InterleavingFrameDescriptor* fDescriptors;};////////// MP3ADUinterleaver //////////MP3ADUinterleaver::MP3ADUinterleaver(UsageEnvironment& env,				     Interleaving const& interleaving,				     FramedSource* inputSource)  : MP3ADUinterleaverBase(env, inputSource),    fInterleaving(interleaving),    fFrames(new InterleavingFrames(interleaving.cycleSize())),    fII(0), fICC(0) {}MP3ADUinterleaver::~MP3ADUinterleaver() {  delete fFrames;}MP3ADUinterleaver* MP3ADUinterleaver::createNew(UsageEnvironment& env,						Interleaving const& interleaving,						FramedSource* inputSource) {  return new MP3ADUinterleaver(env, interleaving, inputSource);}void MP3ADUinterleaver::doGetNextFrame() {  // If there's a frame immediately available, deliver it, otherwise get new  // frames from the source until one's available:  if (fFrames->haveReleaseableFrame()) {    releaseOutgoingFrame();    // Call our own 'after getting' function.  Because we're not a 'leaf'    // source, we can call this directly, without risking infinite recursion.    afterGetting(this);  } else {    fPositionOfNextIncomingFrame = fInterleaving.lookupInverseCycle(fII);    unsigned char* dataPtr;    unsigned bytesAvailable;    fFrames->getIncomingFrameParams(fPositionOfNextIncomingFrame,				    dataPtr, bytesAvailable);    // Read the next incoming frame (asynchronously)    fInputSource->getNextFrame(dataPtr, bytesAvailable,			       &MP3ADUinterleaverBase::afterGettingFrame, this,			       handleClosure, this);  }}void MP3ADUinterleaver::releaseOutgoingFrame() {  unsigned char* fromPtr;  fFrames->getReleasingFrameParams(fFrames->nextIndexToRelease(),				   fromPtr, fFrameSize,				   fPresentationTime, fDurationInMicroseconds);  if (fFrameSize > fMaxSize) {    fNumTruncatedBytes = fFrameSize - fMaxSize;    fFrameSize = fMaxSize;  }  memmove(fTo, fromPtr, fFrameSize);  fFrames->releaseNext();}void MP3ADUinterleaver::afterGettingFrame(unsigned numBytesRead,					  struct timeval presentationTime,					  unsigned durationInMicroseconds) {  // Set the (icc,ii) and frame size of the newly-read frame:  fFrames->setFrameParams(fPositionOfNextIncomingFrame,			  fICC, fII, numBytesRead,			  presentationTime, durationInMicroseconds);  // Prepare our counters for the next frame:  if (++fII == fInterleaving.cycleSize()) {    fII = 0;    fICC = (fICC+1)%8;  }}////////// DeinterleavingFrames (definition) //////////class DeinterleavingFrames {public:  DeinterleavingFrames();  virtual ~DeinterleavingFrames();    Boolean haveReleaseableFrame();  void getIncomingFrameParams(unsigned char*& dataPtr,			      unsigned& bytesAvailable);  void getIncomingFrameParamsAfter(unsigned frameSize,				   struct timeval presentationTime,				   unsigned durationInMicroseconds,				   unsigned char& icc, unsigned char& ii);  void getReleasingFrameParams(unsigned char*& dataPtr,			       unsigned& bytesInUse,			       struct timeval& presentationTime,			       unsigned& durationInMicroseconds);  void moveIncomingFrameIntoPlace();  void releaseNext();  void startNewCycle();private:  unsigned fNextIndexToRelease;  Boolean fHaveEndedCycle;  unsigned fIIlastSeen;  unsigned fMinIndexSeen, fMaxIndexSeen; // actually, max+1  class DeinterleavingFrameDescriptor* fDescriptors;};////////// MP3ADUdeinterleaver //////////MP3ADUdeinterleaver::MP3ADUdeinterleaver(UsageEnvironment& env,					 FramedSource* inputSource)  : MP3ADUinterleaverBase(env, inputSource),    fFrames(new DeinterleavingFrames),    fIIlastSeen(~0), fICClastSeen(~0) {}MP3ADUdeinterleaver::~MP3ADUdeinterleaver() {}MP3ADUdeinterleaver* MP3ADUdeinterleaver::createNew(UsageEnvironment& env,						    FramedSource* inputSource) {  return new MP3ADUdeinterleaver(env, inputSource);}void MP3ADUdeinterleaver::doGetNextFrame() {  // If there's a frame immediately available, deliver it, otherwise get new  // frames from the source until one's available:  if (fFrames->haveReleaseableFrame()) {    releaseOutgoingFrame();    // Call our own 'after getting' function.  Because we're not a 'leaf'    // source, we can call this directly, without risking infinite recursion.    afterGetting(this);  } else {#ifdef TEST_LOSS  NOTE: This code no longer works, because it uses synchronous reads,  which are no longer supported.     static unsigned const framesPerPacket = 3;    static unsigned const frameCount = 0;    static Boolean packetIsLost;    while (1) {      unsigned packetCount = frameCount/framesPerPacket;      if ((frameCount++)%framesPerPacket == 0) {	packetIsLost = (our_random()%10 == 0); // simulate 10% packet loss #####      }      if (packetIsLost) {	// Read and discard the next input frame (that would be part of	// a lost packet):	unsigned char dummyBuf[2000];	unsigned numBytesRead;	struct timeval presentationTime;

⌨️ 快捷键说明

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