Added tc for integration test 94/134494/8
authorSejun Park <sejun79.park@samsung.com>
Mon, 19 Jun 2017 02:37:30 +0000 (11:37 +0900)
committerSejun Park <sejun79.park@samsung.com>
Tue, 20 Jun 2017 01:25:14 +0000 (10:25 +0900)
Change-Id: I13d0659212d3ef8e2022a6ddb9e5319e3f58986e

packaging/capi-media-codec.spec [changed mode: 0755->0644]
test/CMakeLists.txt
test/media_codec_test.c

old mode 100755 (executable)
new mode 100644 (file)
index c58bbf9..8b18995
@@ -4,7 +4,7 @@
 
 Name:       capi-media-codec
 Summary:    A Media Codec library in Tizen Native API
-Version:    0.5.4
+Version:    0.5.5
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
@@ -23,6 +23,7 @@ BuildRequires:  pkgconfig(gstreamer-plugins-base-1.0)
 BuildRequires:  pkgconfig(gstreamer-app-1.0)
 BuildRequires:  pkgconfig(capi-system-info)
 BuildRequires:  pkgconfig(iniparser)
+BuildRequires:  pkgconfig(capi-mediademuxer)
 
 %description
 A Media Codec library in Tizen Native API
index d3e0022..754b501 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 elementary capi-media-camera)
+pkg_check_modules(${fw_test} REQUIRED appcore-efl elementary capi-media-camera capi-mediademuxer)
 FOREACH(flag ${${fw_test}_CFLAGS})
     SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
 ENDFOREACH(flag)
index 9c35563..bb61c69 100644 (file)
@@ -31,6 +31,7 @@
 #include <media_packet_internal.h>
 #include <media_packet_pool.h>
 #include <media_codec_internal.h>
+#include <mediademuxer.h>
 
 #define PACKAGE "media_codec_test"
 #define MAX_HANDLE                     4
@@ -58,7 +59,7 @@
        ((state & (expected_state)) == (expected_state))
 
 #define AAC_CODECDATA_SIZE    16
-#define USE_POOL       1
+#define USE_POOL       0
 
 guint8 buf_adts[ADTS_HEADER_SIZE];
 
