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

📄 isma_rtp_bytestream.cpp

📁 jpeg and mpeg 编解码技术源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
  }
#ifdef DEBUG_ISMA_AAC
  isma_message(LOG_DEBUG, 
	       "processing pak seq %d ts %x len %d", 
	       pak->rtp_pak_seq, pak->rtp_pak_ts, pak->rtp_data_len);
#endif
  // This pak has not had it's header processed
  // length in bytes
  if (pak->rtp_data_len == 0) {
    remove_packet_rtp_queue(pak, 1);
    isma_message(LOG_ERR, "RTP audio packet with data length of 0");
    return;
  }

  header_len = ntohs(*(unsigned short *)pak->rtp_data);
  if (header_len < m_min_first_header_bits) {
    // bye bye, frame...
    remove_packet_rtp_queue(pak, 1);
    isma_message(LOG_ERR, "ISMA rtp - header len %d less than min %d", 
		 header_len, m_min_first_header_bits);
    return;
  }

  m_header_bitstream.init(&pak->rtp_data[sizeof(uint16_t)],
			  header_len);
  if (m_header_bitstream.getbits(m_fmtp.size_length, &frame_len) != 0) 
    return;
  m_header_bitstream.getbits(m_fmtp.index_length, &retvalue);
  get_au_header_bits();
#ifdef DEBUG_ISMA_AAC
  uint64_t wrap_offset = m_wrap_offset;
  uint64_t msec = rtp_ts_to_msec(pak->rtp_pak_ts, wrap_offset);
  isma_message(LOG_DEBUG, 
	       "1st - header len %u frame len %u ts %x %llu", 
	       header_len, frame_len, pak->rtp_pak_ts, msec);
#endif
  if (frame_len == 0) {
    remove_packet_rtp_queue(pak, 1);
    return;
  }
  uint8_t *frame_ptr;
  isma_frame_data_t *frame_data;
  uint32_t ts;
  ts = pak->rtp_pak_ts;
  frame_data = get_frame_data();
  frame_data->pak = pak;
  // frame pointer is after header_len + header_len size.  Header_len
  // is in bits - add 7, divide by 8 to get padding correctly.
  frame_data->frame_ptr = &pak->rtp_data[((header_len + 7) / 8) 
				    + sizeof(uint16_t)];
  frame_data->frame_len = frame_len;
  frame_data->rtp_timestamp = ts;

  // Check if frame is fragmented
  // frame_len plus the length of the 2 headers
  int frag_check = frame_len + sizeof(uint16_t);
  frag_check += m_fmtp.size_length / 8;
  if ((m_fmtp.size_length % 8) != 0) frag_check++;
  if (frag_check > pak->rtp_data_len) {
#ifdef DEBUG_ISMA_AAC
    isma_message(LOG_DEBUG, "Frame is fragmented");
#endif
    frame_data->is_fragment = 1;
    int err = process_fragment(pak, frame_data);
    if (err == 1)
      isma_message(LOG_ERR, "Error in processing the fragment");
    return; 
  }
  else {
#ifdef DEBUG_ISMA_AAC
    isma_message(LOG_DEBUG, "Frame is not fragmented");
#endif
    frame_data->is_fragment = 0;
    frame_data->frag_data = NULL;
  }
  int error = insert_frame_data(frame_data);
  frame_ptr = frame_data->frame_ptr + frame_data->frame_len;
  while (m_header_bitstream.bits_remain() >= m_min_header_bits) {
    uint32_t stride;
    m_header_bitstream.getbits(m_fmtp.size_length, &frame_len);
    m_header_bitstream.getbits(m_fmtp.index_delta_length, &stride);
    get_au_header_bits();
    ts += (m_rtp_ts_add * (1 + stride));
#ifdef DEBUG_ISMA_AAC
    wrap_offset = m_wrap_offset;
    msec = rtp_ts_to_msec(ts, wrap_offset);
    isma_message(LOG_DEBUG, 
		 "Stride %d len %d ts %x %llu", 
		 stride, frame_len, ts, msec);
#endif
    frame_data = get_frame_data();
    frame_data->pak = pak;
    frame_data->is_fragment = 0;
    frame_data->frag_data = NULL;
    frame_data->frame_ptr = frame_ptr;
    frame_data->frame_len = frame_len;
    frame_ptr += frame_len;
    frame_data->rtp_timestamp = ts;
    error |= insert_frame_data(frame_data);
  }
  if (error == 0 && frame_data != NULL) { 
    frame_data->last_in_pak = 1;
  }
  else {
    isma_frame_data_t *p, *last = NULL;
    p = m_frame_data_head;
    while (p != NULL) {
      if (p->pak == pak) last = p;
      p = p->frame_data_next;
    }
    if (last != NULL) {
      last->last_in_pak = 1;
      isma_message(LOG_WARNING, "error at end - marked ts %x", last->rtp_timestamp);
    } else {
      // Didn't find pak in list.  Weird
      isma_message(LOG_ERR, 
		   "Decoded packet with RTP timestamp %x and didn't"
		   "see any good frames", pak->rtp_pak_ts);
      remove_packet_rtp_queue(pak, 1);
      return;
    }
  }
  if (m_fmtp.auxiliary_data_size_length > 0) {
    m_header_bitstream.byte_align();
    uint32_t aux_len;
    m_header_bitstream.getbits(m_fmtp.auxiliary_data_size_length, &aux_len);
    aux_len = (aux_len + 7) / 8;
#ifdef DEBUG_ISMA_AAC
    isma_message(LOG_DEBUG, "Adding %d bytes for aux data size", aux_len);
#endif
    isma_frame_data_t *p;
    p = m_frame_data_head;
    while (p != NULL) {
      if (p->pak == pak) {
	p->frame_ptr += aux_len;
      }
      p = p->frame_data_next;
    }
  }
    
  remove_packet_rtp_queue(pak, 0);
}

