brillcodec: apply struct base memory access for audio decoding 84/27484/3
authorSeokYeon Hwang <syeon.hwang@samsung.com>
Sun, 14 Sep 2014 08:55:00 +0000 (17:55 +0900)
committerSeokYeon Hwang <syeon.hwang@samsung.com>
Mon, 15 Sep 2014 05:38:29 +0000 (14:38 +0900)
Struct base memory access for audio decoder is applied.
DataHandler for audio decoder is applied.

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

index d4e4579..df946d9 100644 (file)
@@ -81,13 +81,25 @@ typedef struct DataContainer {
     bool is_got;
     int32_t len;
     AVCodecContext *avctx;
-
-    // for video decoder
-    size_t picture_buffer_offset;
     AVFrame *frame;
 
-    // for video encoder
-    AVPacket *avpkt;
+    union {
+        // for video decoder
+        struct {
+            size_t picture_buffer_offset;
+        };
+
+        // for video encoder
+        struct {
+            AVPacket *avpkt;
+        };
+
+        // for audio encoder
+        struct {
+            bool resampled;
+            int32_t out_sample_fmt;
+        };
+    };
 } DataContainer;
 
 DeviceMemEntry *entry[CODEC_CONTEXT_MAX];
@@ -715,7 +727,7 @@ static void default_get_picture(void *dst, void *src, enum AVPixelFormat pix_fmt
 
 // video decode data handler
 // FIXME: ignore "size" now...
-static void copy_decode_data(void *dst, void *opaque, size_t dummy)
+static void copy_decode_video_data(void *dst, void *opaque, size_t dummy)
 {
     DataContainer *dc = (DataContainer *)opaque;
     CodecContext *context = (CodecContext *)dc->avctx->opaque;
@@ -747,20 +759,15 @@ static void copy_decode_data(void *dst, void *opaque, size_t dummy)
 }
 
 static void release(void *opaque) {
-    DataContainer *dc = (DataContainer *)opaque;
-    if (dc->avpkt) {
-        g_free(dc->avpkt->data);
-        g_free(dc->avpkt);
-    }
-    g_free(dc);
+    g_free(opaque);
 }
 
 static DataHandler video_decode_data_handler = {
-    .get_data = copy_decode_data,
+    .get_data = copy_decode_video_data,
     .release = release,
 };
 
-static void copy_encode_data(void *dst, void *opaque, size_t dummy)
+static void copy_encode_video_data(void *dst, void *opaque, size_t dummy)
 {
     DataContainer *dc = (DataContainer *)opaque;
     struct video_encode_output *encode_output =
@@ -778,14 +785,16 @@ static void copy_encode_data(void *dst, void *opaque, size_t dummy)
 
         memcpy(&encode_output->data, dc->avpkt->data, dc->avpkt->size);
     }
+
+    g_free(dc->avpkt->data);
+    g_free(dc->avpkt);
 }
 
 static DataHandler video_encode_data_handler = {
-    .get_data = copy_encode_data,
+    .get_data = copy_encode_video_data,
     .release = release,
 };
 
