mirror of
https://git.sr.ht/~thestr4ng3r/chiaki
synced 2025-08-14 02:36:51 -07:00
Shutdown Decoders on Android
This commit is contained in:
parent
01f746ec35
commit
90431d7e2e
7 changed files with 66 additions and 21 deletions
|
@ -41,12 +41,31 @@ ChiakiErrorCode android_chiaki_audio_decoder_init(AndroidChiakiAudioDecoder *dec
|
||||||
decoder->settings_cb = NULL;
|
decoder->settings_cb = NULL;
|
||||||
decoder->frame_cb = NULL;
|
decoder->frame_cb = NULL;
|
||||||
|
|
||||||
return CHIAKI_ERR_SUCCESS;
|
return chiaki_mutex_init(&decoder->codec_mutex, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void android_chiaki_audio_decoder_shutdown_codec(AndroidChiakiAudioDecoder *decoder)
|
||||||
|
{
|
||||||
|
chiaki_mutex_lock(&decoder->codec_mutex);
|
||||||
|
ssize_t codec_buf_index = AMediaCodec_dequeueInputBuffer(decoder->codec, -1);
|
||||||
|
if(codec_buf_index >= 0)
|
||||||
|
{
|
||||||
|
CHIAKI_LOGI(decoder->log, "Audio Decoder sending EOS buffer");
|
||||||
|
AMediaCodec_queueInputBuffer(decoder->codec, (size_t)codec_buf_index, 0, 0, decoder->timestamp_cur++, AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
CHIAKI_LOGE(decoder->log, "Failed to get input buffer for shutting down Audio Decoder!");
|
||||||
|
chiaki_mutex_unlock(&decoder->codec_mutex);
|
||||||
|
chiaki_thread_join(&decoder->output_thread, NULL);
|
||||||
|
AMediaCodec_delete(decoder->codec);
|
||||||
|
decoder->codec = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void android_chiaki_audio_decoder_fini(AndroidChiakiAudioDecoder *decoder)
|
void android_chiaki_audio_decoder_fini(AndroidChiakiAudioDecoder *decoder)
|
||||||
{
|
{
|
||||||
// TODO: shutdown (thread may or may not be running!)
|
if(decoder->codec)
|
||||||
|
android_chiaki_audio_decoder_shutdown_codec(decoder);
|
||||||
|
chiaki_mutex_fini(&decoder->codec_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void android_chiaki_audio_decoder_get_sink(AndroidChiakiAudioDecoder *decoder, ChiakiAudioSink *sink)
|
void android_chiaki_audio_decoder_get_sink(AndroidChiakiAudioDecoder *decoder, ChiakiAudioSink *sink)
|
||||||
|
@ -83,20 +102,21 @@ static void *android_chiaki_audio_decoder_output_thread_func(void *user)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CHIAKI_LOGI(decoder->log, "Audio Decoder Output Thread exiting");
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void android_chiaki_audio_decoder_header(ChiakiAudioHeader *header, void *user)
|
static void android_chiaki_audio_decoder_header(ChiakiAudioHeader *header, void *user)
|
||||||
{
|
{
|
||||||
AndroidChiakiAudioDecoder *decoder = user;
|
AndroidChiakiAudioDecoder *decoder = user;
|
||||||
|
chiaki_mutex_lock(&decoder->codec_mutex);
|
||||||
memcpy(&decoder->audio_header, header, sizeof(decoder->audio_header));
|
memcpy(&decoder->audio_header, header, sizeof(decoder->audio_header));
|
||||||
|
|
||||||
if(decoder->codec)
|
if(decoder->codec)
|
||||||
{
|
{
|
||||||
CHIAKI_LOGI(decoder->log, "Audio decoder already initialized, re-creating");
|
CHIAKI_LOGI(decoder->log, "Audio decoder already initialized, shutting down the old one");
|
||||||
// TODO: stop thread
|
android_chiaki_audio_decoder_shutdown_codec(decoder);
|
||||||
AMediaCodec_delete(decoder->codec);
|
|
||||||
decoder->codec = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *mime = "audio/opus";
|
const char *mime = "audio/opus";
|
||||||
|
@ -104,7 +124,7 @@ static void android_chiaki_audio_decoder_header(ChiakiAudioHeader *header, void
|
||||||
if(!decoder->codec)
|
if(!decoder->codec)
|
||||||
{
|
{
|
||||||
CHIAKI_LOGE(decoder->log, "Failed to create AMediaCodec for mime type %s", mime);
|
CHIAKI_LOGE(decoder->log, "Failed to create AMediaCodec for mime type %s", mime);
|
||||||
return;
|
goto beach;
|
||||||
}
|
}
|
||||||
|
|
||||||
AMediaFormat *format = AMediaFormat_new();
|
AMediaFormat *format = AMediaFormat_new();
|
||||||
|
@ -126,7 +146,6 @@ static void android_chiaki_audio_decoder_header(ChiakiAudioHeader *header, void
|
||||||
decoder->codec = NULL;
|
decoder->codec = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint8_t opus_id_head[0x13];
|
uint8_t opus_id_head[0x13];
|
||||||
memcpy(opus_id_head, "OpusHead", 8);
|
memcpy(opus_id_head, "OpusHead", 8);
|
||||||
opus_id_head[0x8] = 1; // version
|
opus_id_head[0x8] = 1; // version
|
||||||
|
@ -157,16 +176,20 @@ static void android_chiaki_audio_decoder_header(ChiakiAudioHeader *header, void
|
||||||
|
|
||||||
if(decoder->settings_cb)
|
if(decoder->settings_cb)
|
||||||
decoder->settings_cb(header->channels, header->rate, decoder->cb_user);
|
decoder->settings_cb(header->channels, header->rate, decoder->cb_user);
|
||||||
|
|
||||||
|
beach:
|
||||||
|
chiaki_mutex_unlock(&decoder->codec_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void android_chiaki_audio_decoder_frame(uint8_t *buf, size_t buf_size, void *user)
|
static void android_chiaki_audio_decoder_frame(uint8_t *buf, size_t buf_size, void *user)
|
||||||
{
|
{
|
||||||
AndroidChiakiAudioDecoder *decoder = user;
|
AndroidChiakiAudioDecoder *decoder = user;
|
||||||
|
chiaki_mutex_lock(&decoder->codec_mutex);
|
||||||
|
|
||||||
if(!decoder->codec)
|
if(!decoder->codec)
|
||||||
{
|
{
|
||||||
CHIAKI_LOGE(decoder->log, "Received audio data, but decoder is not initialized!");
|
CHIAKI_LOGE(decoder->log, "Received audio data, but decoder is not initialized!");
|
||||||
return;
|
goto beach;
|
||||||
}
|
}
|
||||||
|
|
||||||
while(buf_size > 0)
|
while(buf_size > 0)
|
||||||
|
@ -191,4 +214,7 @@ static void android_chiaki_audio_decoder_frame(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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
beach:
|
||||||
|
chiaki_mutex_unlock(&decoder->codec_mutex);
|
||||||
}
|
}
|
|
@ -31,6 +31,8 @@ typedef struct android_chiaki_audio_decoder_t
|
||||||
{
|
{
|
||||||
ChiakiLog *log;
|
ChiakiLog *log;
|
||||||
ChiakiAudioHeader audio_header;
|
ChiakiAudioHeader audio_header;
|
||||||
|
|
||||||
|
ChiakiMutex codec_mutex;
|
||||||
struct AMediaCodec *codec;
|
struct AMediaCodec *codec;
|
||||||
uint64_t timestamp_cur;
|
uint64_t timestamp_cur;
|
||||||
ChiakiThread output_thread;
|
ChiakiThread output_thread;
|
||||||
|
|
|
@ -121,7 +121,7 @@ oboe::DataCallbackResult AudioOutputCallback::onAudioReady(oboe::AudioStream *st
|
||||||
|
|
||||||
if(buf_size_delivered < buf_size_requested)
|
if(buf_size_delivered < buf_size_requested)
|
||||||
{
|
{
|
||||||
CHIAKI_LOGW(audio_output->log, "Audio Output Buffer Underflow!");
|
CHIAKI_LOGV(audio_output->log, "Audio Output Buffer Underflow!");
|
||||||
memset(buf + buf_size_delivered, 0, buf_size_requested - buf_size_delivered);
|
memset(buf + buf_size_delivered, 0, buf_size_requested - buf_size_delivered);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -281,7 +281,7 @@ beach:
|
||||||
JNIEXPORT void JNICALL Java_com_metallic_chiaki_lib_ChiakiNative_sessionFree(JNIEnv *env, jobject obj, jlong ptr)
|
JNIEXPORT void JNICALL Java_com_metallic_chiaki_lib_ChiakiNative_sessionFree(JNIEnv *env, jobject obj, jlong ptr)
|
||||||
{
|
{
|
||||||
AndroidChiakiSession *session = (AndroidChiakiSession *)ptr;
|
AndroidChiakiSession *session = (AndroidChiakiSession *)ptr;
|
||||||
CHIAKI_LOGI(&global_log, "Free JNI Session");
|
CHIAKI_LOGI(&global_log, "Shutting down JNI Session");
|
||||||
if(!session)
|
if(!session)
|
||||||
return;
|
return;
|
||||||
chiaki_session_fini(&session->session);
|
chiaki_session_fini(&session->session);
|
||||||
|
@ -290,6 +290,7 @@ JNIEXPORT void JNICALL Java_com_metallic_chiaki_lib_ChiakiNative_sessionFree(JNI
|
||||||
android_chiaki_audio_decoder_fini(&session->audio_decoder);
|
android_chiaki_audio_decoder_fini(&session->audio_decoder);
|
||||||
android_chiaki_audio_output_free(session->audio_output);
|
android_chiaki_audio_output_free(session->audio_output);
|
||||||
E->DeleteGlobalRef(env, session->java_session);
|
E->DeleteGlobalRef(env, session->java_session);
|
||||||
|
CHIAKI_LOGI(&global_log, "JNI Session has quit");
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jint JNICALL Java_com_metallic_chiaki_lib_ChiakiNative_sessionStart(JNIEnv *env, jobject obj, jlong ptr)
|
JNIEXPORT jint JNICALL Java_com_metallic_chiaki_lib_ChiakiNative_sessionStart(JNIEnv *env, jobject obj, jlong ptr)
|
||||||
|
|
|
@ -63,7 +63,7 @@ class CircularBuffer
|
||||||
|
|
||||||
~CircularBuffer()
|
~CircularBuffer()
|
||||||
{
|
{
|
||||||
delete buffer;
|
delete [] buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -34,18 +34,32 @@ ChiakiErrorCode android_chiaki_video_decoder_init(AndroidChiakiVideoDecoder *dec
|
||||||
decoder->log = log;
|
decoder->log = log;
|
||||||
decoder->codec = NULL;
|
decoder->codec = NULL;
|
||||||
decoder->timestamp_cur = 0;
|
decoder->timestamp_cur = 0;
|
||||||
return chiaki_mutex_init(&decoder->mutex, false);
|
return chiaki_mutex_init(&decoder->codec_mutex, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void android_chiaki_video_decoder_fini(AndroidChiakiVideoDecoder *decoder)
|
void android_chiaki_video_decoder_fini(AndroidChiakiVideoDecoder *decoder)
|
||||||
{
|
{
|
||||||
// TODO: shutdown (thread may or may not be running!)
|
if(decoder->codec)
|
||||||
chiaki_mutex_fini(&decoder->mutex);
|
{
|
||||||
|
chiaki_mutex_lock(&decoder->codec_mutex);
|
||||||
|
ssize_t codec_buf_index = AMediaCodec_dequeueInputBuffer(decoder->codec, -1);
|
||||||
|
if(codec_buf_index >= 0)
|
||||||
|
{
|
||||||
|
CHIAKI_LOGI(decoder->log, "Video Decoder sending EOS buffer");
|
||||||
|
AMediaCodec_queueInputBuffer(decoder->codec, (size_t)codec_buf_index, 0, 0, decoder->timestamp_cur++, AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
CHIAKI_LOGE(decoder->log, "Failed to get input buffer for shutting down Video Decoder!");
|
||||||
|
chiaki_mutex_unlock(&decoder->codec_mutex);
|
||||||
|
chiaki_thread_join(&decoder->output_thread, NULL);
|
||||||
|
AMediaCodec_delete(decoder->codec);
|
||||||
|
}
|
||||||
|
chiaki_mutex_fini(&decoder->codec_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void android_chiaki_video_decoder_set_surface(AndroidChiakiVideoDecoder *decoder, JNIEnv *env, jobject surface)
|
void android_chiaki_video_decoder_set_surface(AndroidChiakiVideoDecoder *decoder, JNIEnv *env, jobject surface)
|
||||||
{
|
{
|
||||||
chiaki_mutex_lock(&decoder->mutex);
|
chiaki_mutex_lock(&decoder->codec_mutex);
|
||||||
|
|
||||||
if(decoder->codec)
|
if(decoder->codec)
|
||||||
{
|
{
|
||||||
|
@ -92,13 +106,13 @@ void android_chiaki_video_decoder_set_surface(AndroidChiakiVideoDecoder *decoder
|
||||||
}
|
}
|
||||||
|
|
||||||
beach:
|
beach:
|
||||||
chiaki_mutex_unlock(&decoder->mutex);
|
chiaki_mutex_unlock(&decoder->codec_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void android_chiaki_video_decoder_video_sample(uint8_t *buf, size_t buf_size, void *user)
|
void android_chiaki_video_decoder_video_sample(uint8_t *buf, size_t buf_size, void *user)
|
||||||
{
|
{
|
||||||
AndroidChiakiVideoDecoder *decoder = user;
|
AndroidChiakiVideoDecoder *decoder = user;
|
||||||
chiaki_mutex_lock(&decoder->mutex);
|
chiaki_mutex_lock(&decoder->codec_mutex);
|
||||||
|
|
||||||
if(!decoder->codec)
|
if(!decoder->codec)
|
||||||
{
|
{
|
||||||
|
@ -121,7 +135,7 @@ void android_chiaki_video_decoder_video_sample(uint8_t *buf, size_t buf_size, vo
|
||||||
size_t codec_sample_size = buf_size;
|
size_t codec_sample_size = buf_size;
|
||||||
if(codec_sample_size > codec_buf_size)
|
if(codec_sample_size > codec_buf_size)
|
||||||
{
|
{
|
||||||
CHIAKI_LOGD(decoder->log, "Sample is bigger than buffer, splitting");
|
//CHIAKI_LOGD(decoder->log, "Sample is bigger than buffer, splitting");
|
||||||
codec_sample_size = codec_buf_size;
|
codec_sample_size = codec_buf_size;
|
||||||
}
|
}
|
||||||
memcpy(codec_buf, buf, codec_sample_size);
|
memcpy(codec_buf, buf, codec_sample_size);
|
||||||
|
@ -132,7 +146,7 @@ void android_chiaki_video_decoder_video_sample(uint8_t *buf, size_t buf_size, vo
|
||||||
}
|
}
|
||||||
|
|
||||||
beach:
|
beach:
|
||||||
chiaki_mutex_unlock(&decoder->mutex);
|
chiaki_mutex_unlock(&decoder->codec_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *android_chiaki_video_decoder_output_thread_func(void *user)
|
static void *android_chiaki_video_decoder_output_thread_func(void *user)
|
||||||
|
@ -154,5 +168,7 @@ static void *android_chiaki_video_decoder_output_thread_func(void *user)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CHIAKI_LOGI(decoder->log, "Video Decoder Output Thread exiting");
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
|
@ -29,7 +29,7 @@ typedef struct ANativeWindow ANativeWindow;
|
||||||
typedef struct android_chiaki_video_decoder_t
|
typedef struct android_chiaki_video_decoder_t
|
||||||
{
|
{
|
||||||
ChiakiLog *log;
|
ChiakiLog *log;
|
||||||
ChiakiMutex mutex;
|
ChiakiMutex codec_mutex;
|
||||||
AMediaCodec *codec;
|
AMediaCodec *codec;
|
||||||
ANativeWindow *window;
|
ANativeWindow *window;
|
||||||
uint64_t timestamp_cur;
|
uint64_t timestamp_cur;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue