📄 rfc3119_bytestream.cpp
字号:
// 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 + -