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

📄 mpeg3.cpp

📁 完整的RTP RTSP代码库
💻 CPP
📖 第 1 页 / 共 2 页
字号:
  for (sid = 1; sid <= numSamples; sid++) {    sampleSize = maxSampleSize;    MP4Timestamp startTime;    MP4Duration duration;    MP4Duration renderingOffset;    bool isSyncSample;    bool rc = MP4ReadSample(mp4file, trackid, sid,			    &buffer, &sampleSize, 			    &startTime, &duration, 			    &renderingOffset, &isSyncSample);#ifdef DEBUG_MPEG3_HINT    printf("sid %d - sample size %d\n", sid, sampleSize);#endif    if (rc == false) {      MP4DeleteTrack(mp4file, hintTrackId);      return false;    }    // need to add rfc2250 header    offset = 0;    have_seq = 0;    pbuffer = buffer;    stop = false;    do {      uint32_t oldoffset;      oldoffset = offset;      if (MP4AV_Mpeg3FindNextStart(pbuffer + offset, 			sampleSize - offset, 			&offset, 			&scode) < 0) {	// didn't find the start code#ifdef DEBUG_MPEG3_HINT	printf("didn't find start code\n");#endif	stop = true;      } else {	offset += oldoffset;#ifdef DEBUG_MPEG3_HINT	printf("next sscode %x found at %d\n", scode, offset);#endif	if (scode == MPEG3_SEQUENCE_START_CODE) have_seq = 1;	offset += 4; // start with next value      }    } while (scode != MPEG3_PICTURE_START_CODE && stop == false);        pstart = pbuffer + offset; // point to inside of picture start    type = (pstart[1] >> 3) & 0x7;    rfc2250[0] = (*pstart >> 6) & 0x3;    rfc2250[1] = (pstart[0] << 2) | ((pstart[1] >> 6) & 0x3); // temporal ref    rfc2250[2] = type;    rfc2250_2 = rfc2250[2];    rfc2250[3] = 0;    if (type == 2 || type == 3) {      rfc2250[3] = pstart[3] << 5;      if ((pstart[4] & 0x80) != 0) rfc2250[3] |= 0x10;      if (type == 3) {	rfc2250[3] |= (pstart[4] >> 3) & 0xf;      }    }    if (MP4AddRtpVideoHint(mp4file, hintTrackId, 			   type == 3, renderingOffset) == false)      return false;    // Find the next slice.  Then we can add the header if the next    // slice will be in the start.  This lets us set the S bit in     // rfc2250[2].  Then we need to loop to find the next slice that's    // not in the buffer size - this should be in the while loop.        prev_slice = 0;    if (MP4AV_Mpeg3FindNextSliceStart(pbuffer, offset, sampleSize, &next_slice) < 0) {      slice_at_begin = false;    } else {      slice_at_begin = true;    }#ifdef DEBUG_MPEG3_HINT    printf("starting slice at %d\n", next_slice);#endif    offset = 0;    bool nomoreslices = false;    bool found_slice = slice_at_begin;    bool onfirst = true;    while (sampleSize > 0) {      bool isLastPacket;      uint32_t len_to_write;      if (sampleSize <= maxPayloadSize) {	// leave started_slice alone	len_to_write = sampleSize;	isLastPacket = true;	prev_slice = 0;      } else {	found_slice =  (onfirst == false) && (nomoreslices == false) && (next_slice <= maxPayloadSize);	onfirst = false;	isLastPacket = false;	while (nomoreslices == false && next_slice <= maxPayloadSize) {	  prev_slice = next_slice;	  if (MP4AV_Mpeg3FindNextSliceStart(pbuffer, next_slice + 4, sampleSize, &next_slice) >= 0) {#ifdef DEBUG_MPEG3_HINT	    printf("prev_slice %u next slice %u %u\n", prev_slice, next_slice,		   offset + next_slice);#endif	    found_slice = true;	  } else {	    // at end	    nomoreslices = true;	  }	}	// prev_slice should have the end value.  If it's not 0, we have	// the end of the slice.	if (found_slice) len_to_write = prev_slice;	else len_to_write = MIN(maxPayloadSize, sampleSize);      }       rfc2250[2] = rfc2250_2;      if (have_seq != 0) {	rfc2250[2] |= 0x20;	have_seq = 0;      }      if (slice_at_begin) {	rfc2250[2] |= 0x10; // set b bit      }      if (found_slice || isLastPacket) {	rfc2250[2] |= 0x08; // set end of slice bit	slice_at_begin = true; // for next time      } else {	slice_at_begin = false;      }#ifdef DEBUG_MPEG3_HINT      printf("Adding packet, sid %u prev slice %u len_to_write %u\n",	     sid, prev_slice, len_to_write);      printf("Next slice %u offset %u %x %x %x %x\n\n", 	     next_slice, offset, 	     rfc2250[0], rfc2250[1], rfc2250[2], rfc2250[3]);#endif      // okay - we can now write out this packet.      if (MP4AddRtpPacket(mp4file, hintTrackId, isLastPacket) == false ||      // add the 4 byte header	  MP4AddRtpImmediateData(mp4file, hintTrackId, 				 rfc2250, sizeof(rfc2250)) == false ||      // add the immediate data	  MP4AddRtpSampleData(mp4file, hintTrackId, sid, 			      offset, len_to_write) == false) {	MP4DeleteTrack(mp4file, hintTrackId);	return false;      }      offset += len_to_write;      sampleSize -= len_to_write;      prev_slice = 0;      next_slice -= len_to_write;      pbuffer += len_to_write;    }    if (MP4WriteRtpHint(mp4file, hintTrackId, duration, type == 1) == false)      return false;  }  free(buffer);  return true;}// mpeg3_find_dts_from_pts - given a pts, a frame type, and the// temporal reference from the frame type, calculate the dts// pts = presentation time stamp // dts = decode time stamp.int mpeg3_find_dts_from_pts (mpeg3_pts_to_dts_t *ptr,			     uint64_t pts_in_msec,			     int frame_type,			     uint16_t temp_ref,			     uint64_t *return_value){  uint64_t calc;  double dcalc;  double msec_per_frame = 1000.0 / ptr->frame_rate;  int64_t diff;  switch (frame_type) {  case 1: // i frame    // I frame calculation - take the temporal reference + 1, multiple it    // times frame rate, subtract from pts to get dts.    dcalc = (temp_ref + 1);    dcalc *= msec_per_frame;    calc = pts_in_msec - (uint64_t)dcalc;    ptr->last_i_temp_ref = temp_ref;    ptr->last_i_pts = pts_in_msec;    ptr->last_i_dts = calc;    *return_value = calc;    break;  case 2:     // P frames suck.    // see if the difference between temporal references in the last    // frame is the difference between pts of the last I and this P frame    // if they are, we most likely haven't lost a frame    dcalc = (temp_ref - ptr->last_i_temp_ref);     dcalc *= msec_per_frame;    diff = pts_in_msec - ptr->last_i_pts;    calc = (uint64_t)dcalc;    diff -= calc;    if (diff > TO_D64(10) || diff < TO_D64(-10)) {      // out of range - we really can't guess      // we could probably do more work here - record the number of       // consectutive b frames, etc, but what it really means is that      // we need to wait until the next I frame to display sanely.      // We'll still decode, and may even display if B frames are       // present, but we'll jerk a bit on these frames.      // It all comes down to me being lazy...      printf("pts out of range - diff "D64", temps %u %u\n",	     diff, temp_ref, ptr->last_i_temp_ref);      printf("our pts "U64" last "U64"\n", pts_in_msec, ptr->last_i_pts);      return -1;    }    if (ptr->last_i_temp_ref != 0) {      // straight forward calculation      *return_value = ptr->last_i_dts + calc;    } else {      // if the temp ref of the I frame was 0, there's no good calculation      // of how to get to the P frame time.        // a less straight forward calculation - just increment from the      // last dts - there's no real way to calculate this accurately      *return_value = ptr->last_dts + (uint64_t)msec_per_frame;    }    break;  case 3:    *return_value = pts_in_msec;    break;  }  ptr->last_dts = *return_value;  return 0;}uint8_t mpeg2_profile_to_mp4_track_type (uint8_t profile){  if (profile == 0) {    return MP4_MPEG2_VIDEO_TYPE;  }  if ((profile & 0x80) == 0) {    switch ((profile & 0x70) >> 4) {    case 5:      return MP4_MPEG2_SIMPLE_VIDEO_TYPE;    case 4:      return MP4_MPEG2_MAIN_VIDEO_TYPE;    case 3:      return MP4_MPEG2_SNR_VIDEO_TYPE;    case 2:      return MP4_MPEG2_SPATIAL_VIDEO_TYPE;    case 1:      return MP4_MPEG2_HIGH_VIDEO_TYPE;    default:      return MP4_MPEG2_VIDEO_TYPE;    }  }   if (profile == 0x82 || profile == 0x85) {    return MP4_MPEG2_442_VIDEO_TYPE;  }  return MP4_MPEG2_VIDEO_TYPE;}static const char *profile_names[] = {  "Mpeg-2 High@<unk>",  "Mpeg-2 High@High",  "Mpeg-2 High@High 1440",  "Mpeg-2 High@Main",  "Mpeg-2 High@Low"  "Mpeg-2 Spatially Scalable@<unk>",  "Mpeg-2 Spatially Scalable@High",  "Mpeg-2 Spatially Scalable@High 1440",  "Mpeg-2 Spatially Scalable@Main",  "Mpeg-2 Spatially Scalable@Low",  "Mpeg-2 SNR Scalable@<unk>",  "Mpeg-2 SNR Scalable@High",  "Mpeg-2 SNR Scalable@High 1440",  "Mpeg-2 SNR Scalable@Main",  "Mpeg-2 SNR Scalable@Low",  "Mpeg-2 Main@High<unk>",  "Mpeg-2 Main@High",  "Mpeg-2 Main@High 1440",  "Mpeg-2 Main@Main",  "Mpeg-2 Main@Low",  "Mpeg-2 Simple@<unk>",  "Mpeg-2 Simple@High",  "Mpeg-2 Simple@High 1440",  "Mpeg-2 Simple@Main",  "Mpeg-2 Simple@Low", };const char *mpeg2_type (uint8_t profile) {  if (profile == 0) {    return "Mpeg-2";  }    if ((profile & 0x80) == 0) {    uint8_t index;    index = ((profile & 0x70) >> 4);    if (index == 0 || index > 5) {      return "Mpeg-2 unknown profile";    }    index--;    index *= 5;        uint8_t level = profile & 0xf;    if ((level & 1) != 0 ||	(level > 0xb)) {      // no change to index:      return profile_names[index];    }    level >>= 1;    level -= 2;    index += level;    return profile_names[index];  }   if (profile == 0x82)     return "Mpeg-2 4:2:2@High";  if (profile == 0x85) {    return "Mpeg-2 4:2:2@Main";  }  if (profile == 0x8a)     return "Mpeg-2 Multiview@High";  if (profile == 0x8b)     return "Mpeg-2 Multiview@High 1440";  if (profile == 0x8d)     return "Mpeg-2 Multiview@Main";  if (profile == 0x8e)     return "Mpeg-2 Multiview@Low";  return "Mpeg-2 unknown escape profile";}    

⌨️ 快捷键说明

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