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

📄 mpeg2ps.c

📁 完整的RTP RTSP代码库
💻 C
📖 第 1 页 / 共 4 页
字号:
  if (sptr->pes_buffer_size <= sptr->pes_buffer_on + 4) {    if (sptr->pes_buffer_size != sptr->pes_buffer_on)      started_new_pes = true;    if (mpeg2ps_stream_read_next_pes_buffer(sptr) == FALSE) {      return FALSE;    }  }  while (MP4AV_Mpeg3FindNextStart(sptr->pes_buffer + sptr->pes_buffer_on, 				  sptr->pes_buffer_size - sptr->pes_buffer_on,				  &offset,				  &scode) < 0 ||	 (!IS_MPEG_START(scode & 0xff))) {    if (sptr->pes_buffer_size > 3)      sptr->pes_buffer_on = sptr->pes_buffer_size - 3;    else {      sptr->pes_buffer_on = sptr->pes_buffer_size;      started_new_pes = true;    }    if (mpeg2ps_stream_read_next_pes_buffer(sptr) == FALSE) {      return FALSE;    }  }  sptr->pes_buffer_on += offset;  if (offset == 0 && started_new_pes) {    // nothing...  we've copied the timestamp already.  } else {    // we found the new start, but we pulled in a new pes header before    // starting.  So, we want to use the header that we read.    copy_next_pes_ts_to_frame_ts(sptr);    //printf("  %u "U64"\n", sptr->frame_ts.have_dts, sptr->frame_ts.dts);  }#if 0  printf("header %x at %d\n", scode, sptr->pes_buffer_on);#endif  if (scode == MPEG3_PICTURE_START_CODE) {    sptr->pict_header_offset = sptr->pes_buffer_on;    have_pict = true;  } else have_pict = false;  start = 4 + sptr->pes_buffer_on;  while (1) {        if (MP4AV_Mpeg3FindNextStart(sptr->pes_buffer + start, 				 sptr->pes_buffer_size - start,				 &offset,				 &scode) < 0) {      start = sptr->pes_buffer_size - 3;      start -= sptr->pes_buffer_on;      sptr->pict_header_offset -= sptr->pes_buffer_on;      if (mpeg2ps_stream_read_next_pes_buffer(sptr) == FALSE) {	return FALSE;      }      start += sptr->pes_buffer_on;      sptr->pict_header_offset += sptr->pes_buffer_on;    } else {#if 0      printf("2header %x at %d\n", scode, start);#endif      start += offset;      if (have_pict == FALSE) {	if (scode == MPEG3_PICTURE_START_CODE) {	  have_pict = true;	  sptr->pict_header_offset = start;	}      } else {	if (IS_MPEG_START(scode & 0xff) ||	    scode == MPEG3_SEQUENCE_END_START_CODE) {	  sptr->frame_len = start - sptr->pes_buffer_on;	  sptr->have_frame_loaded = true;	  return TRUE;	}      }      start += 4;    }  }  return FALSE;}static bool mpeg2ps_stream_find_h264_video_frame (mpeg2ps_stream_t *sptr){  uint32_t offset;  bool have_pict;  bool started_new_pes = false;  uint32_t start;  uint8_t nal_type;  /*   * First thing - determine if we have enough bytes to read the header.   * if we do, we have the correct timestamp.  If not, we read the new   * pes, so we'd want to use the timestamp we read.   */  sptr->frame_ts = sptr->next_pes_ts;   if (sptr->pes_buffer_size <= sptr->pes_buffer_on + 4) {    if (sptr->pes_buffer_size != sptr->pes_buffer_on)      started_new_pes = true;    if (mpeg2ps_stream_read_next_pes_buffer(sptr) == FALSE) {      return FALSE;    }  }  if (h264_is_start_code(sptr->pes_buffer + sptr->pes_buffer_on) == false) {    do {      uint32_t offset = h264_find_next_start_code(sptr->pes_buffer +						  sptr->pes_buffer_on, 						  sptr->pes_buffer_size -						  sptr->pes_buffer_on);      if (offset == 0) {	if (sptr->pes_buffer_size > 3)	  sptr->pes_buffer_on = sptr->pes_buffer_size - 3;	else {	  sptr->pes_buffer_on = sptr->pes_buffer_size;	  started_new_pes = true;	}	if (mpeg2ps_stream_read_next_pes_buffer(sptr) == FALSE) {	  return FALSE;	}      } else	sptr->pes_buffer_on += offset;    } while (h264_is_start_code(sptr->pes_buffer + sptr->pes_buffer_on) == false);  }  if (started_new_pes) {    // nothing...  we've copied the timestamp already.  } else {    // we found the new start, but we pulled in a new pes header before    // starting.  So, we want to use the header that we read.    copy_next_pes_ts_to_frame_ts(sptr);  }#if 0  printf("header %x at %d\n", scode, sptr->pes_buffer_on);#endif  have_pict = false;  start = 4 + sptr->pes_buffer_on;  while (1) {        if ((offset = h264_find_next_start_code(sptr->pes_buffer + start, 					    sptr->pes_buffer_size - start))	== 0) {      start = sptr->pes_buffer_size - 4;      start -= sptr->pes_buffer_on;      sptr->pict_header_offset -= sptr->pes_buffer_on;      if (mpeg2ps_stream_read_next_pes_buffer(sptr) == FALSE) {	return FALSE;      }      start += sptr->pes_buffer_on;      sptr->pict_header_offset += sptr->pes_buffer_on;    } else {#if 0      printf("2header %x at %d\n", scode, start);#endif      start += offset;      nal_type = h264_nal_unit_type(sptr->pes_buffer + start);      if (have_pict == FALSE) {	if (h264_nal_unit_type_is_slice(nal_type)) {	  have_pict = true;	  sptr->pict_header_offset = start;	}      } else {	if (H264_NAL_TYPE_ACCESS_UNIT == nal_type) {	  sptr->frame_len = start - sptr->pes_buffer_on;	  sptr->have_frame_loaded = true;	  return TRUE;	}      }      start += 4;    }  }  return FALSE;}static bool mpeg2ps_stream_figure_out_video_type (mpeg2ps_stream_t *sptr) {  bool started_new_pes = false;  /*   * First thing - determine if we have enough bytes to read the header.   * if we do, we have the correct timestamp.  If not, we read the new   * pes, so we'd want to use the timestamp we read.   */  sptr->frame_ts = sptr->next_pes_ts;   if (sptr->pes_buffer_size <= sptr->pes_buffer_on + 5) {    if (sptr->pes_buffer_size != sptr->pes_buffer_on)      started_new_pes = true;    if (mpeg2ps_stream_read_next_pes_buffer(sptr) == FALSE) {      return FALSE;    }  }  if (h264_is_start_code(sptr->pes_buffer + sptr->pes_buffer_on) &&      h264_nal_unit_type(sptr->pes_buffer + sptr->pes_buffer_on) ==       H264_NAL_TYPE_ACCESS_UNIT) {    sptr->have_h264 = true;    sptr->determined_type = true;    return mpeg2ps_stream_find_h264_video_frame(sptr);  }   // figure it's mpeg2  sptr->have_h264 = false;  sptr->determined_type = true;  return mpeg2ps_stream_find_mpeg_video_frame(sptr);}static bool mpeg2ps_stream_find_lpcm_frame (mpeg2ps_stream_t *sptr){  uint8_t frames;  uint32_t this_pes_byte_count;  if (sptr->pes_buffer_size == sptr->pes_buffer_on) {    if (mpeg2ps_stream_read_next_pes_buffer(sptr) == false) {      return false;    }  }  if (sptr->channels == 0) {    // means we haven't read anything yet - we need to read for    // frequency and channels.    sptr->channels = 1 + (sptr->audio_private_stream_info[LPCM_INFO] & 0x7);    sptr->freq = lpcm_freq_tab[(sptr->audio_private_stream_info[LPCM_INFO] >> 4) & 7];  }  copy_next_pes_ts_to_frame_ts(sptr);  if (sptr->lpcm_read_offset) {    // we need to read bytes - 4 bytes.  This should only occur when     // we seek.  Otherwise, we've already reall read the bytes when    // we read the last pes    uint32_t bytes_to_skip;    bytes_to_skip =       ntohs(*(uint16_t *)&sptr->audio_private_stream_info[LPCM_PES_OFFSET_MSB]);    bytes_to_skip -= 4;    while (bytes_to_skip > sptr->pes_buffer_size - sptr->pes_buffer_on) {      if (mpeg2ps_stream_read_next_pes_buffer(sptr) == false) {	return FALSE;      }    }     sptr->pes_buffer_on += bytes_to_skip;    sptr->lpcm_read_offset = false;  }  // calculate the number of bytes in this LPCM frame.  There are  // 150 PTS ticks per LPCM frame.  We will read all the PCM frames  // referenced by the header.  frames = sptr->audio_private_stream_info[LPCM_FRAME_COUNT];  this_pes_byte_count = frames;  this_pes_byte_count *= 150;  this_pes_byte_count *= sptr->freq;  this_pes_byte_count *= sptr->channels * sizeof(int16_t);  this_pes_byte_count /= 90000;  //printf("fcount %u bytes %u\n", frames, this_pes_byte_count);  sptr->frame_len = this_pes_byte_count;  while (sptr->pes_buffer_size - sptr->pes_buffer_on < sptr->frame_len) {    if (mpeg2ps_stream_read_next_pes_buffer(sptr) == FALSE) {      return FALSE;    }  }  sptr->have_frame_loaded = true;#if 0  printf("lpcm size %u %u %u %u\n", sptr->pes_buffer_size - sptr->pes_buffer_on, 	 sptr->frame_len,	 sptr->frame_ts.have_dts, sptr->frame_ts.have_pts);#endif  return TRUE;}static bool mpeg2ps_stream_find_ac3_frame (mpeg2ps_stream_t *sptr){  const uint8_t *ret;  uint32_t diff;  bool started_new_pes = false;  sptr->frame_ts = sptr->next_pes_ts; // set timestamp after searching  if (sptr->pes_buffer_size <= sptr->pes_buffer_on + 6) {    if (sptr->pes_buffer_size != sptr->pes_buffer_on)      started_new_pes = true;    if (mpeg2ps_stream_read_next_pes_buffer(sptr) == FALSE) {      return FALSE;    }  }  while (MP4AV_Ac3ParseHeader(sptr->pes_buffer + sptr->pes_buffer_on,			      sptr->pes_buffer_size - sptr->pes_buffer_on,			       &ret, 			      NULL,			      NULL,			      &sptr->frame_len, 			      NULL) <= 0) {    // don't have frame    if (sptr->pes_buffer_size > 6) {      sptr->pes_buffer_on = sptr->pes_buffer_size - 6;      started_new_pes = true;    } else {      sptr->pes_buffer_on = sptr->pes_buffer_size;    }#if 0    printf("no frame - moving %u of %u\n",	   sptr->pes_buffer_on, sptr->pes_buffer_size);#endif    if (mpeg2ps_stream_read_next_pes_buffer(sptr) == FALSE) {      return FALSE;    }  }  // have frame.  diff = ret - (sptr->pes_buffer + sptr->pes_buffer_on);  sptr->pes_buffer_on += diff;  if (diff == 0 && started_new_pes) {    // we might have a new PTS - but it's not here  } else {    copy_next_pes_ts_to_frame_ts(sptr);  }  while (sptr->pes_buffer_size - sptr->pes_buffer_on < sptr->frame_len) {#if 0    printf("don't have enough - on %u size %u %u %u\n", sptr->pes_buffer_on, 	   sptr->pes_buffer_size,	   sptr->pes_buffer_size - sptr->pes_buffer_on, 	   sptr->frame_len);#endif    if (mpeg2ps_stream_read_next_pes_buffer(sptr) == FALSE) {      return FALSE;    }  }  sptr->have_frame_loaded = true;  return TRUE;}static bool mpeg2ps_stream_find_mp3_frame (mpeg2ps_stream_t *sptr){  const uint8_t *ret;  uint32_t diff;  bool started_new_pes = false;  sptr->frame_ts = sptr->next_pes_ts;  if (sptr->pes_buffer_size <= sptr->pes_buffer_on + 4) {    if (sptr->pes_buffer_size != sptr->pes_buffer_on)      started_new_pes = true;    if (mpeg2ps_stream_read_next_pes_buffer(sptr) == FALSE) {      return FALSE;    }  }  while (MP4AV_Mp3GetNextFrame(sptr->pes_buffer + sptr->pes_buffer_on,			       sptr->pes_buffer_size - sptr->pes_buffer_on,			       &ret, 			       &sptr->frame_len, 			       TRUE, 			       TRUE) == FALSE) {    // don't have frame    if (sptr->pes_buffer_size > 3) {      if (sptr->pes_buffer_on != sptr->pes_buffer_size) {	sptr->pes_buffer_on = sptr->pes_buffer_size - 3;      }      started_new_pes = true; // we have left over bytes...    } else {      sptr->pes_buffer_on = sptr->pes_buffer_size;    }#if 0    printf("no frame - moving %u of %u\n",	   sptr->pes_buffer_on, sptr->pes_buffer_size);#endif    if (mpeg2ps_stream_read_next_pes_buffer(sptr) == FALSE) {      return FALSE;    }  }  // have frame.  diff = ret - (sptr->pes_buffer + sptr->pes_buffer_on);  sptr->pes_buffer_on += diff;  if (diff == 0 && started_new_pes) {  } else {    copy_next_pes_ts_to_frame_ts(sptr);  }  while (sptr->pes_buffer_size - sptr->pes_buffer_on < sptr->frame_len) {#if 0    printf("don't have enough - on %u size %u %u %u\n", sptr->pes_buffer_on, 	   sptr->pes_buffer_size,	   sptr->pes_buffer_size - sptr->pes_buffer_on, 	   sptr->frame_len);#endif    if (mpeg2ps_stream_read_next_pes_buffer(sptr) == FALSE) {      return FALSE;    }  }  sptr->have_frame_loaded = true;  return TRUE;}/* * mpeg2ps_stream_read_frame.  read the correct frame based on stream type. * advance_pointers is false when we want to use the data */static bool mpeg2ps_stream_read_frame (mpeg2ps_stream_t *sptr,				       uint8_t **buffer, 				       uint32_t *buflen,				       bool advance_pointers){  //  bool done = FALSE;  if (sptr->is_video) {    if (sptr->determined_type == false) {      if (mpeg2ps_stream_figure_out_video_type(sptr)) {	*buffer = sptr->pes_buffer + sptr->pes_buffer_on;	*buflen = sptr->frame_len;	if (advance_pointers) {	  sptr->pes_buffer_on += sptr->frame_len;	}	return TRUE;      }      return FALSE;    } else {      if (sptr->have_h264) {	if (mpeg2ps_stream_find_h264_video_frame(sptr)) {	  *buffer = sptr->pes_buffer + sptr->pes_buffer_on;	  *buflen = sptr->frame_len;	  if (advance_pointers) {	    sptr->pes_buffer_on += sptr->frame_len;	  }	  return TRUE;	}      } else {	if (mpeg2ps_stream_find_mpeg_video_frame(sptr)) {	  *buffer = sptr->pes_buffer + sptr->pes_buffer_on;	  *buflen = sptr->frame_len;	  if (advance_pointers) {	    sptr->pes_buffer_on += sptr->frame_len;	  }	  return TRUE;	}      }    return FALSE;    }  } else if (sptr->m_stream_id == 0xbd) {    // would need to handle LPCM here    if (sptr->m_substream_id >= 0xa0) {      if (mpeg2ps_stream_find_lpcm_frame(sptr)) {	*buffer = sptr->pes_buffer + sptr->pes_buffer_on;	*buflen = sptr->frame_len;	if (advance_pointers) {	  sptr->pes_buffer_on += sptr->frame_len;	}	return TRUE;      }      return FALSE;    }    if (mpeg2ps_stream_find_ac3_frame(sptr)) {      *buffer = sptr->pes_buffer + sptr->pes_buffer_on;      *buflen = sptr->frame_len;      if (advance_pointers)	sptr->pes_buffer_on += sptr->frame_len;      return TRUE;    }    return FALSE;  } else if (mpeg2ps_stream_find_mp3_frame(sptr)) {    *buffer = sptr->pes_buffer + sptr->pes_buffer_on;    *buflen = sptr->frame_len;    if (advance_pointers)      sptr->pes_buffer_on += sptr->frame_len;    return TRUE;  }  return FALSE;}/* * get_info_from_frame - we have a frame, get the info from it. */static void get_info_from_frame (mpeg2ps_stream_t *sptr, 				 uint8_t *buffer, 				 uint32_t buflen){  if (sptr->is_video) {    if (sptr->have_h264) {      bool found_seq = false;      do {	if (h264_nal_unit_type(buffer) == H264_NAL_TYPE_SEQ_PARAM) {	  h264_decode_t dec;	  found_seq = true;	  if (h264_read_seq_info(buffer, buflen, &dec) >= 0) {	    sptr->video_profile = dec.profile;	    sptr->video_level = dec.level;	    sptr->w = dec.pic_width;	    sptr->h = dec.pic_height;	  }	} else {	  uint32_t offset = h264_find_next_start_code(buffer, buflen);	  if (offset == 0) buflen = 0;	  else {	    buffer += offset;	    buflen -= offset;	  }	}      } while (found_seq == false && buflen > 0);      mpeg2ps_message(LOG_ERR, "need to info h264");      sptr->ticks_per_frame = 90000 / 30;          } else {      if (MP4AV_Mpeg3ParseSeqHdr(buffer, buflen,				 &sptr->have_mpeg2,				 &sptr->h,				 &sptr->w,				 &sptr->frame_rate,				 &sptr->bit_rate,				 NULL,				 &sptr->video_profile) < 0) {	mpeg2ps_message(LOG_ERR, "Can't parse sequence header in first frame - stream\n",			sptr->m_stream_id);	sptr->m_stream_id = 0;	sptr->m_fd = FDNULL;      }            sptr->ticks_per_frame = (uint64_t)(90000.0 / sptr->frame_rate);      mpeg2ps_message(LOG_INFO,"stream %x - %u x %u, %g at %g "U64,		      sptr->m_stream_id, sptr->w, sptr->h, sptr->bit_rate,		      sptr->frame_rate, sptr->ticks_per_frame);    }    return;  }  if (sptr->m_stream_id >= 0xc0) {    // mpeg audio    MP4AV_Mp3Header hdr = MP4AV_Mp3HeaderFromBytes(buffer);    sptr->channels = MP4AV_Mp3GetChannels(hdr);    sptr->freq = MP4AV_Mp3GetHdrSamplingRate(hdr);    sptr->samples_per_frame = MP4AV_Mp3GetHdrSamplingWindow(hdr);    sptr->bitrate = MP4AV_Mp3GetBitRate(hdr) * 1000; // give bps, not kbps    sptr->layer = MP4AV_Mp3GetHdrLayer(hdr);    sptr->version = MP4AV_Mp3GetHdrVersion(hdr);  } else if (sptr->m_stream_id == 0xbd) {    if (sptr->m_substream_id >= 0xa0) {      // PCM - ???      sptr->samples_per_frame = 0;      sptr->bitrate = sptr->freq * sptr->channels * sizeof(int16_t);    } else if (sptr->m_substream_id >= 0x80) {      // ac3      const uint8_t *temp;      MP4AV_Ac3ParseHeader(buffer, buflen, &temp,			   &sptr->bitrate,			   &sptr->freq,			   NULL,			   &sptr->channels);      sptr->samples_per_frame = 256 * 6;    } else {      mpeg2ps_message(LOG_ERR, "unknown audio private stream id %x %x", 

⌨️ 快捷键说明

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