Skip some invalid AAC packets, don't decode outdated frames, wait for timing information to be valid.
This commit is contained in:
@@ -1310,7 +1310,7 @@ int get_ptp_anchor_local_time_info(rtsp_conn_info *conn, uint32_t *anchorRTP,
|
||||
// if the master clock and the anchor clock are the same
|
||||
// wait at least this time before using the new master clock
|
||||
// note that mastershipo may be backdated
|
||||
if (duration_of_mastership < 1500000000) {
|
||||
if (duration_of_mastership < 100000000) {
|
||||
debug(3, "master not old enough yet: %f ms", 0.000001 * duration_of_mastership);
|
||||
response = clock_not_ready;
|
||||
} else if ((duration_of_mastership > 5000000000) ||
|
||||
@@ -1400,6 +1400,7 @@ int get_ptp_anchor_local_time_info(rtsp_conn_info *conn, uint32_t *anchorRTP,
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// debug(1, "anchor_remote_info_is_valid not valid");
|
||||
response = clock_no_anchor_info; // no anchor information
|
||||
}
|
||||
}
|
||||
@@ -2253,7 +2254,14 @@ void *rtp_buffered_audio_processor(void *arg) {
|
||||
int streaming_has_started = 0;
|
||||
int play_enabled = 0;
|
||||
uint32_t flush_from_timestamp;
|
||||
double requested_lead_time = 0.3; // normal lead time minimum
|
||||
double requested_lead_time = 0.0; // normal lead time minimum -- maybe it should be about 0.1
|
||||
|
||||
// wait until our timing information is valid
|
||||
|
||||
// debug(1,"rtp_buffered_audio_processor ready.");
|
||||
while (have_ptp_timing_information(conn) == 0)
|
||||
usleep(1000);
|
||||
|
||||
reset_buffer(conn); // in case there is any garbage in the player
|
||||
// int not_first_time_out = 0;
|
||||
|
||||
@@ -2519,28 +2527,42 @@ void *rtp_buffered_audio_processor(void *arg) {
|
||||
// to decipher it first
|
||||
// debug(1,"seq_no %u, timestamp %u", seq_no, timestamp);
|
||||
|
||||
uint64_t local_should_be_time = 0;
|
||||
int have_time_information = frame_to_local_time(timestamp, &local_should_be_time, conn);
|
||||
int64_t local_lead_time = 0;
|
||||
int64_t requested_lead_time_ns = (int64_t)(requested_lead_time * 1000000000);
|
||||
requested_lead_time_ns = (int64_t)(-300000000);
|
||||
int outdated = 0;
|
||||
if (have_time_information == 0) {
|
||||
local_lead_time = local_should_be_time - get_absolute_time_in_ns();
|
||||
outdated = (local_lead_time < requested_lead_time_ns);
|
||||
// if (outdated != 0)
|
||||
// debug(1,"Frame is outdated %d if lead_time %" PRId64 " is less than requested lead time %" PRId64 " ns.", outdated, local_lead_time, requested_lead_time_ns);
|
||||
} else {
|
||||
debug(1,"Timing information not valid");
|
||||
// outdated = 1;
|
||||
}
|
||||
|
||||
|
||||
if ((flush_requested) && (seq_no >= flushUntilSeq)) {
|
||||
uint64_t should_be_time;
|
||||
if ((frame_to_local_time(timestamp, &should_be_time, conn) == 0) && (play_enabled)) {
|
||||
if ((have_time_information == 0) && (play_enabled)) {
|
||||
// play enabled will be off when this is a full flush and the anchor information is not
|
||||
// valid
|
||||
int64_t lead_time = should_be_time - get_absolute_time_in_ns();
|
||||
debug(1,
|
||||
debug(2,
|
||||
"flush completed to seq: %u, flushUntilTS; %u with rtptime: %u, lead time: "
|
||||
"0x%" PRIx64 " nanoseconds, i.e. %f sec.",
|
||||
seq_no, flushUntilTS, timestamp, lead_time, lead_time * 0.000000001);
|
||||
seq_no, flushUntilTS, timestamp, local_lead_time, local_lead_time * 0.000000001);
|
||||
} else {
|
||||
debug(2, "flush completed to seq: %u with rtptime: %u.", seq_no, timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
if (((flush_requested != 0) && (seq_no == flushUntilSeq)) ||
|
||||
((flush_requested == 0) && (new_buffer_needed))) {
|
||||
|
||||
|
||||
// if we are here because of a flush request, it must be the case that
|
||||
// flushing the pcm buffer wasn't enough, as the request would have been turned off by now
|
||||
// so we better indicate that the pcm buffer is empty and its contents invalid
|
||||
if (flush_requested) {
|
||||
|
||||
// also, if the incomgin frame is outdated, set pcm_buffer_occupancy to 0;
|
||||
if ((flush_requested) || (outdated)){
|
||||
pcm_buffer_occupancy = 0;
|
||||
}
|
||||
|
||||
@@ -2556,6 +2578,11 @@ void *rtp_buffered_audio_processor(void *arg) {
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
if (((flush_requested != 0) && (seq_no == flushUntilSeq)) ||
|
||||
((flush_requested == 0) && (new_buffer_needed))) {
|
||||
|
||||
|
||||
unsigned char nonce[12];
|
||||
memset(nonce, 0, sizeof(nonce));
|
||||
memcpy(nonce + 4, packet + nread - 8,
|
||||
@@ -2596,6 +2623,7 @@ void *rtp_buffered_audio_processor(void *arg) {
|
||||
data_remaining = aac_packet_length;
|
||||
int ret = 0;
|
||||
// there can be more than one av packet (? terminology) in a block
|
||||
int frame_within_block = 0;
|
||||
while (data_remaining > 0) {
|
||||
if (decoded_frame == NULL) {
|
||||
decoded_frame = av_frame_alloc();
|
||||
@@ -2608,14 +2636,20 @@ void *rtp_buffered_audio_processor(void *arg) {
|
||||
if (ret < 0) {
|
||||
debug(1, "error while parsing deciphered audio packet.");
|
||||
} else {
|
||||
frame_within_block++;
|
||||
data_to_process += ret;
|
||||
data_remaining -= ret;
|
||||
// debug(1, "frame found");
|
||||
// now pass each packet to be decoded
|
||||
if (pkt->size) {
|
||||
//if (0) {
|
||||
if (pkt->size <= 7) { // no idea about this...
|
||||
debug(1,"malformed AAC packet skipped.");
|
||||
} else {
|
||||
ret = avcodec_send_packet(codec_context, pkt);
|
||||
|
||||
if (ret < 0) {
|
||||
debug(1, "error sending packet to decoder");
|
||||
debug(1, "error sending frame %d of size %d to decoder, blocks_read: %u, blocks_read_since_flush: %u.", frame_within_block, pkt->size, blocks_read, blocks_read_since_flush);
|
||||
} else {
|
||||
while (ret >= 0) {
|
||||
ret = avcodec_receive_frame(codec_context, decoded_frame);
|
||||
@@ -2672,6 +2706,7 @@ void *rtp_buffered_audio_processor(void *arg) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (decoded_frame == NULL)
|
||||
debug(1, "decoded_frame is NULL");
|
||||
|
||||
Reference in New Issue
Block a user