From 0d7df22c9099c5f44d3d301807f1697958ddaba0 Mon Sep 17 00:00:00 2001 From: SeokYeon Hwang Date: Wed, 13 Aug 2014 15:18:57 +0900 Subject: [PATCH] brillcodec: add new command for reducing I/O Add command CODEC_DECODE_VIDEO2. Clean-up source. Change-Id: I92c6dadba9ff74dad47db617fdbf50e34430cfe4 Signed-off-by: SeokYeon Hwang --- tizen/src/hw/pci/maru_brillcodec.c | 206 ++++++++++++++++++++++++------ tizen/src/hw/pci/maru_brillcodec.h | 12 +- tizen/src/hw/pci/maru_brillcodec_device.c | 54 ++++---- tizen/src/hw/pci/maru_brillcodec_plugin.h | 9 ++ tizen/src/hw/pci/maru_brillcodec_vaapi.c | 19 ++- 5 files changed, 224 insertions(+), 76 deletions(-) diff --git a/tizen/src/hw/pci/maru_brillcodec.c b/tizen/src/hw/pci/maru_brillcodec.c index 9f2035a..4bd4308 100644 --- a/tizen/src/hw/pci/maru_brillcodec.c +++ b/tizen/src/hw/pci/maru_brillcodec.c @@ -63,6 +63,7 @@ enum codec_api_type { CODEC_PICTURE_COPY, CODEC_DEINIT, CODEC_FLUSH_BUFFERS, + CODEC_DECODE_VIDEO2, }; enum codec_type { @@ -119,6 +120,7 @@ static bool codec_decode_audio(MaruBrillCodecState *, int, void *); static bool codec_encode_audio(MaruBrillCodecState *, int, void *); static bool codec_picture_copy(MaruBrillCodecState *, int, void *); static bool codec_flush_buffers(MaruBrillCodecState *, int, void *); +static bool codec_decode_video2(MaruBrillCodecState *, int, void *); typedef bool (*CodecFuncEntry)(MaruBrillCodecState *, int, void *); static CodecFuncEntry codec_func_handler[] = { @@ -130,23 +132,26 @@ static CodecFuncEntry codec_func_handler[] = { codec_picture_copy, codec_deinit, codec_flush_buffers, + codec_decode_video2, }; static AVCodecParserContext *maru_brill_codec_parser_init(AVCodecContext *avctx); -static void maru_brill_codec_push_readqueue(MaruBrillCodecState *s, CodecParam *ioparam); -static void maru_brill_codec_push_writequeue(MaruBrillCodecState *s, void* opaque, +static void brillcodec_push_readqueue(MaruBrillCodecState *s, CodecParam *ioparam); +static void brillcodec_push_write_queue(MaruBrillCodecState *s, void* opaque, size_t data_size, int ctx_id, DataHandler *handler); -static void *maru_brill_codec_store_inbuf(uint8_t *mem_base, CodecParam *ioparam); +static void *brillcodec_store_inbuf(uint8_t *mem_base, CodecParam *ioparam); // default handler -static void default_get_data(void *dst, void *src, size_t size) { +static void default_get_data(void *dst, void *src, size_t size) +{ memcpy(dst, src, size); } -static void default_release(void *opaque) { +static void default_release(void *opaque) +{ g_free(opaque); } @@ -156,15 +161,26 @@ static DataHandler default_data_handler = { }; // default video decode data handler -static void extract(void *dst, void *src, size_t size) { - AVFrame *frame = (AVFrame *)src; - avpicture_layout((AVPicture *)src, PIX_FMT_YUV420P, frame->width, frame->height, dst, size); +static void copy_picture(void *dst, void *opaque, size_t size) +{ + DataContainer *dc = (DataContainer *)opaque; + if (dc->len_data_buffer) { + memcpy(dst, dc->data_buffer, dc->len_data_buffer); + } + if (dc->frame) { + avpicture_layout((AVPicture *)dc->frame, PIX_FMT_YUV420P, dc->frame->width, dc->frame->height, + dst + OFFSET_PICTURE_BUFFER, size - OFFSET_PICTURE_BUFFER); // FIXME + } } -static void release(void *buf) {} +static void release(void *opaque) { + DataContainer *dc = (DataContainer *)opaque; + g_free(dc->data_buffer); + g_free(dc); +} static DataHandler default_video_decode_data_handler = { - .get_data = extract, + .get_data = copy_picture, .release = release, }; @@ -193,7 +209,7 @@ static void maru_brill_codec_thread_exit(MaruBrillCodecState *s) TRACE("leave: %s\n", __func__); } -void maru_brill_codec_wakeup_threads(MaruBrillCodecState *s, int api_index) +void brillcodec_wakeup_threads(MaruBrillCodecState *s, int api_index) { CodecParam *ioparam = NULL; @@ -221,7 +237,7 @@ void maru_brill_codec_wakeup_threads(MaruBrillCodecState *s, int api_index) qemu_mutex_unlock(&s->context_mutex); - maru_brill_codec_push_readqueue(s, ioparam); + brillcodec_push_readqueue(s, ioparam); qemu_mutex_lock(&s->context_mutex); // W/A for threads starvation. @@ -237,7 +253,7 @@ void maru_brill_codec_wakeup_threads(MaruBrillCodecState *s, int api_index) TRACE("after sending conditional signal\n"); } -void *maru_brill_codec_threads(void *opaque) +void *brillcodec_threads(void *opaque) { MaruBrillCodecState *s = (MaruBrillCodecState *)opaque; bool ret = false; @@ -310,7 +326,7 @@ void *maru_brill_codec_threads(void *opaque) if (CONTEXT(s, ctx_id)->requested_close) { INFO("make worker thread to handle deinit\n"); // codec_deinit(s, ctx_id, NULL); - maru_brill_codec_release_context(s, ctx_id); + brillcodec_release_context(s, ctx_id); CONTEXT(s, ctx_id)->requested_close = false; } qemu_mutex_unlock(&s->context_mutex); @@ -330,7 +346,7 @@ void *maru_brill_codec_threads(void *opaque) } // queue -static void maru_brill_codec_push_readqueue(MaruBrillCodecState *s, +static void brillcodec_push_readqueue(MaruBrillCodecState *s, CodecParam *ioparam) { CodecDataStg *elem = NULL; @@ -346,7 +362,8 @@ static void maru_brill_codec_push_readqueue(MaruBrillCodecState *s, switch(ioparam->api_index) { case CODEC_INIT ... CODEC_ENCODE_AUDIO: - data_buf = maru_brill_codec_store_inbuf((uint8_t *)s->vaddr, ioparam); + case CODEC_DECODE_VIDEO2: + data_buf = brillcodec_store_inbuf((uint8_t *)s->vaddr, ioparam); break; default: TRACE("no buffer from guest\n"); @@ -360,7 +377,7 @@ static void maru_brill_codec_push_readqueue(MaruBrillCodecState *s, qemu_mutex_unlock(&s->ioparam_queue_mutex); } -static void *maru_brill_codec_store_inbuf(uint8_t *mem_base, +static void *brillcodec_store_inbuf(uint8_t *mem_base, CodecParam *ioparam) { DeviceMemEntry *elem = NULL; @@ -401,7 +418,7 @@ static void *maru_brill_codec_store_inbuf(uint8_t *mem_base, return elem; } -static void maru_brill_codec_push_writequeue(MaruBrillCodecState *s, void* opaque, +static void brillcodec_push_write_queue(MaruBrillCodecState *s, void* opaque, size_t data_size, int ctx_id, DataHandler *handler) { @@ -423,7 +440,7 @@ static void maru_brill_codec_push_writequeue(MaruBrillCodecState *s, void* opaqu qemu_mutex_unlock(&s->context_queue_mutex); } -void maru_brill_codec_pop_writequeue(MaruBrillCodecState *s, uint32_t ctx_idx) +void brillcodec_pop_writequeue(MaruBrillCodecState *s, uint32_t ctx_idx) { DeviceMemEntry *elem = NULL; uint32_t mem_offset = 0; @@ -534,7 +551,7 @@ static void serialize_audio_data (const struct audio_data *audio, avctx->channels, avctx->sample_rate, avctx->sample_fmt, avctx->channel_layout); } -void maru_brill_codec_release_context(MaruBrillCodecState *s, int32_t ctx_id) +void brillcodec_release_context(MaruBrillCodecState *s, int32_t ctx_id) { DeviceMemEntry *wq_elem = NULL, *wnext = NULL; CodecDataStg *rq_elem = NULL, *rnext = NULL; @@ -596,7 +613,7 @@ void maru_brill_codec_release_context(MaruBrillCodecState *s, int32_t ctx_id) TRACE("leave: %s\n", __func__); } -int maru_brill_codec_query_list (MaruBrillCodecState *s) +int brillcodec_query_list (MaruBrillCodecState *s) { AVCodec *codec = NULL; uint32_t size = 0, mem_size = 0; @@ -664,7 +681,7 @@ int maru_brill_codec_query_list (MaruBrillCodecState *s) return 0; } -int maru_brill_codec_get_context_index(MaruBrillCodecState *s) +int brillcodec_get_context_index(MaruBrillCodecState *s) { int ctx_id; @@ -1035,7 +1052,7 @@ static bool codec_init(MaruBrillCodecState *s, int ctx_id, void *data_buf) } } - maru_brill_codec_push_writequeue(s, tempbuf, tempbuf_size, ctx_id, NULL); + brillcodec_push_write_queue(s, tempbuf, tempbuf_size, ctx_id, NULL); TRACE("leave: %s\n", __func__); @@ -1089,7 +1106,7 @@ static bool codec_deinit(MaruBrillCodecState *s, int ctx_id, void *data_buf) CONTEXT(s, ctx_id)->parser_ctx = NULL; } - maru_brill_codec_push_writequeue(s, NULL, 0, ctx_id, NULL); + brillcodec_push_write_queue(s, NULL, 0, ctx_id, NULL); TRACE("leave: %s\n", __func__); @@ -1115,7 +1132,117 @@ static bool codec_flush_buffers(MaruBrillCodecState *s, int ctx_id, void *data_b avcodec_flush_buffers(avctx); } - maru_brill_codec_push_writequeue(s, NULL, 0, ctx_id, NULL); + brillcodec_push_write_queue(s, NULL, 0, ctx_id, NULL); + + TRACE("leave: %s\n", __func__); + + return ret; +} + +static bool codec_decode_video2(MaruBrillCodecState *s, int ctx_id, void *data_buf) +{ + AVCodecContext *avctx = NULL; + AVFrame *picture = NULL; + AVPacket avpkt; + int got_picture = 0, len = -1; + uint8_t *inbuf = NULL; + int inbuf_size = 0, idx, size = 0; + int64_t in_offset; + DeviceMemEntry *elem = NULL; + uint8_t *tempbuf = NULL; + int tempbuf_size = 0; + + TRACE("enter: %s\n", __func__); + + elem = (DeviceMemEntry *)data_buf; + if (elem && elem->opaque) { + memcpy(&inbuf_size, elem->opaque, sizeof(inbuf_size)); + size += sizeof(inbuf_size); + memcpy(&idx, elem->opaque + size, sizeof(idx)); + size += sizeof(idx); + memcpy(&in_offset, elem->opaque + size, sizeof(in_offset)); + size += sizeof(in_offset); + TRACE("decode_video. inbuf_size %d\n", inbuf_size); + + if (inbuf_size > 0) { + inbuf = elem->opaque + size; + } + } else { + TRACE("decode_video. no input buffer\n"); + // FIXME: improve error handling + // return false; + } + + av_init_packet(&avpkt); + avpkt.data = inbuf; + avpkt.size = inbuf_size; + + avctx = CONTEXT(s, ctx_id)->avctx; + picture = CONTEXT(s, ctx_id)->frame; + if (!avctx) { + ERR("decode_video. %d of AVCodecContext is NULL.\n", ctx_id); + } else if (!avctx->codec) { + ERR("decode_video. %d of AVCodec is NULL.\n", ctx_id); + } else if (!picture) { + ERR("decode_video. %d of AVFrame is NULL.\n", ctx_id); + } else { + TRACE("decode_video. bitrate %d\n", avctx->bit_rate); + + len = + avcodec_decode_video2(avctx, picture, &got_picture, &avpkt); + TRACE("decode_video. in_size %d len %d, frame_size %d\n", avpkt.size, len, got_picture); + } + + tempbuf_size = + sizeof(len) + sizeof(got_picture) + sizeof(struct video_data); + + if (len < 0) { + ERR("failed to decode video. ctx_id: %d, len: %d\n", ctx_id, len); + got_picture = 0; + } + + tempbuf = g_malloc(tempbuf_size); + if (!tempbuf) { + ERR("failed to allocate decoded video buffer\n"); + // FIXME: how to handle this case? + } else { + struct video_data video; + + memcpy(tempbuf, &len, sizeof(len)); + size = sizeof(len); + memcpy(tempbuf + size, &got_picture, sizeof(got_picture)); + size += sizeof(got_picture); + if (avctx) { + avctx->pix_fmt = AV_PIX_FMT_YUV420P; // FIXME + deserialize_video_data(avctx, &video); + memcpy(tempbuf + size, &video, sizeof(struct video_data)); + } + } + + TRACE("decoded image. pix_fmt: %d width: %d, height: %d\n", + avctx->pix_fmt, avctx->width, avctx->height); + int pict_size = avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height); + bool ret = true; + + if ((pict_size) < 0) { + ERR("picture size: %d\n", pict_size); + ret = false; + } else { + TRACE("picture size: %d\n", pict_size); + + DataContainer *dc = g_malloc0(sizeof(DataContainer)); + dc->data_buffer = tempbuf; + dc->len_data_buffer = tempbuf_size; + if (got_picture) { + dc->frame = picture; + } + + if (CONTEXT(s, ctx_id)->is_hwaccel) { + brillcodec_push_write_queue(s, dc, OFFSET_PICTURE_BUFFER + pict_size, ctx_id, s->hwaccel_plugin->video_decode_data_handler); + } else { + brillcodec_push_write_queue(s, dc, OFFSET_PICTURE_BUFFER + pict_size, ctx_id, &default_video_decode_data_handler); + } + } TRACE("leave: %s\n", __func__); @@ -1201,27 +1328,24 @@ static bool codec_decode_video(MaruBrillCodecState *s, int ctx_id, void *data_bu memcpy(tempbuf + size, &got_picture, sizeof(got_picture)); size += sizeof(got_picture); if (avctx) { - - avctx->pix_fmt = AV_PIX_FMT_YUV420P; - //avctx->pix_fmt = AV_PIX_FMT_; - + avctx->pix_fmt = AV_PIX_FMT_YUV420P; // FIXME deserialize_video_data(avctx, &video); memcpy(tempbuf + size, &video, sizeof(struct video_data)); } } - maru_brill_codec_push_writequeue(s, tempbuf, tempbuf_size, ctx_id, NULL); + brillcodec_push_write_queue(s, tempbuf, tempbuf_size, ctx_id, NULL); TRACE("leave: %s\n", __func__); return true; } - +// for old decode API static bool codec_picture_copy (MaruBrillCodecState *s, int ctx_id, void *elem) { AVCodecContext *avctx = NULL; - AVPicture *src = NULL; + AVFrame *frame = NULL; int pict_size = 0; bool ret = true; @@ -1230,14 +1354,14 @@ static bool codec_picture_copy (MaruBrillCodecState *s, int ctx_id, void *elem) TRACE("copy decoded image of %d context.\n", ctx_id); avctx = CONTEXT(s, ctx_id)->avctx; - src = (AVPicture *)CONTEXT(s, ctx_id)->frame; + frame = CONTEXT(s, ctx_id)->frame; if (!avctx) { ERR("picture_copy. %d of AVCodecContext is NULL.\n", ctx_id); ret = false; } else if (!avctx->codec) { ERR("picture_copy. %d of AVCodec is NULL.\n", ctx_id); ret = false; - } else if (!src) { + } else if (!frame) { ERR("picture_copy. %d of AVFrame is NULL.\n", ctx_id); ret = false; } else { @@ -1250,10 +1374,14 @@ static bool codec_picture_copy (MaruBrillCodecState *s, int ctx_id, void *elem) ret = false; } else { TRACE("picture size: %d\n", pict_size); + + DataContainer *dc = g_malloc0(sizeof(DataContainer)); + dc->frame = frame; + if (CONTEXT(s, ctx_id)->is_hwaccel) { - maru_brill_codec_push_writequeue(s, src, pict_size, ctx_id, s->hwaccel_plugin->video_decode_data_handler); + brillcodec_push_write_queue(s, dc, pict_size, ctx_id, s->hwaccel_plugin->video_decode_data_handler); } else { - maru_brill_codec_push_writequeue(s, src, pict_size, ctx_id, &default_video_decode_data_handler); + brillcodec_push_write_queue(s, dc, pict_size, ctx_id, &default_video_decode_data_handler); } } } @@ -1368,7 +1496,7 @@ static bool codec_decode_audio(MaruBrillCodecState *s, int ctx_id, void *data_bu } } - maru_brill_codec_push_writequeue(s, tempbuf, tempbuf_size, ctx_id, NULL); + brillcodec_push_write_queue(s, tempbuf, tempbuf_size, ctx_id, NULL); if (audio_out) { avcodec_free_frame(&audio_out); @@ -1505,7 +1633,7 @@ static bool codec_encode_video(MaruBrillCodecState *s, int ctx_id, void *data_bu g_free(outbuf); } - maru_brill_codec_push_writequeue(s, tempbuf, tempbuf_size, ctx_id, NULL); + brillcodec_push_write_queue(s, tempbuf, tempbuf_size, ctx_id, NULL); TRACE("leave: %s\n", __func__); return true; @@ -1704,7 +1832,7 @@ static bool codec_encode_audio(MaruBrillCodecState *s, int ctx_id, void *data_bu } } - maru_brill_codec_push_writequeue(s, tempbuf, tempbuf_size, ctx_id, NULL); + brillcodec_push_write_queue(s, tempbuf, tempbuf_size, ctx_id, NULL); if (in_frame) { avcodec_free_frame(&in_frame); } diff --git a/tizen/src/hw/pci/maru_brillcodec.h b/tizen/src/hw/pci/maru_brillcodec.h index df035a2..026dca3 100644 --- a/tizen/src/hw/pci/maru_brillcodec.h +++ b/tizen/src/hw/pci/maru_brillcodec.h @@ -116,12 +116,12 @@ extern struct codec_wq codec_wq; extern DeviceMemEntry *entry[CODEC_CONTEXT_MAX]; -int maru_brill_codec_query_list(MaruBrillCodecState *s); -int maru_brill_codec_get_context_index(MaruBrillCodecState *s); -void maru_brill_codec_wakeup_threads(MaruBrillCodecState *s, int api_index); -void maru_brill_codec_release_context(MaruBrillCodecState *s, int32_t ctx_id); -void maru_brill_codec_pop_writequeue(MaruBrillCodecState *s, uint32_t ctx_idx); +int brillcodec_query_list(MaruBrillCodecState *s); +int brillcodec_get_context_index(MaruBrillCodecState *s); +void brillcodec_wakeup_threads(MaruBrillCodecState *s, int api_index); +void brillcodec_release_context(MaruBrillCodecState *s, int32_t ctx_id); +void brillcodec_pop_writequeue(MaruBrillCodecState *s, uint32_t ctx_idx); -void *maru_brill_codec_threads(void *opaque); +void *brillcodec_threads(void *opaque); #endif // __MARU_BRILLCODEC_H__ diff --git a/tizen/src/hw/pci/maru_brillcodec_device.c b/tizen/src/hw/pci/maru_brillcodec_device.c index 7ea5596..3b0040e 100644 --- a/tizen/src/hw/pci/maru_brillcodec_device.c +++ b/tizen/src/hw/pci/maru_brillcodec_device.c @@ -43,7 +43,7 @@ MULTI_DEBUG_CHANNEL(qemu, brillcodec); #define CODEC_DEVICE_NAME "codec-pci" #define CODEC_DEVICE_THREAD "codec-workthread" -#define CODEC_VERSION 2 +#define CODEC_VERSION 3 #define CODEC_REG_SIZE (256) #define DEFAULT_WORKER_THREAD_CNT 8 @@ -65,7 +65,7 @@ enum thread_state { CODEC_TASK_END = 0x1f, }; -static void maru_brill_codec_threads_create(MaruBrillCodecState *s) +static void brillcodec_threads_create(MaruBrillCodecState *s) { int index; QemuThread *pthread = NULL; @@ -89,7 +89,7 @@ static void maru_brill_codec_threads_create(MaruBrillCodecState *s) for (index = 0; index < s->worker_thread_cnt; index++) { qemu_thread_create(&pthread[index], CODEC_DEVICE_THREAD, - maru_brill_codec_threads, (void *)s, QEMU_THREAD_JOINABLE); + brillcodec_threads, (void *)s, QEMU_THREAD_JOINABLE); } s->threadpool.threads = pthread; @@ -97,7 +97,7 @@ static void maru_brill_codec_threads_create(MaruBrillCodecState *s) TRACE("leave: %s\n", __func__); } -static void maru_brill_codec_get_cpu_cores(MaruBrillCodecState *s) +static void brillcodec_get_cpu_cores(MaruBrillCodecState *s) { s->worker_thread_cnt = get_number_of_processors(); if (s->worker_thread_cnt < DEFAULT_WORKER_THREAD_CNT) { @@ -107,7 +107,7 @@ static void maru_brill_codec_get_cpu_cores(MaruBrillCodecState *s) TRACE("number of threads: %d\n", s->worker_thread_cnt); } -static void maru_brill_codec_bh_callback(void *opaque) +static void brillcodec_bh_callback(void *opaque) { MaruBrillCodecState *s = (MaruBrillCodecState *)opaque; @@ -128,7 +128,7 @@ static void maru_brill_codec_bh_callback(void *opaque) TRACE("leave: %s\n", __func__); } -static uint64_t maru_brill_codec_read(void *opaque, +static uint64_t brillcodec_read(void *opaque, hwaddr addr, unsigned size) { @@ -174,11 +174,11 @@ static uint64_t maru_brill_codec_read(void *opaque, break; case CODEC_CMD_GET_ELEMENT: - ret = maru_brill_codec_query_list(s); + ret = brillcodec_query_list(s); break; case CODEC_CMD_GET_CONTEXT_INDEX: - ret = maru_brill_codec_get_context_index(s); + ret = brillcodec_get_context_index(s); TRACE("get context index: %d\n", ret); break; @@ -189,7 +189,7 @@ static uint64_t maru_brill_codec_read(void *opaque, return ret; } -static void maru_brill_codec_write(void *opaque, hwaddr addr, +static void brillcodec_write(void *opaque, hwaddr addr, uint64_t value, unsigned size) { MaruBrillCodecState *s = (MaruBrillCodecState *)opaque; @@ -198,7 +198,7 @@ static void maru_brill_codec_write(void *opaque, hwaddr addr, case CODEC_CMD_API_INDEX: TRACE("set codec_cmd value: %d\n", value); s->ioparam.api_index = value; - maru_brill_codec_wakeup_threads(s, value); + brillcodec_wakeup_threads(s, value); break; case CODEC_CMD_CONTEXT_INDEX: @@ -219,13 +219,13 @@ static void maru_brill_codec_write(void *opaque, hwaddr addr, CONTEXT(s, ctx_id)->requested_close = true; INFO("make running thread to handle deinit\n"); } else { - maru_brill_codec_release_context(s, ctx_id); + brillcodec_release_context(s, ctx_id); } } break; case CODEC_CMD_GET_DATA_FROM_QUEUE: - maru_brill_codec_pop_writequeue(s, (uint32_t)value); + brillcodec_pop_writequeue(s, (uint32_t)value); break; default: @@ -233,9 +233,9 @@ static void maru_brill_codec_write(void *opaque, hwaddr addr, } } -static const MemoryRegionOps maru_brill_codec_mmio_ops = { - .read = maru_brill_codec_read, - .write = maru_brill_codec_write, +static const MemoryRegionOps brillcodec_mmio_ops = { + .read = brillcodec_read, + .write = brillcodec_write, .valid = { .min_access_size = 4, .max_access_size = 4, @@ -264,7 +264,7 @@ static CodecPlugin *vaapi_probe(void) { } #endif -static int maru_brill_codec_initfn(PCIDevice *dev) +static int brillcodec_initfn(PCIDevice *dev) { MaruBrillCodecState *s = DO_UPCAST(MaruBrillCodecState, dev, dev); uint8_t *pci_conf = s->dev.config; @@ -275,7 +275,7 @@ static int maru_brill_codec_initfn(PCIDevice *dev) memory_region_init_ram(&s->vram, OBJECT(s), "maru_brill_codec.vram", CODEC_MEM_SIZE); s->vaddr = (uint8_t *)memory_region_get_ram_ptr(&s->vram); - memory_region_init_io(&s->mmio, OBJECT(s), &maru_brill_codec_mmio_ops, s, + memory_region_init_io(&s->mmio, OBJECT(s), &brillcodec_mmio_ops, s, "maru_brill_codec.mmio", CODEC_REG_SIZE); pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->vram); @@ -285,11 +285,11 @@ static int maru_brill_codec_initfn(PCIDevice *dev) qemu_mutex_init(&s->context_queue_mutex); qemu_mutex_init(&s->ioparam_queue_mutex); - maru_brill_codec_get_cpu_cores(s); - maru_brill_codec_threads_create(s); + brillcodec_get_cpu_cores(s); + brillcodec_threads_create(s); // register a function to qemu bottom-halves to switch context. - s->codec_bh = qemu_bh_new(maru_brill_codec_bh_callback, s); + s->codec_bh = qemu_bh_new(brillcodec_bh_callback, s); // register plugins #ifdef CONFIG_VAAPI @@ -301,7 +301,7 @@ static int maru_brill_codec_initfn(PCIDevice *dev) return 0; } -static void maru_brill_codec_exitfn(PCIDevice *dev) +static void brillcodec_exitfn(PCIDevice *dev) { MaruBrillCodecState *s = DO_UPCAST(MaruBrillCodecState, dev, dev); INFO("device exit\n"); @@ -316,7 +316,7 @@ static void maru_brill_codec_exitfn(PCIDevice *dev) memory_region_destroy(&s->mmio); } -static void maru_brill_codec_reset(DeviceState *d) +static void brillcodec_reset(DeviceState *d) { MaruBrillCodecState *s = (MaruBrillCodecState *)d; INFO("device reset\n"); @@ -327,17 +327,17 @@ static void maru_brill_codec_reset(DeviceState *d) memset(&s->ioparam, 0, sizeof(CodecParam)); } -static void maru_brill_codec_class_init(ObjectClass *klass, void *data) +static void brillcodec_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); - k->init = maru_brill_codec_initfn; - k->exit = maru_brill_codec_exitfn; + k->init = brillcodec_initfn; + k->exit = brillcodec_exitfn; k->vendor_id = PCI_VENDOR_ID_TIZEN; k->device_id = PCI_DEVICE_ID_VIRTUAL_BRILL_CODEC; k->class_id = PCI_CLASS_OTHERS; - dc->reset = maru_brill_codec_reset; + dc->reset = brillcodec_reset; dc->desc = "Virtual new codec device for Tizen emulator"; } @@ -345,7 +345,7 @@ static TypeInfo codec_device_info = { .name = CODEC_DEVICE_NAME, .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(MaruBrillCodecState), - .class_init = maru_brill_codec_class_init, + .class_init = brillcodec_class_init, }; static void codec_register_types(void) diff --git a/tizen/src/hw/pci/maru_brillcodec_plugin.h b/tizen/src/hw/pci/maru_brillcodec_plugin.h index 273efea..4133c91 100644 --- a/tizen/src/hw/pci/maru_brillcodec_plugin.h +++ b/tizen/src/hw/pci/maru_brillcodec_plugin.h @@ -33,6 +33,15 @@ #include "stdbool.h" +#define OFFSET_PICTURE_BUFFER (0x100) + +typedef struct DataContainer { + void *data_buffer; + size_t len_data_buffer; + + AVFrame *frame; +} DataContainer; + typedef struct DataHandler { void (*get_data)(void *dst, void *src, size_t size); void (*release)(void *opaque); diff --git a/tizen/src/hw/pci/maru_brillcodec_vaapi.c b/tizen/src/hw/pci/maru_brillcodec_vaapi.c index 10a761a..c6e16f4 100644 --- a/tizen/src/hw/pci/maru_brillcodec_vaapi.c +++ b/tizen/src/hw/pci/maru_brillcodec_vaapi.c @@ -297,12 +297,23 @@ static void release_surface(AVCodecContext *p_context, *((bool *)frame->opaque) = false; } - -static void vaapi_extract(void *dst, void *src, size_t size) { - extract((AVFrame *)src, dst, size); +static void vaapi_extract(void *dst, void *opaque, size_t size) +{ + DataContainer *dc = (DataContainer *)opaque; + if (dc->len_data_buffer) { + memcpy(dst, dc->data_buffer, dc->len_data_buffer); + } + if (dc->frame) { + extract(dc->frame, dst + OFFSET_PICTURE_BUFFER, size - OFFSET_PICTURE_BUFFER); + } } -static void release(void *buf) {} +static void release(void *opaque) +{ + DataContainer *dc = (DataContainer *)opaque; + g_free(dc->data_buffer); + g_free(dc); +} static DataHandler vaapi_video_decode_data_handler = { .get_data = vaapi_extract, -- 2.7.4