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

📄 h263plusvideostreamparser.cpp

📁 H.264 RTSP 串流(live 555)視窗版本
💻 CPP
📖 第 1 页 / 共 3 页
字号:
void H263plusVideoStreamParser::GetMaxBitrate( MaxBitrate_CTX *ctx,                                               u_int32_t      frameSize,                                               u_int8_t       frameTRDiff){   if (frameTRDiff == 0)      return;   // Calculate the current frame's bitrate as bits per TR unit (round the result   // upwards)   u_int32_t frameBitrate = frameSize * 8 / frameTRDiff + 1;   // for each TRdiff received,   while (frameTRDiff--) {      // Subtract the oldest bitrate entry from the current bitrate      ctx->windowBitrate -= ctx->bitrateTable[ctx->tableIndex];      // Update the oldest bitrate entry with the current frame's bitrate      ctx->bitrateTable[ctx->tableIndex] = frameBitrate;      // Add the current frame's bitrate to the current bitrate      ctx->windowBitrate += frameBitrate;      // Check if we have a new maximum bitrate      if (ctx->windowBitrate > ctx->maxBitrate) {         ctx->maxBitrate = ctx->windowBitrate;	  }      // Advance the table index      // Wrapping around the bitrateTable size      ctx->tableIndex = (ctx->tableIndex + 1) %        ( sizeof(ctx->bitrateTable) / sizeof(ctx->bitrateTable[0]) );   }}////////////////////////////////////////////////////////////////////////////////// CalculateDuration - service routine that calculates the current frame's// duration in milli-seconds using it's duration in TR units.//  - In order not to accumulate the calculation error, we are using the TR// duration to calculate the current and the next frame's presentation time in// milli-seconds.//// Inputs: trDiff - The current frame's duration in TR units// Return: The current frame's duration in milli-seconds////////////////////////////////////////////////////////////////////////////////u_int64_t H263plusVideoStreamParser::CalculateDuration(u_int8_t trDiff){  //static u_int32_t nextTR    = 0;   // The next frame's presentation time in TR units  //static u_int64_t currentPT = 0;   // The current frame's presentation time in milli-seconds  u_int64_t        nextPT;          // The next frame's presentation time in milli-seconds  u_int64_t        duration;        // The current frame's duration in milli-seconds  fnextTR += trDiff;  // Calculate the next frame's presentation time, in milli-seconds  nextPT = (fnextTR * 1001) / H263_BASIC_FRAME_RATE;  // The frame's duration is the difference between the next presentation  // time and the current presentation time.  duration = nextPT - fcurrentPT;  // "Remember" the next presentation time for the next time this function is called  fcurrentPT = nextPT;  return duration;}////////////////////////////////////////////////////////////////////////////////bool H263plusVideoStreamParser::GetWidthAndHeight( u_int8_t  fmt,                                                   u_int16_t *width,                                                   u_int16_t *height){   // The 'fmt' corresponds to bits 5-7 of the PTYPE   static struct {      u_int16_t width;      u_int16_t height;   } dimensionsTable[8] = {	   { 0,    0 },      // 000 - 0 - forbidden, generates an error	   { 128,  96 },     // 001 - 1 - Sub QCIF	   { 176,  144 },    // 010 - 2 - QCIF	   { 352,  288 },    // 011 - 3 - CIF	   { 704,  576 },    // 100 - 4 - 4CIF	   { 1409, 1152 },   // 101 - 5 - 16CIF	   { 0,    0 },      // 110 - 6 - reserved, generates an error	   { 0,    0 }       // 111 - 7 - extended, not supported by profile 0   };   if (fmt > 7)      return false;   *width  = dimensionsTable[fmt].width;   *height = dimensionsTable[fmt].height;   if (*width  == 0)     return false;   return true;}////////////////////////////////////////////////////////////////////////////////u_int8_t H263plusVideoStreamParser::GetTRDifference(                                              u_int8_t nextTR,                                              u_int8_t currentTR){   if (currentTR > nextTR) {      // Wrap around 255...      return nextTR + (256 - currentTR);   } else {      return nextTR - currentTR;   }}////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// this is the h263.c file of MPEG4IP mp4creator/*#include "mp4creator.h"// Default timescale for H.263 (1000ms)#define H263_TIMESCALE 1000// Default H263 frame rate (30fps)#define H263_BASIC_FRAME_RATE 30// Minimum number of bytes needed to parse an H263 header#define H263_REQUIRE_HEADER_SIZE_BYTES 5// Number of bytes the start code requries#define H263_STARTCODE_SIZE_BYTES 3// This is the input buffer's size. It should contain// 1 frame with the following start code#define H263_BUFFER_SIZE 256 * 1024// The default max different (in %) betwqeen max and average bitrates#define H263_DEFAULT_CBR_TOLERANCE  10// The following structure holds information extracted from each frame's header:typedef struct _H263INFO {  u_int8_t  tr;                 // Temporal Reference, used in duration calculation  u_int16_t width;              // Width of the picture  u_int16_t height;             // Height of the picture  bool      isSyncFrame;        // Frame type (true = I frame = "sync" frame)} H263INFO;// Context for the GetMaxBitrate functiontypedef struct _MaxBitrate_CTX {  u_int32_t  bitrateTable[H263_BASIC_FRAME_RATE];// Window of 1 second  u_int32_t  windowBitrate;              // The bitrate of the current window  u_int32_t  maxBitrate;                 // The up-to-date maximum bitrate  u_int32_t  tableIndex;                 // The next TR unit to update} MaxBitrate_CTX;// Forward declarations:static int LoadNextH263Object(  FILE           *inputFileHandle,                                u_int8_t       *frameBuffer,                                u_int32_t      *frameBufferSize,                                u_int32_t       additionalBytesNeeded,                                u_int8_t      **ppNextHeader);static bool ParseShortHeader(   u_int8_t       *headerBuffer,                                H263INFO       *outputInfoStruct);static u_int8_t GetTRDifference(u_int8_t        nextTR,                                u_int8_t        currentTR);static void GetMaxBitrate(      MaxBitrate_CTX *ctx,                                u_int32_t       frameSize,                                u_int8_t        frameTRDiff);static MP4Duration CalculateDuration(u_int8_t   trDiff);static bool GetWidthAndHeight(  u_int8_t        fmt,                                u_int16_t      *width,                                u_int16_t      *height);static char   states[3][256];/ * * H263Creator - Main function * Inputs: *      outputFileHandle - The handle of the output file *      inputFileHandle - The handle of the input file *      Codec-specific parameters: *              H263Level - H.263 Level used for this track *              H263Profile - H.263 Profile used for this track *              H263Bitrates - A Parameter indicating whether the function *                             should calculate H263 bitrates or not. *              cbrTolerance - CBR tolerance indicates when to set the *                             average bitrate. * Outputs: *      This function returns either the track ID of the newly added track upon *      success or a predefined value representing an erroneous state. * /MP4TrackId H263Creator(MP4FileHandle outputFileHandle,                       FILE*         inputFileHandle,                       u_int8_t      h263Profile,                       u_int8_t      h263Level,                       bool          h263Bitrates,                       u_int8_t      cbrTolerance){  H263INFO       nextInfo;   // Holds information about the next frame  H263INFO       currentInfo;// Holds information about the current frame  MaxBitrate_CTX maxBitrateCtx;// Context for the GetMaxBitrate function  memset(&nextInfo, 0, sizeof(nextInfo));  memset(&currentInfo, 0, sizeof(currentInfo));  memset(&maxBitrateCtx, 0, sizeof(maxBitrateCtx));  memset(states, 0, sizeof(states));  u_int8_t       frameBuffer[H263_BUFFER_SIZE]; // The input buffer                 // Pointer which tells LoadNextH263Object where to read data to  u_int8_t*      pFrameBuffer = frameBuffer + 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;  MP4Duration    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;  MP4Duration    totalDuration = 0;// Duration accumulator  MP4Duration    avgBitrate;       // Average bitrate  u_int64_t      totalBytes = 0;   // Size accumulator  MP4TrackId     trackId = MP4_INVALID_TRACK_ID; // Our MP4 track  bool           stay = true;      // loop flag  while (stay) {    currentInfo = nextInfo;    memmove(frameBuffer, pCurrentHeader, H263_REQUIRE_HEADER_SIZE_BYTES);    frameSize = H263_BUFFER_SIZE - H263_REQUIRE_HEADER_SIZE_BYTES;    // Read 1 frame and the next frame's header from the file.    // For the first frame, only the first frame's header is returned.    // For the last frame, only the last frame's data is returned.    if (! LoadNextH263Object(inputFileHandle, pFrameBuffer, &frameSize,          H263_REQUIRE_HEADER_SIZE_BYTES - H263_STARTCODE_SIZE_BYTES,          &pCurrentHeader))      break; // Fatal error ...    if (pCurrentHeader) {      // Parse the returned frame header (if any)      if (!ParseShortHeader(pCurrentHeader, &nextInfo))        break; // Fatal error      trDifference = GetTRDifference(nextInfo.tr, currentInfo.tr);    } else {      // This is the last frame ... we have to fake the trDifference ...      trDifference = 1;      // No header data has been read at this iteration, so we have to manually      // add the frame's header we read at the previous iteration.      // Note that LoadNextH263Object returns the number of bytes read, which      // are the current frame's data and the next frame's header      frameSize += H263_REQUIRE_HEADER_SIZE_BYTES;      // There is no need for the next iteration ...      stay = false;    }    // If this is the first iteration ...    if (currentInfo.width == 0) {      // If we have more data than just the header      if ((frameSize > H263_REQUIRE_HEADER_SIZE_BYTES) ||          !pCurrentHeader)  // Or no header at all        break;     // Fatal error      else        continue;  // We have only the first frame's header ...    }    if (trackId == MP4_INVALID_TRACK_ID) {      //  If a track has not been added yet, add the track to the file.      trackId = MP4AddH263VideoTrack(outputFileHandle, H263_TIMESCALE,          0, currentInfo.width, currentInfo.height,          h263Level, h263Profile, 0, 0);      if (trackId == MP4_INVALID_TRACK_ID)        break; // Fatal error    }    // calculate the current frame duration    currentDuration = CalculateDuration(trDifference);    // Write the current frame to the file.    if (!MP4WriteSample(outputFileHandle, trackId, frameBuffer, frameSize,          currentDuration, 0, currentInfo.isSyncFrame))      break; // Fatal error    // Accumulate the frame's size and duration for avgBitrate calculation    totalDuration += currentDuration;    totalBytes += frameSize;    //  If needed, recalculate bitrate information    if (h263Bitrates)      GetMaxBitrate(&maxBitrateCtx, frameSize, prevTrDifference);    prevTrDifference = trDifference;  } // while (stay)  // If this is the last frame,  if (!stay) {    // If needed and possible, update bitrate information in the file    if (h263Bitrates && totalDuration) {      avgBitrate = (totalBytes * 8 * H263_TIMESCALE) / totalDuration;      if (cbrTolerance == 0)

⌨️ 快捷键说明

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