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

📄 rfc3119_bytestream.cpp

📁 jpeg and mpeg 编解码技术源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	    // calculate timestamp
	    if (adu->first_in_pak == 0) {
	      adu->timestamp = prev_adu->timestamp + m_rtp_ts_add;
	    }
	    insert_processed_adu(adu);
	  }
	  prev_adu = adu;
	}
      } 
    } else if (m_have_interleave && m_deinterleave_list != NULL) {
      m_got_next_idx = 1;
    }

    // done with packet.  If we're interleaved, move things down
    // to ordered ADU list.
    // continue until we've got the cycct index number. 
    // For non-interleaved, skip this step
    if (m_have_interleave != 0) {
      if (m_got_next_idx == 1) {
	// okay - we received the next index - we can move everything 
	// from the interleaved list to the processed list.
	adu_data_t *p, *q;
	int cur_cyc_ct;
	int ts_index;
	uint64_t ts = 0;
	m_got_next_idx = 0;
	q = NULL;
	p = m_deinterleave_list;
	ts_index = -1;
	cur_cyc_ct = p->cyc_ct;
	do {
	  if (ts_index == -1 && p->first_in_pak) {
	    ts = p->timestamp;
	    ts_index = p->interleave_idx;
	  }
	  q = p;
	  p = p->next_adu;
	} while (p != NULL && p->cyc_ct == cur_cyc_ct);
	q->next_adu = NULL;
	m_ordered_adu_list = m_deinterleave_list;
	m_deinterleave_list = p;

	// We've figured out that at least 1 packet has a valid timestamp.
	// Figure out the starting timestamp, then go ahead and set the
	// timestamps for the rest.
	// make sure ts_index is not -1 here
     
	p = m_ordered_adu_list;
	ts -= ((ts_index - p->interleave_idx) * m_rtp_ts_add);
	ts_index = p->interleave_idx;
	while (p != NULL) {
	  if (p->first_in_pak == 0) {
	    // calculate ts
	    p->timestamp = ts + (p->interleave_idx - ts_index) * m_rtp_ts_add;
	  } else {
	    ts = p->timestamp;
	    ts_index = p->interleave_idx;
	  }
#ifdef DEBUG_3119_INTERLEAVE
	  mpa_message(LOG_DEBUG, "cyc %d index %d fip %d ts %llu %d", 
		      p->cyc_ct,
		      p->interleave_idx,
		      p->first_in_pak,
		      p->timestamp,
		      m_rtp_ts_add);
#endif
	  p = p->next_adu;
	}
      } // end moving from deinterleave to processed list
    }
  } while (m_head != NULL && m_ordered_adu_list == NULL);
}

int CRfc3119RtpByteStream::needToGetAnADU (void)
{
  
  if (m_pending_adu_list == NULL) 
    return 1;

  int endOfHeadFrame;
  int frameOffset = 0;
  adu_data_t *p;
 
  p = m_pending_adu_list;

  endOfHeadFrame = p->framesize - p->headerSize - p->sideInfoSize;

  while (p != NULL) {
    int framesize = p->framesize;
    int endOfData = frameOffset - p->backpointer + p->aduDataSize;
    
#ifdef DEBUG_3119
    mpa_message(LOG_DEBUG, "add fr %d hd %d si %d bp %d adu %d", 
		framesize,
		p->headerSize,
		p->sideInfoSize,
		p->backpointer, p->aduDataSize);
    mpa_message(LOG_DEBUG, "foffset %d endOfData %d eohf %d", 
		frameOffset, endOfData, endOfHeadFrame);
#endif
    if (endOfData >= endOfHeadFrame) {
      return 0;
    }
    frameOffset += framesize - p->headerSize - p->sideInfoSize;
    p = p->next_adu;
  }
  return 1;
}

void CRfc3119RtpByteStream::add_and_insertDummyADUsIfNecessary (void)
{
  adu_data_t *tailADU, *prevADU;
  int prevADUend;

  tailADU = m_ordered_adu_list;
  m_ordered_adu_list = m_ordered_adu_list->next_adu;
  tailADU->next_adu = NULL;
  
#ifdef DEBUG_3119
  mpa_message(LOG_DEBUG, "tail fr %d bp %d si %d", 
	      tailADU->framesize,
	      tailADU->backpointer, 
	      tailADU->sideInfoSize);
#endif

  SDL_LockMutex(m_rtp_packet_mutex);
  prevADU = m_pending_adu_list;
  while (prevADU != NULL && prevADU->next_adu != NULL) 
    prevADU = prevADU->next_adu;

  if (prevADU != NULL) {
    prevADU->next_adu = tailADU;
  } else {
    m_pending_adu_list = tailADU;
  }
  SDL_UnlockMutex(m_rtp_packet_mutex);

  while (1) {
    if (m_pending_adu_list != tailADU) {
      prevADUend = prevADU->framesize + 
	prevADU->backpointer -
	prevADU->headerSize -
	prevADU->sideInfoSize;
      if (prevADU->aduDataSize > prevADUend) {
	prevADUend = 0;
      } else {
	prevADUend -= prevADU->aduDataSize;
      }
#ifdef DEBUG_3119
      mpa_message(LOG_DEBUG, "fr %d bp %d si %d", 
		  prevADU->framesize,
		  prevADU->backpointer, 
		  prevADU->sideInfoSize);
      mpa_message(LOG_DEBUG, "prevADUend is %d, prev size %d tail bpointer %d", 
		  prevADUend, prevADU->aduDataSize,
		  tailADU->backpointer);
#endif
    } else {
      prevADUend = 0;
    }

    if (tailADU->backpointer > prevADUend) {
      uint64_t ts;
#ifdef DEBUG_3119
      mpa_message(LOG_DEBUG, "Adding tail ts is %lld", tailADU->timestamp);
#endif
      SDL_LockMutex(m_rtp_packet_mutex);
      if (prevADU == NULL) {
	prevADU = get_adu_data();
	ts = m_pending_adu_list->timestamp - m_rtp_ts_add;
	prevADU->next_adu = m_pending_adu_list;
	m_pending_adu_list = prevADU;
#ifdef DEBUG_3119
	mpa_message(LOG_DEBUG, "Adding zero frame front, ts %lld", ts);
#endif
      } else {

	for (adu_data_t *p = m_pending_adu_list; 
	     p != tailADU;
	     p = p->next_adu) {
#ifdef DEBUG_3119
	  mpa_message(LOG_DEBUG, "Adjusting %lld to %lld", p->timestamp,
		      p->timestamp - m_rtp_ts_add);
#endif
	  p->timestamp -= m_rtp_ts_add;

	}
	ts = tailADU->timestamp - m_rtp_ts_add;
	prevADU->next_adu = get_adu_data();
	prevADU = prevADU->next_adu;
#ifdef DEBUG_3119
	mpa_message(LOG_DEBUG, "Adding zero frame middle %lld", ts);
#endif
      }

      prevADU->next_adu = tailADU;
      SDL_UnlockMutex(m_rtp_packet_mutex);

      prevADU->pak = NULL;
      prevADU->frame_ptr = 
	(uint8_t *)malloc(tailADU->framesize);
      prevADU->aduDataSize = 0;
      prevADU->timestamp = ts;
      prevADU->first_in_pak = 0;
      prevADU->last_in_pak = 0;
      prevADU->freeframe = 1;
      prevADU->headerSize = tailADU->headerSize;
      prevADU->sideInfoSize = tailADU->sideInfoSize;

      memcpy(prevADU->frame_ptr, 
	     tailADU->frame_ptr, 
	     prevADU->headerSize + prevADU->sideInfoSize);

      ZeroOutMP3SideInfo((unsigned char *)prevADU->frame_ptr, 
			 tailADU->framesize,
			 prevADUend);
      prevADU->mp3hdr = MP4AV_Mp3HeaderFromBytes(prevADU->frame_ptr);
      prevADU->framesize = MP4AV_Mp3GetFrameSize(prevADU->mp3hdr);
      prevADU->backpointer = MP4AV_Mp3GetAduOffset(prevADU->frame_ptr,
						   prevADU->framesize);
    } else {
      return;
    }
  }
}

uint64_t CRfc3119RtpByteStream::start_next_frame (uint8_t **buffer, 
						  uint32_t *buflen,
						  void **ud)
{
  adu_data_t *p;

  // Free up last used...
  if (m_pending_adu_list != NULL) {
    SDL_LockMutex(m_rtp_packet_mutex);
    p = m_pending_adu_list->next_adu;
    free_adu(m_pending_adu_list);
    m_pending_adu_list = p;
    SDL_UnlockMutex(m_rtp_packet_mutex);
  }

  /*
   * load up ordered_adu_list here...
   */
  while (m_head != NULL && m_ordered_adu_list == NULL) {
    process_packet();
  }

  /*
   * Start moving things down to the pending list.  If it's NULL, 
   * and the ordered list has data that's not layer 3, just move the
   * first element of the ordered list to the pending list, and use that.
   */
  if (m_pending_adu_list == NULL) {
    if (MP4AV_Mp3GetHdrLayer(m_ordered_adu_list->mp3hdr) != 1) {
      //if (m_ordered_adu_list->mp3hdr.layer != 3)
      SDL_LockMutex(m_rtp_packet_mutex);
      m_pending_adu_list = m_ordered_adu_list;
      m_ordered_adu_list = m_ordered_adu_list->next_adu;
      m_pending_adu_list->next_adu = NULL;
      SDL_UnlockMutex(m_rtp_packet_mutex);
      /*
       * mpeg1 layer 1 or 2
       * No mpa robust - adu contains complete frame
       */
#ifdef DEBUG_3119
      mpa_message(LOG_DEBUG, "Not layer 3");
#endif
      *buffer = m_pending_adu_list->frame_ptr;
      *buflen = m_pending_adu_list->framesize;
      return m_pending_adu_list->timestamp;
    }
  }

  /*
   * Now we need to handle the mpeg1 layer 3 ADU frame to MP3
   * frame conversion
   */
  while (needToGetAnADU()) {
    if (m_ordered_adu_list == NULL) {
      // failure - we need to add, and can't
#ifdef DEBUG_3119
      mpa_message(LOG_DEBUG, "need to get an adu and ordered list is NULL");
#endif
      process_packet();
      if (m_ordered_adu_list == NULL) {
	dump_adu_list(m_pending_adu_list);
	m_pending_adu_list = NULL;
	*buffer = NULL;
	*buflen = 0;
	return 0;
      }
    }
    add_and_insertDummyADUsIfNecessary();
  }

  uint32_t endOfHeadFrame;
  uint32_t frameOffset = 0;
  uint32_t toOffset = 0;

  /*
   * We should have enough on the pending list to fill up a frame
   */
  endOfHeadFrame = m_pending_adu_list->framesize;
  if (m_mp3_frame == NULL ||
      m_mp3_frame_size < endOfHeadFrame) {
    m_mp3_frame_size = endOfHeadFrame * 2;
    m_mp3_frame = (uint8_t *)realloc(m_mp3_frame, m_mp3_frame_size);
  }

  int copy;
  copy = m_pending_adu_list->headerSize + m_pending_adu_list->sideInfoSize;
  memcpy(m_mp3_frame, m_pending_adu_list->frame_ptr, copy);
  uint8_t *start_of_data;

  endOfHeadFrame -= copy;
  memset(m_mp3_frame + copy, 0, endOfHeadFrame);
  start_of_data = m_mp3_frame + copy;

  p = m_pending_adu_list;
  while (toOffset < endOfHeadFrame) {
    int startOfData = frameOffset - p->backpointer;
    if (startOfData > (int)endOfHeadFrame) {
      break;
    }
    int endOfData = startOfData + p->aduDataSize;
    if (endOfData > (int)endOfHeadFrame) {
      endOfData = endOfHeadFrame;
    }

    int fromOffset;
    if (startOfData <= (int)toOffset) {
      fromOffset = toOffset - startOfData;
      startOfData = toOffset;
      if (endOfData < startOfData) {
	endOfData = startOfData;
      }
    } else {
      fromOffset = 0;
      toOffset = startOfData;
    }
    int bytesUsedHere = endOfData - startOfData;

    memcpy(start_of_data + toOffset,
	   p->frame_ptr + p->headerSize + p->sideInfoSize + fromOffset,
	   bytesUsedHere);
    toOffset += bytesUsedHere;
    frameOffset += p->framesize - p->headerSize - p->sideInfoSize;
    p = p->next_adu;
  }

#ifdef DEBUG_3119
  mpa_message(LOG_DEBUG, "ts %llu, framesize %d", 
	      m_pending_adu_list->timestamp, m_pending_adu_list->framesize);
#endif
  *buffer = m_mp3_frame;
  *buflen = m_pending_adu_list->framesize;

  return (m_pending_adu_list->timestamp);
}

void CRfc3119RtpByteStream::used_bytes_for_frame (uint32_t bytes)
{
  // we don't care - we'll move to the next frame ourselves.
}

void CRfc3119RtpByteStream::flush_rtp_packets (void)
{
  SDL_LockMutex(m_rtp_packet_mutex);
 
  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;

  SDL_UnlockMutex(m_rtp_packet_mutex);
  CRtpByteStreamBase::flush_rtp_packets();
}

void CRfc3119RtpByteStream::reset (void)
{
  CRtpByteStreamBase::reset();
}


int CRfc3119RtpByteStream::have_no_data (void)
{
  return (m_head == NULL); // || m_pending_adu_list == NULL);
}

void CRfc3119RtpByteStream::free_adu (adu_data_t *adu)
{
  if (adu->freeframe != 0) {
    free(adu->frame_ptr);
    adu->frame_ptr = NULL;
    adu->freeframe = 0;
  }
  if (adu->last_in_pak != 0 &&
      adu->pak != NULL) {
    xfree(adu->pak);
    adu->pak = NULL;
  }
  adu->next_adu = m_adu_data_free;
  m_adu_data_free = adu;
}

⌨️ 快捷键说明

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