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

📄 multiframedrtpsink.cpp

📁 H.264 RTSP 串流(live 555)視窗版本
💻 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.,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA**********/// "liveMedia"// Copyright (c) 1996-2010 Live Networks, Inc.  All rights reserved.// RTP sink for a common kind of payload format: Those which pack multiple,// complete codec frames (as many as possible) into each RTP packet.// Implementation#include "MultiFramedRTPSink.hh"#include "GroupsockHelper.hh"////////// MultiFramedRTPSink //////////void MultiFramedRTPSink::setPacketSizes(unsigned preferredPacketSize,					unsigned maxPacketSize) {  if (preferredPacketSize > maxPacketSize || preferredPacketSize == 0) return;      // sanity check  delete fOutBuf;  fOutBuf = new OutPacketBuffer(preferredPacketSize, maxPacketSize);  fOurMaxPacketSize = maxPacketSize; // save value, in case subclasses need it}MultiFramedRTPSink::MultiFramedRTPSink(UsageEnvironment& env,				       Groupsock* rtpGS,				       unsigned char rtpPayloadType,				       unsigned rtpTimestampFrequency,				       char const* rtpPayloadFormatName,				       unsigned numChannels)  : RTPSink(env, rtpGS, rtpPayloadType, rtpTimestampFrequency,	    rtpPayloadFormatName, numChannels),  fOutBuf(NULL), fCurFragmentationOffset(0), fPreviousFrameEndedFragmentation(False) {  setPacketSizes(1000, 1448);      // Default max packet size (1500, minus allowance for IP, UDP, UMTP headers)      // (Also, make it a multiple of 4 bytes, just in case that matters.)}MultiFramedRTPSink::~MultiFramedRTPSink() {  delete fOutBuf;}void MultiFramedRTPSink::doSpecialFrameHandling(unsigned /*fragmentationOffset*/,			 unsigned char* /*frameStart*/,			 unsigned /*numBytesInFrame*/,			 struct timeval frameTimestamp,			 unsigned /*numRemainingBytes*/) {  // default implementation: If this is the first frame in the packet,  // use its timestamp for the RTP timestamp:  if (isFirstFrameInPacket()) {    setTimestamp(frameTimestamp);  }}Boolean MultiFramedRTPSink::allowFragmentationAfterStart() const {  return False; // by default}Boolean MultiFramedRTPSink::allowOtherFramesAfterLastFragment() const {  return False; // by default}Boolean MultiFramedRTPSink::frameCanAppearAfterPacketStart(unsigned char const* /*frameStart*/,				 unsigned /*numBytesInFrame*/) const {  return True; // by default}unsigned MultiFramedRTPSink::specialHeaderSize() const {  // default implementation: Assume no special header:  return 0;}unsigned MultiFramedRTPSink::frameSpecificHeaderSize() const {  // default implementation: Assume no frame-specific header:  return 0;}unsigned MultiFramedRTPSink::computeOverflowForNewFrame(unsigned newFrameSize) const {  // default implementation: Just call numOverflowBytes()  return fOutBuf->numOverflowBytes(newFrameSize);}void MultiFramedRTPSink::setMarkerBit() {  unsigned rtpHdr = fOutBuf->extractWord(0);  rtpHdr |= 0x00800000;  fOutBuf->insertWord(rtpHdr, 0);}void MultiFramedRTPSink::setTimestamp(struct timeval timestamp) {  // First, convert the timestamp to a 32-bit RTP timestamp:  fCurrentTimestamp = convertToRTPTimestamp(timestamp);  // Then, insert it into the RTP packet:  fOutBuf->insertWord(fCurrentTimestamp, fTimestampPosition);}void MultiFramedRTPSink::setSpecialHeaderWord(unsigned word,					      unsigned wordPosition) {  fOutBuf->insertWord(word, fSpecialHeaderPosition + 4*wordPosition);}void MultiFramedRTPSink::setSpecialHeaderBytes(unsigned char const* bytes,					       unsigned numBytes,					       unsigned bytePosition) {  fOutBuf->insert(bytes, numBytes, fSpecialHeaderPosition + bytePosition);}void MultiFramedRTPSink::setFrameSpecificHeaderWord(unsigned word,						    unsigned wordPosition) {  fOutBuf->insertWord(word, fCurFrameSpecificHeaderPosition + 4*wordPosition);}void MultiFramedRTPSink::setFrameSpecificHeaderBytes(unsigned char const* bytes,						     unsigned numBytes,						     unsigned bytePosition) {  fOutBuf->insert(bytes, numBytes, fCurFrameSpecificHeaderPosition + bytePosition);}void MultiFramedRTPSink::setFramePadding(unsigned numPaddingBytes) {  if (numPaddingBytes > 0) {    // Add the padding bytes (with the last one being the padding size):    unsigned char paddingBuffer[255]; //max padding    memset(paddingBuffer, 0, numPaddingBytes);    paddingBuffer[numPaddingBytes-1] = numPaddingBytes;    fOutBuf->enqueue(paddingBuffer, numPaddingBytes);    // Set the RTP padding bit:    unsigned rtpHdr = fOutBuf->extractWord(0);    rtpHdr |= 0x20000000;    fOutBuf->insertWord(rtpHdr, 0);  }}Boolean MultiFramedRTPSink::continuePlaying() {  // Send the first packet.  // (This will also schedule any future sends.)  buildAndSendPacket(True);  return True;}void MultiFramedRTPSink::stopPlaying() {  fOutBuf->resetPacketStart();  fOutBuf->resetOffset();  fOutBuf->resetOverflowData();  // Then call the default "stopPlaying()" function:  MediaSink::stopPlaying();}void MultiFramedRTPSink::buildAndSendPacket(Boolean isFirstPacket) {  fIsFirstPacket = isFirstPacket;  // Set up the RTP header:  unsigned rtpHdr = 0x80000000; // RTP version 2  rtpHdr |= (fRTPPayloadType<<16);  rtpHdr |= fSeqNo; // sequence number  fOutBuf->enqueueWord(rtpHdr);  // Note where the RTP timestamp will go.  // (We can't fill this in until we start packing payload frames.)  fTimestampPosition = fOutBuf->curPacketSize();  fOutBuf->skipBytes(4); // leave a hole for the timestamp  fOutBuf->enqueueWord(SSRC());  // Allow for a special, payload-format-specific header following the  // RTP header:  fSpecialHeaderPosition = fOutBuf->curPacketSize();  fSpecialHeaderSize = specialHeaderSize();  fOutBuf->skipBytes(fSpecialHeaderSize);  // Begin packing as many (complete) frames into the packet as we can:  fTotalFrameSpecificHeaderSizes = 0;  fNoFramesLeft = False;  fNumFramesUsedSoFar = 0;  packFrame();}void MultiFramedRTPSink::packFrame() {  // Get the next frame.  // First, see if we have an overflow frame that was too big for the last pkt  if (fOutBuf->haveOverflowData()) {    // Use this frame before reading a new one from the source    unsigned frameSize = fOutBuf->overflowDataSize();    struct timeval presentationTime = fOutBuf->overflowPresentationTime();    unsigned durationInMicroseconds = fOutBuf->overflowDurationInMicroseconds();    fOutBuf->useOverflowData();    afterGettingFrame1(frameSize, 0, presentationTime, durationInMicroseconds);  } else {    // Normal case: we need to read a new frame from the source    if (fSource == NULL) return;    fCurFrameSpecificHeaderPosition = fOutBuf->curPacketSize();    fCurFrameSpecificHeaderSize = frameSpecificHeaderSize();

⌨️ 快捷键说明

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