#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)
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__);
}
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__);
}
{
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__);
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);
continue;
}
- s->thread_state = CODEC_IRQ;
+ s->codec_thread.state = CODEC_IRQ;
qemu_bh_schedule(s->tx_bh);
}
qemu_mutex_unlock(&s->thread_mutex);
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;
}
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__);
{
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)
{
#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;
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);
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));
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;
}
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));
}
/* 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)
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);
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);
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 {
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);
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 {
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));
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,
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;
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);
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;
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) {
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);
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;
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);
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);
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__);
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);
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);
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);
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;
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
*/
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;
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 = {
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__);
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);