📄 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_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 + -