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

📄 h263plusvideostreamparser.cpp

📁 linux下的rtsp/rtp/rtcp协议栈源代码; c++写的
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/**********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-2006 Live Networks, Inc.  All rights reserved.// Author Bernhard Feiten// A filter that breaks up an H.263plus video stream into frames.// Based on MPEG4IP/mp4creator/h263.c#include "H263plusVideoStreamParser.hh"#include "H263plusVideoStreamFramer.hh"//#include <string.h>//#include "GroupsockHelper.hh"H263plusVideoStreamParser::H263plusVideoStreamParser(                              H263plusVideoStreamFramer* usingSource,                              FramedSource* inputSource)                              : StreamParser(inputSource,                                   FramedSource::handleClosure,                                   usingSource,                                   &H263plusVideoStreamFramer::continueReadProcessing,                                   usingSource),                                fUsingSource(usingSource),                                fnextTR(0),                                fcurrentPT(0){   memset(fStates, 0, sizeof(fStates));   memset(&fNextInfo, 0, sizeof(fNextInfo));   memset(&fCurrentInfo, 0, sizeof(fCurrentInfo));   memset(&fMaxBitrateCtx, 0, sizeof(fMaxBitrateCtx));   memset(fNextHeader,0, H263_REQUIRE_HEADER_SIZE_BYTES);}///////////////////////////////////////////////////////////////////////////////H263plusVideoStreamParser::~H263plusVideoStreamParser(){}///////////////////////////////////////////////////////////////////////////////void H263plusVideoStreamParser::restoreSavedParserState(){   StreamParser::restoreSavedParserState();   fTo = fSavedTo;   fNumTruncatedBytes = fSavedNumTruncatedBytes;}///////////////////////////////////////////////////////////////////////////////void H263plusVideoStreamParser::setParseState(){   fSavedTo = fTo;   fSavedNumTruncatedBytes = fNumTruncatedBytes;   saveParserState();  // Needed for the parsing process in StreamParser}///////////////////////////////////////////////////////////////////////////////void H263plusVideoStreamParser::registerReadInterest(                                   unsigned char* to,                                   unsigned maxSize){   fStartOfFrame = fTo = fSavedTo = to;   fLimit = to + maxSize;   fMaxSize = maxSize;   fNumTruncatedBytes = fSavedNumTruncatedBytes = 0;}///////////////////////////////////////////////////////////////////////////////// parse() ,  derived from H263Creator of MPEG4IP, h263.cunsigned H263plusVideoStreamParser::parse(u_int64_t & currentDuration){//   u_int8_t       frameBuffer[H263_BUFFER_SIZE]; // The input buffer                 // Pointer which tells LoadNextH263Object where to read data to//   u_int8_t*      pFrameBuffer = fTo + H263_REQUIRE_HEADER_SIZE_BYTES;   u_int32_t      frameSize;        // The current frame size                                // Pointer to receive address of the header data//   u_int8_t*      pCurrentHeader;// = pFrameBuffer;//   u_int64_t      currentDuration;  // The current frame's duration   u_int8_t       trDifference;     // The current TR difference                                   // The previous TR difference//   u_int8_t       prevTrDifference = H263_BASIC_FRAME_RATE;//   u_int64_t      totalDuration = 0;// Duration accumulator//   u_int64_t      avgBitrate;       // Average bitrate//   u_int64_t      totalBytes = 0;   // Size accumulator   try    // The get data routines of the class FramedFilter returns an error when   {      // the buffer is empty. This occurs at the beginning and at the end of the file.      fCurrentInfo = fNextInfo;      // Parse 1 frame      // For the first time, only the first frame's header is returned.      // The second time the full first frame is returned      frameSize = parseH263Frame();       currentDuration = 0;      if ((frameSize > 0)){          // We were able to acquire a frame from the input.         // Parse the returned frame header (if any)         if (!ParseShortHeader(fTo, &fNextInfo))           ;// fprintf(stderr,"H263plusVideoStreamParser: Fatal error\n");         trDifference = GetTRDifference(fNextInfo.tr, fCurrentInfo.tr);         // calculate the current frame duration         currentDuration = CalculateDuration(trDifference);         // Accumulate the frame's size and duration for avgBitrate calculation         //totalDuration += currentDuration;         //totalBytes += frameSize;         //  If needed, recalculate bitrate information         //    if (h263Bitrates)         //GetMaxBitrate(&fMaxBitrateCtx, frameSize, prevTrDifference);         //prevTrDifference = trDifference;      }   } catch (int /*e*/) {#ifdef DEBUG      fprintf(stderr, "H263plusVideoStreamParser::parse() EXCEPTION (This is normal behavior - *not* an error)\n");#endif      frameSize=0;   }   setParseState(); // Needed for the parsing process in StreamParser   return frameSize;}///////////////////////////////////////////////////////////////////////////////// parseH263Frame derived from LoadNextH263Object of MPEG4IP // - service routine that reads a single frame from the input file.// It shall fill the input buffer with data up until - and including - the// next start code and shall report back both the number of bytes read and a// pointer to the next start code. The first call to this function shall only// yield a pointer with 0 data bytes and the last call to this function shall// only yield data bytes with a NULL pointer as the next header.//// TODO: This function only supports valid bit streams. Upon error, it fails// without the possibility to recover. A Better idea would be to skip frames// until a parsable frame is read from the file.//// Parameters://      ppNextHeader - output parameter that upon return points to the location//                     of the next frame's head in the buffer.//                     This pointer shall be NULL for the last frame read.// Returns the total number of bytes read.// Uses FrameFileSource intantiated by constructor.///////////////////////////////////////////////////////////////////////////////int H263plusVideoStreamParser::parseH263Frame( ){   char     row = 0;   u_int8_t * bufferIndex = fTo;   // The buffer end which will allow the loop to leave place for   // the additionalBytesNeeded   u_int8_t * bufferEnd = fTo + fMaxSize - ADDITIONAL_BYTES_NEEDED - 1;	   memcpy(fTo, fNextHeader, H263_REQUIRE_HEADER_SIZE_BYTES);   bufferIndex += H263_REQUIRE_HEADER_SIZE_BYTES;      // The state table and the following loop implements a state machine enabling   // us to read bytes from the file until (and inclusing) the requested   // start code (00 00 8X) is found   // Initialize the states array, if it hasn't been initialized yet...   if (!fStates[0][0]) {      // One 00 was read      fStates[0][0] = 1;      // Two sequential 0x00 ware read      fStates[1][0] = fStates[2][0] = 2;      // A full start code was read      fStates[2][128] = fStates[2][129] = fStates[2][130] = fStates[2][131] = -1;   }   // Read data from file into the output buffer until either a start code   // is found, or the end of file has been reached.   do {      *bufferIndex = get1Byte();   } while ((bufferIndex < bufferEnd) &&                    // We have place in the buffer            ((row = fStates[(unsigned char)row][*(bufferIndex++)]) != -1)); // Start code was not found   if (row != -1) {      fprintf(stderr, "%s: Buffer too small (%u)\n",         "h263reader:", bufferEnd - fTo + ADDITIONAL_BYTES_NEEDED);      return 0;   }   // Cool ... now we have a start code   // Now we just have to read the additionalBytesNeeded   getBytes(bufferIndex, ADDITIONAL_BYTES_NEEDED);   memcpy(fNextHeader, bufferIndex - H263_STARTCODE_SIZE_BYTES, H263_REQUIRE_HEADER_SIZE_BYTES);	int sz = bufferIndex - fTo - H263_STARTCODE_SIZE_BYTES;   if (sz == 5) // first frame      memcpy(fTo, fTo+H263_REQUIRE_HEADER_SIZE_BYTES, H263_REQUIRE_HEADER_SIZE_BYTES);   return sz;}////////////////////////////////////////////////////////////////////////////////// ParseShortHeader - service routine that accepts a buffer containing a frame// header and extracts relevant codec information from it.//// NOTE: the first bit in the following commnets is 0 (zero).////       0                   1                   2                   3//       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1//      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+//      |      PSC (Picture Start Code=22 bits)     |  (TR=8 bits)  |   >//      |0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0|               |1 0>//      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+//      <   (PTYPE=13 bits)   |//      <. . .|(FMT)|Z|. . . .|//      +-+-+-+-+-+-+-+-+-+-+-+//      -> PTYPE.FMT contains a width/height identification//      -> PTYPE.Z   is 1 for P-Frames, 0 for I-Frames//      Note: When FMT is 111, there is an extended PTYPE...//// Inputs://      headerBuffer - pointer to the current header buffer//      outputInfoStruct - pointer to the structure receiving the data// Outputs://      This function returns a structure of important codec-specific//      information (The Temporal Reference bits, width & height of the current//      frame and the sync - or "frame type" - bit. It reports success or//      failure to the calling function.////////////////////////////////////////////////////////////////////////////////bool H263plusVideoStreamParser::ParseShortHeader(                                   u_int8_t *headerBuffer,                                   H263INFO *outputInfoStruct){   u_int8_t fmt = 0;   // Extract temporal reference (TR) from the buffer (bits 22-29 inclusive)   outputInfoStruct->tr  = (headerBuffer[2] << 6) & 0xC0; // 2 LS bits out of the 3rd byte   outputInfoStruct->tr |= (headerBuffer[3] >> 2) & 0x3F; // 6 MS bits out of the 4th byte   // Extract the FMT part of PTYPE from the buffer (bits 35-37 inclusive)   fmt = (headerBuffer[4] >> 2) & 0x07; // bits 3-5 ouf of the 5th byte   // If PTYPE is not supported, return a failure notice to the calling function   // FIXME: PLUSPTYPE is not supported   if (fmt == 0x07) {      return false;   }   // If PTYPE is supported, calculate the current width and height according to   // a predefined table   if (!GetWidthAndHeight(fmt, &(outputInfoStruct->width),                               &(outputInfoStruct->height))) {      return false;   }   // Extract the frame-type bit, which is the 9th bit of PTYPE (bit 38)   outputInfoStruct->isSyncFrame = !(headerBuffer[4] & 0x02);  return true;}////////////////////////////////////////////////////////////////////////////////// GetMaxBitrate- service routine that accepts frame information and// derives bitrate information from it. This function uses a sliding window// technique to calculate the maximum bitrates in any window of 1 second// inside the file.// The sliding window is implemented with a table of bitrates for the last// second (30 entries - one entry per TR unit).//// Inputs://      ctx - context for this function//      frameSize - the size of the current frame in bytes//      frameTRDiff - the "duration" of the frame in TR units// Outputs://      This function returns the up-to-date maximum bitrate////////////////////////////////////////////////////////////////////////////////void H263plusVideoStreamParser::GetMaxBitrate( MaxBitrate_CTX *ctx,                                               u_int32_t      frameSize,

⌨️ 快捷键说明

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