uint64_t CIsmaAudioRtpByteStream::start_next_frame (uint8_t **buffer, 
						    uint32_t *buflen,
						    void **userdata)
{
  uint64_t timetick;

  if (m_frame_data_on != NULL) {
    uint32_t next_ts;
#ifdef DEBUG_ISMA_AAC
    isma_message(LOG_DEBUG, "Advancing to next pak data - old ts %x", 
		 m_frame_data_on->rtp_timestamp);
#endif
    if (m_frame_data_on->last_in_pak != 0) {
      // We're done with all the data in this packet - get rid
      // of the rtp packet.
      if (m_frame_data_on->is_fragment == 1) {
	// if fragmented, need to get rid of all paks pointed to
	isma_frag_data_t *q =  m_frame_data_on->frag_data;
	while (q != NULL) {
	  rtp_packet *pak = q->pak;
	  q->pak = NULL;
	  if (pak != NULL)
	    xfree(pak);
	  q = q->frag_data_next;
#ifdef DEBUG_ISMA_AAC
	  isma_message(LOG_DEBUG, "removing pak - frag %d", pak->rtp_pak_seq);
#endif
	}
      } else {
	rtp_packet *pak = m_frame_data_on->pak;
	m_frame_data_on->pak = NULL;
	xfree(pak);
#ifdef DEBUG_ISMA_AAC
	isma_message(LOG_DEBUG, "removing pak %d", pak->rtp_pak_seq);
#endif
      }
    }
    /*
     * Remove the frame data head pointer, and put it on the free list
     */
    isma_frame_data_t *p = NULL;
    SDL_LockMutex(m_rtp_packet_mutex);
    p = m_frame_data_on;
    m_frame_data_on = NULL;
    next_ts = p->rtp_timestamp;
    p->frame_data_next = m_frame_data_free;
    m_frame_data_free = p;
    // free all frag_data for this frame
    if (p->is_fragment == 1) {
      isma_frag_data_t * q = p->frag_data;
      while (q != NULL) {
	p->frag_data = q->frag_data_next;
	free(q);
	q = p->frag_data;
      } 
    }
    SDL_UnlockMutex(m_rtp_packet_mutex);

    /* 
     * Now, look for the next timestamp - process a bunch of new
     * rtp packets, if we have to...
     */
    next_ts += m_rtp_ts_add;
    if (m_frame_data_head == NULL ||
	m_frame_data_head->rtp_timestamp != next_ts) {
      // process next pak in list.  Process until next timestamp is found, 
      // or 500 msec worth of data is found (in which case, go with first)
      do {
	process_packet_header();
      } while (m_head != NULL && 
	       ((m_frame_data_head == NULL) || 
		(m_frame_data_head->rtp_timestamp != next_ts)) &&  
	       (m_frame_data_free != NULL));
    }
#ifdef DEBUG_ISMA_AAC
    else {
      // m_frame_data_head is correct
      isma_message(LOG_DEBUG, "frame_data_head is correct");
    }
#endif
  } else {
    // first time.  Process a bunch of packets, go with first one...
    // asdf - will want to eventually add code to drop the first couple
    // of packets if they're not consecutive.
    do {
      process_packet_header();
    } while (m_frame_data_free != NULL);
  }
  /*
   * Init up the offsets
   */
  if (m_frame_data_head != NULL) {
    SDL_LockMutex(m_rtp_packet_mutex);
    m_frame_data_on = m_frame_data_head;
    m_frame_data_head = m_frame_data_head->frame_data_next;
    SDL_UnlockMutex(m_rtp_packet_mutex);

    if (m_frame_data_on->is_fragment == 1) {	  

      m_frag_reass_size = 0;
      isma_frag_data_t *ptr;
      ptr = m_frame_data_on->frag_data;
      while (ptr != NULL) {
	if (m_frag_reass_size + ptr->frag_len > m_frag_reass_size_max) {
	  m_frag_reass_size_max += max(4096, ptr->frag_len);
	  m_frag_reass_buffer = (uint8_t *)realloc(m_frag_reass_buffer, 
							 m_frag_reass_size_max);
	}
	memmove(m_frag_reass_buffer + m_frag_reass_size, 
		ptr->frag_ptr,
		ptr->frag_len);
	m_frag_reass_size += ptr->frag_len;
	ptr = ptr->frag_data_next;
      }
      *buffer = m_frag_reass_buffer;
      *buflen = m_frag_reass_size;
    } else { 
      *buffer = m_frame_data_on->frame_ptr;
      *buflen = m_frame_data_on->frame_len;
    }
  } else {
    *buffer = NULL;
  }
#ifdef ISMA_RTP_DUMP_OUTPUT_TO_FILE
  if (*buffer != NULL) {
    fwrite(*buffer, *buflen,  1, m_outfile);
  }
#endif
  timetick = rtp_ts_to_msec(m_frame_data_on != NULL ? 
			    m_frame_data_on->rtp_timestamp : m_ts, 
			    m_wrap_offset);
  if (m_frame_data_on != NULL)
    m_ts =  m_frame_data_on->rtp_timestamp;
  // We're going to have to handle wrap better...
#ifdef DEBUG_ISMA_AAC
  isma_message(LOG_DEBUG, "start next frame %p %d ts %x "LLU, 
	       *buffer, *buflen, m_ts, timetick);
#endif
  return (timetick);
}

