brillcodec: add new command for reducing I/O 66/26166/4
authorSeokYeon Hwang <syeon.hwang@samsung.com>
Wed, 13 Aug 2014 06:18:57 +0000 (15:18 +0900)
committerSeokYeon Hwang <syeon.hwang@samsung.com>
Fri, 22 Aug 2014 06:13:53 +0000 (23:13 -0700)
Add command CODEC_DECODE_VIDEO2.
Clean-up source.

Change-Id: I92c6dadba9ff74dad47db617fdbf50e34430cfe4
Signed-off-by: SeokYeon Hwang <syeon.hwang@samsung.com>
tizen/src/hw/pci/maru_brillcodec.c
tizen/src/hw/pci/maru_brillcodec.h
tizen/src/hw/pci/maru_brillcodec_device.c
tizen/src/hw/pci/maru_brillcodec_plugin.h
tizen/src/hw/pci/maru_brillcodec_vaapi.c

index 9f2035a..4bd4308 100644 (file)
@@ -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);
     }
index df035a2..026dca3 100644 (file)
@@ -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__
index 7ea5596..3b0040e 100644 (file)
@@ -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)
index 273efea..4133c91 100644 (file)
 
 #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);
index 10a761a..c6e16f4 100644 (file)
@@ -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,