@@ -90,6 +91,7 @@ enum {
        CURRENT_STATUS_GET_OUTPUT,
        CURRENT_STATUS_RESET_OUTPUT_BUFFER,
        CURRENT_STATUS_SET_SIZE,
+       CURRENT_STATUS_AUTO_TEST,
 };
 
 typedef enum {
@@ -119,6 +121,8 @@ typedef enum {
 struct _App {
        GMainLoop *loop;
        guint sourceid;
+       guint audio_id;
+       guint video_id;
 
        GMappedFile *file;
        guint8 *data;
@@ -141,6 +145,20 @@ struct _App {
        gint frame;
        type_e type;
        camera_h camera_handle;
+
+       GThread *thread;
+       GCond thread_cond;
+       GMutex thread_mutex;
+       GMutex eos_mutex;
+       GCond eos_cond;
+       GCond dst_eos_cond;
+       gint demux_eos;
+       gint codec_eos;
+       gint suspend;
+       gchar filepath[256];
+       /* demuxer */
+       mediademuxer_h demuxer;
+       media_format_h format[MAX_HANDLE];
        /* video */
        mediacodec_h mc_handle[MAX_HANDLE];
        guint width;
@@ -148,6 +166,7 @@ struct _App {
        guint fps;
        guint target_bits;
        media_format_mimetype_e mime;
+       gint video_track;
 
        /* Audio */
        guint samplerate;
@@ -155,7 +174,7 @@ struct _App {
        guint bit;
        guint bitrate;
        gboolean is_amr_nb;
-
+       gint audio_track;
 
        /* Render */
        guint w;
@@ -166,6 +185,11 @@ struct _App {
        Ecore_Pipe *pipe;
        GList *packet_list;
        GMutex lock;
+
+       gint etb;
+       gint ftb;
+       gint ebd;
+       gint fbd;
 };
 
 App s_app;
@@ -174,24 +198,28 @@ media_format_h fmt = NULL;
 media_packet_pool_h pkt_pool = NULL;
 
 /* Internal Functions */
-static gint _create_app(void *data);
-static gint _terminate_app(void *data);
-static void displaymenu(void);
-static void display_sub_basic();
-
-static void _mediacodec_unprepare(App *app);
+gint _create_app(void *data);
+gint _terminate_app(void *data);
+void displaymenu(void);
+void display_sub_basic();
+
+void _mediacodec_unprepare(App *app);
+void _mediacodec_destroy(App *app);
+void _mediacodec_auto_test(App *app, char *path);
+void input_filepath(char *filename, App *app);
 /* For debugging */
-static void mc_hex_dump(char *desc, void *addr, gint len);
-static void decoder_output_dump(App *app, media_packet_h pkt);
-static void output_dump(App *app, media_packet_h pkt);
+void mc_hex_dump(char *desc, void *addr, gint len);
+void decoder_output_dump(App *app, media_packet_h pkt);
+void output_dump(App *app, media_packet_h pkt);
 /* */
 const char* codec_type_to_string(mediacodec_codec_type_e media_codec_id);
 
 void (*extractor)(App *app, guint8** data, gint *size, gboolean *have_frame, gboolean *codec_data);
 
 gint g_menu_state = CURRENT_STATUS_MAINMENU;
+void demuxer_error_cb(mediademuxer_error_e error, void *user_data);
 
-static gint _create_app(void *data)
+gint _create_app(void *data)
 {
        g_print("My app is going alive!\n");
        App *app = (App*)data;
@@ -200,7 +228,7 @@ static gint _create_app(void *data)
        return 0;
 }
 
-static gint _terminate_app(void *data)
+gint _terminate_app(void *data)
 {
        g_print("My app is going gone!\n");
        App *app = (App*)data;
@@ -816,7 +844,7 @@ int  _configure(App *app, int codecid, int flag, gboolean *hardware)
        return mime;
 }
 
-static void _mediacodec_process_input(App *app)
+void _mediacodec_process_input(App *app)
 {
        gint i;
        gboolean have_frame = FALSE;
@@ -917,7 +945,7 @@ static void _mediacodec_process_input(App *app)
        }
 }
 
-static gboolean read_data(App *app)
+gboolean read_data(App *app)
 {
        guint len = 0;
        gboolean have_frame = FALSE;
@@ -1040,7 +1068,100 @@ static gboolean read_data(App *app)
        return TRUE;
 }
 
-static void start_feed(App *app)
+void av_feed_suspend(App *app)
+{
+       g_mutex_lock(&app->thread_mutex);
+       app->suspend = 1;
+       g_print("suspend thread\n");
+       g_mutex_unlock(&app->thread_mutex);
+}
+
+void av_feed_resume(App *app)
+{
+       g_mutex_lock(&app->thread_mutex);
+       app->suspend = 0;
+       g_print("resume thread\n");
+       g_cond_broadcast(&app->thread_cond);
+       g_mutex_unlock(&app->thread_mutex);
+}
+
+gpointer av_feed_thread(gpointer data)
+{
+       App *app = (App *)data;
+       int ret = 0;
+       gint track = -1;
+
+       media_packet_h packet = NULL;
+       track = app->audio_track;
+
+       while (1) {
+               g_mutex_lock(&app->thread_mutex);
+
+               while (app->suspend != 0) g_cond_wait(&app->thread_cond, &app->thread_mutex);
+
+               g_mutex_unlock(&app->thread_mutex);
+
+               if (app->demux_eos == 1) {
+                       g_print("got eos!!!\n");
+                       break;
+               }
+
+               ret = mediademuxer_read_sample(app->demuxer, track, &packet);
+               if (ret != MEDIACODEC_ERROR_NONE)
+                       return NULL;
+
+               ret = mediacodec_process_input(app->mc_handle[track], packet, 0);
+               if (ret != MEDIACODEC_ERROR_NONE)
+                       return NULL;
+
+               app->etb++;
+
+       }
+
+       return NULL;
+}
+
+gboolean feed_audio(App *app)
+{
+       gint ret = 0;
+       gint track = -1;
+
+       media_packet_h packet = NULL;
+       track = app->audio_track;
+
+       g_print("read audio sample!!!\n");
+       ret = mediademuxer_read_sample(app->demuxer, track, &packet);
+       if (ret != MEDIACODEC_ERROR_NONE)
+               return FALSE;
+
+       ret = mediacodec_process_input(app->mc_handle[track], packet, 0);
+       if (ret != MEDIACODEC_ERROR_NONE)
+               return FALSE;
+
+       return TRUE;
+}
+
+gboolean feed_video(App *app)
+{
+       gint ret = 0;
+       gint track = -1;
+
+       media_packet_h packet = NULL;
+       track = app->video_track;
+
+       g_print("read video sample!!!\n");
+       ret = mediademuxer_read_sample(app->demuxer, track, &packet);
+       if (ret != MEDIACODEC_ERROR_NONE)
+               return FALSE;
+
+       ret = mediacodec_process_input(app->mc_handle[track], packet, 0);
+       if (ret != MEDIACODEC_ERROR_NONE)
+               return FALSE;
+
+       return TRUE;
+}
+
+void start_feed(App *app)
 {
        if (app->sourceid == 0) {
                app->sourceid = g_idle_add((GSourceFunc)read_data, app);
@@ -1048,7 +1169,7 @@ static void start_feed(App *app)
        }
 }
 
-static void stop_feed(App *app)
+void stop_feed(App *app)
 {
        if (app->sourceid != 0) {
                g_source_remove(app->sourceid);
@@ -1057,19 +1178,86 @@ static void stop_feed(App *app)
        }
 }
 
-static gboolean _mediacodec_inbuf_used_cb(media_packet_h pkt, void *user_data)
+void _mediacodec_inbuf_used_cb(media_packet_h pkt, void *user_data)
 {
+       App *app = (App *)user_data;
+
        g_print("_mediacodec_inbuf_used_cb!!!\n");
 #ifdef USE_POOL
        media_packet_pool_release_packet(pkt_pool, pkt);
 #else
        media_packet_destroy(pkt);
 #endif
+       app->ebd++;
 
-       return TRUE;
+       return;
 }
 
-static gboolean _mediacodec_outbuf_available_cb(media_packet_h pkt, void *user_data)
+void _audio_outbuf_available_cb(media_packet_h pkt, void *user_data)
+{
+       media_packet_h out_pkt = NULL;
+       int ret;
+
+       App *app = (App*)user_data;
+
+       g_print("_audio_outbuf_available_cb\n");
+
+       g_mutex_lock(&app->lock);
+
+       ret = mediacodec_get_output(app->mc_handle[app->audio_track], &out_pkt, 0);
+
+       if (ret != MEDIACODEC_ERROR_NONE)
+               g_print("get_output failed\n");
+
+       if (app->enable_dump)
+               output_dump(app, out_pkt);
+
+       app->frame_count++;
+       app->fbd++;
+
+
+       g_mutex_unlock(&app->lock);
+
+       media_packet_destroy(out_pkt);
+       out_pkt = NULL;
+       g_print("done\n");
+
+       return;
+}
+
+void _video_outbuf_available_cb(media_packet_h pkt, void *user_data)
+{
+       media_packet_h out_pkt = NULL;
+       int ret;
+
+       App *app = (App*)user_data;
+
+       g_print("_video_outbuf_available_cb\n");
+
+       g_mutex_lock(&app->lock);
+
+       ret = mediacodec_get_output(app->mc_handle[app->video_track], &out_pkt, 0);
+
+       if (ret != MEDIACODEC_ERROR_NONE)
+               g_print("get_output failed\n");
+
+       if (app->enable_dump)
+               decoder_output_dump(app, out_pkt);
+
+       app->frame_count++;
+       app->fbd++;
+
+
+       g_mutex_unlock(&app->lock);
+
+       media_packet_destroy(out_pkt);
+       out_pkt = NULL;
+       g_print("done\n");
+
+       return;
+}
+
+void _mediacodec_outbuf_available_cb(media_packet_h pkt, void *user_data)
 {
        media_packet_h out_pkt = NULL;
        int ret;
@@ -1093,6 +1281,7 @@ static gboolean _mediacodec_outbuf_available_cb(media_packet_h pkt, void *user_d
        }
 
        app->frame_count++;
+       app->fbd++;
 
 
        g_mutex_unlock(&app->lock);
@@ -1101,10 +1290,10 @@ static gboolean _mediacodec_outbuf_available_cb(media_packet_h pkt, void *user_d
        out_pkt = NULL;
        g_print("done\n");
 
-       return TRUE;
+       return;
 }
 
-static gboolean _mediacodec_buffer_status_cb(mediacodec_status_e status, void *user_data)
+void _mediacodec_buffer_status_cb(mediacodec_status_e status, void *user_data)
 {
        g_print("_mediacodec_buffer_status_cb %d\n", status);
 
@@ -1115,17 +1304,58 @@ static gboolean _mediacodec_buffer_status_cb(mediacodec_status_e status, void *u
        else if (status == MEDIACODEC_ENOUGH_DATA)
                stop_feed(app);
 
-       return TRUE;
+       return;
 }
 
-static gboolean _mediacodec_error_cb(mediacodec_error_e error, void *user_data)
+void _av_buffer_status_cb(mediacodec_status_e status, void *user_data)
 {
-       return TRUE;
+       g_print("_av_buffer_status_cb %d\n", status);
+
+       App *app = (App*)user_data;
+
+       if (status == MEDIACODEC_NEED_DATA)
+               av_feed_resume(app);
+       else if (status == MEDIACODEC_ENOUGH_DATA)
+               av_feed_suspend(app);
+
+       return;
 }
 
-static gboolean _mediacodec_eos_cb(void *user_data)
+void _mediacodec_error_cb(mediacodec_error_e error, void *user_data)
 {
-       return TRUE;
+       return;
+}
+
+void demuxer_error_cb(mediademuxer_error_e error, void *user_data)
+{
+       g_print("Got Error %d from Mediademuxer\n", error);
+       return;
+}
+
+void _mediacodec_eos_cb(void *user_data)
+{
+       App *app = (App *)user_data;
+
+       g_print("mediacodec eos\n");
+       g_mutex_lock(&app->eos_mutex);
+       app->codec_eos = 1;
+       g_mutex_unlock(&app->eos_mutex);
+       g_cond_broadcast(&app->dst_eos_cond);
+       return;
+}
+
+void _mediademuxer_eos_cb(int track, void *user_data)
+{
+       App *app = (App *)user_data;
+
+       g_print("eos track : %d\n", track);
+       av_feed_suspend(app);
+       g_print("suspended\n");
+       app->demux_eos = 1;
+       av_feed_resume(app);
+       g_cond_broadcast(&app->eos_cond);
+
+       return;
 }
 
 gboolean  _foreach_cb(mediacodec_codec_type_e codec_type, void *user_data)
@@ -1134,7 +1364,7 @@ gboolean  _foreach_cb(mediacodec_codec_type_e codec_type, void *user_data)
        return TRUE;
 }
 
-static void _mediacodec_prepare(App *app, gboolean frame_all)
+void _mediacodec_prepare(App *app, gboolean frame_all)
 {
        int ret;
 
@@ -1206,7 +1436,7 @@ static void _mediacodec_prepare(App *app, gboolean frame_all)
        mediacodec_set_output_buffer_available_cb(app->mc_handle[0], (mediacodec_output_buffer_available_cb) _mediacodec_outbuf_available_cb, app);
        if (frame_all)
                mediacodec_set_buffer_status_cb(app->mc_handle[0], (mediacodec_buffer_status_cb) _mediacodec_buffer_status_cb, app);
-       mediacodec_set_eos_cb(app->mc_handle[0], (mediacodec_eos_cb)_mediacodec_eos_cb, NULL);
+       mediacodec_set_eos_cb(app->mc_handle[0], (mediacodec_eos_cb)_mediacodec_eos_cb, app);
        mediacodec_set_error_cb(app->mc_handle[0], (mediacodec_error_cb)_mediacodec_error_cb, NULL);
 
        /* prepare */
@@ -1228,20 +1458,20 @@ static void _mediacodec_prepare(App *app, gboolean frame_all)
        return;
 }
 
-static void _mediacodec_enc_input_buffer_used_cb(media_packet_h pkt, void *user_data)
+void _mediacodec_enc_input_buffer_used_cb(media_packet_h pkt, void *user_data)
 {
        /* release input raw packet */
        media_packet_destroy(pkt);
 }
 
 /* this callback is called when the input buffer for codec has done to use */
-static void _mediacodec_dec_input_buffer_used_cb(media_packet_h pkt, void *user_data)
+void _mediacodec_dec_input_buffer_used_cb(media_packet_h pkt, void *user_data)
 {
        /* release input encoded packet */
        media_packet_destroy(pkt);
 }
 
-static void _mediacodec_enc_output_buffer_available_cb(media_packet_h pkt, void *user_data)
+void _mediacodec_enc_output_buffer_available_cb(media_packet_h pkt, void *user_data)
 {
        App *app = (App*)user_data;
 
@@ -1252,7 +1482,7 @@ static void _mediacodec_enc_output_buffer_available_cb(media_packet_h pkt, void
        mediacodec_process_input(app->mc_handle[0], output_buf, 0);
 }
 
-static void _mediacodec_dec_output_buffer_available_cb(media_packet_h pkt, void *user_data)
+void _mediacodec_dec_output_buffer_available_cb(media_packet_h pkt, void *user_data)
 {
        App *app = (App*)user_data;
 
@@ -1267,7 +1497,7 @@ static void _mediacodec_dec_output_buffer_available_cb(media_packet_h pkt, void
        media_packet_destroy(output_buf);
 }
 
-static void _media_packet_preview_cb(media_packet_h packet, void *user_data)
+void _media_packet_preview_cb(media_packet_h packet, void *user_data)
 {
        App *app = user_data;
        g_mutex_lock(&app->lock);
@@ -1277,7 +1507,7 @@ static void _media_packet_preview_cb(media_packet_h packet, void *user_data)
        return;
 }
 
-static void _mediacodec_camera_start(App *app)
+void _mediacodec_camera_start(App *app)
 {
        int default_format = CAMERA_PIXEL_FORMAT_NV12;
        app->width = 640;
@@ -1315,7 +1545,7 @@ static void _mediacodec_camera_start(App *app)
 }
 
 
-static void _mediacodec_camera_stop(App *app)
+void _mediacodec_camera_stop(App *app)
 {
        camera_state_e camera_state = CAMERA_STATE_NONE;
 
@@ -1330,12 +1560,230 @@ static void _mediacodec_camera_stop(App *app)
        return;
 }
 
-static void _mediacodec_unprepare(App *app)
+void _mediacodec_auto_test(App *app, char *path)
+{
+       gint ret = 0;
+       gint num_tracks = 0;
+       gint track = 0;
+       gint width = 0;
+       gint height = 0;
+       gint channel = 0;
+       gint samplerate = 0;
+       gint bit = 0;
+       media_format_type_e formattype;
+       media_format_mimetype_e video_mime;
+       media_format_mimetype_e audio_mime;
+       gint codec_mask = 0xFFF0;
+       gint codec_id;
+       app->demux_eos = 0;
+       app->codec_eos = 0;
+       app->etb = 0;
+       app->ebd = 0;
+       app->ftb = 0;
+       app->fbd = 0;
+
+       ret = mediademuxer_create(&app->demuxer);
+       if (ret != MEDIACODEC_ERROR_NONE) {
+               g_print("failed to create demuxer\n");
+               return;
+       }
+
+       ret = mediademuxer_set_data_source(app->demuxer, path);
+       if (ret != MEDIACODEC_ERROR_NONE) {
+               g_print("failed to mediademuxer_set_data_source\n");
+               return;
+       }
+
+       ret = mediademuxer_set_error_cb(app->demuxer, demuxer_error_cb, app->demuxer);
+       if (ret != MEDIACODEC_ERROR_NONE) {
+               g_print("failed to mediademuxer_set_error_cb\n");
+               return;
+       }
+
+       mediademuxer_set_eos_cb(app->demuxer, _mediademuxer_eos_cb, app);
+
+       ret = mediademuxer_prepare(app->demuxer);
+       if (ret != MEDIACODEC_ERROR_NONE) {
+               g_print("failed to prepare\n");
+               return;
+       }
+
+
+       ret = mediademuxer_get_track_count(app->demuxer, &num_tracks);
+       if (ret != MEDIACODEC_ERROR_NONE) {
+               g_print("failed to get track\n");
+               return;
+       }
+
+       for (track = 0; track < num_tracks; track++) {
+               ret = mediademuxer_get_track_info(app->demuxer, track, &app->format[track]);
+               if (ret != MEDIACODEC_ERROR_NONE) {
+                       g_print("failed to get track info\n");
+                       return;
+               }
+
+               media_format_get_type(app->format[track], &formattype);
+
+               if (!app->is_video && formattype == MEDIA_FORMAT_AUDIO) {
+                       app->audio_track = track;
+                       app->type = AUDIO_DEC;
+                       media_format_get_audio_info(app->format[track], &audio_mime, &channel, &samplerate, &bit, NULL);
+
+                       mediademuxer_select_track(app->demuxer, track);
+
+                       ret = mediacodec_create(&app->mc_handle[track]);
+                       if (ret != MEDIACODEC_ERROR_NONE) {
+                               g_print("failed to create mediacocec\n");
+                               return;
+                       }
+
+                       codec_id = audio_mime & codec_mask;
+                       g_print("auido codec_id : %x\n", codec_id);
+
+                       ret = mediacodec_set_codec(app->mc_handle[track], codec_id, MEDIACODEC_DECODER | MEDIACODEC_SUPPORT_TYPE_SW);
+                       if (ret != MEDIACODEC_ERROR_NONE) {
+                               g_print("failed to set codec\n");
+                               return;
+                       }
+
+                       ret = mediacodec_set_adec_info(app->mc_handle[track], samplerate, channel, bit);
+                       if (ret != MEDIACODEC_ERROR_NONE) {
+                               g_print("failed to set adec info\n");
+                               return;
+                       }
+
+                       mediacodec_set_buffer_status_cb(app->mc_handle[track], _av_buffer_status_cb, app);
+                       mediacodec_set_input_buffer_used_cb(app->mc_handle[track], _mediacodec_inbuf_used_cb, app);
+                       mediacodec_set_output_buffer_available_cb(app->mc_handle[track], _audio_outbuf_available_cb, app);
+                       mediacodec_set_eos_cb(app->mc_handle[track], _mediacodec_eos_cb, app);
+                       mediacodec_set_error_cb(app->mc_handle[track], _mediacodec_error_cb, NULL);
+
+               } else if (app->is_video && formattype == MEDIA_FORMAT_VIDEO) {
+                       app->video_track = track;
+                       app->type = VIDEO_DEC;
+                       media_format_get_video_info(app->format[track], &video_mime, &width, &height, NULL, NULL);
+
+                       mediademuxer_select_track(app->demuxer, track);
+
+                       ret = mediacodec_create(&app->mc_handle[track]);
+                       if (ret != MEDIACODEC_ERROR_NONE) {
+                               g_print("failed to create mediacocec\n");
+                               return;
+                       }
+
+                       app->width = width;
+                       app->height = height;
+
+                       codec_id = video_mime & codec_mask;
+                       g_print("video codec_id : %x\n", codec_id);
+
+                       ret = mediacodec_set_codec(app->mc_handle[track], codec_id, MEDIACODEC_DECODER | MEDIACODEC_SUPPORT_TYPE_HW);
+                       if (ret != MEDIACODEC_ERROR_NONE) {
+                               g_print("failed to set codec\n");
+                               return;
+                       }
+
+                       ret = mediacodec_set_vdec_info(app->mc_handle[track], width, height);
+                       if (ret != MEDIACODEC_ERROR_NONE) {
+                               g_print("failed to set vdec info\n");
+                               return;
+                       }
+
+                       mediacodec_set_buffer_status_cb(app->mc_handle[track], _av_buffer_status_cb, app);
+                       mediacodec_set_input_buffer_used_cb(app->mc_handle[track], _mediacodec_inbuf_used_cb, app);
+                       mediacodec_set_output_buffer_available_cb(app->mc_handle[track], _video_outbuf_available_cb, app);
+                       mediacodec_set_eos_cb(app->mc_handle[track], _mediacodec_eos_cb, app);
+                       mediacodec_set_error_cb(app->mc_handle[track], _mediacodec_error_cb, NULL);
+               }
+       }
+
+       ret = mediademuxer_start(app->demuxer);
+       if (ret != MEDIACODEC_ERROR_NONE) {
+               g_print("failed to start mediademuxer\n");
+               return;
+       }
+
+       track = app->is_video ? app->video_track : app->audio_track;
+       ret = mediacodec_prepare(app->mc_handle[track]);
+       if (ret != MEDIACODEC_ERROR_NONE) {
+               g_print("failed to prepare mediacodec\n");
+               return;
+       }
+
+       g_cond_init(&app->thread_cond);
+       g_cond_init(&app->eos_cond);
+       g_cond_init(&app->dst_eos_cond);
+       g_mutex_init(&app->thread_mutex);
+       g_mutex_init(&app->eos_mutex);
+
+       app->thread = g_thread_new("feed thread", &av_feed_thread, app);
+       app->start = clock();
+
+       g_mutex_lock(&app->eos_mutex);
+       while (app->codec_eos != 1) g_cond_wait(&app->dst_eos_cond, &app->eos_mutex);
+       g_mutex_unlock(&app->eos_mutex);
+       g_print("now try to destroy thread!!\n");
+       g_thread_join(app->thread);
+       app->finish = clock();
+
+       ret = mediademuxer_stop(app->demuxer);
+       if (ret != MEDIACODEC_ERROR_NONE) {
+               g_print("failed to stop mediademuxer\n");
+               return;
+       }
+
+       ret = mediademuxer_unselect_track(app->demuxer, track);
+       if (ret != MEDIACODEC_ERROR_NONE) {
+               g_print("failed to unselect mediademuxer\n");
+               return;
+       }
+
+       ret = mediacodec_unprepare(app->mc_handle[track]);
+       if (ret != MEDIACODEC_ERROR_NONE) {
+               g_print("failed to unprepare mediacodec\n");
+               return;
+       }
+
+       ret = mediacodec_destroy(app->mc_handle[track]);
+       if (ret != MEDIACODEC_ERROR_NONE) {
+               g_print("failed to destroy mediacodec\n");
+               return;
+       }
+
+       ret = mediademuxer_unprepare(app->demuxer);
+       if (ret != MEDIACODEC_ERROR_NONE) {
+               g_print("failed to unprepare mediademuxer\n");
+               return;
+       }
+
+       ret = mediademuxer_destroy(app->demuxer);
+       if (ret != MEDIACODEC_ERROR_NONE) {
+               g_print("failed to destroy mediademuxer\n");
+               return;
+       }
+
+       g_cond_clear(&app->thread_cond);
+       g_cond_clear(&app->eos_cond);
+       g_cond_clear(&app->dst_eos_cond);
+       g_mutex_clear(&app->thread_mutex);
+       g_mutex_clear(&app->eos_mutex);
+
+       g_print("resources are released!!!\n\n\n");
+       g_print("-----------------------------------------------------\n");
+       g_print("Input - queued packets : %d, finalized packets : %d\n", app->etb, app->ebd);
+       g_print("Output - queued packets : %d, finalized packets : %d\n", app->fbd, app->fbd);
+       g_print("Average FPS = %3.3f\n", ((double)app->fbd*1000000/(app->finish - app->start)));
+       g_print("-----------------------------------------------------\n");
+
+       return;
+}
+
+void _mediacodec_unprepare(App *app)
 {
        mediacodec_unprepare(app->mc_handle[0]);
 }
 
-static void _mediacodec_destroy(App *app)
+void _mediacodec_destroy(App *app)
 {
 #ifdef USE_POOL
        if (media_packet_pool_deallocate(pkt_pool) != MEDIA_PACKET_ERROR_NONE) {
@@ -1354,7 +1802,7 @@ static void _mediacodec_destroy(App *app)
        mediacodec_destroy(app->mc_handle[0]);
 }
 
-static void input_filepath(char *filename, App *app)
+void input_filepath(char *filename, App *app)
 {
        GError *error = NULL;
 
@@ -1379,7 +1827,6 @@ void quit_program(App *app)
                media_format_unref(fmt);
                g_main_loop_quit(app->loop);
                exit(0);
-
 }
 
 void reset_menu_state()
@@ -1425,6 +1872,8 @@ void _interpret_main_menu(char *cmd, App *app)
                        _mediacodec_camera_start(app);
                else if (strncmp(cmd, "ct", 2) == 0)
                        _mediacodec_camera_stop(app);
+               else if (strncmp(cmd, "au", 2) == 0)
+                       g_menu_state = CURRENT_STATUS_AUTO_TEST;
                else if (strncmp(cmd, "dp", 2) == 0) {
                        if (!app->enable_dump) {
                                app->enable_dump = TRUE;
@@ -1442,7 +1891,7 @@ void _interpret_main_menu(char *cmd, App *app)
        return;
 }
 
-static void displaymenu(void)
+void displaymenu(void)
 {
        if (g_menu_state == CURRENT_STATUS_MAINMENU) {
                display_sub_basic();
@@ -1491,6 +1940,8 @@ static void displaymenu(void)
                g_print("*** input dec process number\n");
        } else if (g_menu_state == CURRENT_STATUS_GET_OUTPUT) {
                g_print("*** input get output buffer number\n");
+       } else if (g_menu_state == CURRENT_STATUS_AUTO_TEST) {
+               g_print("*** enter media path and select the track to decode (0 : audio, 1 : video).\n");
        } else {
                g_print("*** unknown status.\n");
        }
@@ -1503,8 +1954,7 @@ gboolean timeout_menu_display(void* data)
        return FALSE;
 }
 
-
-static void interpret(char *cmd)
+void interpret(char *cmd)
 {
        App *app = &s_app;
        gint tmp = 0;
@@ -1660,7 +2110,7 @@ static void interpret(char *cmd)
                        tmp = atoi(cmd);
 
                        if (tmp <= 0 || tmp > INT_MAX) {
-                               g_print("Invalid value\n");
+                               g_print(";;Invalid value\n");
                                reset_menu_state();
                                break;
                        }
@@ -1695,14 +2145,34 @@ static void interpret(char *cmd)
                reset_menu_state();
        }
        break;
-       default:
-               break;
+       case CURRENT_STATUS_AUTO_TEST:
+       {
+               int len;
+               static int cnt = 0;
+               switch (cnt) {
+               case 0:
+                       len = strlen(cmd);
+                       strncpy(app->filepath, cmd, len + 1);
+                       g_print("%s, %d\n", app->filepath, len);
+                       cnt++;
+                       break;
+               case 1:
+                       app->is_video =  atoi(cmd) ? 1 : 0;
+                       _mediacodec_auto_test(app, app->filepath);
+                       reset_menu_state();
+                       cnt = 0;
+                       break;
+               default:
+                       break;
+               }
+       }
+       break;
        }
 
        g_timeout_add(100, timeout_menu_display, 0);
 }
 
-static void display_sub_basic()
+void display_sub_basic()
 {
        g_print("\n");
        g_print("=========================================================================================\n");
@@ -1725,6 +2195,7 @@ static void display_sub_basic()
        g_print("dp. enable dump \n");
        g_print("-----------------------------------------------------------------------------------------\n");
        g_print("cr. camera preview -> encoder -> decoder\n");
+       g_print("au. interlocking with mediademuxer\n");
        g_print("ct. quit camera test\n");
        g_print("\n");
        g_print("=========================================================================================\n");
@@ -1744,27 +2215,6 @@ gboolean input(GIOChannel *channel, GIOCondition cond, gpointer data)
        return TRUE;
 }
 
-int main(int argc, char *argv[])
-{
-       GIOChannel *stdin_channel;
-       stdin_channel = g_io_channel_unix_new(0);
-       g_io_channel_set_flags(stdin_channel, G_IO_FLAG_NONBLOCK, NULL);
-       g_io_add_watch(stdin_channel, G_IO_IN, (GIOFunc)input, NULL);
-
-       App *app = &s_app;
-
-       displaymenu();
-       app->loop = g_main_loop_new(NULL, TRUE);
-       app->timer = g_timer_new();
-       g_main_loop_run(app->loop);
-
-       ops.data = app;
-
-       return appcore_efl_main(PACKAGE, &argc, &argv, &ops);
-}
-
-
-
 void mc_hex_dump(char *desc, void *addr, gint len)
 {
        int i;
@@ -1799,7 +2249,7 @@ void mc_hex_dump(char *desc, void *addr, gint len)
        g_print("  %s\n", buff);
 }
 
-static void decoder_output_dump(App *app, media_packet_h pkt)
+void decoder_output_dump(App *app, media_packet_h pkt)
 {
        void *temp;
        int i = 0;
@@ -1886,7 +2336,7 @@ void add_adts_header_for_aacenc(App *app, char *buffer, int packetLen)
        buffer[6] = (char)0xFC;
 }
 
-static void output_dump(App *app, media_packet_h pkt)
+void output_dump(App *app, media_packet_h pkt)
 {
        void *temp;
        uint64_t buf_size;
@@ -1906,7 +2356,7 @@ static void output_dump(App *app, media_packet_h pkt)
                add_adts_header_for_aacenc(app, adts, (buf_size + ADTS_HEADER_SIZE));
                fwrite(&adts, 1, ADTS_HEADER_SIZE, fp);
                g_print("adts appended\n");
-       } else if (app->is_encoder && buf_size > 0 && app->codecid == MEDIACODEC_AMR_NB && write_amr_header == 1)       {
+       } else if (app->is_encoder && buf_size > 0 && app->codecid == MEDIACODEC_AMR_NB && write_amr_header == 1) {
                /* This is used only AMR encoder case for adding AMR masic header in only first frame */
                g_print("%s - AMR_header write in first frame\n", __func__);
                fwrite(&AMR_header[0], 1, sizeof(AMR_header)   - 1, fp);         /* AMR-NB magic number */
@@ -1982,5 +2432,24 @@ const char* codec_type_to_string(mediacodec_codec_type_e media_codec_id)
        default:
                return "NONE";
        }
+       return "NONE";
 }
 
+int main(int argc, char *argv[])
+{
+       GIOChannel *stdin_channel;
+       stdin_channel = g_io_channel_unix_new(0);
+       g_io_channel_set_flags(stdin_channel, G_IO_FLAG_NONBLOCK, NULL);
+       g_io_add_watch(stdin_channel, G_IO_IN, (GIOFunc)input, NULL);
+
+       App *app = &s_app;
+
+       displaymenu();
+       app->loop = g_main_loop_new(NULL, TRUE);
+       app->timer = g_timer_new();
+       g_main_loop_run(app->loop);
+
+       ops.data = app;
+
+       return appcore_efl_main(PACKAGE, &argc, &argv, &ops);
+}