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

📄 h263plusvideostreamparser.cpp

📁 H.264 RTSP 串流(live 555)視窗版本
💻 CPP
📖 第 1 页 / 共 3 页
字号:
        cbrTolerance = H263_DEFAULT_CBR_TOLERANCE;      // Same as: if (maxBitrate / avgBitrate > (cbrTolerance + 100) / 100.0)      if (maxBitrateCtx.maxBitrate * 100 > (cbrTolerance + 100) * avgBitrate)        avgBitrate = 0;      MP4SetH263Bitrates(outputFileHandle, trackId,          avgBitrate, maxBitrateCtx.maxBitrate);    }    // Return the newly added track ID    return trackId;  }  // If we got to here... something went wrong ...  fprintf(stderr,    "%s: Could not parse input file, invalid video stream?\n", ProgName);  // Upon failure, delete the newly added track if it has been added  if (trackId != MP4_INVALID_TRACK_ID) {    MP4DeleteTrack(outputFileHandle, trackId);  }  return MP4_INVALID_TRACK_ID;}/ * * LoadNextH263Object - 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: *      inputFileHandle - The handle of the input file *      frameBuffer - buffer where to place read data *      frameBufferSize - in/out parameter indicating the size of the buffer on *                          entry and the number of bytes copied to the buffer upon *                          return *      additionalBytesNeeded - indicates how many additional bytes are to be read *                          from the next frame's header (over the 3 bytes that *                          are already read). *                          NOTE: This number MUST be > 0 *      ppNextHeader - output parameter that upon return points to the location *                     of the next frame's head in the buffer * Outputs: *      This function returns two pieces of information: *      1. The total number of bytes read. *      2. A Pointer to the header of the next frame. This pointer shall be NULL *      for the last frame read. * /static int LoadNextH263Object(  FILE           *inputFileHandle,                                u_int8_t       *frameBuffer,                                u_int32_t      *frameBufferSize,                                u_int32_t       additionalBytesNeeded,                                u_int8_t      **ppNextHeader){  // This table and the following loop implements a state machine enabling  // us to read bytes from the file untill (and inclusing) the requested  // start code (00 00 8X) is found  int8_t        row = 0;  u_int8_t     *bufferStart = frameBuffer;  // The buffer end which will allow the loop to leave place for  // the additionalBytesNeeded  u_int8_t     *bufferEnd = frameBuffer + *frameBufferSize -                                              additionalBytesNeeded - 1;  // Initialize the states array, if it hasn't been initialized yet...  if (!states[0][0]) {    // One 00 was read    states[0][0] = 1;    // Two sequential 0x00 ware read    states[1][0] = states[2][0] = 2;    // A full start code was read    states[2][128] = states[2][129] = states[2][130] = states[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 {    if (fread(frameBuffer, 1, 1, inputFileHandle) != 1){      // EOF or other error before we got a start code      *ppNextHeader = NULL;      *frameBufferSize = frameBuffer - bufferStart;      return 1;    }  } while ((frameBuffer < bufferEnd) &&                    // We have place in the buffer           ((row = states[row][*(frameBuffer++)]) != -1)); // Start code was not found  if (row != -1) {    fprintf(stderr, "%s: Buffer too small (%u)\n",            ProgName, bufferEnd - bufferStart + additionalBytesNeeded);    return 0;  }  // Cool ... now we have a start code  *ppNextHeader = frameBuffer - H263_STARTCODE_SIZE_BYTES;  *frameBufferSize = frameBuffer - bufferStart + additionalBytesNeeded;  // Now we just have to read the additionalBytesNeeded  if(fread(frameBuffer, additionalBytesNeeded, 1, inputFileHandle) != 1) {    /// We got a start code but can't read additionalBytesNeeded ... that's a fatal error    fprintf(stderr, "%s: Invalid H263 bitstream\n", ProgName);    return 0;  }  return 1;}/ * * 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. * /static bool 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 * /static void 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    ctx->tableIndex = (ctx->tableIndex + 1) %        // Wrapping around the bitrateTable size        ( 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 * Outputs: *      The current frame's duration in milli-seconds * /static MP4Duration CalculateDuration(u_int8_t   trDiff){  static u_int32_t    nextTR    = 0;   // The next frame's presentation time in TR units  static MP4Duration  currentPT = 0;   // The current frame's presentation time in milli-seconds  MP4Duration         nextPT;          // The next frame's presentation time in milli-seconds  MP4Duration         duration;        // The current frame's duration in milli-seconds  nextTR += trDiff;  // Calculate the next frame's presentation time, in milli-seconds  nextPT = (nextTR * 1001) / H263_BASIC_FRAME_RATE;  // The frame's duration is the difference between the next presentation  // time and the current presentation time.  duration = nextPT - currentPT;  // "Remember" the next presentation time for the next time this function is  // called  currentPT = nextPT;  return duration;}static bool 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;}static u_int8_t GetTRDifference(u_int8_t        nextTR,                                u_int8_t        currentTR){  if (currentTR > nextTR) {    // Wrap around 255...    return nextTR + (256 - currentTR);  } else {    return nextTR - currentTR;  }}*/

⌨️ 快捷键说明

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