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

📄 mpeg3_rtp_bytestream.cpp

📁 完整的RTP RTSP代码库
💻 CPP
字号:
/* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ *  * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. *  * The Original Code is MPEG4IP. *  * The Initial Developer of the Original Code is Cisco Systems Inc. * Portions created by Cisco Systems Inc. are * Copyright (C) Cisco Systems Inc. 2001-2004.  All Rights Reserved. *  * Contributor(s):  *              Bill May        wmay@cisco.com */#include "mpeg4ip.h"#include <rtp/rtp.h>#include <rtp/memory.h>#include <sdp/sdp.h> // for NTP_TO_UNIX_TIME#include "mpeg3_rtp_bytestream.h"#include "our_config_file.h"//#define DEBUG_RTP_PAKS 1//#define DEBUG_MPEG3_RTP_TIME 1#ifdef _WIN32DEFINE_MESSAGE_MACRO(rtp_message, "rtpbyst")#else#define rtp_message(loglevel, fmt...) message(loglevel, "rtpbyst", fmt)#endif#if 0static rtp_packet *end_of_pak (rtp_packet *start){  while (start->rtp_next->rtp_pak_ts == start->rtp_pak_ts)     start = start->rtp_next;  return start;}#endifCMpeg3RtpByteStream::CMpeg3RtpByteStream(unsigned int rtp_pt,					 format_list_t *fmt,					 int ondemand,					 uint64_t tickpersec,					 rtp_packet **head, 					 rtp_packet **tail,					 int rtp_seq_set,					 uint16_t rtp_base_seq,					 int rtp_ts_set,					 uint32_t rtp_base_ts,					 int rtcp_received,					 uint32_t ntp_frac,					 uint32_t ntp_sec,					 uint32_t rtp_ts) :  CRtpByteStream("mpeg3", fmt, rtp_pt, ondemand, tickpersec, head, tail,		 rtp_seq_set, rtp_base_seq, rtp_ts_set, rtp_base_ts, 		 rtcp_received, ntp_frac, ntp_sec, rtp_ts){}bool CMpeg3RtpByteStream::start_next_frame (uint8_t **buffer, 					    uint32_t *buflen,					    frame_timestamp_t *pts,					    void **ud){  uint16_t seq = 0;  uint32_t ts = 0;  uint64_t timetick;  uint64_t pak_ts = 0;  int first = 0;  int finished = 0;  rtp_packet *rpak;  int32_t diff;  int correct_hdr;  int dropped_seq;  uint8_t temp_ref;  diff = m_buffer_len - m_bytes_used;  if (diff > 4) {    // Still bytes in the buffer...    *buffer = m_buffer + m_bytes_used;    *buflen = diff;#ifdef DEBUG_RTP_PAKS    rtp_message(LOG_DEBUG, "%s Still left - %d bytes", m_name, *buflen);#endif    pts->msec_timestamp = m_last_realtime;    pts->timestamp_is_pts = true;    return true;  }  int frame_type;  m_buffer_len = 0;  dropped_seq = 0;  while (finished == 0) {    rpak = m_head;    if (rpak == NULL) {      *buffer = NULL;      return 0;    }    remove_packet_rtp_queue(rpak, 0);    correct_hdr = 1;    if (check_seq(rpak->rtp_pak_seq) == false) {      correct_hdr = 0;      dropped_seq = 1;      first = 0;    } else {      if (first == 0) {	ts = rpak->rtp_pak_ts;	pak_ts = rpak->pd.rtp_pd_timestamp;	first = 1;      } else {	if (ts != rpak->rtp_pak_ts) {	  rtp_message(LOG_INFO, 		      "%s timestamp error - seq %u should be %x is %x", 		      m_name, seq, ts, rpak->rtp_pak_ts);	  correct_hdr = 0;	}	ts = rpak->rtp_pak_ts;      }    }    if (correct_hdr == 0) {      m_buffer_len = 0;    }     set_last_seq(rpak->rtp_pak_seq);    uint8_t *from;    uint32_t len;    m_skip_on_advance_bytes = 4;    if ((*rpak->rtp_data & 0x4) != 0) {      m_skip_on_advance_bytes = 8;      if ((rpak->rtp_data[4] & 0x40) != 0) {      }    }    frame_type = rpak->rtp_data[2] & 0x7;    temp_ref = ((rpak->rtp_data[0] & 0x3) << 8) | rpak->rtp_data[1];    from = (uint8_t *)rpak->rtp_data + m_skip_on_advance_bytes;    len = rpak->rtp_data_len - m_skip_on_advance_bytes;    if ((m_buffer_len + len) > m_buffer_len_max) {      // realloc      m_buffer_len_max = m_buffer_len + len + 1024;      m_buffer = (uint8_t *)realloc(m_buffer, m_buffer_len_max);    }    memcpy(m_buffer + m_buffer_len, 	   from,	   len);    m_buffer_len += len;      if (rpak->rtp_pak_m == 1) {      finished = 1;    }    xfree(rpak);  }  m_bytes_used = 0;  *buffer = m_buffer + m_bytes_used;  *buflen = m_buffer_len - m_bytes_used;  //  rtp_message(LOG_DEBUG, "frame type %d timestamp %u", frame_type, ts);#ifdef DEBUG_RTP_PAKS  rtp_message(LOG_DEBUG, "%s buffer len %d", m_name, m_buffer_len);#endif#ifdef DEBUG_MPEG3_RTP_TIME  rtp_message(LOG_DEBUG, "frame type %d pak ts %u %d", frame_type, 	      ts, temp_ref);#endif  if (m_rtpinfo_set_from_pak != 0) {    if (ts < m_base_rtp_ts) {      m_base_rtp_ts = ts;    }    m_rtpinfo_set_from_pak = 0;  }  m_last_rtp_ts = ts;  timetick = rtp_ts_to_msec(ts, pak_ts, m_wrap_offset);  pts->msec_timestamp = timetick;  pts->timestamp_is_pts = true;  return true;}#if 0uint32_t CMpeg3RtpByteStream::calc_this_ts_from_future (int frame_type,							uint32_t pak_ts,							uint8_t temp_ref){  int new_frame_type;  uint32_t outts = 0;  m_have_mpeg_ip_ts = 0;  if (frame_type >= 3) {    // B frame - ts is always pak_ts    return pak_ts; //  + m_rtp_frame_add;  }  if (frame_type == 1) {    outts = pak_ts - ((temp_ref + 1) * m_rtp_frame_add);    m_mpeg_ip_ts = pak_ts;    m_have_mpeg_ip_ts = 1;    return outts;  }  SDL_LockMutex(m_rtp_packet_mutex);  if (check_seq(m_head->rtp_pak_seq) == false) {    outts = m_head->rtp_pak_ts - m_rtp_frame_add; // not accurate, but close enuff#ifdef DEBUG_MPEG3_RTP_TIME    rtp_message(LOG_DEBUG, "calc no checkseq");#endif  } else {    new_frame_type = m_head->rtp_data[2] & 0x7;#ifdef DEBUG_MPEG3_RTP_TIME    rtp_message(LOG_DEBUG, "calc ftype %d next %d", frame_type, new_frame_type);#endif    if (new_frame_type >= 3) {      // P frame followed by B frame - take the B frame's timestamp      outts = m_head->rtp_pak_ts - m_rtp_frame_add;      m_mpeg_ip_ts = pak_ts;      m_have_mpeg_ip_ts = 1;    }  else {      // P frame followed by I frame, P frame followed by I or P frame      outts = pak_ts - m_rtp_frame_add;      m_mpeg_ip_ts = pak_ts;      m_have_mpeg_ip_ts = 1;    }   }  SDL_UnlockMutex(m_rtp_packet_mutex);  return outts;}#endif							bool CMpeg3RtpByteStream::skip_next_frame (frame_timestamp_t *pts, 					  int *hasSyncFrame,					  uint8_t **buffer, 					  uint32_t *buflen, 					  void **ud){  uint64_t ts;  *hasSyncFrame = -1;  // we don't know if we have a sync frame  m_buffer_len = m_bytes_used = 0;  if (m_head == NULL) return 0;  ts = m_head->rtp_pak_ts;  do {    check_seq(m_head->rtp_pak_seq);    set_last_seq(m_head->rtp_pak_seq);    remove_packet_rtp_queue(m_head, 1);  } while (m_head != NULL && m_head->rtp_pak_ts == ts);  if (m_head == NULL) return false;  init();  m_buffer_len = m_bytes_used = 0;  return start_next_frame(buffer, buflen, pts, NULL);}bool CMpeg3RtpByteStream::have_frame (void){  rtp_packet *temp, *first;  if (m_head == NULL) return false;  first = temp = m_head;  int count = 0;  SDL_LockMutex(m_rtp_packet_mutex);  do {    if (temp->rtp_pak_m == 1) {      count++;      if (count > 1) {	SDL_UnlockMutex(m_rtp_packet_mutex);	return true;      }    }    temp = temp->rtp_next;  } while (temp != NULL && temp != first);  SDL_UnlockMutex(m_rtp_packet_mutex);  return false;}

⌨️ 快捷键说明

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