Use Decoder Output Thread on Android

This commit is contained in:
Florian Märkl 2019-09-16 15:05:09 +02:00
commit 2c838736e7
No known key found for this signature in database
GPG key ID: 125BC8A5A6A1E857
4 changed files with 42 additions and 18 deletions

View file

@ -9,7 +9,7 @@ android {
buildToolsVersion "29.0.2" buildToolsVersion "29.0.2"
defaultConfig { defaultConfig {
applicationId "com.metallic.chiaki" applicationId "com.metallic.chiaki"
minSdkVersion 21 minSdkVersion 26
targetSdkVersion 29 targetSdkVersion 29
versionCode 1 versionCode 1
versionName "1.0" versionName "1.0"

View file

@ -25,7 +25,7 @@
#include <string.h> #include <string.h>
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) 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) 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; goto beach;
} }
@ -74,6 +78,16 @@ void android_chiaki_video_decoder_set_surface(AndroidChiakiVideoDecoder *decoder
AMediaFormat_delete(format); 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: beach:
chiaki_mutex_unlock(&decoder->mutex); 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; goto beach;
} }
ssize_t codec_buf_index;
CHIAKI_LOGD(decoder->log, "Got video sample of size %zu", buf_size);
while(buf_size > 0) 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) if(codec_buf_index < 0)
{ {
// TODO: handle better // 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 += codec_sample_size;
buf_size -= 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: beach:
android_chiaki_video_decoder_flush(decoder);
chiaki_mutex_unlock(&decoder->mutex); 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;
} }

View file

@ -33,6 +33,7 @@ typedef struct android_chiaki_video_decoder_t
AMediaCodec *codec; AMediaCodec *codec;
ANativeWindow *window; ANativeWindow *window;
uint64_t timestamp_cur; uint64_t timestamp_cur;
ChiakiThread output_thread;
} AndroidChiakiVideoDecoder; } AndroidChiakiVideoDecoder;
ChiakiErrorCode android_chiaki_video_decoder_init(AndroidChiakiVideoDecoder *decoder, ChiakiLog *log); ChiakiErrorCode android_chiaki_video_decoder_init(AndroidChiakiVideoDecoder *decoder, ChiakiLog *log);

View file

@ -42,14 +42,17 @@ class StreamActivity : AppCompatActivity()
surfaceView.holder.addCallback(object: SurfaceHolder.Callback { surfaceView.holder.addCallback(object: SurfaceHolder.Callback {
override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int)
{ {
Log.i("StreamActivity", "surfaceChanged")
} }
override fun surfaceDestroyed(holder: SurfaceHolder) override fun surfaceDestroyed(holder: SurfaceHolder)
{ {
Log.i("StreamActivity", "surfaceDestroyed!!!!!")
} }
override fun surfaceCreated(holder: SurfaceHolder) override fun surfaceCreated(holder: SurfaceHolder)
{ {
Log.i("StreamActivity", "surfaceCreated")
viewModel.session?.setSurface(holder.surface) viewModel.session?.setSurface(holder.surface)
} }
}) })