void CIsmaAudioRtpByteStream::used_bytes_for_frame (uint32_t bytes)
{
}

void CIsmaAudioRtpByteStream::flush_rtp_packets (void)
{
  isma_frame_data_t *p;
  SDL_LockMutex(m_rtp_packet_mutex);
  if (m_frame_data_on != NULL) {
    m_frame_data_on->frame_data_next = m_frame_data_head;
    m_frame_data_head = m_frame_data_on;
    m_frame_data_on = NULL;
  }
  if (m_frame_data_head != NULL) {
    p = m_frame_data_head;
    while (p->frame_data_next != NULL) {
#ifdef DEBUG_ISMA_AAC
      isma_message(LOG_DEBUG, "reset removing pak %d", p->pak->rtp_pak_seq);
#endif
      if (p->last_in_pak != 0) {
	if (p->is_fragment == 1) {
	  // get rid of frag data 
	  isma_frag_data_t * q = NULL;
	  while ((q = p->frag_data) != NULL) {
	    p->frag_data = q->frag_data_next;
	    free(q);
	  } 
	}
	xfree(p->pak);
      }
      p = p->frame_data_next;
    }
    p->frame_data_next = m_frame_data_free;
    m_frame_data_free = m_frame_data_head;
    m_frame_data_head = NULL;
  }
  SDL_UnlockMutex(m_rtp_packet_mutex);
  CRtpByteStreamBase::flush_rtp_packets();
}

void CIsmaAudioRtpByteStream::reset (void)
{
  isma_message(LOG_INFO, "Hit isma rtp reset");
  CRtpByteStreamBase::reset();
}


int CIsmaAudioRtpByteStream::have_no_data (void)
{
  return (m_head == NULL && m_frame_data_head == NULL);
}

⌨️ 快捷键说明

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