enabling sprdcodec for TM1 21/56321/2 accepted/tizen/ivi/20160218.023011 accepted/tizen/mobile/20160107.101004 accepted/tizen/tv/20160107.101023 accepted/tizen/wearable/20160107.101041 submit/tizen/20160106.105721 submit/tizen_common/20160218.142243 submit/tizen_ivi/20160217.000000 submit/tizen_ivi/20160217.000001
authorSejun Park <sejun79.park@samsung.com>
Wed, 6 Jan 2016 09:49:51 +0000 (18:49 +0900)
committerSejun Park <sejun79.park@samsung.com>
Wed, 6 Jan 2016 09:59:37 +0000 (18:59 +0900)
Change-Id: I50a0fa4563f1a2d0dbb33f7798f676d086804e67

include/media_codec_port.h
src/media_codec.c
src/media_codec_ini.c
src/media_codec_port.c
src/media_codec_port_gst.c
test/CMakeLists.txt
test/media_codec_test.c

index aa9e92a..440292c 100755 (executable)
@@ -110,13 +110,6 @@ typedef void (*mc_eos_cb)(void *user_data);
 typedef void (*mc_buffer_status_cb)(mediacodec_status_e status, void *user_data);
 typedef void (*mc_supported_codec_cb)(mediacodec_codec_type_e codec_type, void *user_data);
 
