From 2c838736e79b2bb256cfc1d61afa4584a8e1e7e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=A4rkl?= Date: Mon, 16 Sep 2019 15:05:09 +0200 Subject: [PATCH] Use Decoder Output Thread on Android --- android/app/build.gradle | 2 +- android/app/src/main/cpp/video-decoder.c | 54 +++++++++++++------ android/app/src/main/cpp/video-decoder.h | 1 + .../metallic/chiaki/stream/StreamActivity.kt | 3 ++ 4 files changed, 42 insertions(+), 18 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index a0eefca..a22f442 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -9,7 +9,7 @@ android { buildToolsVersion "29.0.2" defaultConfig { applicationId "com.metallic.chiaki" - minSdkVersion 21 + minSdkVersion 26 targetSdkVersion 29 versionCode 1 versionName "1.0" diff --git a/android/app/src/main/cpp/video-decoder.c b/android/app/src/main/cpp/video-decoder.c index 22672ab..6c20e75 100644 --- a/android/app/src/main/cpp/video-decoder.c +++ b/android/app/src/main/cpp/video-decoder.c @@ -25,7 +25,7 @@ #include -static void android_chiaki_video_decoder_flush(AndroidChiakiVideoDecoder *decoder); +static void *android_chiaki_video_decoder_output_thread_func(void *user); ChiakiErrorCode android_chiaki_video_decoder_init(AndroidChiakiVideoDecoder *decoder, ChiakiLog *log) { @@ -46,8 +46,12 @@ void android_chiaki_video_decoder_set_surface(AndroidChiakiVideoDecoder *decoder if(decoder->codec) { - // TODO: destroy old - CHIAKI_LOGE(decoder->log, "Video Decoder already initialized"); + //CHIAKI_LOGE(decoder->log, "Video Decoder already initialized"); + CHIAKI_LOGI(decoder->log, "Video decoder already initialized, swapping surface"); + ANativeWindow *new_window = surface ? ANativeWindow_fromSurface(env, surface) : NULL; + AMediaCodec_setOutputSurface(decoder->codec, new_window); + ANativeWindow_release(decoder->window); + decoder->window = new_window; goto beach; } @@ -74,6 +78,16 @@ void android_chiaki_video_decoder_set_surface(AndroidChiakiVideoDecoder *decoder AMediaFormat_delete(format); + ChiakiErrorCode err = chiaki_thread_create(&decoder->output_thread, android_chiaki_video_decoder_output_thread_func, decoder); + if(err != CHIAKI_ERR_SUCCESS) + { + CHIAKI_LOGE(decoder->log, "Failed to create output thread for AMediaCodec"); + AMediaCodec_delete(decoder->codec); + decoder->codec = NULL; + ANativeWindow_release(decoder->window); + decoder->window = NULL; + } + beach: chiaki_mutex_unlock(&decoder->mutex); } @@ -89,13 +103,9 @@ void android_chiaki_video_decoder_video_sample(uint8_t *buf, size_t buf_size, vo goto beach; } - ssize_t codec_buf_index; - - CHIAKI_LOGD(decoder->log, "Got video sample of size %zu", buf_size); - while(buf_size > 0) { - codec_buf_index = AMediaCodec_dequeueInputBuffer(decoder->codec, 100); // TODO: lower timeout? + ssize_t codec_buf_index = AMediaCodec_dequeueInputBuffer(decoder->codec, 100); // TODO: lower timeout? if(codec_buf_index < 0) { // TODO: handle better @@ -116,20 +126,30 @@ void android_chiaki_video_decoder_video_sample(uint8_t *buf, size_t buf_size, vo buf += codec_sample_size; buf_size -= codec_sample_size; - AMediaCodecBufferInfo info; - ssize_t status = AMediaCodec_dequeueOutputBuffer(decoder->codec, &info, 0); - if(status >= 0) - { - AMediaCodec_releaseOutputBuffer(decoder->codec, (size_t)status, info.size != 0); - } } beach: - android_chiaki_video_decoder_flush(decoder); chiaki_mutex_unlock(&decoder->mutex); } -static void android_chiaki_video_decoder_flush(AndroidChiakiVideoDecoder *decoder) +static void *android_chiaki_video_decoder_output_thread_func(void *user) { - // decoder->mutex must be already locked + AndroidChiakiVideoDecoder *decoder = user; + + while(1) + { + AMediaCodecBufferInfo info; + ssize_t status = AMediaCodec_dequeueOutputBuffer(decoder->codec, &info, -1); + if(status >= 0) + { + AMediaCodec_releaseOutputBuffer(decoder->codec, (size_t)status, info.size != 0); + if(info.flags & AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM) + { + CHIAKI_LOGI(decoder->log, "AMediaCodec reported EOS"); + break; + } + } + } + + return NULL; } \ No newline at end of file diff --git a/android/app/src/main/cpp/video-decoder.h b/android/app/src/main/cpp/video-decoder.h index 62284d4..0bff080 100644 --- a/android/app/src/main/cpp/video-decoder.h +++ b/android/app/src/main/cpp/video-decoder.h @@ -33,6 +33,7 @@ typedef struct android_chiaki_video_decoder_t AMediaCodec *codec; ANativeWindow *window; uint64_t timestamp_cur; + ChiakiThread output_thread; } AndroidChiakiVideoDecoder; ChiakiErrorCode android_chiaki_video_decoder_init(AndroidChiakiVideoDecoder *decoder, ChiakiLog *log); diff --git a/android/app/src/main/java/com/metallic/chiaki/stream/StreamActivity.kt b/android/app/src/main/java/com/metallic/chiaki/stream/StreamActivity.kt index aa8d5c1..d055821 100644 --- a/android/app/src/main/java/com/metallic/chiaki/stream/StreamActivity.kt +++ b/android/app/src/main/java/com/metallic/chiaki/stream/StreamActivity.kt @@ -42,14 +42,17 @@ class StreamActivity : AppCompatActivity() surfaceView.holder.addCallback(object: SurfaceHolder.Callback { override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) { + Log.i("StreamActivity", "surfaceChanged") } override fun surfaceDestroyed(holder: SurfaceHolder) { + Log.i("StreamActivity", "surfaceDestroyed!!!!!") } override fun surfaceCreated(holder: SurfaceHolder) { + Log.i("StreamActivity", "surfaceCreated") viewModel.session?.setSurface(holder.surface) } })