-
 static uint32_t parse_and_decode_video(AVCodecContext *avctx, AVFrame *picture,
                                 AVCodecParserContext *pctx, int ctx_id,
                                 AVPacket *packet, uint32_t *got_picture,
@@ -1044,6 +1053,17 @@ struct audio_data {
     int64_t channel_layout;
 } __attribute__((packed));
 
+struct audio_decode_input {
+    int32_t inbuf_size;
+    uint8_t inbuf;          // for pointing inbuf address
+} __attribute__((packed));
+
+struct audio_decode_output {
+    int32_t len;
+    int32_t got_frame;
+    uint8_t data;           // for pointing data address
+} __attribute__((packed));
+
 static int convert_audio_sample_fmt(const AVCodec *codec, int codec_type, bool encode)
 {
     int audio_sample_fmt = AV_SAMPLE_FMT_NONE;
@@ -1181,7 +1201,43 @@ static AVFrame *resample_audio(AVCodecContext *avctx, AVFrame *sample_frame,
     return resample_frame;
 }
 
+// FIXME: ignore "size" now...
+static void copy_decode_audio_data(void *dst, void *opaque, size_t dummy)
+{
+    DataContainer *dc = (DataContainer *)opaque;
+
+    struct audio_decode_output *decode_output =
+        (struct audio_decode_output *)dst;
+
+    // FIXME
+    //decode_output->len = dc->len;
+    decode_output->len = dc->frame->linesize[0];
+    decode_output->got_frame = dc->is_got ? 1 : 0;
+
+    if (dc->is_got) {
+        struct audio_data *data = (struct audio_data *)&decode_output->data;
+        data->sample_fmt = dc->resampled ? dc->out_sample_fmt : dc->avctx->sample_fmt;
+        data->sample_rate = dc->avctx->sample_rate;
+        data->channels = dc->avctx->channels;
+        data->channel_layout = dc->avctx->channel_layout;
+
+        memcpy(dst + OFFSET_PICTURE_BUFFER, dc->frame->data[0], decode_output->len);
+
+        if (dc->resampled) {
+            av_free(dc->frame->data[0]);
+            av_free(dc->frame);
+        }
+    }
+}
+
+static DataHandler audio_decode_data_handler = {
+    .get_data = copy_decode_audio_data,
+    .release = release,
+};
+
+
 /*
+ * dc->resampled = resample_frame ? true : false;
  * decode_audio >> raw audio_buffer >> resample
  *
  * audios sink cannot handle planar format, so it is required
@@ -1191,127 +1247,71 @@ static bool codec_decode_audio(MaruBrillCodecState *s, int ctx_id, void *data_bu
 {
     AVCodecContext *avctx;
     AVPacket avpkt;
-    AVFrame *audio_out = NULL;
-    uint8_t *inbuf = NULL;
-    int inbuf_size = 0, size = 0;
-    int len = -1, got_frame = 0;
+    AVFrame *frame = NULL;
 
     DeviceMemEntry *elem = NULL;
-    uint8_t *tempbuf = NULL;
-    int tempbuf_size = 0;
-
-    AVFrame *resample_frame = NULL;
-    uint8_t *resample_buf = NULL;
-    int resample_buf_size = 0;
-    int out_sample_fmt = -1;
+    struct audio_decode_input empty_input = { 0, };
+    struct audio_decode_input *decode_input = &empty_input;
+    int len = -1, got_frame = 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);
-        TRACE("decode_audio. inbuf_size %d\n", inbuf_size);
-
-        if (inbuf_size > 0) {
-            inbuf = elem->opaque + size;
-        }
+    if (!elem || !elem->opaque) {
+        TRACE("decode_video. no input buffer\n");
     } else {
-        ERR("decode_audio. no input buffer\n");
-        // FIXME: improve error handling
-        // return false;
+        decode_input = elem->opaque;
     }
 
     av_init_packet(&avpkt);
-    avpkt.data = inbuf;
-    avpkt.size = inbuf_size;
+    avpkt.data = &decode_input->inbuf;
+    avpkt.size = decode_input->inbuf_size;
 
     avctx = CONTEXT(s, ctx_id)->avctx;
-    // audio_out = CONTEXT(s, ctx_id)->frame;
-    audio_out = avcodec_alloc_frame();
-    if (!avctx) {
-        ERR("decode_audio. %d of AVCodecContext is NULL\n", ctx_id);
-    } else if (!avctx->codec) {
-        ERR("decode_audio. %d of AVCodec is NULL\n", ctx_id);
-    } else if (!audio_out) {
-        ERR("decode_audio. %d of AVFrame is NULL\n", ctx_id);
-    } else {
-        len = avcodec_decode_audio4(avctx, audio_out, &got_frame, &avpkt);
-        TRACE("decode_audio. len %d, channel_layout %lld got_frame %d\n",
+    frame = CONTEXT(s, ctx_id)->frame;
+
+    if(!avctx || !avctx->codec || !frame) {
+        ERR("critical error !!!\n");
+        assert(0);
+    }
+
+    len = avcodec_decode_audio4(avctx, frame, &got_frame, &avpkt);
+    TRACE("decode_audio. len %d, channel_layout %lld, got_frame %d\n",
             len, avctx->channel_layout, got_frame);
 
-        if (got_frame) {
-            if (av_sample_fmt_is_planar(avctx->sample_fmt)) {
-                out_sample_fmt = convert_audio_sample_fmt(avctx->codec, avctx->codec_type, 0);
+    AVFrame *resample_frame = NULL;
+    int resample_buf_size = 0;
+    uint32_t out_sample_fmt = -1;
+
+    if (got_frame) {
+        if (av_sample_fmt_is_planar(avctx->sample_fmt)) {
+            out_sample_fmt = convert_audio_sample_fmt(avctx->codec, avctx->codec_type, 0);
 
-                if (avctx->channel_layout == 0) {
-                    avctx->channel_layout = av_get_default_channel_layout(avctx->channels);
-                    TRACE("decode_audio. channel_layout %lld channels %d\n",
+            if (avctx->channel_layout == 0) {
+                avctx->channel_layout = av_get_default_channel_layout(avctx->channels);
+                TRACE("decode_audio. channel_layout %lld channels %d\n",
                         avctx->channel_layout, avctx->channels);
-                }
-                resample_frame = resample_audio(avctx, audio_out, audio_out->linesize[0],
-                                            avctx->sample_fmt, NULL, &resample_buf_size,
-                                            out_sample_fmt);
-                if (resample_frame) {
-                    resample_buf = resample_frame->data[0];
-                } else {
-                    ERR("failed to resample decoded audio buffer\n");
-                    len = -1;
-                    got_frame = 0;
-                }
-            } else {
-                INFO("decode_audio. linear audio format\n");
-                resample_buf = audio_out->data[0];
-                resample_buf_size = audio_out->linesize[0];
             }
-        }
-    }
-
-    tempbuf_size = (sizeof(len) + sizeof(got_frame));
-    if (len < 0) {
-        ERR("failed to decode audio. ctx_id: %d len: %d got_frame: %d\n",
-            ctx_id, len, got_frame);
-        got_frame = 0;
-    } else {
-        tempbuf_size += (sizeof(out_sample_fmt) + sizeof(avctx->sample_rate)
-                        + sizeof(avctx->channels) +  sizeof(avctx->channel_layout)
-                        + sizeof(resample_buf_size) + resample_buf_size);
-    }
-
-    tempbuf = g_malloc(tempbuf_size);
-    if (!tempbuf) {
-        ERR("failed to allocate decoded audio buffer\n");
-    } else {
-        memcpy(tempbuf, &len, sizeof(len));
-        size = sizeof(len);
-        memcpy(tempbuf + size, &got_frame, sizeof(got_frame));
-        size += sizeof(got_frame);
-        if (got_frame) {
-            memcpy(tempbuf + size, &out_sample_fmt, sizeof(out_sample_fmt));
-            size += sizeof(out_sample_fmt);
-            memcpy(tempbuf + size, &avctx->sample_rate, sizeof(avctx->sample_rate));
-            size += sizeof(avctx->sample_rate);
-            memcpy(tempbuf + size, &avctx->channels, sizeof(avctx->channels));
-            size += sizeof(avctx->channels);
-            memcpy(tempbuf + size, &avctx->channel_layout, sizeof(avctx->channel_layout));
-            size += sizeof(avctx->channel_layout);
-
-            memcpy(tempbuf + size, &resample_buf_size, sizeof(resample_buf_size));
-            size += sizeof(resample_buf_size);
-            if (resample_buf) {
-                TRACE("copy resampled audio buffer\n");
-                memcpy(tempbuf + size, resample_buf, resample_buf_size);
+            resample_frame = resample_audio(avctx, frame, frame->linesize[0],
+                    avctx->sample_fmt, NULL, &resample_buf_size,
+                    out_sample_fmt);
+            if (!resample_frame) {
+                ERR("failed to resample decoded audio buffer\n");
+                len = -1;
+                got_frame = 0;
             }
         }
     }
 
-    brillcodec_push_writequeue(s, tempbuf, tempbuf_size, ctx_id, NULL);
+    DataContainer *dc = g_malloc0(sizeof(DataContainer));
+    dc->len = len;
+    dc->is_got = got_frame;
+    dc->avctx = avctx;
+    dc->resampled = resample_frame ? true : false;
+    dc->out_sample_fmt = out_sample_fmt;
+    dc->frame = resample_frame ? resample_frame : frame;
 
-    if (resample_frame) {
-        TRACE("release decoded frame\n");
-        av_free(resample_buf);
-        av_free(resample_frame);
-    }
+    brillcodec_push_writequeue(s, dc, 0, ctx_id, &audio_decode_data_handler);
 
     TRACE("leave: %s\n", __func__);
     return true;