CRtpByteStreamBase::~CRtpByteStreamBase (void) { flush_rtp_packets(); if (m_rtp_packet_mutex) { SDL_DestroyMutex(m_rtp_packet_mutex); m_rtp_packet_mutex = NULL; } }
/* * recv_callback - callback for when bytestream is active - basically, * put things on the queue */ int CRtpByteStreamBase::recv_callback (struct rtp *session, rtp_event *e) { switch (e->type) { case RX_RTP: rtp_packet *rpak; rpak = (rtp_packet *)e->data; if (rpak->rtp_data_len == 0) { xfree(rpak); } else { // need to add lock/unlock of mutex here if (m_have_recv_last_ts) { int32_t diff = rpak->rtp_pak_ts - m_recv_last_ts; int32_t ts, nts; ts = m_timescale * 2; nts = 0 - ts; if (diff > ts || diff < nts) { rtp_message(LOG_INFO, "%s - rtp timestamp diff %d last %u now %u", m_name, diff, m_recv_last_ts, rpak->rtp_pak_ts); flush_rtp_packets(); reset(); } } m_have_recv_last_ts = true; m_recv_last_ts = rpak->rtp_pak_ts; if (m_buffering == 0) { rpak->pd.rtp_pd_timestamp = get_time_of_day(); rpak->pd.rtp_pd_have_timestamp = 1; } if (SDL_mutexP(m_rtp_packet_mutex) == -1) { rtp_message(LOG_CRIT, "SDL Lock mutex failure in rtp bytestream recv"); break; } add_rtp_packet_to_queue(rpak, &m_head, &m_tail, m_name); if (SDL_mutexV(m_rtp_packet_mutex) == -1) { rtp_message(LOG_CRIT, "SDL Lock mutex failure in rtp bytestream recv"); break; } m_recvd_pak = true; check_buffering(); } break; case RX_SR: rtcp_sr *srpak; srpak = (rtcp_sr *)e->data; if (rtp_my_ssrc(session) != e->ssrc) { //rtp_message(LOG_DEBUG, "%s received rtcp", m_name); calculate_wallclock_offset_from_rtcp(srpak->ntp_frac, srpak->ntp_sec, srpak->rtp_ts); } break; case RX_APP: free(e->data); break; default: #if 0 rtp_message(LOG_DEBUG, "Thread %u - Callback from rtp with %d %p", SDL_ThreadID(),e->type, e->rtp_data); #endif break; } return m_buffering; }
static void reset (rtp_plugin_data_t *pifptr) { flush_rtp_packets(pifptr); }
static bool start_next_frame (rtp_plugin_data_t *pifptr, uint8_t **buffer, uint32_t *buflen, frame_timestamp_t *ts, void **userdata) { rfc3267_data_t *iptr = (rfc3267_data_t *)pifptr; uint64_t uts = 0; uint64_t timetick; #ifdef DEBUG_RFC3267 rfc3267_message(LOG_DEBUG, rfc3267rtp, "start %p frame %u offset %u", iptr->m_pak_on, iptr->m_pak_frame_on, iptr->m_pak_frame_offset); #endif // first check if we're done with this packet // see if we need to read the packet if (iptr->m_pak_on == NULL) { do { iptr->m_pak_on = iptr->m_vft->get_head_and_check(iptr->m_ifptr, false, 0); if (iptr->m_pak_on == NULL) return false; iptr->m_pak_frame_offset = 1; while (((iptr->m_pak_on->rtp_data[iptr->m_pak_frame_offset] & 0x80) != 0) && (iptr->m_pak_frame_offset < iptr->m_pak_on->rtp_data_len)) { iptr->m_pak_frame_offset++; } if (iptr->m_pak_frame_offset >= iptr->m_pak_on->rtp_data_len) { rfc3267_message(LOG_ERR, rfc3267rtp, "frame seq number %x has incorrect rfc3267 TOC - no last frame indication", iptr->m_pak_on->rtp_pak_seq); iptr->m_vft->free_pak(iptr->m_pak_on); iptr->m_pak_on = NULL; } } while (iptr->m_pak_on == NULL); iptr->m_pak_frame_on = 0; iptr->m_pak_frame_offset++; uts = iptr->m_pak_on->pd.rtp_pd_timestamp; #ifdef DEBUG_RFC3267 rfc3267_message(LOG_DEBUG, rfc3267rtp, "start %p frame %u offset %u", iptr->m_pak_on, iptr->m_pak_frame_on, iptr->m_pak_frame_offset); #endif } // now, use the index we have and the offset we have to // determine the buffer size and length uint8_t mode; int16_t frame_len; mode = iptr->m_pak_on->rtp_data[iptr->m_pak_frame_on + 1]; iptr->m_frame[0] = mode; frame_len = MP4AV_AmrFrameSize(mode, iptr->m_amr_is_wb); // copy the frame into our buffer, so we'll have the header and the // frame. memcpy(iptr->m_frame + 1, iptr->m_pak_on->rtp_data + iptr->m_pak_frame_offset, frame_len); iptr->m_pak_frame_offset += frame_len; // calculate the ts. iptr->m_ts = iptr->m_pak_on->rtp_pak_ts; iptr->m_ts += iptr->m_pak_frame_on * iptr->m_rtp_ts_add; #ifdef DEBUG_RFC3267 rfc3267_message(LOG_DEBUG, rfc3267rtp, "mode 0x%x len %d ts %llu", mode, frame_len, iptr->m_ts); #endif // Are we done with this packet ? uint8_t toc = iptr->m_pak_on->rtp_data[1 + iptr->m_pak_frame_on]; if ((toc & 0x80) == 0) { // toc bit indicates last frame in packet // we've already copied the data, so we don't need it anymore... // flush_rtp_packets clears out all the data we want it to flush_rtp_packets(pifptr); } else { // still have more frames in the packet. iptr->m_pak_frame_on++; } *buffer = iptr->m_frame; *buflen = frame_len + 1; // include the header byte // lastly, establish the timestamp timetick = iptr->m_vft->rtp_ts_to_msec(iptr->m_ifptr, iptr->m_ts, iptr->m_pak_on ? iptr->m_pak_on->pd.rtp_pd_timestamp : uts, 0); ts->audio_freq_timestamp = iptr->m_ts; ts->msec_timestamp = timetick; ts->timestamp_is_pts = false; // We're going to have to handle wrap better... #ifdef DEBUG_RFC3267_FRAME rfc3267_message(LOG_DEBUG, rfc3267rtp, "start next frame %p %d ts "X64" "U64, *buffer, *buflen, iptr->m_ts, timetick); #endif return true; }