📄 mpeg4genericrtpsource.cpp
字号:
/**********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.// MPEG4-GENERIC ("audio", "video", or "application") RTP stream sources// Implementation#include "MPEG4GenericRTPSource.hh"#include "BitVector.hh"#include "MPEG4LATMAudioRTPSource.hh" // for parseGeneralConfigStr()////////// MPEG4GenericBufferedPacket and MPEG4GenericBufferedPacketFactoryclass MPEG4GenericBufferedPacket: public BufferedPacket {public: MPEG4GenericBufferedPacket(MPEG4GenericRTPSource* ourSource); virtual ~MPEG4GenericBufferedPacket();private: // redefined virtual functions virtual unsigned nextEnclosedFrameSize(unsigned char*& framePtr, unsigned dataSize);private: MPEG4GenericRTPSource* fOurSource;};class MPEG4GenericBufferedPacketFactory: public BufferedPacketFactory {private: // redefined virtual functions virtual BufferedPacket* createNewPacket(MultiFramedRTPSource* ourSource);};////////// AUHeader //////////struct AUHeader { unsigned size; unsigned index; // indexDelta for the 2nd & subsequent headers};///////// MPEG4GenericRTPSource implementation //////////##### NOTE: INCOMPLETE!!! Support more modes, and interleaving #####MPEG4GenericRTPSource*MPEG4GenericRTPSource::createNew(UsageEnvironment& env, Groupsock* RTPgs, unsigned char rtpPayloadFormat, unsigned rtpTimestampFrequency, char const* mediumName, char const* mode, unsigned sizeLength, unsigned indexLength, unsigned indexDeltaLength ) { return new MPEG4GenericRTPSource(env, RTPgs, rtpPayloadFormat, rtpTimestampFrequency, mediumName, mode, sizeLength, indexLength, indexDeltaLength );}MPEG4GenericRTPSource::MPEG4GenericRTPSource(UsageEnvironment& env, Groupsock* RTPgs, unsigned char rtpPayloadFormat, unsigned rtpTimestampFrequency, char const* mediumName, char const* mode, unsigned sizeLength, unsigned indexLength, unsigned indexDeltaLength ) : MultiFramedRTPSource(env, RTPgs, rtpPayloadFormat, rtpTimestampFrequency, new MPEG4GenericBufferedPacketFactory), fSizeLength(sizeLength), fIndexLength(indexLength), fIndexDeltaLength(indexDeltaLength), fNumAUHeaders(0), fNextAUHeader(0), fAUHeaders(NULL) { unsigned mimeTypeLength = strlen(mediumName) + 14 /* strlen("/MPEG4-GENERIC") */ + 1; fMIMEType = new char[mimeTypeLength]; if (fMIMEType != NULL) { sprintf(fMIMEType, "%s/MPEG4-GENERIC", mediumName); } fMode = strDup(mode); // Check for a "mode" that we don't yet support: //##### if (mode == NULL || (strcmp(mode, "aac-hbr") != 0 && strcmp(mode, "generic") != 0)) { envir() << "MPEG4GenericRTPSource Warning: Unknown or unsupported \"mode\": " << mode << "\n"; }}MPEG4GenericRTPSource::~MPEG4GenericRTPSource() { delete[] fAUHeaders; delete[] fMode; delete[] fMIMEType;}Boolean MPEG4GenericRTPSource::processSpecialHeader(BufferedPacket* packet, unsigned& resultSpecialHeaderSize) { unsigned char* headerStart = packet->data(); unsigned packetSize = packet->dataSize(); fCurrentPacketBeginsFrame = fCurrentPacketCompletesFrame; // whether the *previous* packet ended a frame // The RTP "M" (marker) bit indicates the last fragment of a frame: fCurrentPacketCompletesFrame = packet->rtpMarkerBit(); // default values: resultSpecialHeaderSize = 0; fNumAUHeaders = 0; fNextAUHeader = 0; delete[] fAUHeaders; fAUHeaders = NULL; if (fSizeLength > 0) { // The packet begins with a "AU Header Section". Parse it, to // determine the "AU-header"s for each frame present in this packet: resultSpecialHeaderSize += 2; if (packetSize < resultSpecialHeaderSize) return False; unsigned AU_headers_length = (headerStart[0]<<8)|headerStart[1]; unsigned AU_headers_length_bytes = (AU_headers_length+7)/8; if (packetSize < resultSpecialHeaderSize + AU_headers_length_bytes) return False; resultSpecialHeaderSize += AU_headers_length_bytes; // Figure out how many AU-headers are present in the packet: int bitsAvail = AU_headers_length - (fSizeLength + fIndexLength); if (bitsAvail >= 0 && (fSizeLength + fIndexDeltaLength) > 0) { fNumAUHeaders = 1 + bitsAvail/(fSizeLength + fIndexDeltaLength); } if (fNumAUHeaders > 0) { fAUHeaders = new AUHeader[fNumAUHeaders]; // Fill in each header: BitVector bv(&headerStart[2], 0, AU_headers_length); fAUHeaders[0].size = bv.getBits(fSizeLength); fAUHeaders[0].index = bv.getBits(fIndexLength); for (unsigned i = 1; i < fNumAUHeaders; ++i) { fAUHeaders[i].size = bv.getBits(fSizeLength); fAUHeaders[i].index = bv.getBits(fIndexDeltaLength); } } } return True;}char const* MPEG4GenericRTPSource::MIMEtype() const { return fMIMEType;}////////// MPEG4GenericBufferedPacket////////// and MPEG4GenericBufferedPacketFactory implementationMPEG4GenericBufferedPacket::MPEG4GenericBufferedPacket(MPEG4GenericRTPSource* ourSource) : fOurSource(ourSource) {}MPEG4GenericBufferedPacket::~MPEG4GenericBufferedPacket() {}unsigned MPEG4GenericBufferedPacket::nextEnclosedFrameSize(unsigned char*& /*framePtr*/, unsigned dataSize) { // WE CURRENTLY DON'T IMPLEMENT INTERLEAVING. FIX THIS! ##### AUHeader* auHeader = fOurSource->fAUHeaders; if (auHeader == NULL) return dataSize; unsigned numAUHeaders = fOurSource->fNumAUHeaders; if (fOurSource->fNextAUHeader >= numAUHeaders) { fOurSource->envir() << "MPEG4GenericBufferedPacket::nextEnclosedFrameSize(" << dataSize << "): data error (" << auHeader << "," << fOurSource->fNextAUHeader << "," << numAUHeaders << ")!\n"; return dataSize; } auHeader = &auHeader[fOurSource->fNextAUHeader++]; return auHeader->size <= dataSize ? auHeader->size : dataSize;}BufferedPacket* MPEG4GenericBufferedPacketFactory::createNewPacket(MultiFramedRTPSource* ourSource) { return new MPEG4GenericBufferedPacket((MPEG4GenericRTPSource*)ourSource);}////////// samplingFrequencyFromAudioSpecificConfig() implementation //////////static unsigned samplingFrequencyFromIndex[16] = { 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350, 0, 0, 0};unsigned samplingFrequencyFromAudioSpecificConfig(char const* configStr) { unsigned char* config = NULL; unsigned result = 0; // if returned, indicates an error do { // Begin by parsing the config string: unsigned configSize; config = parseGeneralConfigStr(configStr, configSize); if (config == NULL) break; if (configSize < 2) break; unsigned char samplingFrequencyIndex = ((config[0]&0x07)<<1) | (config[1]>>7); if (samplingFrequencyIndex < 15) { result = samplingFrequencyFromIndex[samplingFrequencyIndex]; break; } // Index == 15 means that the actual frequency is next (24 bits): if (configSize < 5) break; result = ((config[1]&0x7F)<<17) | (config[2]<<9) | (config[3]<<1) | (config[4]>>7); } while (0); delete[] config; return result;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -