📄 isma_rtp_bytestream.cpp
字号:
#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_frame_data_on->pak->pd.rtp_pd_timestamp, 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 + -