diff --git a/android/app/src/main/cpp/audio-output.cpp b/android/app/src/main/cpp/audio-output.cpp index 83c4963..4531830 100644 --- a/android/app/src/main/cpp/audio-output.cpp +++ b/android/app/src/main/cpp/audio-output.cpp @@ -24,7 +24,7 @@ #include -#define BUFFER_CHUNK_SIZE 512 +#define BUFFER_CHUNK_SIZE 1024 #define BUFFER_CHUNKS_COUNT 32 using AudioBuffer = CircularBuffer; diff --git a/android/app/src/main/cpp/chiaki-jni.c b/android/app/src/main/cpp/chiaki-jni.c index 05bf1f4..e0884ce 100644 --- a/android/app/src/main/cpp/chiaki-jni.c +++ b/android/app/src/main/cpp/chiaki-jni.c @@ -262,7 +262,7 @@ JNIEXPORT void JNICALL JNI_FCN(sessionCreate)(JNIEnv *env, jobject obj, jobject } memset(session, 0, sizeof(AndroidChiakiSession)); session->log = log; - err = android_chiaki_video_decoder_init(&session->video_decoder, log); + err = android_chiaki_video_decoder_init(&session->video_decoder, log, connect_info.video_profile.width, connect_info.video_profile.height); if(err != CHIAKI_ERR_SUCCESS) { free(session); diff --git a/android/app/src/main/cpp/video-decoder.c b/android/app/src/main/cpp/video-decoder.c index 05c1f75..ecf9980 100644 --- a/android/app/src/main/cpp/video-decoder.c +++ b/android/app/src/main/cpp/video-decoder.c @@ -29,11 +29,13 @@ static void *android_chiaki_video_decoder_output_thread_func(void *user); -ChiakiErrorCode android_chiaki_video_decoder_init(AndroidChiakiVideoDecoder *decoder, ChiakiLog *log) +ChiakiErrorCode android_chiaki_video_decoder_init(AndroidChiakiVideoDecoder *decoder, ChiakiLog *log, int32_t target_width, int32_t target_height) { decoder->log = log; decoder->codec = NULL; decoder->timestamp_cur = 0; + decoder->target_width = target_width; + decoder->target_height = target_height; return chiaki_mutex_init(&decoder->codec_mutex, false); } @@ -91,8 +93,8 @@ void android_chiaki_video_decoder_set_surface(AndroidChiakiVideoDecoder *decoder AMediaFormat *format = AMediaFormat_new(); AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, mime); - AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_WIDTH, 1280); // TODO: correct values - AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_HEIGHT, 720); + AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_WIDTH, decoder->target_width); + AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_HEIGHT, decoder->target_height); media_status_t r = AMediaCodec_configure(decoder->codec, format, decoder->window, NULL, 0); if(r != AMEDIA_OK) @@ -131,8 +133,9 @@ beach: chiaki_mutex_unlock(&decoder->codec_mutex); } -void android_chiaki_video_decoder_video_sample(uint8_t *buf, size_t buf_size, void *user) +bool android_chiaki_video_decoder_video_sample(uint8_t *buf, size_t buf_size, void *user) { + bool r = true; AndroidChiakiVideoDecoder *decoder = user; chiaki_mutex_lock(&decoder->codec_mutex); @@ -148,7 +151,7 @@ void android_chiaki_video_decoder_video_sample(uint8_t *buf, size_t buf_size, vo if(codec_buf_index < 0) { CHIAKI_LOGE(decoder->log, "Failed to get input buffer"); - // TODO: report corrupt + r = false; goto beach; } @@ -173,6 +176,7 @@ void android_chiaki_video_decoder_video_sample(uint8_t *buf, size_t buf_size, vo beach: chiaki_mutex_unlock(&decoder->codec_mutex); + return r; } static void *android_chiaki_video_decoder_output_thread_func(void *user) diff --git a/android/app/src/main/cpp/video-decoder.h b/android/app/src/main/cpp/video-decoder.h index 7c60652..9e9e27f 100644 --- a/android/app/src/main/cpp/video-decoder.h +++ b/android/app/src/main/cpp/video-decoder.h @@ -34,11 +34,13 @@ typedef struct android_chiaki_video_decoder_t ANativeWindow *window; uint64_t timestamp_cur; ChiakiThread output_thread; + int32_t target_width; + int32_t target_height; } AndroidChiakiVideoDecoder; -ChiakiErrorCode android_chiaki_video_decoder_init(AndroidChiakiVideoDecoder *decoder, ChiakiLog *log); +ChiakiErrorCode android_chiaki_video_decoder_init(AndroidChiakiVideoDecoder *decoder, ChiakiLog *log, int32_t target_width, int32_t target_height); void android_chiaki_video_decoder_fini(AndroidChiakiVideoDecoder *decoder); void android_chiaki_video_decoder_set_surface(AndroidChiakiVideoDecoder *decoder, JNIEnv *env, jobject surface); -void android_chiaki_video_decoder_video_sample(uint8_t *buf, size_t buf_size, void *user); +bool android_chiaki_video_decoder_video_sample(uint8_t *buf, size_t buf_size, void *user); #endif \ No newline at end of file diff --git a/android/app/src/main/java/com/metallic/chiaki/session/StreamInput.kt b/android/app/src/main/java/com/metallic/chiaki/session/StreamInput.kt index 9cd2067..e96b7b5 100644 --- a/android/app/src/main/java/com/metallic/chiaki/session/StreamInput.kt +++ b/android/app/src/main/java/com/metallic/chiaki/session/StreamInput.kt @@ -43,7 +43,7 @@ class StreamInput(val preferences: Preferences) fun dispatchKeyEvent(event: KeyEvent): Boolean { - Log.i("StreamSession", "key event $event") + //Log.i("StreamSession", "key event $event") if(event.action != KeyEvent.ACTION_DOWN && event.action != KeyEvent.ACTION_UP) return false diff --git a/gui/src/streamsession.cpp b/gui/src/streamsession.cpp index b69efbd..8635b07 100644 --- a/gui/src/streamsession.cpp +++ b/gui/src/streamsession.cpp @@ -52,7 +52,7 @@ StreamSessionConnectInfo::StreamSessionConnectInfo(Settings *settings, QString h static void AudioSettingsCb(uint32_t channels, uint32_t rate, void *user); static void AudioFrameCb(int16_t *buf, size_t samples_count, void *user); -static void VideoSampleCb(uint8_t *buf, size_t buf_size, void *user); +static bool VideoSampleCb(uint8_t *buf, size_t buf_size, void *user); static void EventCb(ChiakiEvent *event, void *user); StreamSession::StreamSession(const StreamSessionConnectInfo &connect_info, QObject *parent) @@ -373,10 +373,11 @@ static void AudioFrameCb(int16_t *buf, size_t samples_count, void *user) StreamSessionPrivate::PushAudioFrame(session, buf, samples_count); } -static void VideoSampleCb(uint8_t *buf, size_t buf_size, void *user) +static bool VideoSampleCb(uint8_t *buf, size_t buf_size, void *user) { auto session = reinterpret_cast(user); StreamSessionPrivate::PushVideoSample(session, buf, buf_size); + return true; } static void EventCb(ChiakiEvent *event, void *user) diff --git a/lib/include/chiaki/session.h b/lib/include/chiaki/session.h index 9641117..a18ccfb 100644 --- a/lib/include/chiaki/session.h +++ b/lib/include/chiaki/session.h @@ -152,8 +152,9 @@ typedef void (*ChiakiEventCallback)(ChiakiEvent *event, void *user); /** * buf will always have an allocated padding of at least CHIAKI_VIDEO_BUFFER_PADDING_SIZE after buf_size + * @return whether the sample was successfully pushed into the decoder. On false, a corrupt frame will be reported to get a new keyframe. */ -typedef void (*ChiakiVideoSampleCallback)(uint8_t *buf, size_t buf_size, void *user); +typedef bool (*ChiakiVideoSampleCallback)(uint8_t *buf, size_t buf_size, void *user); diff --git a/lib/src/videoreceiver.c b/lib/src/videoreceiver.c index b97e2ea..fb00f8e 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_complete + 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 { @@ -143,12 +143,21 @@ static ChiakiErrorCode chiaki_video_receiver_flush_frame(ChiakiVideoReceiver *vi // TODO: Error Concealment on CHIAKI_FRAME_PROCESSOR_FLUSH_RESULT_FEC_FAILED + bool succ = flush_result != 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); + { + bool cb_succ = video_receiver->session->video_sample_cb(frame, frame_size, video_receiver->session->video_sample_cb_user); + if(!cb_succ) + { + succ = false; + CHIAKI_LOGW(video_receiver->log, "Video callback did not process frame successfully."); + } + } video_receiver->frame_index_prev = video_receiver->frame_index_cur; - if(flush_result != CHIAKI_FRAME_PROCESSOR_FLUSH_RESULT_FEC_FAILED) + if(succ) video_receiver->frame_index_prev_complete = video_receiver->frame_index_cur; return CHIAKI_ERR_SUCCESS;