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->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)
|
||||
{
|
||||
// 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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
static void android_chiaki_audio_decoder_header(ChiakiAudioHeader *header, void *user)
|
||||
{
|
||||
AndroidChiakiAudioDecoder *decoder = user;
|
||||
chiaki_mutex_lock(&decoder->codec_mutex);
|
||||
memcpy(&decoder->audio_header, header, sizeof(decoder->audio_header));
|
||||
|
||||
if(decoder->codec)
|
||||
{
|
||||
CHIAKI_LOGI(decoder->log, "Audio decoder already initialized, re-creating");
|
||||
// TODO: stop thread
|
||||
AMediaCodec_delete(decoder->codec);
|
||||
decoder->codec = NULL;
|
||||
CHIAKI_LOGI(decoder->log, "Audio decoder already initialized, shutting down the old one");
|
||||
android_chiaki_audio_decoder_shutdown_codec(decoder);
|
||||
}
|
||||
|
||||
const char *mime = "audio/opus";
|
||||
|
@ -104,7 +124,7 @@ static void android_chiaki_audio_decoder_header(ChiakiAudioHeader *header, void
|
|||
if(!decoder->codec)
|
||||
{
|
||||
CHIAKI_LOGE(decoder->log, "Failed to create AMediaCodec for mime type %s", mime);
|
||||
return;
|
||||
goto beach;
|
||||
}
|
||||
|
||||
AMediaFormat *format = AMediaFormat_new();
|
||||
|
@ -126,7 +146,6 @@ static void android_chiaki_audio_decoder_header(ChiakiAudioHeader *header, void
|
|||
decoder->codec = NULL;
|
||||
}
|
||||
|
||||
|
||||
uint8_t opus_id_head[0x13];
|
||||
memcpy(opus_id_head, "OpusHead", 8);
|
||||
opus_id_head[0x8] = 1; // version
|
||||
|
@ -157,16 +176,20 @@ static void android_chiaki_audio_decoder_header(ChiakiAudioHeader *header, void
|
|||
|
||||
if(decoder->settings_cb)
|
||||
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)
|
||||
{
|
||||
AndroidChiakiAudioDecoder *decoder = user;
|
||||
chiaki_mutex_lock(&decoder->codec_mutex);
|
||||
|
||||
if(!decoder->codec)
|
||||
{
|
||||
CHIAKI_LOGE(decoder->log, "Received audio data, but decoder is not initialized!");
|
||||
return;
|
||||
goto beach;
|
||||
}
|
||||
|
||||
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_size -= codec_sample_size;
|
||||
}
|
||||
|
||||
beach:
|
||||
chiaki_mutex_unlock(&decoder->codec_mutex);
|
||||
}
|
|
@ -31,6 +31,8 @@ typedef struct android_chiaki_audio_decoder_t
|
|||
{
|
||||
ChiakiLog *log;
|
||||
ChiakiAudioHeader audio_header;
|
||||
|
||||
ChiakiMutex codec_mutex;
|
||||
struct AMediaCodec *codec;
|
||||
uint64_t timestamp_cur;
|
||||
ChiakiThread output_thread;
|
||||
|
|
|
@ -121,7 +121,7 @@ oboe::DataCallbackResult AudioOutputCallback::onAudioReady(oboe::AudioStream *st
|
|||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -281,7 +281,7 @@ beach:
|
|||
JNIEXPORT void JNICALL Java_com_metallic_chiaki_lib_ChiakiNative_sessionFree(JNIEnv *env, jobject obj, jlong ptr)
|
||||
{
|
||||
AndroidChiakiSession *session = (AndroidChiakiSession *)ptr;
|
||||
CHIAKI_LOGI(&global_log, "Free JNI Session");
|
||||
CHIAKI_LOGI(&global_log, "Shutting down JNI Session");
|
||||
if(!session)
|
||||
return;
|
||||
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_output_free(session->audio_output);
|
||||
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)
|
||||
|
|
|
@ -63,7 +63,7 @@ class CircularBuffer
|
|||
|
||||
~CircularBuffer()
|
||||
{
|
||||
delete buffer;
|
||||
delete [] buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -34,18 +34,32 @@ ChiakiErrorCode android_chiaki_video_decoder_init(AndroidChiakiVideoDecoder *dec
|
|||
decoder->log = log;
|
||||
decoder->codec = NULL;
|
||||
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)
|
||||
{
|
||||
// TODO: shutdown (thread may or may not be running!)
|
||||
chiaki_mutex_fini(&decoder->mutex);
|
||||
if(decoder->codec)
|
||||
{
|
||||
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)
|
||||
{
|
||||
chiaki_mutex_lock(&decoder->mutex);
|
||||
chiaki_mutex_lock(&decoder->codec_mutex);
|
||||
|
||||
if(decoder->codec)
|
||||
{
|
||||
|
@ -92,13 +106,13 @@ void android_chiaki_video_decoder_set_surface(AndroidChiakiVideoDecoder *decoder
|
|||
}
|
||||
|
||||
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)
|
||||
{
|
||||
AndroidChiakiVideoDecoder *decoder = user;
|
||||
chiaki_mutex_lock(&decoder->mutex);
|
||||
chiaki_mutex_lock(&decoder->codec_mutex);
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
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:
|
||||
chiaki_mutex_unlock(&decoder->mutex);
|
||||
chiaki_mutex_unlock(&decoder->codec_mutex);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
|
@ -29,7 +29,7 @@ typedef struct ANativeWindow ANativeWindow;
|
|||
typedef struct android_chiaki_video_decoder_t
|
||||
{
|
||||
ChiakiLog *log;
|
||||
ChiakiMutex mutex;
|
||||
ChiakiMutex codec_mutex;
|
||||
AMediaCodec *codec;
|
||||
ANativeWindow *window;
|
||||
uint64_t timestamp_cur;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue