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

📄 rfc3119_bytestream.cpp

📁 网络MPEG4IP流媒体开发源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* * 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. 2002.  All Rights Reserved. *  * Contributor(s):  *              Bill May        wmay@cisco.com *//* * rfc3119_bytestream.cpp - an implemention of rfc 3119 */#include "systems.h"#include <rtp/rtp.h>#include <rtp/memory.h>#include <sdp/sdp.h> // for NTP_TO_UNIX_TIME#include "rfc3119_bytestream.h"#include <mp3util/MP3Internals.hh>//#define DEBUG_3119 1//#define DEBUG_3119_INTERLEAVE 1#ifdef _WIN32DEFINE_MESSAGE_MACRO(mpa_message, "mparobust")#else#define mpa_message(loglevel, fmt...) message(loglevel, "mparobust", fmt)#endifCRfc3119RtpByteStream::CRfc3119RtpByteStream (unsigned int rtp_pt,					      format_list_t *fmt,					      int ondemand,					      uint64_t tps,					      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) :  CRtpByteStreamBase("mparobust", fmt, rtp_pt, ondemand, tps, head, tail, 		     rtp_seq_set, rtp_base_seq, rtp_ts_set, rtp_base_ts,		     rtcp_received, ntp_frac, ntp_sec, rtp_ts){#ifdef ISMA_RTP_DUMP_OUTPUT_TO_FILE  m_outfile = fopen("isma.aac", "w");#endif  m_adu_data_free = NULL;  m_deinterleave_list = NULL;  m_ordered_adu_list = NULL;  m_pending_adu_list = NULL;  adu_data_t *p;  for (int ix = 0; ix < 25; ix++) {    p = MALLOC_STRUCTURE(adu_data_t);    p->next_adu = m_adu_data_free;    m_adu_data_free = p;  }  m_rtp_ts_add = 0;  m_recvd_first_pak = 0;  m_got_next_idx = 0;  m_mp3_frame = NULL;  m_mp3_frame_size = 0;}CRfc3119RtpByteStream::~CRfc3119RtpByteStream (void){#ifdef ISMA_RTP_DUMP_OUTPUT_TO_FILE  fclose(m_outfile);#endif  adu_data_t *p;#if 0  if (m_frag_reass_buffer != NULL) {    free(m_frag_reass_buffer);    m_frag_reass_buffer = NULL;  }#endif  dump_adu_list(m_deinterleave_list);  m_deinterleave_list = NULL;  dump_adu_list(m_ordered_adu_list);  m_ordered_adu_list = NULL;  dump_adu_list(m_pending_adu_list);  m_pending_adu_list = NULL;  while (m_adu_data_free != NULL) {    p = m_adu_data_free;    m_adu_data_free = p->next_adu;    free(p);  }}void CRfc3119RtpByteStream::insert_interleave_adu (adu_data_t *adu){  adu_data_t *p, *q;#ifdef DEBUG_3119_INTERLEAVE  mpa_message(LOG_DEBUG, "inserting interleave %d %d %d", adu->aduDataSize,	      adu->cyc_ct, adu->interleave_idx);#endif  SDL_LockMutex(m_rtp_packet_mutex);    if (m_deinterleave_list == NULL) {    m_got_next_idx = 0;    m_deinterleave_list = adu;  } else {    q = NULL;    p = m_deinterleave_list;    if (adu->cyc_ct != p->cyc_ct) {      m_got_next_idx = 1;      do {	q = p;	p = p->next_adu;      } while (p != NULL && p->cyc_ct != adu->cyc_ct);      if (p == NULL) {	q->next_adu = adu;	SDL_UnlockMutex(m_rtp_packet_mutex);	return;      }     }    while (p != NULL && p->interleave_idx < adu->interleave_idx) {      q = p;      p = p->next_adu;    }    q->next_adu = adu;    adu->next_adu = p;  }  SDL_UnlockMutex(m_rtp_packet_mutex);}int CRfc3119RtpByteStream::insert_processed_adu (adu_data_t *adu){#ifdef DEBUG_3119  mpa_message(LOG_DEBUG, "inserting processed %d", adu->aduDataSize);#endif  SDL_LockMutex(m_rtp_packet_mutex);  if (m_ordered_adu_list == NULL) {    m_ordered_adu_list = adu;  } else {    int32_t diff;    adu_data_t *p, *q;    q = NULL;    p = m_ordered_adu_list;    do {      diff = adu->timestamp - p->timestamp;      if (diff == 0) {	mpa_message(LOG_ERR, "Duplicate timestamp of "LLU" found in RTP packet",		    adu->timestamp);	mpa_message(LOG_DEBUG, 		     "Seq number orig %d new %d", 		     p->pak->rtp_pak_seq, adu->pak->rtp_pak_seq); 	mpa_message(LOG_ERR, "Dumping all processed packets");		// put frame_data on free list	if (adu->last_in_pak == 0) {	  free_adu(adu);	} else {	  mpa_message(LOG_ERR, "Im lazy - duplicate ADU leads to memory leak");	}	SDL_UnlockMutex(m_rtp_packet_mutex);	return -1;      } else if (diff < 0) {#ifdef DEBUG_3119	mpa_message(LOG_DEBUG, "Inserting in front of ts %llu", p->timestamp);#endif	if (q == NULL) {	  adu->next_adu = m_ordered_adu_list;	  m_ordered_adu_list = adu;	} else {	  q->next_adu = adu;	  adu->next_adu = p;	}	SDL_UnlockMutex(m_rtp_packet_mutex);	return 0;      }      q = p;      p = p->next_adu;    } while (p != NULL);    // insert at end;    q->next_adu = adu;  }  SDL_UnlockMutex(m_rtp_packet_mutex);  return 0;}void CRfc3119RtpByteStream::process_packet (void){  rtp_packet *pak;  uint64_t pak_ts;  int adu_offset;  adu_data_t *prev_adu;  int thisAduSize;  do {    /*     * Take packet off list.  Loop through, looking for ADU headersize     * packets     */    pak = m_head;    if (pak != NULL) {      remove_packet_rtp_queue(m_head, 0);      pak_ts = rtp_ts_to_msec(pak->rtp_pak_ts, 			      pak->pd.rtp_pd_timestamp,			      m_wrap_offset);      adu_offset = 0;      prev_adu = NULL;#ifdef DEBUG_3119      mpa_message(LOG_DEBUG, "Process pak seq %d", pak->rtp_pak_seq);#endif      while (pak != NULL && adu_offset < pak->rtp_data_len) {	uint8_t *ptr;	ptr = (uint8_t *)(pak->rtp_data + adu_offset);	if ((*ptr & 0x80) == 0x80) {	  // first one has a c field of 1 - that's bad	  xfree(pak);	  pak = NULL;	  adu_offset = 0;	} else {	  /*	   * Get a new adu - start loading the data	   */	  adu_data_t *adu = get_adu_data();	  adu->pak = pak;	  adu->next_adu = NULL;	  adu->last_in_pak = 0;	  adu->freeframe = 0;	  if (adu_offset == 0) {	    adu->first_in_pak = 1;	    adu->timestamp = pak_ts;	  } else {	    adu->first_in_pak = 0;	  }	  /*	   * Read the ADU header.  It will be 1 byte or 2	   */	  if ((*ptr & 0x40) == 0) {	    // 1 byte header	    adu->frame_ptr = ptr + 1;	    adu->aduDataSize = *ptr & 0x3f;	    adu_offset++;	  } else {	    // 2 byte header	    adu->aduDataSize = ((*ptr & 0x3f) << 8) + ptr[1];	    adu->frame_ptr = ptr + 2;	    adu_offset += 2;	  }	  /*	   * See if we're past the end of the packet	   */	  thisAduSize = adu->aduDataSize;	  if (adu_offset + adu->aduDataSize > pak->rtp_data_len) {	    // have a fragment here...	    // malloc a frame pointer, and copy the rest... 	    uint16_t seq = pak->rtp_pak_seq;	    uint8_t *to, *from;	    to = (uint8_t *)malloc(adu->aduDataSize);	    int copied = pak->rtp_data_len - adu_offset;	    memcpy(to, adu->frame_ptr, copied);	    if (prev_adu != NULL) {	      prev_adu->last_in_pak = 1;	    } else {	      xfree(pak);	    }	    adu->frame_ptr = to;	    adu->freeframe = 1;	    to += copied;	    while (m_head != NULL && 		   m_head->rtp_pak_seq == seq + 1 && 		   (*m_head->rtp_data & 0x80) == 0x80 && 		   copied < adu->aduDataSize) {	      uint32_t bytes;	      pak = m_head;	      remove_packet_rtp_queue(m_head, 0);	      ptr = (uint8_t *)pak->rtp_data;	      if ((*ptr & 0x40) == 0) {		// 1 byte header		bytes = *ptr & 0x3f;		from = ptr++;	      } else {		// 2 byte header		bytes = ((*ptr & 0x3f) << 8) + ptr[1];		from = ptr + 2;	      }	      memcpy(to, from, bytes);	      copied += bytes;	      to += bytes;	      seq++;	      adu_offset = 0;	      pak = NULL;	    }	    if (copied < adu->aduDataSize) {	      free_adu(adu);	      continue;	    }	  } else {	    /*	     * adu_offset now points past the end of this adu	     */	    adu_offset += adu->aduDataSize;	    if (adu_offset >= pak->rtp_data_len) {	      adu->last_in_pak = 1;	    }	  }	  /*	   * Calculate the interleave index and the cyc_ct count	   * Fill in those values with all 1's	   */	  adu->interleave_idx = *adu->frame_ptr;	  adu->cyc_ct = *(adu->frame_ptr + 1) >> 5;	  adu->frame_ptr[0] = 0xff;	  adu->frame_ptr[1] |= 0xe0;	  /*	   * Decode the mp3 header	   */	  adu->mp3hdr = MP4AV_Mp3HeaderFromBytes(adu->frame_ptr);	  adu->framesize = MP4AV_Mp3GetFrameSize(adu->mp3hdr);	  /*	   * Headersize, sideInfoSize and aduDataSize 	   */	  adu->headerSize = 4;	  adu->sideInfoSize = MP4AV_Mp3GetSideInfoSize(adu->mp3hdr);	  adu->aduDataSize -= (adu->headerSize + adu->sideInfoSize);	  /*	   * Calculate the timestamp add	   */	  if (m_rtp_ts_add == 0) {	    m_rtp_ts_add = 	      ( 1000 * MP4AV_Mp3GetHdrSamplingWindow(adu->mp3hdr));	    m_rtp_ts_add /= MP4AV_Mp3GetHdrSamplingRate(adu->mp3hdr);	  }		  // here we make a few decisions as to where the packet should	  // go.	  // Look at first packet.  If it's got interleave, we're interleaved	  // if not, set up the timestamp, put it in the ordered_adu_list.	  // (Don't set recvd_first pak).  If it's the 2nd, and not interleaved,	  // leave the first, go on non-interleaved	  // If the first isn't, and the 2nd is, move the first to the	  // m_deinterleave_list, put the 2nd on the deinterleave list, 	  // continue.	  // If not the first, put on the interleaved or deinterleaved list.	  int insert_interleaved = 0;	  if (m_recvd_first_pak == 0) {	    if (adu->interleave_idx == 0xff &&		adu->cyc_ct == 0x7) {	      /*	       * Have an packet all 1's.  It's either the last of the	       * sequence for interleave, or indicates no interleave.	       * Put it on the ordered list if there's nothing there.	       * If there is something on the ordered list, we're not doing	       * interleaved.	       */	      if (m_ordered_adu_list == NULL) {		insert_interleaved = 0;	      } else {		// this is the 2nd packet with the regular		// header - we're not doing interleaved		insert_interleaved = 0;		m_recvd_first_pak = 1;		m_have_interleave = 0;	      }	    } else {	      /*	       * Have an interleaved packet	       * If there was something on the ordered list, move it to 	       * the deinterleaved list	       */	      m_recvd_first_pak = 1;	      if (m_ordered_adu_list != NULL) {		m_deinterleave_list = m_ordered_adu_list;		m_ordered_adu_list = NULL;	      } 	      m_have_interleave = 1;	      insert_interleaved = 1;	      mpa_message(LOG_INFO, "mpa robust format is interleaved");	    }	  } else {	    insert_interleaved = m_have_interleave;	  }	  adu->backpointer =  MP4AV_Mp3GetAduOffset(adu->frame_ptr, 						    thisAduSize);	  if (insert_interleaved) {	    insert_interleave_adu(adu);

⌨️ 快捷键说明

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