-int (*mc_sniff_bitstream)(mc_handle_t *handle, media_packet_h pkt);
-
-int mc_sniff_h264_bitstream(mc_handle_t *handle, media_packet_h pkt);
-int mc_sniff_mpeg4_bitstream(mc_handle_t *handle, media_packet_h pkt);
-int mc_sniff_h263_bitstream(mc_handle_t *handle, media_packet_h pkt);
-int mc_sniff_yuv(mc_handle_t *handle, media_packet_h pkt);
-
 typedef enum {
     _MEDIACODEC_EVENT_TYPE_COMPLETE,
     _MEDIACODEC_EVENT_TYPE_EMPTYBUFFER,
index 2fc4d08..f018d6f 100755 (executable)
@@ -31,7 +31,6 @@ static gboolean __mediacodec_eos_cb(void *user_data);
 static gboolean __mediacodec_supported_codec_cb(mediacodec_codec_type_e codec_type, void *user_data);
 static gboolean __mediacodec_buffer_status_cb(mediacodec_status_e status, void *user_data);
 
-
 /*
  * Internal Implementation
  */
@@ -563,4 +562,3 @@ static gboolean __mediacodec_buffer_status_cb(mediacodec_status_e status, void *
 
        return 1;
 }
-
index 05a1044..695fb34 100755 (executable)
@@ -45,6 +45,9 @@
 #define DEFAULT_SW_ENCODER_MIME ""
 #define DEFAULT_SW_ENCODER_FORMAT ""
 
+
+#define CNAME_SIZE 512
+
 typedef struct {
        gchar cname[MEDIA_CODEC_INI_MAX_STRLEN];
        mediacodec_codec_type_e ctype;
@@ -90,9 +93,9 @@ do {\
        if (str &&  \
                        (strlen(str) > 0) && \
                        (strlen(str) < MEDIA_CODEC_INI_MAX_STRLEN)) \
-               strcpy(x_item, str); \
+               strncpy(x_item, str, strlen(str) + 1); \
        else \
-               strcpy(x_item, x_default); \
+               strncpy(x_item, x_default, strlen(x_default) + 1); \
 } while (0)
 
 #define MEDIA_CODEC_INI_GET_STRING_FROM_LIST(x_dict, x_list, x_ini, x_default) \
@@ -295,7 +298,7 @@ endf:
 
 int mc_ini_load(mc_ini_t *ini)
 {
-       gchar cname[256];
+       gchar cname[CNAME_SIZE];
        int i = 0;
        dictionary *dict = NULL;
 
@@ -330,24 +333,24 @@ int mc_ini_load(mc_ini_t *ini)
                MEDIA_CODEC_INI_GET_STRING(dict, ini->port_name, "port_in_use:media_codec_port", DEFAULT_PORT);
                /* codec */
                for (i = 0; i < codec_list; i++) {
-                       memset(cname, 0x00, 256);
-                       strcpy(cname, general_codec_list[i].cname);
+                       memset(cname, 0x00, CNAME_SIZE);
+                       snprintf(cname, CNAME_SIZE, "%s", general_codec_list[i].cname);
                        int len = strlen(cname);
                        ini->codec[i].codec_id =  general_codec_list[i].ctype;
-                       sprintf(cname+len, "%s", ":hw_decoder");
+                       snprintf(cname+len, CNAME_SIZE - len, "%s", ":hw_decoder");
                        MEDIA_CODEC_INI_GET_STRING_FROM_LIST(dict, ini->codec[i].codec_info[0], cname, DEFAULT_VALUE);
-                       sprintf(cname+len, "%s", ":hw_encoder");
+                       snprintf(cname+len, CNAME_SIZE - len, "%s", ":hw_encoder");
                        MEDIA_CODEC_INI_GET_STRING_FROM_LIST(dict, ini->codec[i].codec_info[1], cname, DEFAULT_VALUE);
-                       sprintf(cname+len, "%s", ":sw_decoder");
+                       snprintf(cname+len, CNAME_SIZE - len, "%s", ":sw_decoder");
                        MEDIA_CODEC_INI_GET_STRING_FROM_LIST(dict, ini->codec[i].codec_info[2], cname, DEFAULT_VALUE);
-                       sprintf(cname+len, "%s", ":sw_encoder");
+                       snprintf(cname+len, CNAME_SIZE - len, "%s", ":sw_encoder");
                        MEDIA_CODEC_INI_GET_STRING_FROM_LIST(dict, ini->codec[i].codec_info[3], cname, DEFAULT_VALUE);
                }
        } else {/* if dict is not available just fill the structure with default value */
 
                LOGW("failed to load ini. using hardcoded default\n");
                /* general */
-               strncpy(ini->port_name, DEFAULT_PORT, MEDIA_CODEC_INI_MAX_STRLEN - 1);
+               snprintf(ini->port_name, sizeof(ini->port_name), "%s", DEFAULT_PORT);
                for (i = 0; i < codec_list; i++) {
                        MEDIA_CODEC_GET_DEFAULT_LIST(ini->codec[i].codec_info[0].name,   DEFAULT_HW_DECODER_NAME);
                        MEDIA_CODEC_GET_DEFAULT_LIST(ini->codec[i].codec_info[0].mime,   DEFAULT_HW_DECODER_MIME);
@@ -371,23 +374,25 @@ int mc_ini_load(mc_ini_t *ini)
                ini->port_type = GST_PORT;
        else {
                LOGE("Invalid port is set to [%s] [%d]\n", ini->port_name, ini->port_type);
+               iniparser_freedict(dict);
                goto ERROR;
        }
        LOGD("The port is set to [%s] [%d]\n", ini->port_name, ini->port_type);
 
-       for (i = 0; i < codec_list; i++) {
-               memset(cname, 0x00, 256);
-               strcpy(cname, general_codec_list[i].cname);
+    for (i = 0;i < codec_list; i++) {
+               memset(cname, 0x00, CNAME_SIZE);
+               snprintf(cname, CNAME_SIZE, "%s", general_codec_list[i].cname);
                int len = strlen(cname);
-               sprintf(cname+len, "%s", ":hw_decoder");
-               MEDIA_CODEC_PRINT_LIST(ini->codec[i].codec_info[0], cname);
-               sprintf(cname+len, "%s", ":hw_encoder");
-               MEDIA_CODEC_PRINT_LIST(ini->codec[i].codec_info[1], cname);
-               sprintf(cname+len, "%s", ":sw_decoder");
-               MEDIA_CODEC_PRINT_LIST(ini->codec[i].codec_info[2], cname);
-               sprintf(cname+len, "%s", ":sw_encoder");
-               MEDIA_CODEC_PRINT_LIST(ini->codec[i].codec_info[3], cname);
-       }
+
+               snprintf(cname+len, CNAME_SIZE-len, "%s",":hw_decoder");
+               MEDIA_CODEC_PRINT_LIST(ini->codec[i].codec_info[0],cname);
+               snprintf(cname+len, CNAME_SIZE-len, "%s",":hw_encoder");
+               MEDIA_CODEC_PRINT_LIST(ini->codec[i].codec_info[1],cname);
+               snprintf(cname+len, CNAME_SIZE-len, "%s",":sw_decoder");
+               MEDIA_CODEC_PRINT_LIST(ini->codec[i].codec_info[2],cname);
+               snprintf(cname+len, CNAME_SIZE-len, "%s",":sw_encoder");
+               MEDIA_CODEC_PRINT_LIST(ini->codec[i].codec_info[3],cname);
+    }
 
        /* free dict as we got our own structure */
        iniparser_freedict(dict);
index ba7bb1f..d9aa4d4 100755 (executable)
@@ -184,22 +184,6 @@ int mc_set_vdec_info(MMHandleType mediacodec, int width, int height)
 
        mc_handle->is_prepared = true;
 
-       switch (mc_handle->codec_id) {
-       case MEDIACODEC_H264:
-               mc_sniff_bitstream = mc_sniff_h264_bitstream;
-               LOGD("mc_sniff_h264_bitstream");
-               break;
-       case MEDIACODEC_MPEG4:
-               mc_sniff_bitstream = mc_sniff_mpeg4_bitstream;
-               break;
-       case MEDIACODEC_H263:
-               mc_sniff_bitstream = mc_sniff_h263_bitstream;
-               break;
-       default:
-               LOGE("NOT SUPPORTED!!!!");
-               break;
-       }
-
        return ret;
 }
 
@@ -224,7 +208,6 @@ int mc_set_venc_info(MMHandleType mediacodec, int width, int height, int fps, in
        mc_handle->info.encoder.fps = fps;
        mc_handle->info.encoder.bitrate = target_bits;
        mc_handle->is_prepared = true;
-       mc_sniff_bitstream = mc_sniff_yuv;
 
        return ret;
 }
@@ -351,11 +334,6 @@ int mc_process_input(MMHandleType mediacodec, media_packet_h inbuf, uint64_t tim
                return MC_INVALID_ARG;
        }
 
-       if (mc_handle->is_video) {
-               if ((ret = mc_sniff_bitstream(mc_handle, inbuf)) != MC_ERROR_NONE)
-                       return MC_INVALID_IN_BUF;
-       }
-
        switch (mc_handle->port_type) {
        case MEDIACODEC_PORT_TYPE_GENERAL:
                break;
@@ -738,119 +716,3 @@ CALLBACK_ERROR:
        return ret;
 }
 
-int mc_sniff_h264_bitstream(mc_handle_t *handle, media_packet_h pkt)
-{
-       int ret = MC_ERROR_NONE;
-       void *buf_data = NULL;
-       void *codec_data = NULL;
-       unsigned int codec_data_size = 0;
-       uint64_t buf_size = 0;
-       bool eos = false;
-       bool codec_config = false;
-
-       media_packet_get_buffer_size(pkt, &buf_size);
-       media_packet_get_buffer_data_ptr(pkt, &buf_data);
-       media_packet_get_codec_data(pkt, &codec_data, &codec_data_size);
-       media_packet_is_end_of_stream(pkt, &eos);
-       media_packet_is_codec_config(pkt, &codec_config);
-
-       LOGD("codec_data_size : %d, buf_size : %d, codec_config : %d, eos : %d",
-                       codec_data_size, (int)buf_size, codec_config, eos);
-
-       if (codec_config) {
-               if (codec_data_size == 0)
-                       ret = _mc_check_h264_bytestream(buf_data, (int)buf_size, 0, NULL, NULL, NULL);
-       }
-
-       return ret;
-}
-
-int mc_sniff_mpeg4_bitstream(mc_handle_t *handle, media_packet_h pkt)
-{
-       uint64_t buf_size = 0;
-       unsigned char *buf_data = NULL;
-       void *codec_data = NULL;
-       int codec_data_size = 0, voss_size = 0;
-       bool eos = false;
-       bool codec_config = false;
-       bool sync_frame = false;
-
-       media_packet_get_buffer_size(pkt, &buf_size);
-       media_packet_get_buffer_data_ptr(pkt, (void *)&buf_data);
-       media_packet_get_codec_data(pkt, &codec_data, &codec_data_size);
-       media_packet_is_end_of_stream(pkt, &eos);
-       media_packet_is_codec_config(pkt, &codec_config);
-       media_packet_is_sync_frame(pkt, &sync_frame);
-
-       LOGD("codec_data_size : %d, buff_size : %d, codec_config : %d, sync_frame : %d, eos : %d",
-                       codec_data_size, (int)buf_size, codec_config, sync_frame, eos);
-
-       if (eos)
-               return MC_ERROR_NONE;
-
-       if (codec_config) {
-               if (codec_data) {
-                       if (!_mc_is_voss(codec_data, codec_data_size, NULL))/*voss not in codec data */
-                               return MC_INVALID_IN_BUF;
-               }
-               /* Codec data + I-frame in buffer */
-               if (_mc_is_voss(buf_data, buf_size, &voss_size)) {
-                       if (_mc_is_ivop(buf_data, buf_size, voss_size))   /* IVOP after codec_data */
-                               return MC_ERROR_NONE;
-               } else {
-                       if (_mc_is_ivop(buf_data, buf_size, 0))            /* IVOP at the start */
-                               return MC_ERROR_NONE;
-               }
-       } else if (_mc_is_vop(buf_data, buf_size, 0))
-               return MC_ERROR_NONE;
-
-       return MC_INVALID_IN_BUF;
-}
-
-int mc_sniff_h263_bitstream(mc_handle_t *handle, media_packet_h pkt)
-{
-       void *buf_data = NULL;
-       uint64_t buf_size = 0;
-       bool eos = false;
-
-       media_packet_get_buffer_size(pkt, &buf_size);
-       media_packet_get_buffer_data_ptr(pkt, &buf_data);
-       media_packet_is_end_of_stream(pkt, &eos);
-
-       if (eos)
-               return MC_ERROR_NONE;
-
-       return _mc_check_valid_h263_frame((unsigned char *)buf_data, (int)buf_size);
-}
-
-int mc_sniff_yuv(mc_handle_t *handle, media_packet_h pkt)
-{
-       int ret = MC_ERROR_NONE;
-
-#if 0 /* libtbm, media-tool should be updated */
-       uint64_t buf_size = 0;
-       int plane_num = 0;
-       int padded_width = 0;
-       int padded_height = 0;
-       int allocated_buffer = 0;
-       int index;
-
-       media_packet_get_buffer_size(pkt, &buf_size);
-       media_packet_get_video_number_of_planes(pkt, &plane_num);
-
-       for (index = 0; index < plane_num; index++) {
-               media_packet_get_video_stride_width(pkt, index, &padded_width);
-               media_packet_get_video_stride_height(pkt, index, &padded_height);
-               allocated_buffer += padded_width * padded_height;
-
-               LOGD("%d plane size : %d", padded_width * padded_height);
-       }
-
-       if (buf_size > allocated_buffer) {
-               LOGE("Buffer exceeds maximum size [buf_size: %d, allocated_size :%d", (int)buf_size, allocated_buffer);
-               ret = MC_INVALID_IN_BUF;
-       }
-#endif
-       return ret;
-}
-
index 777961b..2681bb7 100755 (executable)
@@ -66,6 +66,7 @@ static gint __gst_transform_gsterror(mc_gst_core_t *core, GstMessage *message, G
 static gint __gst_handle_resource_error(mc_gst_core_t *core, int code);
 static gint __gst_handle_library_error(mc_gst_core_t *core, int code);
 static gint __gst_handle_core_error(mc_gst_core_t *core, int code);
+static const gchar * _mc_error_to_string(mc_ret_e err);
 
 static int _mc_link_vtable(mc_gst_core_t *core, mediacodec_codec_type_e id, gboolean is_encoder, gboolean is_hw);
 #ifdef TIZEN_PROFILE_LITE
@@ -220,7 +221,7 @@ int __mc_fill_inbuf_with_mm_video_buffer(mc_gst_core_t *core, media_packet_h pkt
                gst_buffer_prepend_memory(mc_buffer->buffer,
                                gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY, buf_data, buf_size, 0,
                                        buf_size, mc_buffer, (GDestroyNotify)gst_mediacodec_buffer_finalize));
-               LOGD("packet data is apended, %d, %d", buf_size, gst_buffer_n_memory(mc_buffer->buffer));
+               LOGD("packet data apended, %d, %d", buf_size, gst_buffer_n_memory(mc_buffer->buffer));
        }
        return ret;
 }
@@ -247,7 +248,7 @@ int __mc_fill_inbuf_with_packet(mc_gst_core_t *core, media_packet_h pkt, GstMCBu
                gst_buffer_append_memory(mc_buffer->buffer,
                                gst_memory_new_wrapped(GST_MEMORY_FLAG_READONLY, buf_data, buf_size, 0,
                                        buf_size, mc_buffer, (GDestroyNotify)gst_mediacodec_buffer_finalize));
-               LOGD("packet data is apended");
+               LOGD("packet data apended");
        }
 
        return ret;
@@ -494,8 +495,8 @@ int __mc_fill_video_packet_with_mm_video_buffer(mc_gst_core_t *core, void *data,
                                        tsurf_info.planes[i].offset = tsurf_info.planes[i-1].offset + tsurf_info.planes[i - 1].size;
 
                                tsurf_info.size += tsurf_info.planes[i].size;
+                               LOGD("%d plane stride : %d, size : %d", i, tsurf_info.planes[i].stride, tsurf_info.planes[i].size);
                        }
-                       LOGD("%d plane stride : %d, size : %d", tsurf_info.planes[i].stride, tsurf_info.planes[i].size);
                        tsurf = tbm_surface_internal_create_with_bos(&tsurf_info, (tbm_bo *)mm_vbuffer->handle.bo, bo_num);
                }
 
@@ -704,7 +705,6 @@ int __mc_sprddec_caps(mc_gst_core_t *core, GstCaps **caps, GstMCBuffer* buff, bo
 {
        g_return_val_if_fail(core != NULL, MC_PARAM_ERROR);
 
-
        mc_decoder_info_t *dec_info = (mc_decoder_info_t *)core->codec_info;
 
        LOGD("%d, %d, ", dec_info->width, dec_info->height);
@@ -2411,7 +2411,7 @@ GstMCBuffer *_mc_gst_media_packet_to_gstbuffer(mc_gst_core_t* core, GstCaps **ca
 
        ret = __mc_fill_input_buffer(core, pkt, mc_buffer);
        if (ret != MC_ERROR_NONE) {
-               LOGW("failed to fill inbuf");
+               LOGW("failed to fill inbuf: %s (ox%08x)", _mc_error_to_string(ret), ret);
                return NULL;
        }
 
@@ -2428,9 +2428,14 @@ GstMCBuffer *_mc_gst_media_packet_to_gstbuffer(mc_gst_core_t* core, GstCaps **ca
 
 media_packet_h __mc_gst_make_media_packet(mc_gst_core_t *core, unsigned char *data, int size)
 {
+       int ret = MEDIA_PACKET_ERROR_NONE;
        media_packet_h pkt = NULL;
 
-       __mc_fill_output_buffer(core, data, size,  &pkt);
+       ret = __mc_fill_output_buffer(core, data, size,  &pkt);
+       if (ret != MC_ERROR_NONE) {
+               LOGW("failed to fill outbuf: %s (ox%08x)", _mc_error_to_string(ret), ret);
+               return NULL;
+       }
 
 
        return pkt;
@@ -2466,8 +2471,6 @@ gboolean __mc_gst_bus_callback(GstBus *bus, GstMessage *msg, gpointer data)
                        break;
                }
 
-               LOGW("Error: %s\n", error->message);
-
                if (error) {
                        if (error->domain == GST_STREAM_ERROR)
                                ret = __gst_handle_stream_error(core, error, msg);
@@ -2483,6 +2486,7 @@ gboolean __mc_gst_bus_callback(GstBus *bus, GstMessage *msg, gpointer data)
                        if (core->user_cb[_MEDIACODEC_EVENT_TYPE_ERROR]) {
                                ((mc_error_cb) core->user_cb[_MEDIACODEC_EVENT_TYPE_ERROR])
                                        (ret, core->user_data[_MEDIACODEC_EVENT_TYPE_ERROR]);
+                                       LOGW("Error : %s (ox%08x)", _mc_error_to_string(ret), ret);
                        }
                }
                g_error_free(error);
@@ -3209,3 +3213,51 @@ void _mc_wait_for_eos(mc_gst_core_t *core)
        LOGD("received EOS");
        g_mutex_unlock(&core->eos_mutex);
 }
+
+const gchar * _mc_error_to_string(mc_ret_e err)
+{
+       guint err_u = (guint) err;
+
+       switch (err_u) {
+       case MC_ERROR:
+               return "Error";
+       case MC_PARAM_ERROR:
+               return "Parameter error";
+       case MC_INVALID_ARG:
+               return "Invailid argument";
+       case MC_PERMISSION_DENIED:
+               return "Permission denied";
+       case MC_INVALID_STATUS:
+               return "Invalid status";
+       case MC_NOT_SUPPORTED:
+               return "Not supported";
+       case MC_INVALID_IN_BUF:
+               return "Invalid inputbuffer";
+       case MC_INVALID_OUT_BUF:
+               return "Invalid outputbuffer";
+       case MC_INTERNAL_ERROR:
+               return "Internal error";
+       case MC_HW_ERROR:
+               return "Hardware error";
+       case MC_NOT_INITIALIZED:
+               return "Not initialized";
+       case MC_INVALID_STREAM:
+               return "Invalid stream";
+       case MC_CODEC_NOT_FOUND:
+               return "Codec not found";
+       case MC_ERROR_DECODE:
+               return "Decode error";
+       case MC_OUTPUT_BUFFER_EMPTY:
+               return "Outputbuffer empty";
+       case MC_OUTPUT_BUFFER_OVERFLOW:
+               return "Outputbuffer overflow";
+       case MC_MEMORY_ALLOCED:
+               return "Memory allocated";
+       case MC_COURRPTED_INI:
+               return "Courrpted ini";
+       default:
+               return "Unknown error";
+
+       }
+}
+
index e9400f4..d6a1257 100755 (executable)
@@ -6,7 +6,7 @@ INCLUDE_DIRECTORIES(../include/headers)
 link_directories(${CMAKE_SOURCE_DIR}/../)
 
 INCLUDE(FindPkgConfig)
-pkg_check_modules(${fw_test} REQUIRED appcore-efl)
+pkg_check_modules(${fw_test} REQUIRED appcore-efl elementary)
 FOREACH(flag ${${fw_test}_CFLAGS})
     SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
 ENDFOREACH(flag)
index 59fcd5b..67cab1c 100755 (executable)
@@ -52,6 +52,7 @@
 #define CHECK_VALID_PACKET(state, expected_state) \
        ((state & (expected_state)) == (expected_state))
 
+#define AAC_CODECDATA_SIZE    16
 static int samplerate = DEFAULT_SAMPPLERATE;
 static int channel = DEFAULT_CHANNEL;
 static int bit = DEFAULT_BIT;
@@ -330,6 +331,170 @@ DONE:
        app->offset += read;
 }
 
+void h263_extractor(App * app, unsigned char **data, int *size, bool * have_frame)
+{
+       int len = 0;
+       size_t result;
+       int read_size = 1, state = 1, bStart = 0;
+       unsigned char val;
+       unsigned char *pH263 = app->data + app->offset;
+       *data = pH263;
+       int max = app->length - app->offset;
+       *have_frame = TRUE;
+
+       while (1) {
+               if (len >= max) {
+                       read_size = (len - 1);
+                       *have_frame = FALSE;
+                       goto DONE;
+               }
+               val = pH263[len++];
+               switch (state) {
+               case 1:
+                       if (val == 0x00)
+                               state++;
+                       break;
+               case 2:
+                       if (val == 0x00)
+                               state++;
+                       else
+                               state = 1;
+                       break;
+               case 3:
+                       state = 1;
+                       if ((val & 0xFC) == 0x80) {
+                               if (bStart) {
+                                       read_size = len - 3;
+                                       goto DONE;
+                               } else {
+                                       bStart = 1;
+                               }
+                       }
+                       break;
+               }
+       }
+ DONE:
+       *size = read_size;
+       app->offset += read_size;
+}
+
+void mpeg4_extractor(App * app, unsigned char **data, int *size, bool * have_frame)
+{
+       int static temp;
+       int len = 0;
+       int result;
+       int read_size = 1, state = 1, bType = 0, bStart = 0;
+       unsigned char val;
+       unsigned char *pMpeg4 = app->data + app->offset;
+       *data = pMpeg4;
+       int max = app->length - app->offset;
+
+       while (1) {
+               if (len >= max) {
+                       read_size = (len - 1);
+                       *have_frame = FALSE;
+                       goto DONE;
+               }
+
+               val = pMpeg4[len++];
+
+               switch (state) {
+               case 1:
+                       if (val == 0x00)
+                               state++;
+                       break;
+               case 2:
+                       if (val == 0x00)
+                               state++;
+                       else
+                               state = 1;
+                       break;
+               case 3:
+                       if (val == 0x01) {
+                               state++;
+                       } else
+                               state = 1;
+                       break;
+               case 4:
+                       state = 1;
+                       if (val == 0xB0 || val == 0xB6) {
+                               if (bType == 0xB6) {
+                                       result = len - 4;
+                                       goto DONE;
+                               }
+                               if (!bType) {
+                                       if (have_frame && val == 0xB0)
+                                               *have_frame = TRUE;
+                               }
+                               bType = val;
+                       }
+                       break;
+               }
+       }
+ DONE:
+       *size = result;
+       app->offset += result;
+       *have_frame = TRUE;
+}
+
+/**
+  * Extract Input data for AMR-NB/WB decoder
+  *  - AMR-NB  : mime type ("audio/AMR")          /   8Khz / 1 ch / 16 bits
+  *  - AMR-WB : mime type ("audio/AMR-WB")  / 16Khz / 1 ch / 16 bits
+  **/
+static const char AMR_header[] = "#!AMR\n";
+static const char AMRWB_header[] = "#!AMR-WB\n";
+#define AMR_NB_MIME_HDR_SIZE          6
+#define AMR_WB_MIME_HDR_SIZE          9
+static const int block_size_nb[16] = { 12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0 };
+static const int block_size_wb[16] = { 17, 23, 32, 36, 40, 46, 50, 58, 60, 5, -1, -1, -1, -1, 0, 0 };
+
+int *blocksize_tbl;
+void amrdec_extractor(App * app, unsigned char **data, int *size, bool * have_frame)
+{
+       int readsize = 0, mode_temp;
+       size_t result;
+       unsigned int mime_size = AMR_NB_MIME_HDR_SIZE;
+       unsigned int fsize, mode;
+       unsigned char *pAmr = app->data + app->offset;
+       int max = app->length - app->offset;
+       //change the below one to frame count
+       if (app->offset == 0) {
+               if (!memcmp(pAmr, AMR_header, AMR_NB_MIME_HDR_SIZE)) {
+                       blocksize_tbl = (int *)block_size_nb;
+                       mode_temp = pAmr[AMR_NB_MIME_HDR_SIZE];
+                       pAmr = pAmr + AMR_NB_MIME_HDR_SIZE;
+                       app->offset += AMR_NB_MIME_HDR_SIZE;
+               } else {
+                       if (!memcmp(pAmr, AMRWB_header, AMR_WB_MIME_HDR_SIZE)) {
+                               mime_size = AMR_WB_MIME_HDR_SIZE;
+                               blocksize_tbl = (int *)block_size_wb;
+                               mode_temp = pAmr[AMR_WB_MIME_HDR_SIZE];
+                               pAmr = pAmr + AMR_WB_MIME_HDR_SIZE;
+                               app->offset += AMR_WB_MIME_HDR_SIZE;
+                       } else {
+                               g_print("[ERROR] AMR-NB/WB don't detected..\n");
+                               return 0;
+                       }
+               }
+       }
+       mode_temp = pAmr[0];
+       if ((mode_temp & 0x83) == 0) {
+               mode = (mode_temp >> 3) & 0x0F; /* Yep. Retrieve the frame size */
+               fsize = blocksize_tbl[mode];
+               readsize = fsize + 1;
+       } else {
+               readsize = 0;
+               g_print("[FAIL] Not found amr frame sync.....\n");
+       }
+
+ DONE:
+       *size = readsize;
+       app->offset += readsize;
+       *data = pAmr;
+       *have_frame = TRUE;
+}
+
 void nv12_extractor(App *app, unsigned char **data, int *size, bool *have_frame)
 {
        int yuv_size;
@@ -529,25 +694,25 @@ void mp3dec_extractor(App *app, unsigned char **data, int *size, bool *have_fram
 
        app->offset += *size;
 }
-#if 0
-void extract_input_aacdec_m4a_test(App *app, unsigned char* data, int *size, bool *have_frame)
+
+#if 1
+void extract_input_aacdec_m4a_test(App * app, unsigned char **data, int *size, bool * have_frame)
 {
-       int readsize = 0;
+       int readsize = 0, read_size = 0;
        size_t result;
        unsigned int header_size = ADTS_HEADER_SIZE;
        unsigned char buffer[1000000];
-       unsigned char codecdata[AAC_CODECDATA_SIZE] = {0,};
-
+       unsigned char codecdata[AAC_CODECDATA_SIZE] = { 0, };
+       int offset = app->length - app->offset;
+       unsigned char *pData = app->data + app->offset;
        /*
         * It is not support full parsing MP4 container box.
         * So It MUST start as RAW valid frame sequence.
         * Testsuit that are not guaranteed to be available on functionality of all General DEMUXER/PARSER.
         */
 
-       if (feof(fd))
-               return 0;
-
-       if (frame_count == 0) {
+       //change the below one later
+       if (app->offset == 0) {
                /*
                 * CAUTION : Codec data is needed only once  in first time
                 * Codec data is made(or extracted) by MP4 demuxer in 'esds' box.
@@ -595,38 +760,38 @@ void extract_input_aacdec_m4a_test(App *app, unsigned char* data, int *size, boo
                codecdata[6] = 0x80;
 #endif
 
-               memcpy(aacdata, codecdata, AAC_CODECDATA_SIZE);
-
-               result = fread(buffer, 1, header_size, fd);   /* adts header */
-               if (result != header_size)
-                       return -1;
-
-               if ((buffer != NULL) && (buffer[0] == 0xff) && ((buffer[1] & 0xf6) == 0xf0)) {
-                       readsize = ((buffer[3] & 0x03) << 11) | (buffer[4] << 3) | ((buffer[5] & 0xe0) >> 5);
-                       readsize = readsize -header_size;
-                       result = fread(buffer, 1, readsize, fd);    /* Make only RAW data, so exclude header 7 bytes */
-                       memcpy(aacdata+AAC_CODECDATA_SIZE, buffer, readsize);
+               memcpy(buffer, codecdata, AAC_CODECDATA_SIZE);
+               if ((pData != NULL) && (pData[0] == 0xff) && ((pData[1] & 0xf6) == 0xf0)) {
+                       read_size = ((pData[3] & 0x03) << 11) | (pData[4] << 3) | ((pData[5] & 0xe0) >> 5);
+               } else {
+                       read_size = 0;
+                       g_print("[FAIL] Not found aac frame sync.....\n");
                }
-
-               g_print("[example] Insert 'codec_data' in 1st frame buffer size (%d)\n", readsize+AAC_CODECDATA_SIZE);
-               return (readsize + AAC_CODECDATA_SIZE);           /* return combination of (codec_data + raw_data) */
+               readsize = read_size - header_size;
+               memcpy(buffer + AAC_CODECDATA_SIZE, pData + 7, readsize);
+               read_size = readsize + AAC_CODECDATA_SIZE;      //return combination of (codec_data + raw_data)
+               app->offset += header_size + readsize;
+               goto DONE;
        }
 
-       result = fread(buffer, 1, header_size, fd);   /* adts header */
-       if (result != header_size)
-               exit(1);
+       if ((pData != NULL) && (pData[0] == 0xff) && ((pData[1] & 0xf6) == 0xf0)) {
+               read_size = ((pData[3] & 0x03) << 11) | (pData[4] << 3) | ((pData[5] & 0xe0) >> 5);
+               readsize = read_size - header_size;
+               memcpy(buffer, pData + 7, readsize);    //Make only RAW data, so exclude header 7 bytes
+               read_size = readsize;
+               app->offset += header_size + readsize;
 
-       if ((buffer != NULL) && (buffer[0] == 0xff) && ((buffer[1] & 0xf6) == 0xf0)) {
-               readsize = ((buffer[3] & 0x03) << 11) | (buffer[4] << 3) | ((buffer[5] & 0xe0) >> 5);
-               readsize = readsize -header_size;
-               result = fread(buffer, 1, readsize, fd);    /* Make only RAW data, so exclude header 7 bytes */
-               memcpy(aacdata, buffer, readsize);
        } else {
-               readsize = 0;
-               g_print("[FAIL] Not found aac frame sync.....\n");
+               read_size = 0;
+               g_print("[FAIL] Not found aac frame sync. \n");
        }
-
-       return readsize;            /* return only raw_data */
+ DONE:
+       *data = buffer;
+       *have_frame = TRUE;
+       if (read_size >= offset)
+               *size = offset;
+       else
+               *size = read_size;
 }
 #endif
 
@@ -686,16 +851,16 @@ int  _mediacodec_set_codec(int codecid, int flag, int *hardware)
                        extractor = yuv_extractor;
                        mime = *hardware ? MEDIA_FORMAT_NV12 : MEDIA_FORMAT_I420;
                } else {
-                       extractor = h264_extractor;
+                       extractor = mpeg4_extractor;
                        mime = MEDIA_FORMAT_MPEG4_SP;
                }
                break;
        case MEDIACODEC_H263:
                if (encoder) {
-                       extractor = yuv_extractor;
+                       extractor = h263_extractor;
                        mime = *hardware ? MEDIA_FORMAT_NV12 : MEDIA_FORMAT_I420;
                } else {
-                       extractor = h264_extractor;
+                       extractor = h263_extractor;
                        mime = MEDIA_FORMAT_H263P;
                }
                break;
@@ -713,7 +878,7 @@ int  _mediacodec_set_codec(int codecid, int flag, int *hardware)
                        extractor = aacenc_extractor;
                        mime = MEDIA_FORMAT_PCM;
                } else {
-                       /*extractor = aacdec_extractor;*/
+                       extractor = extract_input_aacdec_m4a_test;
                        mime = MEDIA_FORMAT_AAC_HE;
                }
                break;
@@ -735,6 +900,14 @@ int  _mediacodec_set_codec(int codecid, int flag, int *hardware)
                break;
        case MEDIACODEC_WMALSL:
                break;
+       case MEDIACODEC_AMR_NB:
+               extractor = amrdec_extractor;
+               mime = MEDIA_FORMAT_AMR_NB;
+               break;
+       case MEDIACODEC_AMR_WB:
+               extractor = amrdec_extractor;
+               mime = MEDIA_FORMAT_AMR_WB;
+               break;
        default:
                LOGE("NOT SUPPORTED!!!!");
                break;
@@ -870,11 +1043,11 @@ static bool _mediacodec_outbuf_available_cb(media_packet_h pkt, void *user_data)
        if (ret != MEDIACODEC_ERROR_NONE)
                g_print("get_output failed\n");
 
-       decoder_output_dump(app, out_pkt);
+       //decoder_output_dump(app, out_pkt);
 
 #if DUMP_OUTBUF
        void *data;
-       uint64_t buf_size;
+       int buf_size;
        int stride_width, stride_height;
 
        media_packet_get_buffer_data_ptr(out_pkt, &data);
@@ -1038,6 +1211,7 @@ void quit_program()
        if (fp_out)
                fclose(fp_out);
 #endif
+               elm_exit();
 
 }
 
@@ -1419,6 +1593,7 @@ static void decoder_output_dump(App *app, media_packet_h pkt)
        media_packet_get_video_plane_data_ptr(pkt, 0, &temp);
        media_packet_get_video_stride_width(pkt, 0, &stride_width);
        media_packet_get_video_stride_height(pkt, 0, &stride_height);
+       g_printf("stride : %d, %d\n", stride_width, stride_height);
 
        for (i = 0; i < app->height; i++) {
                ret = fwrite(temp, app->width, 1, fp);