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

📄 mpeg4videostreamframer.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.// A filter that breaks up an MPEG-4 video elementary stream into//   frames for:// - Visual Object Sequence (VS) Header + Visual Object (VO) Header//   + Video Object Layer (VOL) Header// - Group of VOP (GOV) Header// - VOP frame// Implementation#include "MPEG4VideoStreamFramer.hh"#include "MPEGVideoStreamParser.hh"#include <string.h>////////// MPEG4VideoStreamParser definition //////////// An enum representing the current state of the parser:enum MPEGParseState {  PARSING_VISUAL_OBJECT_SEQUENCE,  PARSING_VISUAL_OBJECT_SEQUENCE_SEEN_CODE,  PARSING_VISUAL_OBJECT,  PARSING_VIDEO_OBJECT_LAYER,  PARSING_GROUP_OF_VIDEO_OBJECT_PLANE,  PARSING_VIDEO_OBJECT_PLANE,  PARSING_VISUAL_OBJECT_SEQUENCE_END_CODE}; class MPEG4VideoStreamParser: public MPEGVideoStreamParser {public:  MPEG4VideoStreamParser(MPEG4VideoStreamFramer* usingSource,			 FramedSource* inputSource);  virtual ~MPEG4VideoStreamParser();private: // redefined virtual functions:  virtual void flushInput();  virtual unsigned parse();private:  MPEG4VideoStreamFramer* usingSource() {    return (MPEG4VideoStreamFramer*)fUsingSource;  }  void setParseState(MPEGParseState parseState);  unsigned parseVisualObjectSequence(Boolean haveSeenStartCode = False);  unsigned parseVisualObject();  unsigned parseVideoObjectLayer();  unsigned parseGroupOfVideoObjectPlane();  unsigned parseVideoObjectPlane();  unsigned parseVisualObjectSequenceEndCode();  // These are used for parsing within an already-read frame:  Boolean getNextFrameBit(u_int8_t& result);  Boolean getNextFrameBits(unsigned numBits, u_int32_t& result);  // Which are used by:  void analyzeVOLHeader();private:  MPEGParseState fCurrentParseState;  unsigned fNumBitsSeenSoFar; // used by the getNextFrameBit*() routines   u_int32_t vop_time_increment_resolution;  unsigned fNumVTIRBits;      // # of bits needed to count to "vop_time_increment_resolution"  u_int8_t fixed_vop_rate;  unsigned fixed_vop_time_increment; // used if 'fixed_vop_rate' is set  unsigned fSecondsSinceLastTimeCode, fTotalTicksSinceLastTimeCode, fPrevNewTotalTicks;   unsigned fPrevPictureCountDelta;};////////// MPEG4VideoStreamFramer implementation //////////MPEG4VideoStreamFramer*MPEG4VideoStreamFramer::createNew(UsageEnvironment& env,				  FramedSource* inputSource) {  // Need to add source type checking here???  #####  return new MPEG4VideoStreamFramer(env, inputSource);}unsigned char* MPEG4VideoStreamFramer::getConfigBytes(unsigned& numBytes) const {  numBytes = fNumConfigBytes;  return fConfigBytes;}MPEG4VideoStreamFramer::MPEG4VideoStreamFramer(UsageEnvironment& env,					       FramedSource* inputSource,					       Boolean createParser)  : MPEGVideoStreamFramer(env, inputSource),    fProfileAndLevelIndication(0),    fConfigBytes(NULL), fNumConfigBytes(0),    fNewConfigBytes(NULL), fNumNewConfigBytes(0) {  fParser = createParser    ? new MPEG4VideoStreamParser(this, inputSource)    : NULL;}MPEG4VideoStreamFramer::~MPEG4VideoStreamFramer() {  delete[] fConfigBytes; delete[] fNewConfigBytes;}void MPEG4VideoStreamFramer::startNewConfig() {  delete[] fNewConfigBytes; fNewConfigBytes = NULL;  fNumNewConfigBytes = 0;}void MPEG4VideoStreamFramer::appendToNewConfig(unsigned char* newConfigBytes, unsigned numNewBytes) {  // Allocate a new block of memory for the new config bytes:  unsigned char* configNew    = new unsigned char[fNumNewConfigBytes + numNewBytes];  // Copy the old, then the new, config bytes there:  memmove(configNew, fNewConfigBytes, fNumNewConfigBytes);  memmove(&configNew[fNumNewConfigBytes], newConfigBytes, numNewBytes);    delete[] fNewConfigBytes; fNewConfigBytes = configNew;  fNumNewConfigBytes += numNewBytes;}void MPEG4VideoStreamFramer::completeNewConfig() {  delete fConfigBytes; fConfigBytes = fNewConfigBytes;  fNewConfigBytes = NULL;  fNumConfigBytes = fNumNewConfigBytes;  fNumNewConfigBytes = 0;}Boolean MPEG4VideoStreamFramer::isMPEG4VideoStreamFramer() const {  return True;}////////// MPEG4VideoStreamParser implementation //////////MPEG4VideoStreamParser::MPEG4VideoStreamParser(MPEG4VideoStreamFramer* usingSource,			 FramedSource* inputSource)  : MPEGVideoStreamParser(usingSource, inputSource),    fCurrentParseState(PARSING_VISUAL_OBJECT_SEQUENCE),    vop_time_increment_resolution(0), fNumVTIRBits(0),    fixed_vop_rate(0), fixed_vop_time_increment(0),    fSecondsSinceLastTimeCode(0), fTotalTicksSinceLastTimeCode(0),    fPrevNewTotalTicks(0), fPrevPictureCountDelta(1) {}MPEG4VideoStreamParser::~MPEG4VideoStreamParser() {}void MPEG4VideoStreamParser::setParseState(MPEGParseState parseState) {  fCurrentParseState = parseState;  MPEGVideoStreamParser::setParseState();}void MPEG4VideoStreamParser::flushInput() {  fSecondsSinceLastTimeCode = 0;  fTotalTicksSinceLastTimeCode = 0;  fPrevNewTotalTicks = 0;  fPrevPictureCountDelta = 1;  StreamParser::flushInput();  if (fCurrentParseState != PARSING_VISUAL_OBJECT_SEQUENCE) {    setParseState(PARSING_VISUAL_OBJECT_SEQUENCE); // later, change to GOV or VOP? #####  }}unsigned MPEG4VideoStreamParser::parse() {  try {    switch (fCurrentParseState) {    case PARSING_VISUAL_OBJECT_SEQUENCE: {      return parseVisualObjectSequence();    }    case PARSING_VISUAL_OBJECT_SEQUENCE_SEEN_CODE: {      return parseVisualObjectSequence(True);    }    case PARSING_VISUAL_OBJECT: {      return parseVisualObject();    }    case PARSING_VIDEO_OBJECT_LAYER: {      return parseVideoObjectLayer();    }    case PARSING_GROUP_OF_VIDEO_OBJECT_PLANE: {      return parseGroupOfVideoObjectPlane();    }    case PARSING_VIDEO_OBJECT_PLANE: {      return parseVideoObjectPlane();    }    case PARSING_VISUAL_OBJECT_SEQUENCE_END_CODE: {      return parseVisualObjectSequenceEndCode();    }    default: {      return 0; // shouldn't happen    }    }  } catch (int /*e*/) {#ifdef DEBUG    fprintf(stderr, "MPEG4VideoStreamParser::parse() EXCEPTION (This is normal behavior - *not* an error)\n");#endif    return 0;  // the parsing got interrupted  }}#define VISUAL_OBJECT_SEQUENCE_START_CODE 0x000001B0#define VISUAL_OBJECT_SEQUENCE_END_CODE   0x000001B1#define GROUP_VOP_START_CODE              0x000001B3#define VISUAL_OBJECT_START_CODE          0x000001B5#define VOP_START_CODE                    0x000001B6unsigned MPEG4VideoStreamParser::parseVisualObjectSequence(Boolean haveSeenStartCode) {#ifdef DEBUG  fprintf(stderr, "parsing VisualObjectSequence\n");#endif  usingSource()->startNewConfig();  u_int32_t first4Bytes;  if (!haveSeenStartCode) {    while ((first4Bytes = test4Bytes()) != VISUAL_OBJECT_SEQUENCE_START_CODE) {#ifdef DEBUG      fprintf(stderr, "ignoring non VS header: 0x%08x\n", first4Bytes);#endif      get1Byte(); setParseState(PARSING_VISUAL_OBJECT_SEQUENCE);          // ensures we progress over bad data    }    first4Bytes = get4Bytes();  } else {    // We've already seen the start code    first4Bytes = VISUAL_OBJECT_SEQUENCE_START_CODE;  }  save4Bytes(first4Bytes);  // The next byte is the "profile_and_level_indication":  u_int8_t pali = get1Byte();#ifdef DEBUG  fprintf(stderr, "profile_and_level_indication: %02x\n", pali);#endif  saveByte(pali);  usingSource()->fProfileAndLevelIndication = pali;  // Now, copy all bytes that we see, up until we reach  // a VISUAL_OBJECT_START_CODE:  u_int32_t next4Bytes = get4Bytes();  while (next4Bytes != VISUAL_OBJECT_START_CODE) {    saveToNextCode(next4Bytes);  }    setParseState(PARSING_VISUAL_OBJECT);  // Compute this frame's presentation time:  usingSource()->computePresentationTime(fTotalTicksSinceLastTimeCode);  // This header forms part of the 'configuration' information:  usingSource()->appendToNewConfig(fStartOfFrame, curFrameSize());  return curFrameSize();}static inline Boolean isVideoObjectStartCode(u_int32_t code) {  return code >= 0x00000100 && code <= 0x0000011F;}unsigned MPEG4VideoStreamParser::parseVisualObject() {#ifdef DEBUG  fprintf(stderr, "parsing VisualObject\n");#endif  // Note that we've already read the VISUAL_OBJECT_START_CODE  save4Bytes(VISUAL_OBJECT_START_CODE);  // Next, extract the "visual_object_type" from the next 1 or 2 bytes:  u_int8_t nextByte = get1Byte(); saveByte(nextByte);  Boolean is_visual_object_identifier = (nextByte&0x80) != 0;  u_int8_t visual_object_type;  if (is_visual_object_identifier) {#ifdef DEBUG    fprintf(stderr, "visual_object_verid: 0x%x; visual_object_priority: 0x%x\n", (nextByte&0x78)>>3, (nextByte&0x07));#endif    nextByte = get1Byte(); saveByte(nextByte);    visual_object_type = (nextByte&0xF0)>>4;  } else {    visual_object_type = (nextByte&0x78)>>3;  }#ifdef DEBUG  fprintf(stderr, "visual_object_type: 0x%x\n", visual_object_type);#endif  // At present, we support only the "Video ID" "visual_object_type" (1)  if (visual_object_type != 1) {    usingSource()->envir() << "MPEG4VideoStreamParser::parseVisualObject(): Warning: We don't handle visual_object_type " << visual_object_type << "\n";  }    // Now, copy all bytes that we see, up until we reach  // a video_object_start_code  u_int32_t next4Bytes = get4Bytes();  while (!isVideoObjectStartCode(next4Bytes)) {    saveToNextCode(next4Bytes);  }  save4Bytes(next4Bytes);#ifdef DEBUG  fprintf(stderr, "saw a video_object_start_code: 0x%08x\n", next4Bytes);#endif  setParseState(PARSING_VIDEO_OBJECT_LAYER);  // Compute this frame's presentation time:  usingSource()->computePresentationTime(fTotalTicksSinceLastTimeCode);  // This header forms part of the 'configuration' information:  usingSource()->appendToNewConfig(fStartOfFrame, curFrameSize());  return curFrameSize();}static inline Boolean isVideoObjectLayerStartCode(u_int32_t code) {  return code >= 0x00000120 && code <= 0x0000012F;}

⌨️ 快捷键说明

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