From: Kitae Kim Date: Mon, 17 Dec 2012 17:14:11 +0000 (+0900) Subject: maru_codec : Fixed multi-decoding audio codecs. X-Git-Tag: TizenStudio_2.0_p2.3~1139 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=de135bdf9723872fc7ac67c8d2f8d039ee847ad2;p=sdk%2Femulator%2Fqemu.git maru_codec : Fixed multi-decoding audio codecs. Source clean-up and codec device can decode a number of audio codecs concurrently. As codec device memory region is divided into each 256K size, emulator can decode 64 audio codecs simultaneously. Signed-off-by: Kitae Kim --- diff --git a/tizen/src/hw/maru_codec.c b/tizen/src/hw/maru_codec.c index c5c6b19..88451d7 100644 --- a/tizen/src/hw/maru_codec.c +++ b/tizen/src/hw/maru_codec.c @@ -31,9 +31,10 @@ #include "maru_codec.h" #include "qemu-common.h" +#include "qemu-thread.h" #define MARU_CODEC_DEV_NAME "codec" -#define MARU_CODEC_VERSION "1.3" +#define MARU_CODEC_VERSION 13 /* Needs 16M to support 1920x1080 video resolution. * Output size for encoding has to be greater than (width * height * 6) @@ -49,11 +50,28 @@ MULTI_DEBUG_CHANNEL(qemu, marucodec); void codec_thread_init(SVCodecState *s) { + int index = 0; + QemuThread *pthread = NULL; TRACE("Enter, %s\n", __func__); - qemu_thread_create(&s->thread_id, codec_worker_thread, (void *)s, + pthread = g_malloc0(sizeof(QemuThread) * CODEC_MAX_THREAD); + if (!pthread) { + ERR("Failed to allocate wrk_thread memory.\n"); + return; + } + qemu_cond_init(&s->codec_thread.cond); + qemu_mutex_init(&s->codec_thread.mutex); + + qemu_mutex_lock(&s->thread_mutex); + s->isrunning = 1; + qemu_mutex_unlock(&s->thread_mutex); + + for (; index < CODEC_MAX_THREAD; index++) { + qemu_thread_create(&pthread[index], codec_worker_thread, (void *)s, QEMU_THREAD_JOINABLE); + } + s->codec_thread.wrk_thread = pthread; TRACE("Leave, %s\n", __func__); } @@ -62,10 +80,9 @@ void codec_thread_exit(SVCodecState *s) TRACE("Enter, %s\n", __func__); TRACE("destroy mutex and conditional.\n"); - qemu_mutex_destroy(&s->thread_mutex); - qemu_cond_destroy(&s->thread_cond); + qemu_mutex_destroy(&s->codec_thread.mutex); + qemu_cond_destroy(&s->codec_thread.cond); -/* qemu_thread_exit((void*)0); */ TRACE("Leave, %s\n", __func__); } @@ -73,7 +90,7 @@ void wake_codec_worker_thread(SVCodecState *s) { TRACE("Enter, %s\n", __func__); - qemu_cond_signal(&s->thread_cond); + qemu_cond_signal(&s->codec_thread.cond); TRACE("sent a conditional signal to a worker thread.\n"); TRACE("Leave, %s\n", __func__); @@ -82,18 +99,19 @@ void wake_codec_worker_thread(SVCodecState *s) void *codec_worker_thread(void *opaque) { SVCodecState *s = (SVCodecState *)opaque; + QemuThread thread; AVCodecContext *avctx; TRACE("Enter, %s\n", __func__); qemu_mutex_lock(&s->thread_mutex); - while (1) { - TRACE("wait conditional signal.\n"); - qemu_cond_wait(&s->thread_cond, &s->thread_mutex); + while (s->isrunning) { + TRACE("wait for conditional signal.\n"); + qemu_cond_wait(&s->codec_thread.cond, &s->thread_mutex); - TRACE("wake up a worker thread.\n"); - avctx = s->ctx_arr[s->codec_param.ctx_index].avctx; - /* decode and encode */ + qemu_thread_get_self(&thread); + TRACE("wake up a worker thread. :%x\n", thread.thread); + avctx = s->codec_ctx[s->codec_param.ctx_index].avctx; if (avctx) { if (avctx->codec->decode) { decode_codec(s); @@ -106,7 +124,7 @@ void *codec_worker_thread(void *opaque) continue; } - s->thread_state = CODEC_IRQ; + s->codec_thread.state = CODEC_IRQ; qemu_bh_schedule(s->tx_bh); } qemu_mutex_unlock(&s->thread_mutex); @@ -119,20 +137,18 @@ int decode_codec(SVCodecState *s) uint32_t len = 0, ctx_index; TRACE("Enter, %s\n", __func__); - qemu_mutex_unlock(&s->thread_mutex); -/* qemu_mutex_lock(&s->thread_mutex); */ + qemu_mutex_lock(&s->codec_thread.mutex); ctx_index = s->codec_param.ctx_index; - avctx = s->ctx_arr[ctx_index].avctx; + qemu_mutex_unlock(&s->codec_thread.mutex); + + avctx = s->codec_ctx[ctx_index].avctx; if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) { len = qemu_avcodec_decode_video(s, ctx_index); } else { len = qemu_avcodec_decode_audio(s, ctx_index); } -/* qemu_mutex_unlock(&s->thread_mutex); */ - qemu_mutex_lock(&s->thread_mutex); - TRACE("Leave, %s\n", __func__); return len; } @@ -145,17 +161,15 @@ int encode_codec(SVCodecState *s) TRACE("Enter, %s\n", __func__); qemu_mutex_unlock(&s->thread_mutex); -/* qemu_mutex_lock(&s->thread_mutex); */ ctx_index = s->codec_param.ctx_index; - avctx = s->ctx_arr[ctx_index].avctx; + avctx = s->codec_ctx[ctx_index].avctx; if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) { len = qemu_avcodec_encode_video(s, ctx_index); } else { len = qemu_avcodec_encode_audio(s, ctx_index); } -/* qemu_mutex_unlock(&s->thread_mutex); */ qemu_mutex_lock(&s->thread_mutex); TRACE("Leave, %s\n", __func__); @@ -282,51 +296,37 @@ void qemu_parser_init(SVCodecState *s, int ctx_index) { TRACE("[%s] Enter\n", __func__); - s->ctx_arr[ctx_index].parser_buf = NULL; - s->ctx_arr[ctx_index].parser_use = false; + s->codec_ctx[ctx_index].parser_buf = NULL; + s->codec_ctx[ctx_index].parser_use = false; TRACE("[%s] Leave\n", __func__); } -void qemu_codec_close(SVCodecState *s, uint32_t value) +void qemu_reset_codec_info(SVCodecState *s, uint32_t value) { int i; - int ctx_index = 0; + int ctx_index = 0, mem_index; TRACE("[%s] Enter\n", __func__); qemu_mutex_lock(&s->thread_mutex); - for (i = 0; i < CODEC_MAX_CONTEXT; i++) { - if (s->ctx_arr[i].file_value == value) { - ctx_index = i; + for (i = 0; i < CODEC_CONTEXT_MAX; i++) { + if (s->codec_ctx[i].file_index == value) { + TRACE("[%s] close %d context\n", __func__, i); + s->codec_ctx[i].avctx_use = false; break; } } - TRACE("[%s] close %d context\n", __func__, ctx_index); - s->ctx_arr[ctx_index].ctx_used = false; + mem_index = s->codec_ctx[i].mem_index; + s->codec_offset[mem_index] = 0; + qemu_parser_init(s, ctx_index); qemu_mutex_unlock(&s->thread_mutex); TRACE("[%s] Leave\n", __func__); } -void qemu_get_codec_ver(SVCodecState *s) -{ - char codec_ver[32]; - off_t offset; - int ctx_index; - - offset = s->codec_param.mmap_offset; - ctx_index = s->codec_param.ctx_index; - - memset(codec_ver, 0, 32); - pstrcpy(codec_ver, sizeof(codec_ver), MARU_CODEC_VERSION); - - TRACE("%d of codec_version:%s\n", ctx_index, codec_ver); - memcpy((uint8_t *)s->vaddr + offset, codec_ver, sizeof(codec_ver)); -} - /* void av_register_all() */ void qemu_av_register_all(void) { @@ -358,7 +358,7 @@ void qemu_avcodec_release_buffer(AVCodecContext *context, AVFrame *picture) #endif /* int avcodec_open(AVCodecContext *avctx, AVCodec *codec) */ -int qemu_avcodec_open(SVCodecState *s, int ctx_index) +int qemu_avcodec_open(SVCodecState *s) { AVCodecContext *avctx; AVCodec *codec; @@ -367,18 +367,28 @@ int qemu_avcodec_open(SVCodecState *s, int ctx_index) int ret = -1; int bEncode = 0; int size = 0; + int ctx_index = 0; + + + av_register_all(); + TRACE("av_register_all\n"); + + ctx_index = qemu_avcodec_alloc_context(s); + if (ctx_index < 0) { + return ret; + } qemu_mutex_lock(&s->thread_mutex); + offset = s->codec_param.mmap_offset; + qemu_mutex_unlock(&s->thread_mutex); - avctx = s->ctx_arr[ctx_index].avctx; + avctx = s->codec_ctx[ctx_index].avctx; if (!avctx) { ERR("[%s] %d of AVCodecContext is NULL!\n", __func__, ctx_index); qemu_mutex_unlock(&s->thread_mutex); return ret; } - offset = s->codec_param.mmap_offset; - TRACE("[%s] Context Index:%d, offset:%d\n", __func__, ctx_index, offset); memcpy(&avctx->bit_rate, (uint8_t *)s->vaddr + offset, sizeof(int)); size = sizeof(int); @@ -475,8 +485,10 @@ int qemu_avcodec_open(SVCodecState *s, int ctx_index) avctx->sample_rate, avctx->channels); } - memcpy((uint8_t *)s->vaddr + offset, &avctx->pix_fmt, sizeof(int)); + memcpy((uint8_t *)s->vaddr + offset, &ctx_index, sizeof(int)); size = sizeof(int); + memcpy((uint8_t *)s->vaddr + offset + size, &avctx->pix_fmt, sizeof(int)); + size += sizeof(int); size += qemu_serialize_rational(&avctx->time_base, (uint8_t *)s->vaddr + offset + size); memcpy((uint8_t *)s->vaddr + offset + size, &avctx->channels, sizeof(int)); @@ -509,7 +521,6 @@ int qemu_avcodec_open(SVCodecState *s, int ctx_index) memcpy((uint8_t *)s->vaddr + offset + size, &ret, sizeof(int)); size += sizeof(int); - qemu_mutex_unlock(&s->thread_mutex); TRACE("Leave, %s\n", __func__); return ret; } @@ -526,7 +537,7 @@ int qemu_avcodec_close(SVCodecState *s, int ctx_index) offset = s->codec_param.mmap_offset; - avctx = s->ctx_arr[ctx_index].avctx; + avctx = s->codec_ctx[ctx_index].avctx; if (!avctx) { ERR("[%s] %d of AVCodecContext is NULL\n", __func__, ctx_index); memcpy((uint8_t *)s->vaddr + offset, &ret, sizeof(int)); @@ -546,64 +557,43 @@ int qemu_avcodec_close(SVCodecState *s, int ctx_index) } /* AVCodecContext* avcodec_alloc_context (void) */ -void qemu_avcodec_alloc_context(SVCodecState *s) +int qemu_avcodec_alloc_context(SVCodecState *s) { off_t offset; int index; TRACE("[%s] Enter\n", __func__); - qemu_mutex_lock(&s->thread_mutex); offset = s->codec_param.mmap_offset; - for (index = 0; index < CODEC_MAX_CONTEXT; index++) { - if (s->ctx_arr[index].ctx_used == false) { - TRACE("[%s] Succeeded to get context[%d].\n", __func__, index); + for (index = 0; index < CODEC_CONTEXT_MAX; index++) { + if (s->codec_ctx[index].avctx_use == false) { + TRACE("Succeeded to get %d of context.\n", index); break; } - TRACE("[%s] Failed to get context[%d].\n", __func__, index); + TRACE("Failed to get context.\n"); } - if (index == CODEC_MAX_CONTEXT) { - ERR("[%s] Failed to get available codec context from now\n", __func__); - ERR("[%s] Try to run codec again\n", __func__); - qemu_mutex_unlock(&s->thread_mutex); - return; + if (index == CODEC_CONTEXT_MAX) { + ERR("Failed to get available codec context."); + ERR(" Try to run codec again.\n"); + return -1; } TRACE("allocate %d of context and frame.\n", index); - s->ctx_arr[index].avctx = avcodec_alloc_context(); - s->ctx_arr[index].frame = avcodec_alloc_frame(); + s->codec_ctx[index].avctx = avcodec_alloc_context(); + s->codec_ctx[index].frame = avcodec_alloc_frame(); - s->ctx_arr[index].file_value = s->codec_param.file_index; - s->ctx_arr[index].ctx_used = true; - memcpy((uint8_t *)s->vaddr + offset, &index, sizeof(int)); + s->codec_ctx[index].file_index = s->codec_param.file_index; + s->codec_ctx[index].mem_index = s->codec_param.mem_index; + s->codec_ctx[index].avctx_use = true; +// memcpy((uint8_t *)s->vaddr + offset, &index, sizeof(int)); qemu_parser_init(s, index); - qemu_mutex_unlock(&s->thread_mutex); - TRACE("[%s] Leave\n", __func__); -} - -#if 0 -/* AVFrame *avcodec_alloc_frame(void) */ -void qemu_avcodec_alloc_frame(SVCodecState *s, int ctx_index) -{ - AVFrame *frame = NULL; - TRACE("[%s] Enter\n", __func__); - qemu_mutex_lock(&s->thread_mutex); - - frame = avcodec_alloc_frame(); - if (!frame) { - ERR("[%s] Failed to allocate frame\n", __func__); - } - s->ctx_arr[ctx_index].frame = frame; - - qemu_mutex_unlock(&s->thread_mutex); - TRACE("[%s] Leave\n", __func__); + return index; } -#endif /* void av_free(void *ptr) */ void qemu_av_free(SVCodecState *s, int ctx_index) @@ -614,8 +604,8 @@ void qemu_av_free(SVCodecState *s, int ctx_index) TRACE("enter %s\n", __func__); qemu_mutex_lock(&s->thread_mutex); - avctx = s->ctx_arr[ctx_index].avctx; - avframe = s->ctx_arr[ctx_index].frame; + avctx = s->codec_ctx[ctx_index].avctx; + avframe = s->codec_ctx[ctx_index].frame; if (avctx && avctx->palctrl) { av_free(avctx->palctrl); @@ -631,13 +621,13 @@ void qemu_av_free(SVCodecState *s, int ctx_index) if (avctx) { TRACE("free codec context\n"); av_free(avctx); - s->ctx_arr[ctx_index].avctx = NULL; + s->codec_ctx[ctx_index].avctx = NULL; } if (avframe) { TRACE("free codec frame\n"); av_free(avframe); - s->ctx_arr[ctx_index].frame = NULL; + s->codec_ctx[ctx_index].frame = NULL; } qemu_mutex_unlock(&s->thread_mutex); @@ -652,7 +642,7 @@ void qemu_avcodec_flush_buffers(SVCodecState *s, int ctx_index) TRACE("Enter\n"); qemu_mutex_lock(&s->thread_mutex); - avctx = s->ctx_arr[ctx_index].avctx; + avctx = s->codec_ctx[ctx_index].avctx; if (avctx) { avcodec_flush_buffers(avctx); } else { @@ -682,22 +672,22 @@ int qemu_avcodec_decode_video(SVCodecState *s, int ctx_index) off_t offset; TRACE("Enter, %s\n", __func__); - qemu_mutex_lock(&s->thread_mutex); + qemu_mutex_lock(&s->codec_thread.mutex); TRACE("[%s] Video Context Index : %d\n", __func__, ctx_index); - avctx = s->ctx_arr[ctx_index].avctx; - picture = s->ctx_arr[ctx_index].frame; + avctx = s->codec_ctx[ctx_index].avctx; + picture = s->codec_ctx[ctx_index].frame; if (!avctx || !picture) { ERR("[%s] %d of Context or Frame is NULL!\n", __func__, ctx_index); - qemu_mutex_unlock(&s->thread_mutex); + qemu_mutex_unlock(&s->codec_thread.mutex); return ret; } offset = s->codec_param.mmap_offset; - parser_buf = s->ctx_arr[ctx_index].parser_buf; - parser_use = s->ctx_arr[ctx_index].parser_use; + parser_buf = s->codec_ctx[ctx_index].parser_buf; + parser_use = s->codec_ctx[ctx_index].parser_use; TRACE("[%s] Parser Buffer : %p, Parser:%d\n", __func__, parser_buf, parser_use); @@ -716,8 +706,6 @@ int qemu_avcodec_decode_video(SVCodecState *s, int ctx_index) buf = parser_buf; } else if (buf_size > 0) { TRACE("[%s] not use parser, codec_id:%x\n", __func__, avctx->codec_id); -/* buf = av_mallocz(buf_size); - memcpy(buf, (uint8_t *)s->vaddr + offset + size, buf_size); */ buf = (uint8_t *)s->vaddr + offset + size; size += buf_size; } else { @@ -744,11 +732,6 @@ int qemu_avcodec_decode_video(SVCodecState *s, int ctx_index) memcpy((uint8_t *)s->vaddr + offset, &avctx->pix_fmt, sizeof(int)); size = sizeof(int); -#if 0 - memcpy((uint8_t *)s->vaddr + offset + size, - &avctx->time_base, sizeof(AVRational)); - size += sizeof(AVRational); -#endif size += qemu_serialize_rational(&avctx->time_base, (uint8_t *)s->vaddr + offset + size); memcpy((uint8_t *)s->vaddr + offset + size, &avctx->width, sizeof(int)); @@ -761,11 +744,6 @@ int qemu_avcodec_decode_video(SVCodecState *s, int ctx_index) memcpy((uint8_t *)s->vaddr + offset + size, &avctx->frame_number, sizeof(int)); size += sizeof(int); -#if 0 - memcpy((uint8_t *)s->vaddr + offset + size, - &avctx->sample_aspect_ratio, sizeof(AVRational)); - size += sizeof(AVRational); -#endif size += qemu_serialize_rational(&avctx->sample_aspect_ratio, (uint8_t *)s->vaddr + offset + size); memcpy((uint8_t *)s->vaddr + offset + size, @@ -786,18 +764,16 @@ int qemu_avcodec_decode_video(SVCodecState *s, int ctx_index) memcpy((uint8_t *)s->vaddr + offset + size, dst.data[0], numbytes); av_free(buffer); -/* av_free(buf); */ - if (parser_buf && parser_use) { TRACE("[%s] Free input buffer after decoding video\n", __func__); TRACE("[%s] input buffer : %p, %p\n", __func__, avpkt.data, parser_buf); av_free(avpkt.data); - s->ctx_arr[ctx_index].parser_buf = NULL; + s->codec_ctx[ctx_index].parser_buf = NULL; } #endif - qemu_mutex_unlock(&s->thread_mutex); + qemu_mutex_unlock(&s->codec_thread.mutex); TRACE("Leave, %s\n", __func__); return ret; @@ -819,10 +795,10 @@ int qemu_avcodec_encode_video(SVCodecState *s, int ctx_index) off_t offset; TRACE("Enter, %s\n", __func__); - qemu_mutex_lock(&s->thread_mutex); + qemu_mutex_lock(&s->codec_thread.mutex); - avctx = s->ctx_arr[ctx_index].avctx; - pict = s->ctx_arr[ctx_index].frame; + avctx = s->codec_ctx[ctx_index].avctx; + pict = s->codec_ctx[ctx_index].frame; if (!avctx || !pict) { ERR("[%s] %d of Context or Frame is NULL\n", __func__, ctx_index); qemu_mutex_unlock(&s->thread_mutex); @@ -873,7 +849,7 @@ int qemu_avcodec_encode_video(SVCodecState *s, int ctx_index) memcpy((uint8_t *)s->vaddr + offset + outbufSize, &ret, sizeof(int)); - qemu_mutex_unlock(&s->thread_mutex); + qemu_mutex_unlock(&s->codec_thread.mutex); TRACE("Leave, %s\n", __func__); return ret; @@ -898,29 +874,32 @@ int qemu_avcodec_decode_audio(SVCodecState *s, int ctx_index) off_t offset; TRACE("Enter, %s\n", __func__); - qemu_mutex_lock(&s->thread_mutex); TRACE("Audio Context Index : %d\n", ctx_index); - avctx = s->ctx_arr[ctx_index].avctx; + avctx = s->codec_ctx[ctx_index].avctx; if (!avctx) { ERR("[%s] %d of Context is NULL!\n", __func__, ctx_index); - qemu_mutex_unlock(&s->thread_mutex); + qemu_mutex_unlock(&s->codec_thread.mutex); return ret; } if (!avctx->codec) { ERR("[%s] %d of Codec is NULL\n", __func__, ctx_index); - qemu_mutex_unlock(&s->thread_mutex); + qemu_mutex_unlock(&s->codec_thread.mutex); return ret; } offset = s->codec_param.mmap_offset; - parser_buf = s->ctx_arr[ctx_index].parser_buf; - parser_use = s->ctx_arr[ctx_index].parser_use; + parser_buf = s->codec_ctx[ctx_index].parser_buf; + parser_use = s->codec_ctx[ctx_index].parser_use; memcpy(&buf_size, (uint8_t *)s->vaddr + offset, sizeof(int)); size = sizeof(int); + memcpy(&avctx->channel_layout, (uint8_t *)s->vaddr + offset, sizeof(int64_t)); + size += sizeof(int64_t); + memcpy(&avctx->request_channel_layout, (uint8_t *)s->vaddr + offset, sizeof(int64_t)); + size += sizeof(int64_t); TRACE("input buffer size : %d\n", buf_size); if (parser_buf && parser_use) { @@ -950,7 +929,7 @@ int qemu_avcodec_decode_audio(SVCodecState *s, int ctx_index) memcpy((uint8_t *)s->vaddr + offset, &avctx->bit_rate, sizeof(int)); size = sizeof(int); memcpy((uint8_t *)s->vaddr + offset + size, - &avctx->sample_rate, sizeof(int)); + &avctx->sample_rate, sizeof(int)); size += sizeof(int); memcpy((uint8_t *)s->vaddr + offset + size, &avctx->channels, sizeof(int)); size += sizeof(int); @@ -978,10 +957,9 @@ int qemu_avcodec_decode_audio(SVCodecState *s, int ctx_index) if (parser_buf && parser_use) { TRACE("[%s] free parser buf\n", __func__); av_free(avpkt.data); - s->ctx_arr[ctx_index].parser_buf = NULL; + s->codec_ctx[ctx_index].parser_buf = NULL; } - qemu_mutex_unlock(&s->thread_mutex); TRACE("[%s] Leave\n", __func__); return ret; @@ -1009,8 +987,8 @@ void qemu_av_picture_copy(SVCodecState *s, int ctx_index) TRACE("Enter :%s\n", __func__); qemu_mutex_lock(&s->thread_mutex); - avctx = s->ctx_arr[ctx_index].avctx; - src = (AVPicture *)s->ctx_arr[ctx_index].frame; + avctx = s->codec_ctx[ctx_index].avctx; + src = (AVPicture *)s->codec_ctx[ctx_index].frame; if (!avctx && !src) { ERR("[%s] %d of context or frame is NULL\n", __func__, ctx_index); qemu_mutex_unlock(&s->thread_mutex); @@ -1057,7 +1035,7 @@ void qemu_av_parser_init(SVCodecState *s, int ctx_index) TRACE("Enter :%s\n", __func__); qemu_mutex_lock(&s->thread_mutex); - avctx = s->ctx_arr[ctx_index].avctx; + avctx = s->codec_ctx[ctx_index].avctx; if (!avctx) { ERR("[%s] %d of AVCodecContext is NULL!!\n", __func__, ctx_index); qemu_mutex_unlock(&s->thread_mutex); @@ -1070,12 +1048,12 @@ void qemu_av_parser_init(SVCodecState *s, int ctx_index) parser_ctx = av_parser_init(avctx->codec_id); if (parser_ctx) { TRACE("[%s] using parser\n", __func__); - s->ctx_arr[ctx_index].parser_use = true; + s->codec_ctx[ctx_index].parser_use = true; } else { TRACE("[%s] no parser\n", __func__); - s->ctx_arr[ctx_index].parser_use = false; + s->codec_ctx[ctx_index].parser_use = false; } - s->ctx_arr[ctx_index].parser_ctx = parser_ctx; + s->codec_ctx[ctx_index].parser_ctx = parser_ctx; qemu_mutex_unlock(&s->thread_mutex); TRACE("[%s] Leave\n", __func__); @@ -1103,8 +1081,8 @@ int qemu_av_parser_parse(SVCodecState *s, int ctx_index) TRACE("Enter %s\n", __func__); qemu_mutex_lock(&s->thread_mutex); - parser_ctx = s->ctx_arr[ctx_index].parser_ctx; - avctx = s->ctx_arr[ctx_index].avctx; + parser_ctx = s->codec_ctx[ctx_index].parser_ctx; + avctx = s->codec_ctx[ctx_index].avctx; if (!avctx) { ERR("[%s] %d of AVCodecContext is NULL\n", __func__, ctx_index); qemu_mutex_unlock(&s->thread_mutex); @@ -1151,7 +1129,7 @@ int qemu_av_parser_parse(SVCodecState *s, int ctx_index) TRACE("after parsing, outbuf size :%d, ret:%d\n", poutbuf_size, ret); if (poutbuf) { - s->ctx_arr[ctx_index].parser_buf = poutbuf; + s->codec_ctx[ctx_index].parser_buf = poutbuf; } TRACE("[%s] inbuf : %p, outbuf : %p\n", __func__, inbuf, poutbuf); @@ -1188,7 +1166,7 @@ void qemu_av_parser_close(SVCodecState *s, int ctx_index) TRACE("Enter, %s\n", __func__); qemu_mutex_lock(&s->thread_mutex); - parser_ctx = s->ctx_arr[ctx_index].parser_ctx; + parser_ctx = s->codec_ctx[ctx_index].parser_ctx; if (!parser_ctx) { ERR("AVCodecParserContext is NULL\n"); qemu_mutex_unlock(&s->thread_mutex); @@ -1211,46 +1189,21 @@ int codec_operate(uint32_t api_index, uint32_t ctx_index, SVCodecState *s) qemu_av_register_all(); break; case EMUL_AVCODEC_OPEN: - ret = qemu_avcodec_open(s, ctx_index); + ret = qemu_avcodec_open(s); break; case EMUL_AVCODEC_CLOSE: ret = qemu_avcodec_close(s, ctx_index); - break; - case EMUL_AVCODEC_ALLOC_CONTEXT: - qemu_avcodec_alloc_context(s); - break; -#if 0 - case EMUL_AVCODEC_ALLOC_FRAME: - qemu_avcodec_alloc_frame(s, ctx_index); - break; -#endif - case EMUL_AV_FREE: qemu_av_free(s, ctx_index); break; case EMUL_AVCODEC_FLUSH_BUFFERS: qemu_avcodec_flush_buffers(s, ctx_index); break; -#ifndef CODEC_THREAD case EMUL_AVCODEC_DECODE_VIDEO: case EMUL_AVCODEC_ENCODE_VIDEO: case EMUL_AVCODEC_DECODE_AUDIO: case EMUL_AVCODEC_ENCODE_AUDIO: wake_codec_worker_thread(s); break; -#else - case EMUL_AVCODEC_DECODE_VIDEO: - ret = qemu_avcodec_decode_video(s, ctx_index); - break; - case EMUL_AVCODEC_ENCODE_VIDEO: - ret = qemu_avcodec_encode_video(s, ctx_index); - break; - case EMUL_AVCODEC_DECODE_AUDIO: - ret = qemu_avcodec_decode_audio(s, ctx_index); - break; - case EMUL_AVCODEC_ENCODE_AUDIO: - ret = qemu_avcodec_encode_audio(s, ctx_index); - break; -#endif case EMUL_AV_PICTURE_COPY: qemu_av_picture_copy(s, ctx_index); break; @@ -1263,15 +1216,26 @@ int codec_operate(uint32_t api_index, uint32_t ctx_index, SVCodecState *s) case EMUL_AV_PARSER_CLOSE: qemu_av_parser_close(s, ctx_index); break; - case EMUL_GET_CODEC_VER: - qemu_get_codec_ver(s); - break; default: WARN("api index %d does not exist!.\n", api_index); } return ret; } +static uint32_t qemu_get_mmap_offset (SVCodecState *s) +{ + int index = 0; + + for (; index < AUDIO_CODEC_MEM_OFFSET_MAX; index++) { + if (s->codec_offset[index] == 0) { + s->codec_offset[index] = 1; + break; + } + } + + return index; +} + /* * Codec Device APIs */ @@ -1281,14 +1245,32 @@ uint64_t codec_read(void *opaque, target_phys_addr_t addr, unsigned size) uint64_t ret = 0; switch (addr) { - case CODEC_QUERY_STATE: - ret = s->thread_state; - s->thread_state = 0; - TRACE("thread state: %d\n", s->thread_state); + case CODEC_CMD_GET_THREAD_STATE: + qemu_mutex_lock(&s->thread_mutex); + ret = s->codec_thread.state; + s->codec_thread.state = 0; + qemu_mutex_unlock(&s->thread_mutex); + TRACE("ret: %d, thread state: %d\n", ret, s->codec_thread.state); qemu_irq_lower(s->dev.irq[0]); break; + case CODEC_CMD_GET_VERSION: + ret = MARU_CODEC_VERSION; + TRACE("codec version: %d\n", ret); + break; + case CODEC_CMD_GET_DEVICE_MEM: + qemu_mutex_lock(&s->thread_mutex); + ret = s->device_mem_avail; + if (s->device_mem_avail != 1) { + s->device_mem_avail = 1; + } + qemu_mutex_unlock(&s->thread_mutex); + break; + case CODEC_CMD_GET_MMAP_OFFSET: + ret = qemu_get_mmap_offset(s); + INFO("mem index: %d\n", ret); + break; default: - ERR("There is no avaiable command for %s\n", MARU_CODEC_DEV_NAME); + ERR("no avaiable command for read. %d\n", addr); } return ret; @@ -1300,29 +1282,37 @@ void codec_write(void *opaque, target_phys_addr_t addr, int ret = -1; SVCodecState *s = (SVCodecState *)opaque; -/* qemu_mutex_lock(&s->thread_mutex); */ switch (addr) { - case CODEC_API_INDEX: + case CODEC_CMD_API_INDEX: ret = codec_operate(value, s->codec_param.ctx_index, s); break; - case CODEC_CONTEXT_INDEX: + case CODEC_CMD_CONTEXT_INDEX: s->codec_param.ctx_index = value; TRACE("Context Index: %d\n", s->codec_param.ctx_index); break; - case CODEC_MMAP_OFFSET: + case CODEC_CMD_FILE_INDEX: + s->codec_param.file_index = value; + break; + case CODEC_CMD_DEVICE_MEM_OFFSET: s->codec_param.mmap_offset = value; TRACE("MMAP Offset: %d\n", s->codec_param.mmap_offset); break; - case CODEC_FILE_INDEX: - s->codec_param.file_index = value; + case CODEC_CMD_RESET_CODEC_INFO: + qemu_reset_codec_info(s, value); break; - case CODEC_CLOSED: - qemu_codec_close(s, value); + case CODEC_CMD_SET_DEVICE_MEM: + qemu_mutex_lock(&s->thread_mutex); + s->device_mem_avail = value; + printf("set device_mem: %d\n", value); + qemu_mutex_unlock(&s->thread_mutex); break; + case CODEC_CMD_SET_MMAP_OFFSET: + printf("set mem index: %d\n", value); + s->codec_param.mem_index = value; + break; default: - ERR("There is no avaiable command for %s\n", MARU_CODEC_DEV_NAME); + ERR("no avaiable command for write. %d\n", addr); } -/* qemu_mutex_unlock(&s->thread_mutex); */ } static const MemoryRegionOps codec_mmio_ops = { @@ -1339,17 +1329,15 @@ static void codec_tx_bh(void *opaque) AVCodecContext *ctx; ctx_index = s->codec_param.ctx_index; - ctx = s->ctx_arr[ctx_index].avctx; + ctx = s->codec_ctx[ctx_index].avctx; TRACE("Enter, %s\n", __func__); /* raise irq as soon as a worker thread had finished a job*/ - if (s->thread_state) { + if (s->codec_thread.state) { TRACE("raise codec irq. state:%d, codec:%d\n", - s->thread_state, ctx->codec_type); + s->codec_thread.state, ctx->codec_type); qemu_irq_raise(s->dev.irq[0]); -/* s->thread_state = 0; - qemu_bh_schedule(s->tx_bh); */ } TRACE("Leave, %s\n", __func__); @@ -1363,15 +1351,10 @@ static int codec_initfn(PCIDevice *dev) INFO("[%s] device init\n", __func__); memset(&s->codec_param, 0, sizeof(SVCodecParam)); -/* pthread_mutex_init(&s->codec_mutex, NULL); */ -#ifndef CODEC_THREAD - qemu_mutex_init(&s->thread_mutex); - qemu_cond_init(&s->thread_cond); + qemu_mutex_init(&s->thread_mutex); codec_thread_init(s); - s->tx_bh = qemu_bh_new(codec_tx_bh, s); -#endif pci_config_set_interrupt_pin(pci_conf, 1); diff --git a/tizen/src/hw/maru_codec.h b/tizen/src/hw/maru_codec.h index b564b8e..25e1bdc 100644 --- a/tizen/src/hw/maru_codec.h +++ b/tizen/src/hw/maru_codec.h @@ -40,8 +40,11 @@ #include -#define CODEC_MAX_CONTEXT 1024 -#define CODEC_COPY_DATA +#define CODEC_CONTEXT_MAX 1024 +#define VIDEO_CODEC_MEM_OFFSET_MAX 16 +#define AUDIO_CODEC_MEM_OFFSET_MAX 64 + +#define CODEC_MAX_THREAD 10 /* * Codec Device Structures @@ -50,6 +53,7 @@ typedef struct _SVCodecParam { uint32_t api_index; uint32_t ctx_index; uint32_t file_index; + uint32_t mem_index; uint32_t mmap_offset; } SVCodecParam; @@ -58,42 +62,56 @@ typedef struct _SVCodecContext { AVFrame *frame; AVCodecParserContext *parser_ctx; uint8_t *parser_buf; - bool parser_use; - bool ctx_used; - uint32_t file_value; + uint8_t parser_use; + uint8_t avctx_use; + uint32_t file_index; + uint32_t mem_index; } SVCodecContext; +typedef struct _SVCodecThreadPool { + QemuThread *wrk_thread; + QemuMutex mutex; + QemuCond cond; + uint32_t state; + uint8_t isrunning; +} SVCodecThreadPool; + typedef struct _SVCodecState { PCIDevice dev; - SVCodecContext ctx_arr[CODEC_MAX_CONTEXT]; - SVCodecParam codec_param; uint8_t *vaddr; MemoryRegion vram; MemoryRegion mmio; QEMUBH *tx_bh; - QemuThread thread_id; QemuMutex thread_mutex; - QemuCond thread_cond; - uint8_t thread_state; + + SVCodecContext codec_ctx[CODEC_CONTEXT_MAX]; + SVCodecParam codec_param; + SVCodecThreadPool codec_thread; + uint8_t codec_offset[AUDIO_CODEC_MEM_OFFSET_MAX]; + uint8_t device_mem_avail; + uint8_t isrunning; } SVCodecState; -enum { - CODEC_API_INDEX = 0x00, - CODEC_QUERY_STATE = 0x04, - CODEC_CONTEXT_INDEX = 0x08, - CODEC_MMAP_OFFSET = 0x0c, - CODEC_FILE_INDEX = 0x10, - CODEC_CLOSED = 0x14, +enum codec_io_cmd { + CODEC_CMD_API_INDEX = 0x00, + CODEC_CMD_CONTEXT_INDEX = 0x04, + CODEC_CMD_FILE_INDEX = 0x08, + CODEC_CMD_DEVICE_MEM_OFFSET = 0x0c, + CODEC_CMD_GET_THREAD_STATE = 0x10, + CODEC_CMD_GET_VERSION = 0x14, + CODEC_CMD_GET_DEVICE_MEM = 0x18, + CODEC_CMD_SET_DEVICE_MEM = 0x1C, + CODEC_CMD_GET_MMAP_OFFSET = 0x20, + CODEC_CMD_SET_MMAP_OFFSET = 0x24, + CODEC_CMD_RESET_CODEC_INFO = 0x28, }; enum { EMUL_AV_REGISTER_ALL = 1, - EMUL_AVCODEC_ALLOC_CONTEXT, EMUL_AVCODEC_OPEN, EMUL_AVCODEC_CLOSE, - EMUL_AV_FREE, EMUL_AVCODEC_FLUSH_BUFFERS, EMUL_AVCODEC_DECODE_VIDEO, EMUL_AVCODEC_ENCODE_VIDEO, @@ -103,7 +121,6 @@ enum { EMUL_AV_PARSER_INIT, EMUL_AV_PARSER_PARSE, EMUL_AV_PARSER_CLOSE, - EMUL_GET_CODEC_VER = 50, }; @@ -139,9 +156,9 @@ void qemu_get_codec_ver(SVCodecState *s); * FFMPEG Functions */ void qemu_av_register_all(void); -int qemu_avcodec_open(SVCodecState *s, int ctx_index); +int qemu_avcodec_open(SVCodecState *s); int qemu_avcodec_close(SVCodecState *s, int ctx_index); -void qemu_avcodec_alloc_context(SVCodecState *s); +int qemu_avcodec_alloc_context(SVCodecState *s); void qemu_avcodec_flush_buffers(SVCodecState *s, int ctx_index); int qemu_avcodec_decode_video(SVCodecState *s, int ctx_index); int qemu_avcodec_encode_video(SVCodecState *s, int ctx_index);