mirror of
https://git.sr.ht/~thestr4ng3r/chiaki
synced 2025-08-20 05:23:12 -07:00
Use Decoder Output Thread on Android
This commit is contained in:
parent
1996e0a5c5
commit
2c838736e7
4 changed files with 42 additions and 18 deletions
|
@ -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"
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue