diff --git a/lib/include/chiaki/videoreceiver.h b/lib/include/chiaki/videoreceiver.h index 83542c1..0ce8f0c 100644 --- a/lib/include/chiaki/videoreceiver.h +++ b/lib/include/chiaki/videoreceiver.h @@ -39,7 +39,8 @@ typedef struct chiaki_video_receiver_t int profile_cur; // < 1 if no profile selected yet, else index in profiles int32_t frame_index_cur; // frame that is currently being filled - int32_t frame_index_prev; // last frame that has been completely decoded/reported + int32_t frame_index_prev; // last frame that has been at least partially decoded + int32_t frame_index_prev_complete; // last frame that has been completely decoded ChiakiFrameProcessor frame_processor; } ChiakiVideoReceiver; diff --git a/lib/src/frameprocessor.c b/lib/src/frameprocessor.c index 7653961..4b76c3c 100644 --- a/lib/src/frameprocessor.c +++ b/lib/src/frameprocessor.c @@ -245,19 +245,25 @@ CHIAKI_EXPORT ChiakiFrameProcessorFlushResult chiaki_frame_processor_flush(Chiak if(frame_processor->units_source_received < frame_processor->units_source_expected) { ChiakiErrorCode err = chiaki_frame_processor_fec(frame_processor); - if(err != CHIAKI_ERR_SUCCESS) - return CHIAKI_FRAME_PROCESSOR_FLUSH_RESULT_FAILED; - result = CHIAKI_FRAME_PROCESSOR_FLUSH_RESULT_FEC_SUCCESS; + if(err == CHIAKI_ERR_SUCCESS) + result = CHIAKI_FRAME_PROCESSOR_FLUSH_RESULT_FEC_SUCCESS; + else + result = CHIAKI_FRAME_PROCESSOR_FLUSH_RESULT_FEC_FAILED; } size_t cur = 0; for(size_t i=0; iunits_source_expected; i++) { ChiakiFrameUnit *unit = frame_processor->unit_slots + i; + if(!unit->data_size) + { + CHIAKI_LOGW(frame_processor->log, "Missing unit %#llx", (unsigned long long)i); + continue; + } if(unit->data_size < 2) { CHIAKI_LOGE(frame_processor->log, "Saved unit has size < 2"); - chiaki_log_hexdump(frame_processor->log, CHIAKI_LOG_DEBUG, frame_processor->frame_buf + i*frame_processor->buf_size_per_unit, 0x50); + chiaki_log_hexdump(frame_processor->log, CHIAKI_LOG_VERBOSE, frame_processor->frame_buf + i*frame_processor->buf_size_per_unit, 0x50); continue; } size_t part_size = unit->data_size - 2; diff --git a/lib/src/videoreceiver.c b/lib/src/videoreceiver.c index c1729cf..879ecbf 100644 --- a/lib/src/videoreceiver.c +++ b/lib/src/videoreceiver.c @@ -100,7 +100,7 @@ CHIAKI_EXPORT void chiaki_video_receiver_av_packet(ChiakiVideoReceiver *video_re if(video_receiver->frame_index_cur >= 0 && video_receiver->frame_index_prev != video_receiver->frame_index_cur) chiaki_video_receiver_flush_frame(video_receiver); - ChiakiSeqNum16 next_frame_expected = (ChiakiSeqNum16)video_receiver->frame_index_prev + 1; + ChiakiSeqNum16 next_frame_expected = (ChiakiSeqNum16)video_receiver->frame_index_prev_complete + 1; if(chiaki_seq_num_16_gt(frame_index, next_frame_expected) && !(frame_index == 1 && video_receiver->frame_index_cur < 0)) // ok for frame 1 { @@ -123,22 +123,33 @@ CHIAKI_EXPORT void chiaki_video_receiver_av_packet(ChiakiVideoReceiver *video_re } } +#define FLUSH_CORRUPT_FRAMES + static ChiakiErrorCode chiaki_video_receiver_flush_frame(ChiakiVideoReceiver *video_receiver) { uint8_t *frame; size_t frame_size; ChiakiFrameProcessorFlushResult flush_result = chiaki_frame_processor_flush(&video_receiver->frame_processor, &frame, &frame_size); - if(flush_result == CHIAKI_FRAME_PROCESSOR_FLUSH_RESULT_FAILED) + if(flush_result == CHIAKI_FRAME_PROCESSOR_FLUSH_RESULT_FAILED +#ifndef FLUSH_CORRUPT_FRAMES + || flush_result == CHIAKI_FRAME_PROCESSOR_FLUSH_RESULT_FEC_FAILED +#endif + ) { - // TODO: fake frame? CHIAKI_LOGW(video_receiver->log, "Failed to complete frame %d", (int)video_receiver->frame_index_cur); return CHIAKI_ERR_UNKNOWN; } + // TODO: Error Concealment on CHIAKI_FRAME_PROCESSOR_FLUSH_RESULT_FEC_FAILED + if(video_receiver->session->video_sample_cb) video_receiver->session->video_sample_cb(frame, frame_size, video_receiver->session->video_sample_cb_user); video_receiver->frame_index_prev = video_receiver->frame_index_cur; + + if(flush_result != CHIAKI_FRAME_PROCESSOR_FLUSH_RESULT_FEC_FAILED) + video_receiver->frame_index_prev_complete = video_receiver->frame_index_cur; + return CHIAKI_ERR_SUCCESS; } \ No newline at end of file