Pointers changed to guint8 type in order to calculate offset properly
[platform/core/api/mediacodec.git] / test / media_codec_test.c
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <unistd.h>
19 #include <glib.h>
20 #include <Elementary.h>
21 #include <appcore-efl.h>
22 #include <gst/gst.h>
23 #include <limits.h>
24
25 #include <tbm_surface.h>
26 #include <dlog.h>
27 #include <time.h>
28 #include <media_codec.h>
29 #include <media_packet.h>
30 #include <media_packet_internal.h>
31 #include <media_packet_pool.h>
32 #include <media_codec_internal.h>
33 #ifdef TIZEN_FEATURE_INTEGRATION
34 #include <camera.h>
35 #include <mediademuxer.h>
36 #include <mediamuxer.h>
37 #endif
38
39 #define PACKAGE "media_codec_test"
40 #define MAX_HANDLE                      4
41 #define TEST_FILE_SIZE        (10 * 1024 * 1024)
42 #define MAX_STRING_LEN        256
43
44 #define DEFAULT_SAMPPLERATE   44100
45 #define DEFAULT_CHANNEL             2
46 #define DEFAULT_BIT                           16
47 #define DEFAULT_BITRATE       128
48 #define DEFAULT_SAMPLEBYTE        1024
49 #define ADTS_HEADER_SIZE      7
50 #define AMRNB_PCM_INPUT_SIZE      320
51 #define AMRWB_PCM_INPUT_SIZE      640
52
53 #define CHECK_BIT(x, y) (((x) >> (y)) & 0x01)
54 #define GET_IS_ENCODER(x) CHECK_BIT(x, 0)
55 #define GET_IS_DECODER(x) CHECK_BIT(x, 1)
56 #define GET_IS_HW(x) CHECK_BIT(x, 2)
57 #define ES_DEFAULT_VIDEO_PTS_OFFSET 33000000
58 #define CHECK_VALID_PACKET(state, expected_state) \
59         ((state & (expected_state)) == (expected_state))
60
61 #define AAC_CODECDATA_SIZE    16
62
63 guint8 buf_adts[ADTS_HEADER_SIZE];
64
65 enum {
66         MC_EXIST_SPS    = 1 << 0,
67         MC_EXIST_PPS    = 1 << 1,
68         MC_EXIST_IDR    = 1 << 2,
69         MC_EXIST_SLICE  = 1 << 3,
70
71         MC_VALID_HEADER = (MC_EXIST_SPS | MC_EXIST_PPS),
72         MC_VALID_FIRST_SLICE = (MC_EXIST_SPS | MC_EXIST_PPS | MC_EXIST_IDR)
73 };
74
75 typedef struct _App App;
76
77 enum {
78         CURRENT_STATUS_MAINMENU,
79         CURRENT_STATUS_FILENAME,
80         CURRENT_STATUS_CREATE,
81         CURRENT_STATUS_DESTROY,
82         CURRENT_STATUS_SET_CODEC,
83         CURRENT_STATUS_SET_VDEC_INFO,
84         CURRENT_STATUS_SET_VENC_INFO,
85         CURRENT_STATUS_SET_ADEC_INFO,
86         CURRENT_STATUS_SET_AENC_INFO,
87         CURRENT_STATUS_PREPARE,
88         CURRENT_STATUS_UNPREPARE,
89         CURRENT_STATUS_PROCESS_INPUT,
90         CURRENT_STATUS_GET_OUTPUT,
91         CURRENT_STATUS_RESET_OUTPUT_BUFFER,
92         CURRENT_STATUS_SET_SIZE,
93         CURRENT_STATUS_AUTO_TEST,
94 };
95
96 typedef enum {
97         NAL_SLICE_NO_PARTITIONING = 1,
98         NAL_SLICE_PART_A,
99         NAL_SLICE_PART_B,
100         NAL_SLICE_PART_C,
101         NAL_SLICE_IDR,
102         NAL_SEI,
103         NAL_SEQUENCE_PARAMETER_SET,
104         NAL_PICTURE_PARAMETER_SET,
105         NAL_PICTURE_DELIMITER,
106         NAL_END_OF_SEQUENCE,
107         NAL_END_OF_STREAM,
108         NAL_FILLER_DATA,
109         NAL_PREFIX_SVC = 14
110 } nal_unit_type;
111
112 typedef enum {
113         VIDEO_DEC,
114         VIDEO_ENC,
115         AUDIO_DEC,
116         AUDIO_ENC
117 } type_e;
118
119
120 struct _App {
121         GMainLoop *loop;
122         guint sourceid;
123         guint audio_id;
124         guint video_id;
125
126         GMappedFile *file;
127         guint8 *data;
128         gint length;
129         gint offset;
130         gint obj;
131
132         GTimer *timer;
133         glong start;
134         glong finish;
135         glong process_time;
136         gint frame_count;
137
138         gint codecid;
139         gint flag;
140         gboolean is_video;
141         gboolean is_encoder;
142         gboolean hardware;
143         gboolean enable_dump;
144         gboolean enable_muxer;
145         gint frame;
146         type_e type;
147
148 #ifdef TIZEN_FEATURE_INTEGRATION
149         camera_h camera_handle;
150         mediademuxer_h demuxer;
151         mediamuxer_h muxer;
152 #endif
153
154         GThread *thread;
155         GCond thread_cond;
156         GMutex thread_mutex;
157         GMutex eos_mutex;
158         GCond eos_cond;
159         GCond dst_eos_cond;
160         gint demux_eos;
161         gint codec_eos;
162         gint suspend;
163         gchar filepath[256];
164         /* demuxer */
165         media_format_h format[MAX_HANDLE];
166         /* video */
167         mediacodec_h mc_handle[MAX_HANDLE];
168         guint width;
169         guint height;
170         guint fps;
171         guint target_bits;
172         media_format_mimetype_e mime;
173         gint track;
174         gint video_track;
175
176         /* Audio */
177         guint samplerate;
178         guint channel;
179         guint bit;
180         guint bitrate;
181         gboolean is_amr_nb;
182         gint audio_track;
183
184         /* Render */
185         guint w;
186         guint h;
187         Evas_Object *win;
188         Evas_Object *img;
189         media_packet_h packet;
190         Ecore_Pipe *pipe;
191         GList *packet_list;
192         GMutex lock;
193
194         gint etb;
195         gint ftb;
196         gint ebd;
197         gint fbd;
198 };
199
200 App s_app;
201
202 media_format_h fmt = NULL;
203 media_packet_pool_h pkt_pool = NULL;
204
205 /* Internal Functions */
206 gint _create_app(void *data);
207 gint _terminate_app(void *data);
208 void displaymenu(void);
209 void display_sub_basic();
210
211 void _mediacodec_unprepare(App *app);
212 void _mediacodec_destroy(App *app);
213 void _mediacodec_auto_test(App *app, char *path);
214 void input_filepath(char *filename, App *app);
215 /* For debugging */
216 void mc_hex_dump(char *desc, void *addr, gint len);
217 void decoder_output_dump(App *app, media_packet_h pkt);
218 void output_dump(App *app, media_packet_h pkt);
219 /* */
220 const char* codec_type_to_string(mediacodec_codec_type_e media_codec_id);
221
222 void (*extractor)(App *app, guint8** data, gint *size, gboolean *have_frame, gboolean *codec_data);
223
224 gint g_menu_state = CURRENT_STATUS_MAINMENU;
225
226 gint _create_app(void *data)
227 {
228         g_print("My app is going alive!\n");
229         App *app = (App*)data;
230
231         g_mutex_init(&app->lock);
232         return 0;
233 }
234
235 gint _terminate_app(void *data)
236 {
237         g_print("My app is going gone!\n");
238         App *app = (App*)data;
239
240         g_mutex_clear(&app->lock);
241         return 0;
242 }
243
244
245 struct appcore_ops ops = {
246         .create = _create_app,
247         .terminate = _terminate_app,
248 };
249
250 static const guint mp3types_bitrates[2][3][16] = {
251         {
252                 {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448,},
253                 {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384,},
254                 {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320,}
255         },
256         {
257                 {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256,},
258                 {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,},
259                 {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,}
260         },
261 };
262
263 static const guint mp3types_freqs[3][3] = { {44100, 48000, 32000},
264         {22050, 24000, 16000},
265         {11025, 12000, 8000}
266 };
267
268 void h264_extractor(App *app, guint8 **data, gint *size, gboolean *have_frame, gboolean *codec_data)
269 {
270         guint8 val, zero_count;
271         guint8 *pNal = app->data + app->offset;
272         gint max = app->length - app->offset;
273         gint index = 0;
274         gint nal_unit_type = 0;
275         gboolean init;
276         gboolean slice;
277         gboolean idr;
278         static gint state;
279         gint read;
280
281         zero_count = 0;
282
283         val = pNal[index++];
284         while (!val) {
285                 zero_count++;
286                 val = pNal[index++];
287         }
288
289         zero_count = 0;
290
291         while (1) {
292                 if (index >= max) {
293                         read = (index - 1);
294                         goto DONE;
295                 }
296
297                 val = pNal[index++];
298
299                 if (!val)
300                         zero_count++;
301                 else {
302                         if ((zero_count >= 2) && (val == 1))
303                                 break;
304                         else
305                                 zero_count = 0;
306                 }
307         }
308
309         if (zero_count > 3)
310                 zero_count = 3;
311
312         read = (index - zero_count - 1);
313
314         nal_unit_type = *(app->data+app->offset+4) & 0x1F;
315         g_print("nal_unit_type : %x\n", nal_unit_type);
316
317         switch (nal_unit_type) {
318         case NAL_SEQUENCE_PARAMETER_SET:
319                 g_print("nal_unit_type : SPS\n");
320                 state |= MC_EXIST_SPS;
321                 break;
322         case NAL_PICTURE_PARAMETER_SET:
323                 g_print("nal_unit_type : PPS\n");
324                 state |= MC_EXIST_PPS;
325                 break;
326         case NAL_SLICE_IDR:
327         case NAL_SEI:
328                 g_print ("nal_unit_type : IDR\n");
329                 state |= MC_EXIST_IDR;
330                 break;
331         case NAL_SLICE_NO_PARTITIONING:
332         case NAL_SLICE_PART_A:
333         case NAL_SLICE_PART_B:
334         case NAL_SLICE_PART_C:
335                 state |= MC_EXIST_SLICE;
336                 break;
337         default:
338                 g_print ("nal_unit_type : %x", nal_unit_type);
339                 break;
340         }
341
342         init = CHECK_VALID_PACKET(state, MC_VALID_FIRST_SLICE) ? 1 : 0;
343         slice = CHECK_VALID_PACKET(state, MC_EXIST_SLICE) ? 1 : 0;
344         idr = CHECK_VALID_PACKET(state, MC_EXIST_IDR) ? 1 : 0;
345         g_print("status : %d, slice : %d, idr : %d\n", init, slice, idr);
346
347         if (init || idr || slice) {
348                 *have_frame = TRUE;
349                 if (init) {
350                         *data = app->data;
351                         *size = app->offset + read;
352                 } else {
353                         *data = app->data+app->offset;
354                         *size = read;
355                 }
356                 state = 0;
357         } else {
358                 *data = app->data+app->offset;
359                 *size = read;
360         }
361 DONE:
362         app->offset += read;
363 }
364
365 void h263_extractor(App * app, guint8 **data, gint *size, gboolean * have_frame, gboolean *codec_data)
366 {
367         int len = 0;
368         int read_size = 1, state = 1, bStart = 0;
369         guint8 val;
370         guint8 *pH263 = app->data + app->offset;
371         *data = pH263;
372         int max = app->length - app->offset;
373
374         while (1) {
375                 if (len >= max) {
376                         read_size = (len - 1);
377                         goto DONE;
378                 }
379                 val = pH263[len++];
380                 switch (state) {
381                 case 1:
382                         if (val == 0x00)
383                                 state++;
384                         break;
385                 case 2:
386                         if (val == 0x00)
387                                 state++;
388                         else
389                                 state = 1;
390                         break;
391                 case 3:
392                         state = 1;
393                         if ((val & 0xFC) == 0x80) {
394                                 if (bStart) {
395                                         read_size = len - 3;
396                                         goto DONE;
397                                 } else {
398                                         bStart = 1;
399                                 }
400                         }
401                         break;
402                 }
403         }
404  DONE:
405         *size = read_size;
406         app->offset += read_size;
407         *have_frame = TRUE;
408 }
409
410 void mpeg4_extractor(App * app, guint8 **data, gint *size, gboolean * have_frame, gboolean *codec_data)
411 {
412         int len = 0;
413         int result = 0;
414         int state = 1, bType = 0;
415         guint8 val;
416         guint8 *pMpeg4 = app->data + app->offset;
417         *data = pMpeg4;
418         int max = app->length - app->offset;
419
420         while (1) {
421                 if (len >= max) {
422                         result = (len - 1);
423                         goto DONE;
424                 }
425
426                 val = pMpeg4[len++];
427
428                 switch (state) {
429                 case 1:
430                         if (val == 0x00)
431                                 state++;
432                         break;
433                 case 2:
434                         if (val == 0x00)
435                                 state++;
436                         else
437                                 state = 1;
438                         break;
439                 case 3:
440                         if (val == 0x01)
441                                 state++;
442                         else
443                                 state = 1;
444                         break;
445                 case 4:
446                         state = 1;
447                         if (val == 0xB0 || val == 0xB6) {
448                                 if (bType == 0xB6) {
449                                         result = len - 4;
450                                         goto DONE;
451                                 }
452                                 if (!bType) {
453                                         if (val == 0xB0)
454                                                 *have_frame = TRUE;
455                                 }
456                                 bType = val;
457                         }
458                         break;
459                 }
460         }
461  DONE:
462         *size = result;
463         app->offset += result;
464         *have_frame = TRUE;
465 }
466
467 /**
468   * Extract Input data for AMR-NB/WB decoder
469   *  - AMR-NB  : mime type ("audio/AMR")          /   8Khz / 1 ch / 16 bits
470   *  - AMR-WB : mime type ("audio/AMR-WB")  / 16Khz / 1 ch / 16 bits
471   **/
472 gint write_amr_header = 1;                   /* write  magic number for AMR Header at one time */
473 static const gchar AMR_header[] = "#!AMR\n";
474 static const gchar AMRWB_header[] = "#!AMR-WB\n";
475 #define AMR_NB_MIME_HDR_SIZE          6
476 #define AMR_WB_MIME_HDR_SIZE          9
477 static const gint block_size_nb[16] = { 12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0 };
478 static const gint block_size_wb[16] = { 17, 23, 32, 36, 40, 46, 50, 58, 60, 5, -1, -1, -1, -1, 0, 0 };
479
480 gint *blocksize_tbl;
481 void amrdec_extractor(App * app, guint8 **data, gint *size, gboolean * have_frame, gboolean *codec_data)
482 {
483         gint readsize = 0, mode_temp;
484         gint fsize, mode;
485         guint8 *pAmr = app->data + app->offset;
486         /* change the below one to frame count */
487         if (app->offset == 0) {
488                 if (!memcmp(pAmr, AMR_header, AMR_NB_MIME_HDR_SIZE)) {
489                         blocksize_tbl = (int *)block_size_nb;
490                         mode_temp = pAmr[AMR_NB_MIME_HDR_SIZE];
491                         pAmr = pAmr + AMR_NB_MIME_HDR_SIZE;
492                         app->offset += AMR_NB_MIME_HDR_SIZE;
493                 } else {
494                         if (!memcmp(pAmr, AMRWB_header, AMR_WB_MIME_HDR_SIZE)) {
495                                 blocksize_tbl = (int *)block_size_wb;
496                                 mode_temp = pAmr[AMR_WB_MIME_HDR_SIZE];
497                                 pAmr = pAmr + AMR_WB_MIME_HDR_SIZE;
498                                 app->offset += AMR_WB_MIME_HDR_SIZE;
499                         } else {
500                                 g_print("[ERROR] AMR-NB/WB don't detected..\n");
501                                 return;
502                         }
503                 }
504         }
505         mode_temp = pAmr[0];
506         if ((mode_temp & 0x83) == 0) {
507                 mode = (mode_temp >> 3) & 0x0F; /* Yep. Retrieve the frame size */
508                 fsize = blocksize_tbl[mode];
509                 readsize = fsize + 1;
510         } else {
511                 readsize = 0;
512                 g_print("[FAIL] Not found amr frame sync.....\n");
513         }
514
515         *size = readsize;
516         app->offset += readsize;
517         *data = pAmr;
518         *have_frame = TRUE;
519 }
520
521 void nv12_extractor(App *app, guint8 **data, gint *size, gboolean *have_frame, gboolean *codec_data)
522 {
523         gint yuv_size;
524         gint offset = app->length - app->offset;
525
526         yuv_size = app->width * app->height * 3 / 2;
527
528         if (offset >= yuv_size)
529                 *size = offset;
530
531         *have_frame = TRUE;
532         *data = app->data + app->offset;
533
534         if (yuv_size >= offset)
535                 *size = offset;
536         else
537                 *size = yuv_size;
538
539         app->offset += *size;
540 }
541
542 void yuv_extractor(App *app, guint8 **data, int *size, gboolean *have_frame, gboolean *codec_data)
543 {
544         gint yuv_size;
545         gint offset = app->length - app->offset;
546
547         yuv_size = app->width * app->height * 3 / 2;
548
549         if (yuv_size >= offset)
550                 *size = offset;
551
552         *have_frame = TRUE;
553         *data = app->data + app->offset;
554
555         if (yuv_size >= offset)
556                 *size = offset;
557         else
558                 *size = yuv_size;
559
560         app->offset += *size;
561 }
562
563 void aacenc_extractor(App *app, guint8 **data, int *size, gboolean *have_frame, gboolean *codec_data)
564 {
565         gint read_size;
566         gint offset = app->length - app->offset;
567
568         read_size = ((DEFAULT_SAMPLEBYTE * app->channel)*(app->bit/8) * 2);
569
570         *have_frame = TRUE;
571         *data = app->data + app->offset;
572
573         if (read_size >= offset)
574                 *size = offset;
575         else
576                 *size = read_size;
577
578         app->offset += *size;
579 }
580
581 void amrenc_extractor(App *app, guint8 **data, int *size, gboolean *have_frame, gboolean *codec_data)
582 {
583         gint read_size;
584         gint offset = app->length - app->offset;
585
586         if (app->is_amr_nb)
587                 read_size = AMRNB_PCM_INPUT_SIZE;
588         else
589                 read_size = AMRWB_PCM_INPUT_SIZE;
590
591         *have_frame = TRUE;
592         *data = app->data + app->offset;
593
594         if (read_size >= offset)
595                 *size = offset;
596         else
597                 *size = read_size;
598
599         app->offset += *size;
600 }
601
602 /**
603  * Extract Input data for AAC decoder
604  * (case of (LC profile) ADTS format)
605  * codec_data : Don't need
606  **/
607 void aacdec_extractor(App *app, guint8 **data, int *size, gboolean *have_frame, gboolean *codec_data)
608 {
609         int read_size;
610         int offset = app->length - app->offset;
611         guint8 *pData = app->data + app->offset;
612
613         if ((pData != NULL) && (pData[0] == 0xff) && ((pData[1] & 0xf6) == 0xf0)) {
614                 read_size = ((pData[3] & 0x03) << 11) | (pData[4] << 3) | ((pData[5] & 0xe0) >> 5);
615         } else {
616                 read_size = 0;
617                 g_print("[FAIL] Not found aac frame sync.....\n");
618         }
619
620         *have_frame = TRUE;
621         *data = app->data + app->offset;
622
623         if (read_size >= offset)
624                 *size = offset;
625         else
626                 *size = read_size;
627
628         app->offset += *size;
629 }
630
631 void mp3dec_extractor(App *app, guint8 **data, int *size, gboolean *have_frame, gboolean *codec_data)
632 {
633         gint read_size;
634         guint header;
635         guint padding, bitrate, lsf = 0, layer = 0, mpg25 = 0;
636         guint hdr_bitrate = 0, sf = 0;
637         gint offset = app->length - app->offset;
638         guint8 *pData = app->data + app->offset;
639
640         header = GST_READ_UINT32_BE(pData);
641
642         if (header == 0) {
643                 g_print ("[ERROR] read header size is 0\n");
644                 *have_frame = FALSE;
645                 return;
646         }
647
648         /* if it's not a valid sync */
649         if ((header & 0xffe00000) != 0xffe00000) {
650                 g_print ("[ERROR] invalid sync\n");
651                 *have_frame = FALSE;
652                 return;
653         }
654
655         if (((header >> 19) & 3) == 0x1) {
656                 g_print ("[ERROR] invalid MPEG version: %d\n", (header >> 19) & 3);
657                 *have_frame = FALSE;
658                 return;
659         } else {
660                 if (header & (1 << 20)) {
661                         lsf = (header & (1 << 19)) ? 0 : 1;
662                         mpg25 = 0;
663                 } else {
664                         lsf = 1;
665                         mpg25 = 1;
666                 }
667         }
668
669         /* if it's an invalid layer */
670         if (!((header >> 17) & 3)) {
671                 g_print("[ERROR] invalid layer: %d\n", (header >> 17) & 3);
672                 *have_frame = FALSE;
673                 return;
674         } else {
675                 layer = 4 - ((header >> 17) & 0x3);
676         }
677
678         /* if it's an invalid bitrate */
679         if (((header >> 12) & 0xf) == 0xf) {
680                 g_print ("[ERROR] invalid bitrate: %d\n", (header >> 12) & 0xf);
681                 *have_frame = FALSE;
682                 return;
683         } else {
684                 bitrate = (header >> 12) & 0xF;
685                 hdr_bitrate = mp3types_bitrates[lsf][layer - 1][bitrate] * 1000;
686                 /* The caller has ensured we have a valid header, so bitrate can't be zero here. */
687                 if (hdr_bitrate == 0) {
688                         *have_frame = FALSE;
689                         return;
690                 }
691         }
692
693         /* if it's an invalid samplerate */
694         if (((header >> 10) & 0x3) == 0x3) {
695                 g_print ("[ERROR] invalid samplerate: %d\n", (header >> 10) & 0x3);
696                 *have_frame = FALSE;
697                 return;
698         } else {
699                 sf = (header >> 10) & 0x3;
700                 sf = mp3types_freqs[lsf + mpg25][sf];
701         }
702
703         padding = (header >> 9) & 0x1;
704
705         switch (layer) {
706         case 1:
707                 read_size = 4 * ((hdr_bitrate * 12) / sf + padding);
708                 break;
709         case 2:
710                 read_size = (hdr_bitrate * 144) / sf + padding;
711                 break;
712         default:
713         case 3:
714                 read_size = (hdr_bitrate * 144) / (sf << lsf) + padding;
715                 break;
716         }
717         g_print("header : %d, read : %d\n", header, read_size);
718
719         *have_frame = TRUE;
720         *data = app->data + app->offset;
721
722         if (read_size >= offset)
723                 *size = offset;
724         else
725                 *size = read_size;
726
727         app->offset += *size;
728 }
729
730 /**
731  * Extract Input data for AAC encoder
732  **/
733 /*
734    void aacenc_extractor(App *app, guint8 **data, int *size, gboolean *have_frame)
735    {
736    int read_size;
737    int offset = app->length - app->offset;
738
739    read_size = ((DEFAULT_SAMPLEBYTE*DEFAULT_CHANNEL)*(DEFAULT_BIT/8));
740
741    if (read_size >= offset)
742  *size = offset;
743
744  *have_frame = TRUE;
745  *data = app->data + app->offset;
746
747  if (read_size >= offset)
748  *size = offset;
749  else
750  *size = read_size;
751
752  app->offset += *size;
753  }
754  */
755 int  _configure(App *app, int codecid, int flag, gboolean *hardware, media_format_mimetype_e *codec_mime)
756 {
757         gboolean encoder;
758         media_format_mimetype_e mime = 0;
759         encoder = GET_IS_ENCODER(flag) ? 1 : 0;
760         *hardware = GET_IS_HW(flag) ? 1 : 0;
761         app->is_encoder = encoder;
762
763         switch (codecid) {
764         case MEDIACODEC_H264:
765                 if (encoder) {
766                         extractor = yuv_extractor;
767                         mime = *hardware ? MEDIA_FORMAT_NV12 : MEDIA_FORMAT_I420;
768                         *codec_mime = MEDIA_FORMAT_H264_SP;
769                 } else {
770                         extractor = h264_extractor;
771                         mime = MEDIA_FORMAT_H264_SP;
772                 }
773                 break;
774         case MEDIACODEC_MPEG4:
775                 if (encoder) {
776                         extractor = yuv_extractor;
777                         mime = *hardware ? MEDIA_FORMAT_NV12 : MEDIA_FORMAT_I420;
778                         *codec_mime = MEDIA_FORMAT_MPEG4_SP;
779                 } else {
780                         extractor = mpeg4_extractor;
781                         mime = MEDIA_FORMAT_MPEG4_SP;
782                 }
783                 break;
784         case MEDIACODEC_H263:
785                 if (encoder) {
786                         extractor = yuv_extractor;
787                         mime = *hardware ? MEDIA_FORMAT_NV12 : MEDIA_FORMAT_I420;
788                         *codec_mime = MEDIA_FORMAT_H263;
789                 } else {
790                         extractor = h263_extractor;
791                         mime = MEDIA_FORMAT_H263;
792                 }
793                 break;
794         case MEDIACODEC_AAC:
795                 if (encoder) {
796                         extractor = aacenc_extractor;
797                         mime = MEDIA_FORMAT_PCM_F32LE;  /* FIXME need to check according to verdor */
798                         *codec_mime = MEDIA_FORMAT_AAC;
799                 } else {
800                         extractor = aacdec_extractor;
801                         mime = MEDIA_FORMAT_AAC;
802                 }
803                 break;
804         case MEDIACODEC_AAC_HE:
805                 if (encoder) {
806                         extractor = aacenc_extractor;
807                         mime = MEDIA_FORMAT_PCM_F32LE;  /* FIXME need to check according to verdor */
808                         *codec_mime = MEDIA_FORMAT_AAC_HE;
809                 }
810                 break;
811         case MEDIACODEC_AAC_HE_PS:
812                 break;
813         case MEDIACODEC_MP3:
814                 extractor = mp3dec_extractor;
815                 mime = MEDIA_FORMAT_MP3;
816                 break;
817         case MEDIACODEC_VORBIS:
818                 break;
819         case MEDIACODEC_FLAC:
820                 break;
821         case MEDIACODEC_WMAV1:
822                 break;
823         case MEDIACODEC_WMAV2:
824                 break;
825         case MEDIACODEC_WMAPRO:
826                 break;
827         case MEDIACODEC_WMALSL:
828                 break;
829         case MEDIACODEC_AMR_NB:
830                 if (encoder) {
831                         extractor = amrenc_extractor;
832                         mime = MEDIA_FORMAT_PCM_F32LE;  /* FIXME need to check according to verdor */
833                         app->is_amr_nb = TRUE;
834                 } else {
835                         extractor = amrdec_extractor;
836                         mime = MEDIA_FORMAT_AMR_NB;
837                 }
838                 break;
839         case MEDIACODEC_AMR_WB:
840                 if (encoder) {
841                         extractor = amrenc_extractor;
842                         mime = MEDIA_FORMAT_PCM_F32LE;  /* FIXME need to check according to verdor */
843                         app->is_amr_nb = FALSE;
844                 } else {
845                         extractor = amrdec_extractor;
846                         mime = MEDIA_FORMAT_AMR_WB;
847                 }
848                 break;
849         default:
850                 LOGE("NOT SUPPORTED!!!!");
851                 break;
852         }
853         return mime;
854 }
855
856 void _mediacodec_process_input(App *app)
857 {
858         gint i, j;
859         gboolean have_frame = FALSE;
860         gint ret;
861         static guint64 pts = 0L;
862         guint8 *buf_data_ptr = NULL;
863         media_packet_h pkt = NULL;
864         guint8 *tmp;
865         gint read;
866         gint size;
867         gint offset;
868         gint stride_width;
869         gboolean codec_config = FALSE;
870
871         for (i = 0; i < app->frame; i++) {
872                 g_print("----------read data------------\n");
873
874                 extractor(app, &tmp, &read, &have_frame, &codec_config);
875
876                 if (have_frame) {
877 #ifdef USE_POOL
878                 if (media_packet_pool_acquire_packet(pkt_pool, &pkt, -1) != MEDIA_PACKET_ERROR_NONE) {
879                         g_print("media_packet_pool_aquire_packet failed\n");
880                         return;
881                 }
882 #else
883                 if (media_packet_create_alloc(fmt, NULL, NULL, &pkt) != MEDIA_PACKET_ERROR_NONE) {
884                         g_print("media_packet_create_alloc failed\n");
885                         return;
886                 }
887 #endif
888
889                         if (media_packet_set_pts(pkt, (uint64_t)(pts)) != MEDIA_PACKET_ERROR_NONE) {
890                                 g_print("media_packet_set_pts failed\n");
891                                 return;
892                         }
893
894                         if (app->type != VIDEO_ENC) {
895                                 media_packet_get_buffer_data_ptr(pkt, (void **)&buf_data_ptr);
896                                 media_packet_set_buffer_size(pkt, (uint64_t)read);
897                                 memcpy(buf_data_ptr, tmp, read);
898                                 g_print("tmp:%p, read:%d\n", tmp, read);
899                         } else {
900                                 /* Y */
901                                 media_packet_get_video_plane_data_ptr(pkt, 0, (void **)&buf_data_ptr);
902                                 media_packet_get_video_stride_width(pkt, 0, &stride_width);
903                                 offset = app->width*app->height;
904
905                                 for (j = 0; j < app->height; j++) {
906                                         memcpy(buf_data_ptr, tmp, app->width);
907                                         buf_data_ptr += stride_width;
908                                         tmp += app->width;
909                                 }
910
911                                 if (app->hardware == TRUE) {
912                                         media_packet_get_video_plane_data_ptr(pkt, 1, (void **)&buf_data_ptr);
913                                         media_packet_get_video_stride_width(pkt, 1, &stride_width);
914                                         size = app->width * app->height / 2;
915
916                                         for (j = 0; j < app->height / 2; j++) {
917                                                 memcpy(buf_data_ptr, tmp, app->width);
918                                                 buf_data_ptr += stride_width;
919                                                 tmp += app->width;
920                                         }
921                                 } else {
922                                         /* U */
923                                         media_packet_get_video_plane_data_ptr(pkt, 1, (void **)&buf_data_ptr);
924                                         media_packet_get_video_stride_width(pkt, 1, &stride_width);
925                                         size = (app->width>>1) * (app->height>>1);
926
927                                         for (j = 0; j < app->height/2; j++) {
928                                                 memcpy(buf_data_ptr, tmp, app->width/2);
929                                                 buf_data_ptr += stride_width;
930                                                 tmp += app->width/2;
931                                         }
932
933                                         /* V */
934                                         media_packet_get_video_plane_data_ptr(pkt, 2, (void **)&buf_data_ptr);
935                                         media_packet_get_video_stride_width(pkt, 2, &stride_width);
936                                         offset += size;
937
938                                         for (j = 0; j < app->height/2; j++) {
939                                                 memcpy(buf_data_ptr, tmp, app->width/2);
940                                                 buf_data_ptr += stride_width;
941                                                 tmp += app->width/2;
942                                         }
943
944                                 }
945                         }
946                         mc_hex_dump("inbuf", tmp, 48);
947
948                         ret = mediacodec_process_input(app->mc_handle[0], pkt, 1000);
949                         if (ret != MEDIACODEC_ERROR_NONE)
950                                 return;
951
952                         pts += ES_DEFAULT_VIDEO_PTS_OFFSET;
953                 }
954         }
955 }
956
957 gboolean read_data(App *app)
958 {
959         guint len = 0;
960         gboolean have_frame = FALSE;
961         gboolean codec_config = FALSE;
962         gint ret;
963         static guint64 pts = 0L;
964         guint8 *buf_data_ptr = NULL;
965         media_packet_h pkt = NULL;
966         guint8 *tmp;
967         gint i;
968         gint read;
969         gint size;
970         gint offset;
971         gint stride_width;
972
973         if (app->offset == 0) {
974                 app->frame_count = 0;
975                 app->start = clock();
976         }
977
978         g_print("----------read data------------\n");
979         extractor(app, &tmp, &read, &have_frame, &codec_config);
980
981         if (app->offset >= app->length - 4) {
982                 /* EOS */
983                 g_print("EOS\n");
984                 app->finish = clock();
985                 g_print("Average FPS = %3.3f\n", ((double)app->frame_count*1000000/(app->finish - app->start)));
986                 g_print("---------------------------\n");
987                 return FALSE;
988         }
989         g_print("length : %d, offset : %d\n", app->length, app->offset);
990
991         if (app->offset + len > app->length)
992                 len = app->length - app->offset;
993
994         g_print("%p, %d, have_frame :%d, read: %d\n", tmp, (int)read, have_frame, read);
995
996         if (have_frame) {
997 #ifdef USE_POOL
998                 if (media_packet_pool_acquire_packet(pkt_pool, &pkt, -1) != MEDIA_PACKET_ERROR_NONE) {
999                         g_print("media_packet_pool_aquire_packet failed\n");
1000                         return FALSE;
1001                 }
1002 #else
1003                 if (media_packet_create_alloc(fmt, NULL, NULL, &pkt) != MEDIA_PACKET_ERROR_NONE) {
1004                         g_print("media_packet_create_alloc failed\n");
1005                         return FALSE;
1006                 }
1007 #endif
1008                 if (media_packet_set_pts(pkt, (uint64_t)(pts)) != MEDIA_PACKET_ERROR_NONE) {
1009                         g_print("media_packet_set_pts failed\n");
1010                         return FALSE;
1011                 }
1012
1013
1014                 if (app->type != VIDEO_ENC) {
1015                         media_packet_get_buffer_data_ptr(pkt, (void **)&buf_data_ptr);
1016                         media_packet_set_buffer_size(pkt, (uint64_t)read);
1017
1018                         memcpy(buf_data_ptr, tmp, read);
1019                         g_print("tmp:%p, read:%d\n", tmp, read);
1020                 } else {
1021                         /* Y */
1022                         media_packet_get_video_plane_data_ptr(pkt, 0, (void **)&buf_data_ptr);
1023                         media_packet_get_video_stride_width(pkt, 0, &stride_width);
1024                         offset = app->width*app->height;
1025
1026                         for (i = 0; i < app->height; i++) {
1027                                 memcpy(buf_data_ptr, tmp, app->width);
1028                                 buf_data_ptr += stride_width;
1029                                 tmp += app->width;
1030                         }
1031
1032                         if (app->hardware == TRUE) {
1033                                 media_packet_get_video_plane_data_ptr(pkt, 1, (void **)&buf_data_ptr);
1034                                 media_packet_get_video_stride_width(pkt, 1, &stride_width);
1035                                 size = app->width * app->height>>1;
1036
1037                                 for (i = 0; i < app->height>>1; i++) {
1038                                         memcpy(buf_data_ptr, tmp, app->width);
1039                                         buf_data_ptr += stride_width;
1040                                         tmp += app->width;
1041                                 }
1042
1043                         } else {
1044                                 /* U */
1045                                 media_packet_get_video_plane_data_ptr(pkt, 1, (void **)&buf_data_ptr);
1046                                 media_packet_get_video_stride_width(pkt, 1, &stride_width);
1047                                 size = (app->width>>1) * (app->height>>1);
1048
1049                                 for (i = 0; i < app->height/2; i++) {
1050                                         memcpy(buf_data_ptr, tmp, app->width>>1);
1051                                         buf_data_ptr += stride_width;
1052                                         tmp += (app->width>>1);
1053                                 }
1054
1055                                 /* V */
1056                                 media_packet_get_video_plane_data_ptr(pkt, 2, (void **)&buf_data_ptr);
1057                                 media_packet_get_video_stride_width(pkt, 2, &stride_width);
1058                                 offset += size;
1059
1060                                 for (i = 0; i < app->height/2; i++) {
1061                                         memcpy(buf_data_ptr, tmp, app->width>>1);
1062                                         buf_data_ptr += stride_width;
1063                                         tmp += (app->width>>1);
1064                                 }
1065
1066                         }
1067                 }
1068                 mc_hex_dump("inbuf", tmp, 48);
1069
1070                 ret = mediacodec_process_input(app->mc_handle[0], pkt, 0);
1071                 if (ret != MEDIACODEC_ERROR_NONE)
1072                         return FALSE;
1073
1074                 pts += ES_DEFAULT_VIDEO_PTS_OFFSET;
1075         }
1076
1077         return TRUE;
1078 }
1079
1080 void av_feed_suspend(App *app)
1081 {
1082         g_mutex_lock(&app->thread_mutex);
1083         app->suspend = 1;
1084         g_print("suspend thread\n");
1085         g_mutex_unlock(&app->thread_mutex);
1086 }
1087
1088 void av_feed_resume(App *app)
1089 {
1090         g_mutex_lock(&app->thread_mutex);
1091         app->suspend = 0;
1092         g_print("resume thread\n");
1093         g_cond_broadcast(&app->thread_cond);
1094         g_mutex_unlock(&app->thread_mutex);
1095 }
1096
1097 #ifdef TIZEN_FEATURE_INTEGRATION
1098 gpointer av_feed_thread(gpointer data)
1099 {
1100         App *app = (App *)data;
1101         int ret = 0;
1102         gint track = -1;
1103
1104         media_packet_h packet = NULL;
1105         track = app->audio_track;
1106
1107         while (1) {
1108                 g_mutex_lock(&app->thread_mutex);
1109
1110                 while (app->suspend != 0) g_cond_wait(&app->thread_cond, &app->thread_mutex);
1111
1112                 g_mutex_unlock(&app->thread_mutex);
1113
1114                 if (app->demux_eos == 1) {
1115                         g_print("got eos!!!\n");
1116                         break;
1117                 }
1118
1119                 ret = mediademuxer_read_sample(app->demuxer, track, &packet);
1120                 if (ret != MEDIACODEC_ERROR_NONE)
1121                         return NULL;
1122
1123                 ret = mediacodec_process_input(app->mc_handle[track], packet, 0);
1124                 if (ret != MEDIACODEC_ERROR_NONE)
1125                         return NULL;
1126
1127                 app->etb++;
1128
1129         }
1130
1131         return NULL;
1132 }
1133
1134 gboolean feed_audio(App *app)
1135 {
1136         gint ret = 0;
1137         gint track = -1;
1138
1139         media_packet_h packet = NULL;
1140         track = app->audio_track;
1141
1142         g_print("read audio sample!!!\n");
1143         ret = mediademuxer_read_sample(app->demuxer, track, &packet);
1144         if (ret != MEDIACODEC_ERROR_NONE)
1145                 return FALSE;
1146
1147         ret = mediacodec_process_input(app->mc_handle[track], packet, 0);
1148         if (ret != MEDIACODEC_ERROR_NONE)
1149                 return FALSE;
1150
1151         return TRUE;
1152 }
1153
1154 gboolean feed_video(App *app)
1155 {
1156         gint ret = 0;
1157         gint track = -1;
1158
1159         media_packet_h packet = NULL;
1160         track = app->video_track;
1161
1162         g_print("read video sample!!!\n");
1163         ret = mediademuxer_read_sample(app->demuxer, track, &packet);
1164         if (ret != MEDIACODEC_ERROR_NONE)
1165                 return FALSE;
1166
1167         ret = mediacodec_process_input(app->mc_handle[track], packet, 0);
1168         if (ret != MEDIACODEC_ERROR_NONE)
1169                 return FALSE;
1170
1171         return TRUE;
1172 }
1173 #endif
1174
1175 void start_feed(App *app)
1176 {
1177         if (app->sourceid == 0) {
1178                 app->sourceid = g_idle_add((GSourceFunc)read_data, app);
1179                 g_print("start_feed\n");
1180         }
1181 }
1182
1183 void stop_feed(App *app)
1184 {
1185         if (app->sourceid != 0) {
1186                 g_source_remove(app->sourceid);
1187                 app->sourceid = 0;
1188                 g_print("stop_feed\n");
1189         }
1190 }
1191
1192 void _mediacodec_inbuf_used_cb(media_packet_h pkt, void *user_data)
1193 {
1194         App *app = (App *)user_data;
1195
1196         g_print("_mediacodec_inbuf_used_cb!!!\n");
1197 #ifdef USE_POOL
1198         media_packet_pool_release_packet(pkt_pool, pkt);
1199 #else
1200         media_packet_destroy(pkt);
1201 #endif
1202         app->ebd++;
1203
1204         return;
1205 }
1206
1207 void _audio_outbuf_available_cb(media_packet_h pkt, void *user_data)
1208 {
1209         media_packet_h out_pkt = NULL;
1210         int ret;
1211
1212         App *app = (App*)user_data;
1213
1214         g_print("_audio_outbuf_available_cb\n");
1215
1216         g_mutex_lock(&app->lock);
1217
1218         ret = mediacodec_get_output(app->mc_handle[app->audio_track], &out_pkt, 0);
1219
1220         if (ret != MEDIACODEC_ERROR_NONE)
1221                 g_print("get_output failed\n");
1222
1223         if (app->enable_dump)
1224                 output_dump(app, out_pkt);
1225
1226         app->frame_count++;
1227         app->fbd++;
1228
1229
1230         g_mutex_unlock(&app->lock);
1231
1232         media_packet_destroy(out_pkt);
1233         out_pkt = NULL;
1234         g_print("done\n");
1235
1236         return;
1237 }
1238
1239 void _video_outbuf_available_cb(media_packet_h pkt, void *user_data)
1240 {
1241         media_packet_h out_pkt = NULL;
1242         int ret;
1243
1244         App *app = (App*)user_data;
1245
1246         g_print("_video_outbuf_available_cb\n");
1247
1248         g_mutex_lock(&app->lock);
1249
1250         ret = mediacodec_get_output(app->mc_handle[app->video_track], &out_pkt, 0);
1251
1252         if (ret != MEDIACODEC_ERROR_NONE)
1253                 g_print("get_output failed\n");
1254
1255         if (app->enable_dump)
1256                 decoder_output_dump(app, out_pkt);
1257
1258         app->frame_count++;
1259         app->fbd++;
1260
1261
1262         g_mutex_unlock(&app->lock);
1263
1264         media_packet_destroy(out_pkt);
1265         out_pkt = NULL;
1266         g_print("done\n");
1267
1268         return;
1269 }
1270
1271 void _mediacodec_outbuf_available_cb(media_packet_h pkt, void *user_data)
1272 {
1273         media_packet_h out_pkt = NULL;
1274         int ret;
1275
1276         App *app = (App*)user_data;
1277
1278         g_print("_mediacodec_outbuf_available_cb\n");
1279
1280         g_mutex_lock(&app->lock);
1281
1282         ret = mediacodec_get_output(app->mc_handle[0], &out_pkt, 0);
1283
1284         if (ret != MEDIACODEC_ERROR_NONE)
1285                 g_print("get_output failed\n");
1286
1287         if (app->enable_dump) {
1288                 if (app->type == VIDEO_DEC)
1289                         decoder_output_dump(app, out_pkt);
1290                 else
1291                         output_dump(app, out_pkt);
1292         }
1293 #ifdef TIZEN_FEATURE_INTEGRATION
1294         if (app->enable_muxer) {
1295                 if (mediamuxer_write_sample(app->muxer, app->track, out_pkt) != MEDIAMUXER_ERROR_NONE)
1296                         g_print("mediamuxer_write_sample failed\n");
1297                 g_print("write sample!!!\n");
1298         }
1299 #endif
1300         app->frame_count++;
1301         app->fbd++;
1302
1303
1304         g_mutex_unlock(&app->lock);
1305
1306         media_packet_destroy(out_pkt);
1307         out_pkt = NULL;
1308         g_print("done\n");
1309
1310         return;
1311 }
1312
1313 void _mediacodec_buffer_status_cb(mediacodec_status_e status, void *user_data)
1314 {
1315         g_print("_mediacodec_buffer_status_cb %d\n", status);
1316
1317         App *app = (App*)user_data;
1318
1319         if (status == MEDIACODEC_NEED_DATA)
1320                 start_feed(app);
1321         else if (status == MEDIACODEC_ENOUGH_DATA)
1322                 stop_feed(app);
1323
1324         return;
1325 }
1326
1327 void _av_buffer_status_cb(mediacodec_status_e status, void *user_data)
1328 {
1329         g_print("_av_buffer_status_cb %d\n", status);
1330
1331         App *app = (App*)user_data;
1332
1333         if (status == MEDIACODEC_NEED_DATA)
1334                 av_feed_resume(app);
1335         else if (status == MEDIACODEC_ENOUGH_DATA)
1336                 av_feed_suspend(app);
1337
1338         return;
1339 }
1340
1341 void _mediacodec_error_cb(mediacodec_error_e error, void *user_data)
1342 {
1343         return;
1344 }
1345
1346
1347 void _mediacodec_eos_cb(void *user_data)
1348 {
1349         App *app = (App *)user_data;
1350
1351         g_print("mediacodec eos\n");
1352         g_mutex_lock(&app->eos_mutex);
1353         app->codec_eos = 1;
1354         g_mutex_unlock(&app->eos_mutex);
1355         g_cond_broadcast(&app->dst_eos_cond);
1356         return;
1357 }
1358
1359 #ifdef TIZEN_FEATURE_INTEGRATION
1360 void demuxer_error_cb(mediademuxer_error_e error, void *user_data)
1361 {
1362         g_print("Got Error %d from Mediademuxer\n", error);
1363         return;
1364 }
1365
1366 void _mediademuxer_eos_cb(int track, void *user_data)
1367 {
1368         App *app = (App *)user_data;
1369
1370         g_print("eos track : %d\n", track);
1371         av_feed_suspend(app);
1372         g_print("suspended\n");
1373         app->demux_eos = 1;
1374         av_feed_resume(app);
1375         g_cond_broadcast(&app->eos_cond);
1376
1377         return;
1378 }
1379
1380 void _mediamuxer_eos_cb(void *user_data)
1381 {
1382         if (user_data == NULL) {
1383                 g_print("invalid param");
1384                 return;
1385         }
1386
1387         App *app = (App *)user_data;
1388
1389         g_print("muxer eos\n");
1390
1391         if (mediamuxer_stop(app->muxer) != MEDIAMUXER_ERROR_NONE)
1392                 g_print(" mediamuxer_stop failed\n");
1393
1394         if (mediamuxer_unprepare(app->muxer) != MEDIAMUXER_ERROR_NONE)
1395                 g_print(" mediamuxer_unprepare failed\n");
1396
1397         if (mediamuxer_destroy(app->muxer) != MEDIAMUXER_ERROR_NONE)
1398                 g_print(" mediamuxer_destory failed\n");
1399
1400         g_print("mediamuxer destroyed\n");
1401 }
1402 #endif
1403
1404 gboolean  _foreach_cb(mediacodec_codec_type_e codec_type, void *user_data)
1405 {
1406         g_print("codec type : %x %s\n", codec_type, codec_type_to_string(codec_type));
1407         return TRUE;
1408 }
1409
1410 void _mediacodec_prepare(App *app, gboolean frame_all)
1411 {
1412         int ret;
1413         media_format_mimetype_e codec_mime;
1414         media_format_h codec_format;
1415
1416         g_print("supported codec lists -internal-\n");
1417         mediacodec_foreach_supported_codec_static((mediacodec_supported_codec_cb)_foreach_cb, app);
1418
1419         /* create instance */
1420         ret = mediacodec_create(&app->mc_handle[0]);
1421         if (ret  != MEDIACODEC_ERROR_NONE) {
1422                 g_print("mediacodec_create  failed\n");
1423                 return;
1424         }
1425 #if 0
1426         /* set codec */
1427         ret = mediacodec_set_codec(app->mc_handle[0], app->codecid, app->flag);
1428         if (ret  != MEDIACODEC_ERROR_NONE) {
1429                 g_print("mediacodec_set_codec failed\n");
1430                 return;
1431         }
1432 #endif
1433         /* get mime and link to each codec parser */
1434         app->mime = _configure(app, app->codecid, app->flag, &app->hardware, &codec_mime);
1435
1436         /* set codec info */
1437         ret = media_format_create(&fmt);
1438
1439         switch (app->type) {
1440         case VIDEO_DEC:
1441                 media_format_set_video_mime(fmt, app->mime);
1442                 media_format_set_video_width(fmt, app->width);
1443                 media_format_set_video_height(fmt, app->height);
1444
1445                 ret = mediacodec_configure_from_media_format(app->mc_handle[0], fmt, app->flag);
1446                 if (ret  != MEDIACODEC_ERROR_NONE)
1447                         g_print("mediacodec_configure failed\n");
1448                 break;
1449         case VIDEO_ENC:
1450                 media_format_set_video_mime(fmt, app->mime);
1451                 media_format_set_video_width(fmt, app->width);
1452                 media_format_set_video_height(fmt, app->height);
1453                 media_format_set_video_avg_bps(fmt, app->target_bits);
1454
1455                 media_format_create(&codec_format);
1456                 media_format_set_video_mime(codec_format, codec_mime);
1457                 media_format_set_video_width(codec_format, app->width);
1458                 media_format_set_video_height(codec_format, app->height);
1459                 media_format_set_video_avg_bps(codec_format, app->target_bits);
1460                 media_format_set_video_frame_rate(codec_format, app->fps);
1461
1462                 ret = mediacodec_configure_from_media_format(app->mc_handle[0], codec_format, app->flag);
1463                 if (ret  != MEDIACODEC_ERROR_NONE)
1464                         g_print("mediacodec_configure failed\n");
1465                 media_format_unref(codec_format);
1466                 break;
1467         case AUDIO_DEC:
1468                 media_format_set_audio_mime(fmt, app->mime);
1469                 media_format_set_audio_channel(fmt, app->channel);
1470                 media_format_set_audio_samplerate(fmt, app->samplerate);
1471                 media_format_set_audio_bit(fmt, app->bit);
1472
1473                 ret = mediacodec_configure_from_media_format(app->mc_handle[0], fmt, app->flag);
1474                 if (ret  != MEDIACODEC_ERROR_NONE)
1475                         g_print("mediacodec_configure failed\n");
1476                 break;
1477         case AUDIO_ENC:
1478                 media_format_set_audio_mime(fmt, app->mime);
1479                 media_format_set_audio_channel(fmt, app->channel);
1480                 media_format_set_audio_samplerate(fmt, app->samplerate);
1481                 media_format_set_audio_bit(fmt, app->bit);
1482
1483                 media_format_create(&codec_format);
1484                 media_format_set_audio_mime(codec_format, codec_mime);
1485                 media_format_set_audio_channel(codec_format, app->channel);
1486                 media_format_set_audio_samplerate(codec_format, app->samplerate);
1487                 media_format_set_audio_bit(codec_format, app->bit);
1488                 media_format_set_audio_avg_bps(codec_format, app->bitrate);
1489
1490                 ret = mediacodec_configure_from_media_format(app->mc_handle[0], codec_format, app->flag);
1491                 if (ret  != MEDIACODEC_ERROR_NONE)
1492                         g_print("mediacodec_set_configure failed\n");
1493                 media_format_unref(codec_format);
1494                 break;
1495         default:
1496                 g_print("invaild type\n");
1497                 break;
1498         }
1499
1500         if (ret  != MEDIACODEC_ERROR_NONE) {
1501                 g_print("mediacodec_set_xxxc(%d)_info failed\n", app->type);
1502                 return;
1503         }
1504
1505         /* set callback */
1506         g_print("supported codec lists\n");
1507         mediacodec_foreach_supported_codec(app->mc_handle[0], (mediacodec_supported_codec_cb)_foreach_cb, app);
1508         mediacodec_set_input_buffer_used_cb(app->mc_handle[0], (mediacodec_input_buffer_used_cb)_mediacodec_inbuf_used_cb, app);
1509         mediacodec_set_output_buffer_available_cb(app->mc_handle[0], (mediacodec_output_buffer_available_cb) _mediacodec_outbuf_available_cb, app);
1510         if (frame_all)
1511                 mediacodec_set_buffer_status_cb(app->mc_handle[0], (mediacodec_buffer_status_cb) _mediacodec_buffer_status_cb, app);
1512         mediacodec_set_eos_cb(app->mc_handle[0], (mediacodec_eos_cb)_mediacodec_eos_cb, app);
1513         mediacodec_set_error_cb(app->mc_handle[0], (mediacodec_error_cb)_mediacodec_error_cb, NULL);
1514
1515         /* prepare */
1516         ret = mediacodec_prepare(app->mc_handle[0]);
1517         if (ret  != MEDIACODEC_ERROR_NONE) {
1518                 g_print("mediacodec_prepare failed\n");
1519                 return;
1520         }
1521
1522 #ifdef TIZEN_FEATURE_INTEGRATION
1523         if (app->enable_muxer) {
1524                 if (mediamuxer_create(&app->muxer) != MEDIAMUXER_ERROR_NONE)
1525                         g_print("mediamuxer_create failed\n");
1526
1527                 if (mediamuxer_set_data_sink(app->muxer, "/tmp/muxtest.mp4", MEDIAMUXER_CONTAINER_FORMAT_MP4) != MEDIAMUXER_ERROR_NONE)
1528                         g_print("mediamuxer_set_data_sink failed\n");
1529
1530                 media_format_create(&app->format[0]);
1531                 if (app->type == AUDIO_ENC)
1532                         media_format_set_audio_mime(app->format[0], codec_mime);
1533                 else if (app->type == VIDEO_ENC)
1534                         media_format_set_video_mime(app->format[0], codec_mime);
1535                 else
1536                         g_print("invalid format\n");
1537
1538                 if (mediamuxer_set_eos_cb(app->muxer, _mediamuxer_eos_cb, app) != MEDIAMUXER_ERROR_NONE)
1539                         g_print("mediamuxer_set_eos_cb failed\n");
1540
1541                 if (mediamuxer_add_track(app->muxer, app->format[0], &app->track) != MEDIAMUXER_ERROR_NONE)
1542                         g_print("mediamuxer_add_track failed\n");
1543
1544                 if (mediamuxer_prepare(app->muxer) != MEDIAMUXER_ERROR_NONE)
1545                         g_print("mediamuxer_prepare failed\n");
1546
1547                 if (mediamuxer_start(app->muxer) != MEDIAMUXER_ERROR_NONE)
1548                         g_print("mediamuxer_start failed\n");
1549         }
1550 #endif
1551
1552
1553         /* get packet pool instance */
1554         ret = mediacodec_get_packet_pool(app->mc_handle[0], &pkt_pool);
1555         if (ret != MEDIA_PACKET_ERROR_NONE) {
1556                 g_print("mediacodec_get_packet_pool failed\n");
1557                 return;
1558         }
1559         g_print("\n\nmediacodec start\n\n");
1560
1561         return;
1562 }
1563
1564 void _mediacodec_enc_input_buffer_used_cb(media_packet_h pkt, void *user_data)
1565 {
1566         /* release input raw packet */
1567         media_packet_destroy(pkt);
1568 }
1569
1570 /* this callback is called when the input buffer for codec has done to use */
1571 void _mediacodec_dec_input_buffer_used_cb(media_packet_h pkt, void *user_data)
1572 {
1573         /* release input encoded packet */
1574         media_packet_destroy(pkt);
1575 }
1576
1577 void _mediacodec_enc_output_buffer_available_cb(media_packet_h pkt, void *user_data)
1578 {
1579         App *app = (App*)user_data;
1580
1581         mediacodec_h media_codec_handle = app->mc_handle[1];
1582         media_packet_h output_buf = NULL;
1583         mediacodec_get_output(media_codec_handle, &output_buf, 0);
1584         /* decode encoded camera preview */
1585         mediacodec_process_input(app->mc_handle[0], output_buf, 0);
1586 }
1587
1588 void _mediacodec_dec_output_buffer_available_cb(media_packet_h pkt, void *user_data)
1589 {
1590         App *app = (App*)user_data;
1591
1592         mediacodec_h media_codec_handle = app->mc_handle[0];
1593         media_packet_h output_buf = NULL;
1594
1595         mediacodec_get_output(media_codec_handle, &output_buf, 0);
1596
1597         if (app->enable_dump)
1598                 decoder_output_dump(app, output_buf);
1599
1600         media_packet_destroy(output_buf);
1601 }
1602
1603 void _media_packet_preview_cb(media_packet_h packet, void *user_data)
1604 {
1605         App *app = user_data;
1606         g_mutex_lock(&app->lock);
1607         mediacodec_process_input(app->mc_handle[1], packet, 0);
1608         g_mutex_unlock(&app->lock);
1609
1610         return;
1611 }
1612
1613 #ifdef TIZEN_FEATURE_INTEGRATION
1614 void _mediacodec_camera_start(App *app)
1615 {
1616         int default_format = CAMERA_PIXEL_FORMAT_NV12;
1617         app->width = 640;
1618         app->height = 480;
1619         app->hardware = TRUE;
1620
1621         /*create decoder instance and setup */
1622         mediacodec_create(&app->mc_handle[0]);
1623         mediacodec_set_codec(app->mc_handle[0], MEDIACODEC_H264, MEDIACODEC_DECODER | MEDIACODEC_SUPPORT_TYPE_HW);
1624         mediacodec_set_vdec_info(app->mc_handle[0], app->width, app->height);
1625         /* set callback */
1626         mediacodec_set_input_buffer_used_cb(app->mc_handle[0], _mediacodec_dec_input_buffer_used_cb, NULL);
1627         mediacodec_set_output_buffer_available_cb(app->mc_handle[0], _mediacodec_dec_output_buffer_available_cb, app);
1628         mediacodec_prepare(app->mc_handle[0]);
1629
1630         /*create encoder instance and setup */
1631         mediacodec_create(&app->mc_handle[1]);
1632         mediacodec_set_codec(app->mc_handle[1], MEDIACODEC_H264, MEDIACODEC_ENCODER | MEDIACODEC_SUPPORT_TYPE_HW);
1633         mediacodec_set_venc_info(app->mc_handle[1], app->width, app->height, 30, 1000);
1634         /* set callback */
1635         mediacodec_set_input_buffer_used_cb(app->mc_handle[1], _mediacodec_enc_input_buffer_used_cb, NULL);
1636         mediacodec_set_output_buffer_available_cb(app->mc_handle[1], _mediacodec_enc_output_buffer_available_cb, app);
1637         mediacodec_prepare(app->mc_handle[1]);
1638
1639         /* create camera instance and setup and then start preview */
1640         camera_create(CAMERA_DEVICE_CAMERA0, &app->camera_handle);
1641         camera_set_media_packet_preview_cb(app->camera_handle, _media_packet_preview_cb, app);
1642         camera_get_preview_format(app->camera_handle, &default_format);
1643         camera_set_preview_format(app->camera_handle, default_format);
1644         camera_set_preview_resolution(app->camera_handle, app->width, app->height);
1645         camera_set_display(app->camera_handle, CAMERA_DISPLAY_TYPE_NONE, NULL);
1646         camera_start_preview(app->camera_handle);
1647
1648         return;
1649 }
1650
1651
1652 void _mediacodec_camera_stop(App *app)
1653 {
1654         camera_state_e camera_state = CAMERA_STATE_NONE;
1655
1656         camera_get_state(app->camera_handle, &camera_state);
1657         camera_stop_preview(app->camera_handle);
1658         camera_destroy(app->camera_handle);
1659
1660         mediacodec_unprepare(app->mc_handle[0]);
1661         mediacodec_unprepare(app->mc_handle[1]);
1662         mediacodec_destroy(app->mc_handle[0]);
1663         mediacodec_destroy(app->mc_handle[1]);
1664         return;
1665 }
1666 #endif
1667
1668 #ifdef TIZEN_FEATURE_INTEGRATION
1669 void _mediacodec_auto_test(App *app, char *path)
1670 {
1671         gint ret = 0;
1672         gint num_tracks = 0;
1673         gint track = 0;
1674         gint width = 0;
1675         gint height = 0;
1676         gint channel = 0;
1677         gint samplerate = 0;
1678         gint bit = 0;
1679         media_format_type_e formattype;
1680         media_format_mimetype_e video_mime;
1681         media_format_mimetype_e audio_mime;
1682         gint codec_mask = 0xFFF0;
1683         gint codec_id;
1684         app->demux_eos = 0;
1685         app->codec_eos = 0;
1686         app->etb = 0;
1687         app->ebd = 0;
1688         app->ftb = 0;
1689         app->fbd = 0;
1690
1691         ret = mediademuxer_create(&app->demuxer);
1692         if (ret != MEDIACODEC_ERROR_NONE) {
1693                 g_print("failed to create demuxer\n");
1694                 return;
1695         }
1696
1697         ret = mediademuxer_set_data_source(app->demuxer, path);
1698         if (ret != MEDIACODEC_ERROR_NONE) {
1699                 g_print("failed to mediademuxer_set_data_source\n");
1700                 return;
1701         }
1702
1703         ret = mediademuxer_set_error_cb(app->demuxer, demuxer_error_cb, app->demuxer);
1704         if (ret != MEDIACODEC_ERROR_NONE) {
1705                 g_print("failed to mediademuxer_set_error_cb\n");
1706                 return;
1707         }
1708
1709         mediademuxer_set_eos_cb(app->demuxer, _mediademuxer_eos_cb, app);
1710
1711         ret = mediademuxer_prepare(app->demuxer);
1712         if (ret != MEDIACODEC_ERROR_NONE) {
1713                 g_print("failed to prepare\n");
1714                 return;
1715         }
1716
1717
1718         ret = mediademuxer_get_track_count(app->demuxer, &num_tracks);
1719         if (ret != MEDIACODEC_ERROR_NONE) {
1720                 g_print("failed to get track\n");
1721                 return;
1722         }
1723
1724         for (track = 0; track < num_tracks; track++) {
1725                 ret = mediademuxer_get_track_info(app->demuxer, track, &app->format[track]);
1726                 if (ret != MEDIACODEC_ERROR_NONE) {
1727                         g_print("failed to get track info\n");
1728                         return;
1729                 }
1730
1731                 media_format_get_type(app->format[track], &formattype);
1732
1733                 if (!app->is_video && formattype == MEDIA_FORMAT_AUDIO) {
1734                         app->audio_track = track;
1735                         app->type = AUDIO_DEC;
1736                         media_format_get_audio_info(app->format[track], &audio_mime, &channel, &samplerate, &bit, NULL);
1737
1738                         mediademuxer_select_track(app->demuxer, track);
1739
1740                         ret = mediacodec_create(&app->mc_handle[track]);
1741                         if (ret != MEDIACODEC_ERROR_NONE) {
1742                                 g_print("failed to create mediacocec\n");
1743                                 return;
1744                         }
1745
1746                         codec_id = audio_mime & codec_mask;
1747                         g_print("auido codec_id : %x\n", codec_id);
1748
1749                         ret = mediacodec_set_codec(app->mc_handle[track], codec_id, MEDIACODEC_DECODER | MEDIACODEC_SUPPORT_TYPE_SW);
1750                         if (ret != MEDIACODEC_ERROR_NONE) {
1751                                 g_print("failed to set codec\n");
1752                                 return;
1753                         }
1754
1755                         ret = mediacodec_set_adec_info(app->mc_handle[track], samplerate, channel, bit);
1756                         if (ret != MEDIACODEC_ERROR_NONE) {
1757                                 g_print("failed to set adec info\n");
1758                                 return;
1759                         }
1760
1761                         mediacodec_set_buffer_status_cb(app->mc_handle[track], _av_buffer_status_cb, app);
1762                         mediacodec_set_input_buffer_used_cb(app->mc_handle[track], _mediacodec_inbuf_used_cb, app);
1763                         mediacodec_set_output_buffer_available_cb(app->mc_handle[track], _audio_outbuf_available_cb, app);
1764                         mediacodec_set_eos_cb(app->mc_handle[track], _mediacodec_eos_cb, app);
1765                         mediacodec_set_error_cb(app->mc_handle[track], _mediacodec_error_cb, NULL);
1766
1767                 } else if (app->is_video && formattype == MEDIA_FORMAT_VIDEO) {
1768                         app->video_track = track;
1769                         app->type = VIDEO_DEC;
1770                         media_format_get_video_info(app->format[track], &video_mime, &width, &height, NULL, NULL);
1771
1772                         mediademuxer_select_track(app->demuxer, track);
1773
1774                         ret = mediacodec_create(&app->mc_handle[track]);
1775                         if (ret != MEDIACODEC_ERROR_NONE) {
1776                                 g_print("failed to create mediacocec\n");
1777                                 return;
1778                         }
1779
1780                         app->width = width;
1781                         app->height = height;
1782
1783                         codec_id = video_mime & codec_mask;
1784                         g_print("video codec_id : %x\n", codec_id);
1785
1786                         ret = mediacodec_set_codec(app->mc_handle[track], codec_id, MEDIACODEC_DECODER | MEDIACODEC_SUPPORT_TYPE_HW);
1787                         if (ret != MEDIACODEC_ERROR_NONE) {
1788                                 g_print("failed to set codec\n");
1789                                 return;
1790                         }
1791
1792                         ret = mediacodec_set_vdec_info(app->mc_handle[track], width, height);
1793                         if (ret != MEDIACODEC_ERROR_NONE) {
1794                                 g_print("failed to set vdec info\n");
1795                                 return;
1796                         }
1797
1798                         mediacodec_set_buffer_status_cb(app->mc_handle[track], _av_buffer_status_cb, app);
1799                         mediacodec_set_input_buffer_used_cb(app->mc_handle[track], _mediacodec_inbuf_used_cb, app);
1800                         mediacodec_set_output_buffer_available_cb(app->mc_handle[track], _video_outbuf_available_cb, app);
1801                         mediacodec_set_eos_cb(app->mc_handle[track], _mediacodec_eos_cb, app);
1802                         mediacodec_set_error_cb(app->mc_handle[track], _mediacodec_error_cb, NULL);
1803                 }
1804         }
1805
1806         ret = mediademuxer_start(app->demuxer);
1807         if (ret != MEDIACODEC_ERROR_NONE) {
1808                 g_print("failed to start mediademuxer\n");
1809                 return;
1810         }
1811
1812         track = app->is_video ? app->video_track : app->audio_track;
1813         ret = mediacodec_prepare(app->mc_handle[track]);
1814         if (ret != MEDIACODEC_ERROR_NONE) {
1815                 g_print("failed to prepare mediacodec\n");
1816                 return;
1817         }
1818
1819         g_cond_init(&app->thread_cond);
1820         g_cond_init(&app->eos_cond);
1821         g_cond_init(&app->dst_eos_cond);
1822         g_mutex_init(&app->thread_mutex);
1823         g_mutex_init(&app->eos_mutex);
1824
1825         app->thread = g_thread_new("feed thread", &av_feed_thread, app);
1826         app->start = clock();
1827
1828         g_mutex_lock(&app->eos_mutex);
1829         while (app->codec_eos != 1) g_cond_wait(&app->dst_eos_cond, &app->eos_mutex);
1830         g_mutex_unlock(&app->eos_mutex);
1831         g_print("now try to destroy thread!!\n");
1832         g_thread_join(app->thread);
1833         app->finish = clock();
1834
1835         ret = mediademuxer_stop(app->demuxer);
1836         if (ret != MEDIACODEC_ERROR_NONE) {
1837                 g_print("failed to stop mediademuxer\n");
1838                 return;
1839         }
1840
1841         ret = mediademuxer_unselect_track(app->demuxer, track);
1842         if (ret != MEDIACODEC_ERROR_NONE) {
1843                 g_print("failed to unselect mediademuxer\n");
1844                 return;
1845         }
1846
1847         ret = mediacodec_unprepare(app->mc_handle[track]);
1848         if (ret != MEDIACODEC_ERROR_NONE) {
1849                 g_print("failed to unprepare mediacodec\n");
1850                 return;
1851         }
1852
1853         ret = mediacodec_destroy(app->mc_handle[track]);
1854         if (ret != MEDIACODEC_ERROR_NONE) {
1855                 g_print("failed to destroy mediacodec\n");
1856                 return;
1857         }
1858
1859         ret = mediademuxer_unprepare(app->demuxer);
1860         if (ret != MEDIACODEC_ERROR_NONE) {
1861                 g_print("failed to unprepare mediademuxer\n");
1862                 return;
1863         }
1864
1865         ret = mediademuxer_destroy(app->demuxer);
1866         if (ret != MEDIACODEC_ERROR_NONE) {
1867                 g_print("failed to destroy mediademuxer\n");
1868                 return;
1869         }
1870
1871         g_cond_clear(&app->thread_cond);
1872         g_cond_clear(&app->eos_cond);
1873         g_cond_clear(&app->dst_eos_cond);
1874         g_mutex_clear(&app->thread_mutex);
1875         g_mutex_clear(&app->eos_mutex);
1876
1877         g_print("resources are released!!!\n\n\n");
1878         g_print("-----------------------------------------------------\n");
1879         g_print("Input - queued packets : %d, finalized packets : %d\n", app->etb, app->ebd);
1880         g_print("Output - queued packets : %d, finalized packets : %d\n", app->fbd, app->fbd);
1881         g_print("Average FPS = %3.3f\n", ((double)app->fbd*1000000/(app->finish - app->start)));
1882         g_print("-----------------------------------------------------\n");
1883
1884         return;
1885 }
1886 #endif
1887
1888 void _mediacodec_unprepare(App *app)
1889 {
1890         mediacodec_unprepare(app->mc_handle[0]);
1891 }
1892
1893 void _mediacodec_destroy(App *app)
1894 {
1895         if (app == NULL) {
1896                 g_print("invalid param");
1897                 return;
1898         }
1899 #ifdef USE_POOL
1900         if (media_packet_pool_deallocate(pkt_pool) != MEDIA_PACKET_ERROR_NONE) {
1901
1902                 g_print("media_packet_pool_deallocatet failed\n");
1903                 return;
1904         }
1905
1906         if (media_packet_pool_destroy(pkt_pool) != MEDIA_PACKET_ERROR_NONE) {
1907
1908                 g_print(" media_packet_pool_destroy failed\n");
1909                 return;
1910         }
1911         g_print("media packet pool destroyed! \n");
1912 #endif
1913         mediacodec_destroy(app->mc_handle[0]);
1914 #ifdef TIZEN_FEATURE_INTEGRATION
1915         if (app->enable_muxer) {
1916                 if (mediamuxer_close_track(app->muxer, app->track) != MEDIAMUXER_ERROR_NONE)
1917                         g_print("mediamuxer_close_track failed\n");
1918         }
1919 #endif
1920 }
1921
1922 void input_filepath(char *filename, App *app)
1923 {
1924         GError *error = NULL;
1925
1926         app->obj++;
1927         app->file = g_mapped_file_new(filename, FALSE, &error);
1928         if (error) {
1929                 g_print("failed to open file : %s\n", error->message);
1930                 g_error_free(error);
1931                 return;
1932         }
1933
1934         app->length = g_mapped_file_get_length(app->file);
1935         app->data = (guint8 *)g_mapped_file_get_contents(app->file);
1936         app->offset = 0;
1937         g_print("len : %d, offset : %d, obj : %d", app->length, app->offset, app->obj);
1938
1939         return;
1940 }
1941
1942 void quit_program(App *app)
1943 {
1944                 media_format_unref(fmt);
1945                 g_main_loop_quit(app->loop);
1946                 exit(0);
1947 }
1948
1949 void reset_menu_state()
1950 {
1951         g_menu_state = CURRENT_STATUS_MAINMENU;
1952         return;
1953 }
1954
1955 void _interpret_main_menu(char *cmd, App *app)
1956 {
1957         gint len =  strlen(cmd);
1958         if (len == 1) {
1959                 if (strncmp(cmd, "a", 1) == 0)
1960                         g_menu_state = CURRENT_STATUS_FILENAME;
1961                 else if (strncmp(cmd, "o", 1) == 0)
1962                         g_menu_state = CURRENT_STATUS_GET_OUTPUT;
1963                 else if (strncmp(cmd, "q", 1) == 0)
1964                         quit_program(app);
1965                 else
1966                         g_print("unknown menu \n");
1967         } else if (len == 2) {
1968                 if (strncmp(cmd, "pr", 2) == 0)
1969                         _mediacodec_prepare(app, 0);
1970                 else if (strncmp(cmd, "pa", 2) == 0)
1971                         _mediacodec_prepare(app, 1);
1972                 else if (strncmp(cmd, "sc", 2) == 0)
1973                         g_menu_state = CURRENT_STATUS_SET_CODEC;
1974                 else if (strncmp(cmd, "vd", 2) == 0)
1975                         g_menu_state = CURRENT_STATUS_SET_VDEC_INFO;
1976                 else if (strncmp(cmd, "ve", 2) == 0)
1977                         g_menu_state = CURRENT_STATUS_SET_VENC_INFO;
1978                 else if (strncmp(cmd, "ad", 2) == 0)
1979                         g_menu_state = CURRENT_STATUS_SET_ADEC_INFO;
1980                 else if (strncmp(cmd, "ae", 2) == 0)
1981                         g_menu_state = CURRENT_STATUS_SET_AENC_INFO;
1982                 else if (strncmp(cmd, "pi", 2) == 0)
1983                         g_menu_state = CURRENT_STATUS_PROCESS_INPUT;
1984                 else if (strncmp(cmd, "un", 2) == 0)
1985                         _mediacodec_unprepare(app);
1986                 else if (strncmp(cmd, "dt", 2) == 0)
1987                         _mediacodec_destroy(app);
1988 #ifdef TIZEN_FEATURE_INTEGRATION
1989                 else if (strncmp(cmd, "cr", 2) == 0)
1990                         _mediacodec_camera_start(app);
1991                 else if (strncmp(cmd, "ct", 2) == 0)
1992                         _mediacodec_camera_stop(app);
1993                 else if (strncmp(cmd, "au", 2) == 0)
1994                         g_menu_state = CURRENT_STATUS_AUTO_TEST;
1995                 else if (strncmp(cmd, "mp", 2) == 0) {
1996                         if (!app->enable_muxer) {
1997                                 app->enable_muxer = TRUE;
1998                                 g_print("muxer enabled\n");
1999                         } else {
2000                                 app->enable_dump = FALSE;
2001                                 g_print("dump disabled\n");
2002                         }
2003                 }
2004 #endif
2005                 else if (strncmp(cmd, "dp", 2) == 0) {
2006                         if (!app->enable_dump) {
2007                                 app->enable_dump = TRUE;
2008                                 g_print("dump enabled\n");
2009                         } else {
2010                                 app->enable_dump = FALSE;
2011                                 g_print("dump disabled\n");
2012                         }
2013                 } else
2014                         display_sub_basic();
2015         } else {
2016                 g_print("unknown menu \n");
2017         }
2018
2019         return;
2020 }
2021
2022 void displaymenu(void)
2023 {
2024         if (g_menu_state == CURRENT_STATUS_MAINMENU) {
2025                 display_sub_basic();
2026         } else if (g_menu_state == CURRENT_STATUS_FILENAME) {
2027                 g_print("*** input mediapath.\n");
2028         } else if (g_menu_state == CURRENT_STATUS_SET_CODEC) {
2029                 g_print("*** Codec id : Select Codec ID Numbe  (e.g. AAC_LC = 96)\n");
2030                 g_print("               L16    =  16 (0x10)\n");
2031                 g_print("               ALAW   =  32 (0x20)\n");
2032                 g_print("               ULAW   =  48 (0x30)\n");
2033                 g_print("               AMR_NB =  64 (0x40)\n");
2034                 g_print("               AMR_WB =  65 (0x41)\n");
2035                 g_print("               G729   =  80 (0x50)\n");
2036                 g_print("               AAC_LC =  96 (0x60)\n");
2037                 g_print("               AAC_HE =  97 (0x61)\n");
2038                 g_print("               AAC_PS =  98 (0x62)\n");
2039                 g_print("               MP3    = 112 (0x70)\n");
2040                 g_print("               VORBIS = 128 (0x80)\n");
2041                 g_print("               FLAC   = 144 (0x90)\n");
2042                 g_print("               WMAV1  = 160 (0xA0)\n");
2043                 g_print("               WMAV2  = 161 (0xA1)\n");
2044                 g_print("               WMAPRO = 162 (0xA2)\n");
2045                 g_print("               WMALSL = 163 (0xA3)\n");
2046                 g_print("               -------------------\n");
2047                 g_print("               H261   = 101\n");
2048                 g_print("               H263   = 102\n");
2049                 g_print("               H264   = 103\n");
2050                 g_print("               MJPEG  = 104\n");
2051                 g_print("               MPEG1  = 105\n");
2052                 g_print("               MPEG2  = 106\n");
2053                 g_print("               MPEG4  = 107\n");
2054                 g_print("               -------------------\n");
2055                 g_print("*** Flags : Select Combination Number (e.g. DEOCDER + TYPE_SW = 10)\n");
2056                 g_print("               CODEC : ENCODER =  1       DECODER =  2\n");
2057                 g_print("               TYPE  : HW      =  4       SW      =  8\n");
2058                 g_print("*** input codec id, falgs.\n");
2059         } else if (g_menu_state == CURRENT_STATUS_SET_VDEC_INFO) {
2060                 g_print("*** input video decode configure.(width, height)\n");
2061         } else if (g_menu_state == CURRENT_STATUS_SET_VENC_INFO) {
2062                 g_print("*** input video encode configure.(width, height, fps, target_bits)\n");
2063         } else if (g_menu_state == CURRENT_STATUS_SET_ADEC_INFO) {
2064                 g_print("*** input audio decode configure.(samplerate, channel, bit (e.g. 48000,  2, 16))\n");
2065         } else if (g_menu_state == CURRENT_STATUS_SET_AENC_INFO) {
2066                 g_print("*** input audio encode configure.(samplerate, channel, bit, bitrate (e.g. 48000,  2, 16, 128000))\n");
2067         } else if (g_menu_state == CURRENT_STATUS_PROCESS_INPUT) {
2068                 g_print("*** input dec process number\n");
2069         } else if (g_menu_state == CURRENT_STATUS_GET_OUTPUT) {
2070                 g_print("*** input get output buffer number\n");
2071 #ifdef TIZEN_FEATURE_INTEGRATION
2072         } else if (g_menu_state == CURRENT_STATUS_AUTO_TEST) {
2073                 g_print("*** enter media path and select the track to decode (0 : audio, 1 : video).\n");
2074 #endif
2075         } else {
2076                 g_print("*** unknown status.\n");
2077         }
2078         g_print(" >>> ");
2079 }
2080
2081 gboolean timeout_menu_display(void* data)
2082 {
2083         displaymenu();
2084         return FALSE;
2085 }
2086
2087 void interpret(char *cmd)
2088 {
2089         App *app = &s_app;
2090         gint tmp = 0;
2091
2092         switch (g_menu_state) {
2093         case CURRENT_STATUS_MAINMENU:
2094                 _interpret_main_menu(cmd, app);
2095                 break;
2096         case CURRENT_STATUS_FILENAME:
2097                 input_filepath(cmd, app);
2098                 reset_menu_state();
2099                 break;
2100         case CURRENT_STATUS_SET_CODEC:
2101         {
2102                 static gint cnt = 0;
2103                 gchar **ptr = NULL;
2104                 switch (cnt) {
2105                 case 0:
2106                         tmp = atoi(cmd);
2107
2108                         if (tmp > 100 &&
2109                                 (tmp != 112) &&
2110                                 (tmp != 128) &&
2111                                 (tmp != 144) &&
2112                                 (tmp != 160) && (tmp != 161) && (tmp != 162) && (tmp != 163)) {
2113                                         tmp = strtol(cmd, ptr, 16);
2114                                         app->codecid = 0x2000 + ((tmp & 0xFF) << 4);
2115                         } else
2116                                 app->codecid = 0x1000 + tmp;
2117
2118                         cnt++;
2119                         break;
2120                 case 1:
2121                         app->flag = atoi(cmd);
2122                         cnt = 0;
2123                         reset_menu_state();
2124                         break;
2125                 default:
2126                         break;
2127                 }
2128         }
2129         break;
2130         case CURRENT_STATUS_SET_VDEC_INFO:
2131         {
2132                 static gint cnt = 0;
2133                 switch (cnt) {
2134                 case 0:
2135                         app->width = atoi(cmd);
2136                         cnt++;
2137                         break;
2138                 case 1:
2139                         app->height = atoi(cmd);
2140                         app->type = VIDEO_DEC;
2141
2142                         reset_menu_state();
2143                         cnt = 0;
2144                         break;
2145                 default:
2146                         break;
2147                 }
2148         }
2149         break;
2150         case CURRENT_STATUS_SET_VENC_INFO:
2151         {
2152                 static gint cnt = 0;
2153                 switch (cnt) {
2154                 case 0:
2155                         app->width = atoi(cmd);
2156                         cnt++;
2157                         break;
2158                 case 1:
2159                         app->height = atoi(cmd);
2160                         cnt++;
2161                         break;
2162                 case 2:
2163                         app->fps = atol(cmd);
2164                         cnt++;
2165                         break;
2166                 case 3:
2167                         app->target_bits = atoi(cmd);
2168                         app->type = VIDEO_ENC;
2169
2170                         reset_menu_state();
2171                         cnt = 0;
2172                         break;
2173                 default:
2174                         break;
2175                 }
2176         }
2177         break;
2178         case CURRENT_STATUS_SET_ADEC_INFO:
2179         {
2180                 static gint cnt = 0;
2181                 switch (cnt) {
2182                 case 0:
2183                         app->samplerate = atoi(cmd);
2184                         cnt++;
2185                         break;
2186                 case 1:
2187                         app->channel = atoi(cmd);
2188                         cnt++;
2189                         break;
2190                 case 2:
2191                         app->bit = atoi(cmd);
2192                         app->type = AUDIO_DEC;
2193
2194                         reset_menu_state();
2195                         cnt = 0;
2196                         break;
2197                 default:
2198                         break;
2199                 }
2200         }
2201         break;
2202         case CURRENT_STATUS_SET_AENC_INFO:
2203         {
2204                 static int cnt = 0;
2205                 switch (cnt) {
2206                 case 0:
2207                         tmp = atoi(cmd);
2208
2209                         if (tmp <= 0 || tmp > 96000) {
2210                                 g_print("Invalid value\n");
2211                                 reset_menu_state();
2212                                 break;
2213                         }
2214                         app->samplerate = tmp;
2215                         cnt++;
2216                         break;
2217                 case 1:
2218                         tmp = atoi(cmd);
2219
2220                         if (tmp <= 0 || tmp > 6) {
2221                                 g_print("Invalid value\n");
2222                                 reset_menu_state();
2223                                 break;
2224                         }
2225                         app->channel = tmp;
2226                         cnt++;
2227                         break;
2228                 case 2:
2229                         tmp = atoi(cmd);
2230
2231                         if (tmp <= 0 || tmp > 32) {
2232                                 g_print("Invalid value\n");
2233                                 reset_menu_state();
2234                                 break;
2235                         }
2236                         app->bit = tmp;
2237                         cnt++;
2238                         break;
2239                 case 3:
2240                         tmp = atoi(cmd);
2241
2242                         if (tmp <= 0 || tmp >= INT_MAX) {
2243                                 g_print(";;Invalid value\n");
2244                                 reset_menu_state();
2245                                 break;
2246                         }
2247                         app->type = AUDIO_ENC;
2248                         app->bitrate = tmp;
2249
2250                         reset_menu_state();
2251                         cnt = 0;
2252                         break;
2253                 default:
2254                         break;
2255                 }
2256         }
2257         break;
2258         case CURRENT_STATUS_PROCESS_INPUT:
2259         {
2260                 tmp = atoi(cmd);
2261
2262                 if (tmp <= 0 || tmp >= 10) {
2263                         g_print("Invalid value\n");
2264                         reset_menu_state();
2265                         break;
2266                 }
2267                 app->frame = tmp;
2268
2269                 _mediacodec_process_input(app);
2270                 reset_menu_state();
2271         }
2272         break;
2273         case CURRENT_STATUS_GET_OUTPUT:
2274         {
2275                 reset_menu_state();
2276         }
2277         break;
2278 #ifdef TIZEN_FEATURE_INTEGRATION
2279         case CURRENT_STATUS_AUTO_TEST:
2280         {
2281                 int len;
2282                 static int cnt = 0;
2283                 switch (cnt) {
2284                 case 0:
2285                         len = strlen(cmd);
2286                         strncpy(app->filepath, cmd, len + 1);
2287                         g_print("%s, %d\n", app->filepath, len);
2288                         cnt++;
2289                         break;
2290                 case 1:
2291                         app->is_video =  atoi(cmd) ? 1 : 0;
2292                         _mediacodec_auto_test(app, app->filepath);
2293                         reset_menu_state();
2294                         cnt = 0;
2295                         break;
2296                 default:
2297                         break;
2298                 }
2299         }
2300         break;
2301 #endif
2302         }
2303
2304         g_timeout_add(100, timeout_menu_display, 0);
2305 }
2306
2307 void display_sub_basic()
2308 {
2309         g_print("\n");
2310         g_print("=========================================================================================\n");
2311         g_print("                                    media codec test\n");
2312         g_print("-----------------------------------------------------------------------------------------\n");
2313         g_print("a. Create \t\t");
2314         g_print("sc. Set codec \n");
2315         g_print("vd. Set vdec info \t");
2316         g_print("ve. Set venc info \n");
2317         g_print("ad. Set adec info \t");
2318         g_print("ae. Set aenc info \n");
2319         g_print("pr. Prepare \t");
2320         g_print("pa. Prepare and process all\t\t");
2321         g_print("pi. process input with num\n");
2322         g_print("o. Get output \t\t");
2323         g_print("rb. Reset output buffer \n");
2324         g_print("un. Unprepare \t\t");
2325         g_print("dt. Destroy \t\t");
2326         g_print("q. quit test suite \n");
2327         g_print("dp. enable dump \n");
2328 #ifdef TIZEN_FEATURE_INTEGRATION
2329         g_print("mp. enable muxer \n");
2330         g_print("-----------------------------------------------------------------------------------------\n");
2331         g_print("cr. camera preview -> encoder -> decoder\n");
2332         g_print("au. integration test with mediademuxer\n");
2333         g_print("ct. quit camera test\n");
2334 #endif
2335         g_print("\n");
2336         g_print("=========================================================================================\n");
2337 }
2338
2339 gboolean input(GIOChannel *channel, GIOCondition cond, gpointer data)
2340 {
2341         gchar buf[MAX_STRING_LEN];
2342         gsize read;
2343         GError *error = NULL;
2344
2345         g_io_channel_read_chars(channel, buf, MAX_STRING_LEN, &read, &error);
2346         buf[read] = '\0';
2347         g_strstrip(buf);
2348         interpret(buf);
2349
2350         return TRUE;
2351 }
2352
2353 void mc_hex_dump(char *desc, void *addr, gint len)
2354 {
2355         int i;
2356         guint8 buff[17];
2357         guint8 *pc = (guint8 *)addr;
2358
2359         if (desc != NULL)
2360                 g_print("%s:\n", desc);
2361
2362         for (i = 0; i < len; i++) {
2363
2364                 if ((i % 16) == 0) {
2365                         if (i != 0)
2366                                 g_print("  %s\n", buff);
2367
2368                         g_print("  %04x ", i);
2369                 }
2370
2371                 g_print(" %02x", pc[i]);
2372
2373                 if ((pc[i] < 0x20) || (pc[i] > 0x7e))
2374                         buff[i % 16] = '.';
2375                 else
2376                         buff[i % 16] = pc[i];
2377                 buff[(i % 16) + 1] = '\0';
2378         }
2379
2380         while ((i % 16) != 0) {
2381                 g_print("   ");
2382                 i++;
2383         }
2384         g_print("  %s\n", buff);
2385 }
2386
2387 void decoder_output_dump(App *app, media_packet_h pkt)
2388 {
2389         guint8 *temp;
2390         int i = 0;
2391         int stride_width, stride_height;
2392         gchar filename[100] = {0};
2393         FILE *fp = NULL;
2394         int ret = 0;
2395
2396         g_snprintf(filename, MAX_STRING_LEN, "/tmp/dec_output_dump_%d_%d.yuv", app->width, app->height);
2397         fp = fopen(filename, "ab");
2398
2399         media_packet_get_video_plane_data_ptr(pkt, 0, (void **)&temp);
2400         media_packet_get_video_stride_width(pkt, 0, &stride_width);
2401         media_packet_get_video_stride_height(pkt, 0, &stride_height);
2402         g_print("stride : %d, %d\n", stride_width, stride_height);
2403
2404         for (i = 0; i < app->height; i++) {
2405                 ret = fwrite(temp, app->width, 1, fp);
2406                 temp += stride_width;
2407         }
2408
2409         if (app->hardware == TRUE) {
2410                 media_packet_get_video_plane_data_ptr(pkt, 1, (void **)&temp);
2411                 media_packet_get_video_stride_width(pkt, 1, &stride_width);
2412                 for (i = 0; i < app->height/2; i++) {
2413                         ret = fwrite(temp, app->width, 1, fp);
2414                         temp += stride_width;
2415                 }
2416         } else {
2417                 media_packet_get_video_plane_data_ptr(pkt, 1, (void **)&temp);
2418                 media_packet_get_video_stride_width(pkt, 1, &stride_width);
2419                 for (i = 0; i < app->height/2; i++) {
2420                         ret = fwrite(temp, app->width/2, 1, fp);
2421                         temp += stride_width;
2422                 }
2423
2424                 media_packet_get_video_plane_data_ptr(pkt, 2, (void **)&temp);
2425                 media_packet_get_video_stride_width(pkt, 2, &stride_width);
2426                 for (i = 0; i < app->height/2; i++) {
2427                         ret = fwrite(temp, app->width/2, 1, fp);
2428                         temp += stride_width;
2429                 }
2430         }
2431
2432         g_print("codec dec output dumped!!%d\n", ret);
2433         fclose(fp);
2434
2435 }
2436
2437 /**
2438  *  Add ADTS header at the beginning of each and every AAC packet.
2439  *  This is needed as MediaCodec encoder generates a packet of raw AAC data.
2440  *  Note the packetLen must count in the ADTS header itself.
2441  **/
2442 void add_adts_header_for_aacenc(App *app, char *buffer, int packetLen)
2443 {
2444         int profile = 2;    /* AAC LC (0x01) */
2445         int freqIdx = 3;    /* 48KHz (0x03) */
2446         int chanCfg = 2;    /* CPE (0x02) */
2447
2448         if (app->samplerate == 96000) freqIdx = 0;
2449         else if (app->samplerate == 88200) freqIdx = 1;
2450         else if (app->samplerate == 64000) freqIdx = 2;
2451         else if (app->samplerate == 48000) freqIdx = 3;
2452         else if (app->samplerate == 44100) freqIdx = 4;
2453         else if (app->samplerate == 32000) freqIdx = 5;
2454         else if (app->samplerate == 24000) freqIdx = 6;
2455         else if (app->samplerate == 22050) freqIdx = 7;
2456         else if (app->samplerate == 16000) freqIdx = 8;
2457         else if (app->samplerate == 12000) freqIdx = 9;
2458         else if (app->samplerate == 11025) freqIdx = 10;
2459         else if (app->samplerate == 8000) freqIdx = 11;
2460
2461         if ((app->channel == 1) || (app->channel == 2))
2462                 chanCfg = app->channel;
2463
2464         /* fill in ADTS data */
2465         buffer[0] = (char)0xFF;
2466         buffer[1] = (char)0xF1;
2467         buffer[2] = (char)(((profile-1)<<6) + (freqIdx<<2) +(chanCfg>>2));
2468         buffer[3] = (char)(((chanCfg&3)<<6) + (packetLen>>11));
2469         buffer[4] = (char)((packetLen&0x7FF) >> 3);
2470         buffer[5] = (char)(((packetLen&7)<<5) + 0x1F);
2471         buffer[6] = (char)0xFC;
2472 }
2473
2474 void output_dump(App *app, media_packet_h pkt)
2475 {
2476         void *temp;
2477         uint64_t buf_size;
2478         gchar filename[100] = {0};
2479         FILE *fp = NULL;
2480         int ret = 0;
2481         char adts[100] = {0, };
2482
2483         g_snprintf(filename, MAX_STRING_LEN, "/tmp/dec_output_dump_%d.out", app->type);
2484         fp = fopen(filename, "ab");
2485
2486         media_packet_get_buffer_data_ptr(pkt, &temp);
2487         media_packet_get_buffer_size(pkt, &buf_size);
2488         g_print("output data : %p, size %d\n", temp, (int)buf_size);
2489
2490         if (app->is_encoder && buf_size > 0 && app->codecid == MEDIACODEC_AAC_LC) {
2491                 add_adts_header_for_aacenc(app, adts, (buf_size + ADTS_HEADER_SIZE));
2492                 fwrite(&adts, 1, ADTS_HEADER_SIZE, fp);
2493                 g_print("adts appended\n");
2494         } else if (app->is_encoder && buf_size > 0 && app->codecid == MEDIACODEC_AMR_NB && write_amr_header == 1) {
2495                 /* This is used only AMR encoder case for adding AMR masic header in only first frame */
2496                 g_print("%s - AMR_header write in first frame\n", __func__);
2497                 fwrite(&AMR_header[0], 1, sizeof(AMR_header)   - 1, fp);         /* AMR-NB magic number */
2498                 write_amr_header = 0;
2499         }
2500
2501         fwrite(temp, (int)buf_size, 1, fp);
2502
2503         g_print("codec dec output dumped!!%d\n", ret);
2504         fclose(fp);
2505
2506 }
2507
2508 const char* codec_type_to_string(mediacodec_codec_type_e media_codec_id)
2509 {
2510         guint media_codec_id_u = (guint)media_codec_id;
2511
2512         switch (media_codec_id_u) {
2513         case MEDIACODEC_L16:
2514                 return "L16";
2515         case MEDIACODEC_ALAW:
2516                 return "ALAW";
2517         case MEDIACODEC_ULAW:
2518                 return "ULAW";
2519         case MEDIACODEC_AMR_NB:
2520                 return "AMR_NB";
2521         case MEDIACODEC_AMR_WB:
2522                 return "AMR_WB";
2523         case MEDIACODEC_G729:
2524                 return "G729";
2525         case MEDIACODEC_AAC_LC:
2526                 return "AAC_LC";
2527         case MEDIACODEC_AAC_HE:
2528                 return "AAC_HE";
2529         case MEDIACODEC_AAC_HE_PS:
2530                 return "AAC_HE_PS";
2531         case MEDIACODEC_MP3:
2532                 return "MP3";
2533         case MEDIACODEC_VORBIS:
2534                 return "VORBIS";
2535         case MEDIACODEC_FLAC:
2536                 return "FLAC";
2537         case MEDIACODEC_WMAV1:
2538                 return "WMAV1";
2539         case MEDIACODEC_WMAV2:
2540                 return "WMAV2";
2541         case MEDIACODEC_WMAPRO:
2542                 return "WMAPRO";
2543         case MEDIACODEC_WMALSL:
2544                 return "WMALSL";
2545         case MEDIACODEC_H261:
2546                 return "H261";
2547         case MEDIACODEC_H263:
2548                 return "H263";
2549         case MEDIACODEC_H264:
2550                 return "H264";
2551         case MEDIACODEC_MJPEG:
2552                 return "MJPEG";
2553         case MEDIACODEC_MPEG1:
2554                 return "MPEG1";
2555         case MEDIACODEC_MPEG2:
2556                 return "MPEG2";
2557         case MEDIACODEC_MPEG4:
2558                 return "MPEG4";
2559         case MEDIACODEC_HEVC:
2560                 return "HEVC";
2561         case MEDIACODEC_VP8:
2562                 return "VP8";
2563         case MEDIACODEC_VP9:
2564                 return "VP9";
2565         case MEDIACODEC_VC1:
2566                 return "VC1";
2567         default:
2568                 return "NONE";
2569         }
2570         return "NONE";
2571 }
2572
2573 int main(int argc, char *argv[])
2574 {
2575         GIOChannel *stdin_channel;
2576         stdin_channel = g_io_channel_unix_new(0);
2577         g_io_channel_set_flags(stdin_channel, G_IO_FLAG_NONBLOCK, NULL);
2578         g_io_add_watch(stdin_channel, G_IO_IN, (GIOFunc)input, NULL);
2579
2580         App *app = &s_app;
2581
2582         displaymenu();
2583         app->loop = g_main_loop_new(NULL, TRUE);
2584         app->timer = g_timer_new();
2585         g_main_loop_run(app->loop);
2586
2587         ops.data = app;
2588
2589         return appcore_efl_main(PACKAGE, &argc, &argv, &ops);
2590 }