37bb55193cac70ac62d45a377bdd6079c47615a3
[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
24 #include <media_codec.h>
25 #include <media_packet.h>
26 #include <media_packet_pool.h>
27 #include <tbm_surface.h>
28 #include <dlog.h>
29 #include <time.h>
30
31 #define PACKAGE "media_codec_test"
32 #define MAX_HANDLE                      4
33 #if 0
34 #define DUMP_OUTBUF           1
35 #endif
36 #define TEST_FILE_SIZE        (10 * 1024 * 1024)
37 #define MAX_STRING_LEN        256
38
39 #define DEFAULT_SAMPPLERATE   44100
40 #define DEFAULT_CHANNEL             2
41 #define DEFAULT_BIT                           16
42 #define DEFAULT_BITRATE       128
43 #define DEFAULT_SAMPLEBYTE        1024
44 #define ADTS_HEADER_SIZE      7
45 #define AMRNB_PCM_INPUT_SIZE      320
46 #define AMRWB_PCM_INPUT_SIZE      640
47
48 #define CHECK_BIT(x, y) (((x) >> (y)) & 0x01)
49 #define GET_IS_ENCODER(x) CHECK_BIT(x, 0)
50 #define GET_IS_DECODER(x) CHECK_BIT(x, 1)
51 #define GET_IS_HW(x) CHECK_BIT(x, 2)
52 #define ES_DEFAULT_VIDEO_PTS_OFFSET 33000000
53 #define CHECK_VALID_PACKET(state, expected_state) \
54         ((state & (expected_state)) == (expected_state))
55
56 #define AAC_CODECDATA_SIZE    16
57
58 unsigned char buf_adts[ADTS_HEADER_SIZE];
59
60 enum {
61         MC_EXIST_SPS    = 1 << 0,
62         MC_EXIST_PPS    = 1 << 1,
63         MC_EXIST_IDR    = 1 << 2,
64         MC_EXIST_SLICE  = 1 << 3,
65
66         MC_VALID_HEADER = (MC_EXIST_SPS | MC_EXIST_PPS),
67         MC_VALID_FIRST_SLICE = (MC_EXIST_SPS | MC_EXIST_PPS | MC_EXIST_IDR)
68 };
69
70 typedef struct _App App;
71
72 enum {
73         CURRENT_STATUS_MAINMENU,
74         CURRENT_STATUS_FILENAME,
75         CURRENT_STATUS_CREATE,
76         CURRENT_STATUS_DESTROY,
77         CURRENT_STATUS_SET_CODEC,
78         CURRENT_STATUS_SET_VDEC_INFO,
79         CURRENT_STATUS_SET_VENC_INFO,
80         CURRENT_STATUS_SET_ADEC_INFO,
81         CURRENT_STATUS_SET_AENC_INFO,
82         CURRENT_STATUS_PREPARE,
83         CURRENT_STATUS_UNPREPARE,
84         CURRENT_STATUS_PROCESS_INPUT,
85         CURRENT_STATUS_GET_OUTPUT,
86         CURRENT_STATUS_RESET_OUTPUT_BUFFER,
87         CURRENT_STATUS_SET_SIZE,
88 };
89
90 typedef enum {
91         NAL_SLICE_NO_PARTITIONING = 1,
92         NAL_SLICE_PART_A,
93         NAL_SLICE_PART_B,
94         NAL_SLICE_PART_C,
95         NAL_SLICE_IDR,
96         NAL_SEI,
97         NAL_SEQUENCE_PARAMETER_SET,
98         NAL_PICTURE_PARAMETER_SET,
99         NAL_PICTURE_DELIMITER,
100         NAL_END_OF_SEQUENCE,
101         NAL_END_OF_STREAM,
102         NAL_FILLER_DATA,
103         NAL_PREFIX_SVC = 14
104 } nal_unit_type;
105
106 typedef enum {
107         VIDEO_DEC,
108         VIDEO_ENC,
109         AUDIO_DEC,
110         AUDIO_ENC
111 } type_e;
112
113
114 struct _App {
115         GMainLoop *loop;
116         guint sourceid;
117
118         GMappedFile *file;
119         guint8 *data;
120         gint length;
121         gint offset;
122         gint obj;
123
124         GTimer *timer;
125         long start;
126         long finish;
127         long process_time;
128         int frame_count;
129
130         int codecid;
131         int flag;
132         bool is_video;
133         bool is_encoder;
134         bool hardware;
135         bool enable_dump;
136         int frame;
137         type_e type;
138         /* video */
139         mediacodec_h mc_handle[MAX_HANDLE];
140         guint width;
141         guint height;
142         guint fps;
143         guint target_bits;
144         media_format_mimetype_e mime;
145
146         /* Audio */
147         guint samplerate;
148         guint channel;
149         guint bit;
150         guint bitrate;
151         bool is_amr_nb;
152
153
154         /* Render */
155         guint w;
156         guint h;
157         Evas_Object *win;
158         Evas_Object *img;
159         media_packet_h packet;
160         Ecore_Pipe *pipe;
161         GList *packet_list;
162         GMutex lock;
163 };
164
165 App s_app;
166
167 media_format_h fmt = NULL;
168 media_packet_pool_h pkt_pool = NULL;
169
170 /* Internal Functions */
171 static int _create_app(void *data);
172 static int _terminate_app(void *data);
173 static void displaymenu(void);
174 static void display_sub_basic();
175
176 static void _mediacodec_unprepare(App *app);
177 /* For debugging */
178 static void mc_hex_dump(char *desc, void *addr, int len);
179 static void decoder_output_dump(App *app, media_packet_h pkt);
180 static void output_dump(App *app, media_packet_h pkt);
181 /* */
182
183 void (*extractor)(App *app, unsigned char** data, int *size, bool *have_frame);
184
185 int g_menu_state = CURRENT_STATUS_MAINMENU;
186
187 static int _create_app(void *data)
188 {
189         printf("My app is going alive!\n");
190         App *app = (App*)data;
191
192         g_mutex_init(&app->lock);
193         return 0;
194 }
195
196 static int _terminate_app(void *data)
197 {
198         printf("My app is going gone!\n");
199         App *app = (App*)data;
200
201         g_mutex_clear(&app->lock);
202         return 0;
203 }
204
205
206 struct appcore_ops ops = {
207         .create = _create_app,
208         .terminate = _terminate_app,
209 };
210
211 static const guint mp3types_bitrates[2][3][16] = {
212         {
213                 {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448,},
214                 {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384,},
215                 {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320,}
216         },
217         {
218                 {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256,},
219                 {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,},
220                 {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,}
221         },
222 };
223
224 static const guint mp3types_freqs[3][3] = { {44100, 48000, 32000},
225         {22050, 24000, 16000},
226         {11025, 12000, 8000}
227 };
228
229 void h264_extractor(App *app, unsigned char **data, int *size, bool *have_frame)
230 {
231         unsigned char val, zero_count;
232         unsigned char *pNal = app->data + app->offset;
233         int max = app->length - app->offset;
234         int index = 0;
235         int nal_unit_type = 0;
236         bool init;
237         bool slice;
238         bool idr;
239         static int state;
240         int read;
241
242         zero_count = 0;
243
244         val = pNal[index++];
245         while (!val) {
246                 zero_count++;
247                 val = pNal[index++];
248         }
249
250         zero_count = 0;
251
252         while (1) {
253                 if (index >= max) {
254                         read = (index - 1);
255                         goto DONE;
256                 }
257
258                 val = pNal[index++];
259
260                 if (!val)
261                         zero_count++;
262                 else {
263                         if ((zero_count >= 2) && (val == 1))
264                                 break;
265                         else
266                                 zero_count = 0;
267                 }
268         }
269
270         if (zero_count > 3)
271                 zero_count = 3;
272
273         read = (index - zero_count - 1);
274
275         nal_unit_type = *(app->data+app->offset+4) & 0x1F;
276         g_print("nal_unit_type : %x\n", nal_unit_type);
277
278         switch (nal_unit_type) {
279         case NAL_SEQUENCE_PARAMETER_SET:
280                 g_print("nal_unit_type : SPS\n");
281                 state |= MC_EXIST_SPS;
282                 break;
283         case NAL_PICTURE_PARAMETER_SET:
284                 g_print("nal_unit_type : PPS\n");
285                 state |= MC_EXIST_PPS;
286                 break;
287         case NAL_SLICE_IDR:
288         case NAL_SEI:
289                 g_print ("nal_unit_type : IDR\n");
290                 state |= MC_EXIST_IDR;
291                 break;
292         case NAL_SLICE_NO_PARTITIONING:
293         case NAL_SLICE_PART_A:
294         case NAL_SLICE_PART_B:
295         case NAL_SLICE_PART_C:
296                 state |= MC_EXIST_SLICE;
297                 break;
298         default:
299                 g_print ("nal_unit_type : %x", nal_unit_type);
300                 break;
301         }
302
303         init = CHECK_VALID_PACKET(state, MC_VALID_FIRST_SLICE) ? 1 : 0;
304         slice = CHECK_VALID_PACKET(state, MC_EXIST_SLICE) ? 1 : 0;
305         idr = CHECK_VALID_PACKET(state, MC_EXIST_IDR) ? 1 : 0;
306         g_print("status : %d, slice : %d, idr : %d\n", init, slice, idr);
307
308         if (init || idr || slice) {
309                 *have_frame = TRUE;
310                 if (init) {
311                         *data = app->data;
312                         *size = app->offset + read;
313                 } else {
314                         *data = app->data+app->offset;
315                         *size = read;
316                 }
317                 state = 0;
318         } else {
319                 *data = app->data+app->offset;
320                 *size = read;
321         }
322 DONE:
323         app->offset += read;
324 }
325
326 void h263_extractor(App * app, unsigned char **data, int *size, bool * have_frame)
327 {
328         int len = 0;
329         int read_size = 1, state = 1, bStart = 0;
330         unsigned char val;
331         unsigned char *pH263 = app->data + app->offset;
332         *data = pH263;
333         int max = app->length - app->offset;
334
335         while (1) {
336                 if (len >= max) {
337                         read_size = (len - 1);
338                         goto DONE;
339                 }
340                 val = pH263[len++];
341                 switch (state) {
342                 case 1:
343                         if (val == 0x00)
344                                 state++;
345                         break;
346                 case 2:
347                         if (val == 0x00)
348                                 state++;
349                         else
350                                 state = 1;
351                         break;
352                 case 3:
353                         state = 1;
354                         if ((val & 0xFC) == 0x80) {
355                                 if (bStart) {
356                                         read_size = len - 3;
357                                         goto DONE;
358                                 } else {
359                                         bStart = 1;
360                                 }
361                         }
362                         break;
363                 }
364         }
365  DONE:
366         *size = read_size;
367         app->offset += read_size;
368         *have_frame = TRUE;
369 }
370
371 void mpeg4_extractor(App * app, unsigned char **data, int *size, bool * have_frame)
372 {
373         int len = 0;
374         int result = 0;
375         int state = 1, bType = 0;
376         unsigned char val;
377         unsigned char *pMpeg4 = app->data + app->offset;
378         *data = pMpeg4;
379         int max = app->length - app->offset;
380
381         while (1) {
382                 if (len >= max) {
383                         result = (len - 1);
384                         goto DONE;
385                 }
386
387                 val = pMpeg4[len++];
388
389                 switch (state) {
390                 case 1:
391                         if (val == 0x00)
392                                 state++;
393                         break;
394                 case 2:
395                         if (val == 0x00)
396                                 state++;
397                         else
398                                 state = 1;
399                         break;
400                 case 3:
401                         if (val == 0x01)
402                                 state++;
403                         else
404                                 state = 1;
405                         break;
406                 case 4:
407                         state = 1;
408                         if (val == 0xB0 || val == 0xB6) {
409                                 if (bType == 0xB6) {
410                                         result = len - 4;
411                                         goto DONE;
412                                 }
413                                 if (!bType) {
414                                         if (have_frame && val == 0xB0)
415                                                 *have_frame = TRUE;
416                                 }
417                                 bType = val;
418                         }
419                         break;
420                 }
421         }
422  DONE:
423         *size = result;
424         app->offset += result;
425         *have_frame = TRUE;
426 }
427
428 /**
429   * Extract Input data for AMR-NB/WB decoder
430   *  - AMR-NB  : mime type ("audio/AMR")          /   8Khz / 1 ch / 16 bits
431   *  - AMR-WB : mime type ("audio/AMR-WB")  / 16Khz / 1 ch / 16 bits
432   **/
433 int write_amr_header = 1;                   /* write  magic number for AMR Header at one time */
434 static const char AMR_header[] = "#!AMR\n";
435 static const char AMRWB_header[] = "#!AMR-WB\n";
436 #define AMR_NB_MIME_HDR_SIZE          6
437 #define AMR_WB_MIME_HDR_SIZE          9
438 static const int block_size_nb[16] = { 12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0 };
439 static const int block_size_wb[16] = { 17, 23, 32, 36, 40, 46, 50, 58, 60, 5, -1, -1, -1, -1, 0, 0 };
440
441 int *blocksize_tbl;
442 void amrdec_extractor(App * app, unsigned char **data, int *size, bool * have_frame)
443 {
444         int readsize = 0, mode_temp;
445         unsigned int fsize, mode;
446         unsigned char *pAmr = app->data + app->offset;
447         /* change the below one to frame count */
448         if (app->offset == 0) {
449                 if (!memcmp(pAmr, AMR_header, AMR_NB_MIME_HDR_SIZE)) {
450                         blocksize_tbl = (int *)block_size_nb;
451                         mode_temp = pAmr[AMR_NB_MIME_HDR_SIZE];
452                         pAmr = pAmr + AMR_NB_MIME_HDR_SIZE;
453                         app->offset += AMR_NB_MIME_HDR_SIZE;
454                 } else {
455                         if (!memcmp(pAmr, AMRWB_header, AMR_WB_MIME_HDR_SIZE)) {
456                                 blocksize_tbl = (int *)block_size_wb;
457                                 mode_temp = pAmr[AMR_WB_MIME_HDR_SIZE];
458                                 pAmr = pAmr + AMR_WB_MIME_HDR_SIZE;
459                                 app->offset += AMR_WB_MIME_HDR_SIZE;
460                         } else {
461                                 g_print("[ERROR] AMR-NB/WB don't detected..\n");
462                                 return;
463                         }
464                 }
465         }
466         mode_temp = pAmr[0];
467         if ((mode_temp & 0x83) == 0) {
468                 mode = (mode_temp >> 3) & 0x0F; /* Yep. Retrieve the frame size */
469                 fsize = blocksize_tbl[mode];
470                 readsize = fsize + 1;
471         } else {
472                 readsize = 0;
473                 g_print("[FAIL] Not found amr frame sync.....\n");
474         }
475
476         *size = readsize;
477         app->offset += readsize;
478         *data = pAmr;
479         *have_frame = TRUE;
480 }
481
482 void nv12_extractor(App *app, unsigned char **data, int *size, bool *have_frame)
483 {
484         int yuv_size;
485         int offset = app->length - app->offset;
486
487         yuv_size = app->width * app->height * 3 / 2;
488
489         if (offset >= yuv_size)
490                 *size = offset;
491
492         *have_frame = TRUE;
493         *data = app->data + app->offset;
494
495         if (offset >= yuv_size)
496                 *size = offset;
497         else
498                 *size = yuv_size;
499 }
500
501 void yuv_extractor(App *app, unsigned char **data, int *size, bool *have_frame)
502 {
503         int yuv_size;
504         int offset = app->length - app->offset;
505
506         yuv_size = app->width * app->height * 3 / 2;
507
508         if (yuv_size >= offset)
509                 *size = offset;
510
511         *have_frame = TRUE;
512         *data = app->data + app->offset;
513
514         if (yuv_size >= offset)
515                 *size = offset;
516         else
517                 *size = yuv_size;
518
519         app->offset += *size;
520
521 }
522
523 void aacenc_extractor(App *app, unsigned char **data, int *size, bool *have_frame)
524 {
525         int read_size;
526         int offset = app->length - app->offset;
527
528         read_size = ((DEFAULT_SAMPLEBYTE * app->channel)*(app->bit/8) * 2);
529
530         *have_frame = TRUE;
531         *data = app->data + app->offset;
532
533         if (read_size >= offset)
534                 *size = offset;
535         else
536                 *size = read_size;
537
538         app->offset += *size;
539 }
540
541 void amrenc_extractor(App *app, unsigned char **data, int *size, bool *have_frame)
542 {
543         int read_size;
544         int offset = app->length - app->offset;
545
546         if (app->is_amr_nb)
547                 read_size = AMRNB_PCM_INPUT_SIZE;
548         else
549                 read_size = AMRWB_PCM_INPUT_SIZE;
550
551         *have_frame = TRUE;
552         *data = app->data + app->offset;
553
554         if (read_size >= offset)
555                 *size = offset;
556         else
557                 *size = read_size;
558
559         app->offset += *size;
560 }
561
562 /**
563  * Extract Input data for AAC decoder
564  * (case of (LC profile) ADTS format)
565  * codec_data : Don't need
566  **/
567 void aacdec_extractor(App *app, unsigned char **data, int *size, bool *have_frame)
568 {
569         int read_size;
570         int offset = app->length - app->offset;
571         unsigned char *pData = app->data + app->offset;
572
573         if ((pData != NULL) && (pData[0] == 0xff) && ((pData[1] & 0xf6) == 0xf0)) {
574                 read_size = ((pData[3] & 0x03) << 11) | (pData[4] << 3) | ((pData[5] & 0xe0) >> 5);
575         } else {
576                 read_size = 0;
577                 g_print("[FAIL] Not found aac frame sync.....\n");
578         }
579
580         *have_frame = TRUE;
581         *data = app->data + app->offset;
582
583         if (read_size >= offset)
584                 *size = offset;
585         else
586                 *size = read_size;
587
588         app->offset += *size;
589
590 }
591
592 void mp3dec_extractor(App *app, unsigned char **data, int *size, bool *have_frame)
593 {
594         int read_size;
595         guint header;
596         guint padding, bitrate, lsf = 0, layer = 0, mpg25 = 0;
597         guint hdr_bitrate = 0, sf = 0;
598         int offset = app->length - app->offset;
599         unsigned char *pData = app->data + app->offset;
600
601         header = GST_READ_UINT32_BE(pData);
602
603         if (header == 0) {
604                 g_print ("[ERROR] read header size is 0\n");
605                 *have_frame = FALSE;
606         }
607
608         /* if it's not a valid sync */
609         if ((header & 0xffe00000) != 0xffe00000) {
610                 g_print ("[ERROR] invalid sync\n");
611                 *have_frame = FALSE;
612         }
613
614         if (((header >> 19) & 3) == 0x1) {
615                 g_print ("[ERROR] invalid MPEG version: %d\n", (header >> 19) & 3);
616                 *have_frame = FALSE;
617         } else {
618                 if (header & (1 << 20)) {
619                         lsf = (header & (1 << 19)) ? 0 : 1;
620                         mpg25 = 0;
621                 } else {
622                         lsf = 1;
623                         mpg25 = 1;
624                 }
625         }
626
627         /* if it's an invalid layer */
628         if (!((header >> 17) & 3)) {
629                 g_print("[ERROR] invalid layer: %d\n", (header >> 17) & 3);
630                 *have_frame = FALSE;
631         } else {
632                 layer = 4 - ((header >> 17) & 0x3);
633         }
634
635         /* if it's an invalid bitrate */
636         if (((header >> 12) & 0xf) == 0xf) {
637                 g_print ("[ERROR] invalid bitrate: %d\n", (header >> 12) & 0xf);
638                 *have_frame = FALSE;
639         } else {
640                 bitrate = (header >> 12) & 0xF;
641                 hdr_bitrate = mp3types_bitrates[lsf][layer - 1][bitrate] * 1000;
642                 /* The caller has ensured we have a valid header, so bitrate can't be zero here. */
643                 if (hdr_bitrate == 0)
644                         *have_frame = FALSE;
645         }
646
647         /* if it's an invalid samplerate */
648         if (((header >> 10) & 0x3) == 0x3) {
649                 g_print ("[ERROR] invalid samplerate: %d\n", (header >> 10) & 0x3);
650                 *have_frame = FALSE;
651                 return;
652         } else {
653                 sf = (header >> 10) & 0x3;
654                 sf = mp3types_freqs[lsf + mpg25][sf];
655         }
656
657         padding = (header >> 9) & 0x1;
658
659         switch (layer) {
660         case 1:
661                 read_size = 4 * ((hdr_bitrate * 12) / sf + padding);
662                 break;
663         case 2:
664                 read_size = (hdr_bitrate * 144) / sf + padding;
665                 break;
666         default:
667         case 3:
668                 read_size = (hdr_bitrate * 144) / (sf << lsf) + padding;
669                 break;
670         }
671         g_print("header : %d, read : %d\n", header, read_size);
672
673         *have_frame = TRUE;
674         *data = app->data + app->offset;
675
676         if (read_size >= offset)
677                 *size = offset;
678         else
679                 *size = read_size;
680
681         app->offset += *size;
682 }
683
684 #if 1
685 void extract_input_aacdec_m4a_test(App * app, unsigned char **data, int *size, bool * have_frame)
686 {
687         int readsize = 0, read_size = 0;
688         unsigned int header_size = ADTS_HEADER_SIZE;
689         unsigned char buffer[100000];
690         unsigned char codecdata[AAC_CODECDATA_SIZE] = { 0, };
691         int offset = app->length - app->offset;
692         unsigned char *pData = app->data + app->offset;
693         /*
694          * It is not support full parsing MP4 container box.
695          * So It MUST start as RAW valid frame sequence.
696          * Testsuit that are not guaranteed to be available on functionality of all General DEMUXER/PARSER.
697          */
698
699         /* change the below one later */
700         if (app->offset == 0) {
701                 /*
702                  * CAUTION : Codec data is needed only once  in first time
703                  * Codec data is made(or extracted) by MP4 demuxer in 'esds' box.
704                  * So I use this data (byte) as hard coding for temporary our testing.
705                  */
706 #if 1
707                 /*
708                  * The codec_data data is according to AudioSpecificConfig,
709                  *  ISO/IEC 14496-3, 1.6.2.1
710                  *
711                  *  below example is test for using "test.aac" or "TestSample-AAC-LC.m4a"
712                  * case : M4A - LC profile
713                  * codec_data=(buffer)119056e5000000000000000000000000
714                  * savs aac decoder get codec_data. size: 16  (Tag size : 5 byte)
715                  *     - codec data: profile  : 2
716                  *     - codec data: samplrate: 48000
717                  *     - codec data: channels : 2
718                  */
719                 /* 2 bytes are mandatory */
720                 codecdata[0] = 0x11;         /* ex) (5bit) 2 (LC) / (4bit) 3 (48khz)*/
721                 codecdata[1] = 0x90;         /* ex) (4bit) 2 (2ch) */
722                 /* othter bytes are (optional) epconfig information */
723                 codecdata[2] = 0x56;
724                 codecdata[3] = 0xE5;
725                 codecdata[4] = 0x00;
726 #else
727                 /*
728                  *  below example is test for using "TestSample-EAAC+.m4a"
729                  *
730                  * case : M4A - HE-AAC v1 and v2 profile
731                  * codec_data=(buffer)138856e5a54880000000000000000000
732                  * savs aac decoder get codec_data. size: 16  (Tag size : 7 byte)
733                  *     - codec data: profile  : 2
734                  *     - codec data: samplrate: 22050
735                  *     - codec data: channels : 1
736                  */
737                 /* 2 bytes are mandatory */
738                 codecdata[0] = 0x13;         /* ex) (5bit) 2 (LC) / (4bit) 9 (22khz) */
739                 codecdata[1] = 0x88;         /* ex) (4bit) 1 (1ch) */
740                 /* othter bytes are (optional) epconfig information */
741                 codecdata[2] = 0x56;
742                 codecdata[3] = 0xE5;
743                 codecdata[4] = 0xA5;
744                 codecdata[5] = 0x48;
745                 codecdata[6] = 0x80;
746 #endif
747
748                 memcpy(buffer, codecdata, AAC_CODECDATA_SIZE);
749                 if ((pData != NULL) && (pData[0] == 0xff) && ((pData[1] & 0xf6) == 0xf0)) {
750                         read_size = ((pData[3] & 0x03) << 11) | (pData[4] << 3) | ((pData[5] & 0xe0) >> 5);
751                 } else {
752                         read_size = 0;
753                         g_print("[FAIL] Not found aac frame sync.....\n");
754                 }
755                 readsize = read_size - header_size;
756                 memcpy(buffer + AAC_CODECDATA_SIZE, pData + 7, readsize);
757                 read_size = readsize + AAC_CODECDATA_SIZE;      /* return combination of (codec_data + raw_data) */
758                 app->offset += header_size + readsize;
759                 goto DONE;
760         }
761
762         if ((pData != NULL) && (pData[0] == 0xff) && ((pData[1] & 0xf6) == 0xf0)) {
763                 read_size = ((pData[3] & 0x03) << 11) | (pData[4] << 3) | ((pData[5] & 0xe0) >> 5);
764                 readsize = read_size - header_size;
765                 memcpy(buffer, pData + 7, readsize);    /* Make only RAW data, so exclude header 7 bytes */
766                 read_size = readsize;
767                 app->offset += header_size + readsize;
768
769         } else {
770                 read_size = 0;
771                 g_print("[FAIL] Not found aac frame sync. \n");
772         }
773  DONE:
774         *data = buffer;
775         *have_frame = TRUE;
776         if (read_size >= offset)
777                 *size = offset;
778         else
779                 *size = read_size;
780 }
781 #endif
782
783 /**
784  * Extract Input data for AAC encoder
785  **/
786 /*
787    void aacenc_extractor(App *app, unsigned char **data, int *size, bool *have_frame)
788    {
789    int read_size;
790    int offset = app->length - app->offset;
791
792    read_size = ((DEFAULT_SAMPLEBYTE*DEFAULT_CHANNEL)*(DEFAULT_BIT/8));
793
794    if (read_size >= offset)
795  *size = offset;
796
797  *have_frame = TRUE;
798  *data = app->data + app->offset;
799
800  if (read_size >= offset)
801  *size = offset;
802  else
803  *size = read_size;
804
805  app->offset += *size;
806  }
807  */
808 #if 0
809 static void _mediacodec_empty_buffer_cb(media_packet_h pkt, void *user_data)
810 {
811         if (pkt != NULL) {
812                 g_print("Used input buffer = %p\n", pkt);
813                 media_packet_destroy(pkt);
814         }
815         return;
816 }
817 #endif
818 int  _mediacodec_set_codec(App *app, int codecid, int flag, bool *hardware)
819 {
820         bool encoder;
821         media_format_mimetype_e mime = 0;
822         encoder = GET_IS_ENCODER(flag) ? 1 : 0;
823         *hardware = GET_IS_HW(flag) ? 1 : 0;
824         app->is_encoder = encoder;
825
826         switch (codecid) {
827         case MEDIACODEC_H264:
828                 if (encoder) {
829                         extractor = yuv_extractor;
830                         mime = *hardware ? MEDIA_FORMAT_NV12 : MEDIA_FORMAT_I420;
831                 } else {
832                         extractor = h264_extractor;
833                         mime = MEDIA_FORMAT_H264_SP;
834                 }
835                 break;
836         case MEDIACODEC_MPEG4:
837                 if (encoder) {
838                         extractor = yuv_extractor;
839                         mime = *hardware ? MEDIA_FORMAT_NV12 : MEDIA_FORMAT_I420;
840                 } else {
841                         extractor = mpeg4_extractor;
842                         mime = MEDIA_FORMAT_MPEG4_SP;
843                 }
844                 break;
845         case MEDIACODEC_H263:
846                 if (encoder) {
847                         extractor = h263_extractor;
848                         mime = *hardware ? MEDIA_FORMAT_NV12 : MEDIA_FORMAT_I420;
849                 } else {
850                         extractor = h263_extractor;
851                         mime = MEDIA_FORMAT_H263P;
852                 }
853                 break;
854         case MEDIACODEC_AAC:
855                 if (encoder) {
856                         extractor = aacenc_extractor;
857                         mime = MEDIA_FORMAT_PCM;
858                 } else {
859                         extractor = aacdec_extractor;
860                         mime = MEDIA_FORMAT_AAC;
861                 }
862                 break;
863         case MEDIACODEC_AAC_HE:
864                 if (encoder) {
865                         extractor = aacenc_extractor;
866                         mime = MEDIA_FORMAT_PCM;
867                 } else {
868                         extractor = extract_input_aacdec_m4a_test;
869                         mime = MEDIA_FORMAT_AAC_HE;
870                 }
871                 break;
872         case MEDIACODEC_AAC_HE_PS:
873                 break;
874         case MEDIACODEC_MP3:
875                 extractor = mp3dec_extractor;
876                 mime = MEDIA_FORMAT_MP3;
877                 break;
878         case MEDIACODEC_VORBIS:
879                 break;
880         case MEDIACODEC_FLAC:
881                 break;
882         case MEDIACODEC_WMAV1:
883                 break;
884         case MEDIACODEC_WMAV2:
885                 break;
886         case MEDIACODEC_WMAPRO:
887                 break;
888         case MEDIACODEC_WMALSL:
889                 break;
890         case MEDIACODEC_AMR_NB:
891                 if (encoder) {
892                         extractor = amrenc_extractor;
893                         mime = MEDIA_FORMAT_PCM;
894                         app->is_amr_nb = TRUE;
895                 } else {
896                         extractor = amrdec_extractor;
897                         mime = MEDIA_FORMAT_AMR_NB;
898                 }
899                 break;
900         case MEDIACODEC_AMR_WB:
901                 if (encoder) {
902                         extractor = amrenc_extractor;
903                         mime = MEDIA_FORMAT_PCM;
904                         app->is_amr_nb = FALSE;
905                 } else {
906                         extractor = amrdec_extractor;
907                         mime = MEDIA_FORMAT_AMR_WB;
908                 }
909                 break;
910         default:
911                 LOGE("NOT SUPPORTED!!!!");
912                 break;
913         }
914         return mime;
915 }
916
917 static void _mediacodec_process_input(App *app)
918 {
919         int i;
920         bool have_frame = FALSE;
921         int ret;
922         static guint64 pts = 0L;
923         void *buf_data_ptr = NULL;
924         media_packet_h pkt = NULL;
925         unsigned char *tmp;
926         int read;
927         int offset;
928         int stride_width, stride_height;
929
930         for (i = 0; i < app->frame; i++) {
931                 g_print("----------read data------------\n");
932
933                 extractor(app, &tmp, &read, &have_frame);
934
935                 if (have_frame) {
936                         if (media_packet_create_alloc(fmt, NULL, NULL, &pkt) != MEDIA_PACKET_ERROR_NONE) {
937                                 fprintf(stderr, "media_packet_create_alloc failed\n");
938                                 return;
939                         }
940
941                         if (media_packet_set_pts(pkt, (uint64_t)(pts)) != MEDIA_PACKET_ERROR_NONE) {
942                                 fprintf(stderr, "media_packet_set_pts failed\n");
943                                 return;
944                         }
945
946                         if (app->type != VIDEO_ENC) {
947                                 media_packet_get_buffer_data_ptr(pkt, &buf_data_ptr);
948                                 media_packet_set_buffer_size(pkt, (uint64_t)read);
949
950                                 memcpy(buf_data_ptr, tmp, read);
951                                 g_print("tmp:%p, read:%d\n", tmp, read);
952                         } else {
953                                 /* Y */
954                                 media_packet_get_video_plane_data_ptr(pkt, 0, &buf_data_ptr);
955                                 media_packet_get_video_stride_width(pkt, 0, &stride_width);
956                                 media_packet_get_video_stride_height(pkt, 0, &stride_height);
957
958                                 offset = stride_width*stride_height;
959
960                                 memcpy(buf_data_ptr, tmp, offset);
961
962                                 /* UV or U*/
963                                 media_packet_get_video_plane_data_ptr(pkt, 1, &buf_data_ptr);
964                                 media_packet_get_video_stride_width(pkt, 1, &stride_width);
965                                 media_packet_get_video_stride_height(pkt, 1, &stride_height);
966                                 memcpy(buf_data_ptr, tmp + offset, stride_width*stride_height);
967
968                                 if (app->hardware == FALSE) {
969                                         /* V */
970                                         media_packet_get_video_plane_data_ptr(pkt, 2, &buf_data_ptr);
971                                         media_packet_get_video_stride_width(pkt, 2, &stride_width);
972                                         media_packet_get_video_stride_height(pkt, 2, &stride_height);
973
974                                         offset += stride_width * stride_height;
975
976
977                                         memcpy(buf_data_ptr, tmp + offset, stride_width*stride_height);
978                                 }
979                         }
980                         mc_hex_dump("inbuf", tmp, 48);
981
982                         ret = mediacodec_process_input(app->mc_handle[0], pkt, 1000);
983                         if (ret != MEDIACODEC_ERROR_NONE)
984                                 return;
985
986                         pts += ES_DEFAULT_VIDEO_PTS_OFFSET;
987                 }
988         }
989 }
990
991 static gboolean read_data(App *app)
992 {
993         guint len = 0;
994         bool have_frame = FALSE;
995         int ret;
996         static guint64 pts = 0L;
997         void *buf_data_ptr = NULL;
998         media_packet_h pkt = NULL;
999         unsigned char *tmp;
1000         int read;
1001         int offset;
1002         int stride_width, stride_height;
1003
1004         if (app->offset == 0) {
1005                 app->frame_count = 0;
1006                 app->start = clock();
1007         }
1008
1009         g_print("----------read data------------\n");
1010         extractor(app, &tmp, &read, &have_frame);
1011
1012         if (app->offset >= app->length - 4) {
1013                 /* EOS */
1014                 g_print("EOS\n");
1015                 app->finish = clock();
1016                 g_print("Average FPS = %3.3f\n", ((double)app->frame_count*1000000/(app->finish - app->start)));
1017                 g_print("---------------------------\n");
1018                 return FALSE;
1019         }
1020         g_print("length : %d, offset : %d\n", app->length, app->offset);
1021
1022         if (app->offset + len > app->length)
1023                 len = app->length - app->offset;
1024
1025         g_print("%p, %d, have_frame :%d, read: %d\n", tmp, (int)read, have_frame, read);
1026
1027         if (have_frame) {
1028 #ifdef USE_POOL
1029                 if (media_packet_pool_acquire_packet(pkt_pool, &pkt, -1) != MEDIA_PACKET_ERROR_NONE) {
1030                         fprintf(stderr, "media_packet_pool_aquire_packet failed\n");
1031                         return FALSE;
1032                 }
1033 #else
1034                 if (media_packet_create_alloc(fmt, NULL, NULL, &pkt) != MEDIA_PACKET_ERROR_NONE) {
1035                         fprintf(stderr, "media_packet_create_alloc failed\n");
1036                         return FALSE;
1037                 }
1038 #endif
1039                 if (media_packet_set_pts(pkt, (uint64_t)(pts)) != MEDIA_PACKET_ERROR_NONE) {
1040                         fprintf(stderr, "media_packet_set_pts failed\n");
1041                         return FALSE;
1042                 }
1043
1044                 if (app->type != VIDEO_ENC) {
1045                         media_packet_get_buffer_data_ptr(pkt, &buf_data_ptr);
1046                         media_packet_set_buffer_size(pkt, (uint64_t)read);
1047
1048                         memcpy(buf_data_ptr, tmp, read);
1049                         g_print("tmp:%p, read:%d\n", tmp, read);
1050                 } else {
1051                         /* Y */
1052                         media_packet_get_video_plane_data_ptr(pkt, 0, &buf_data_ptr);
1053                         media_packet_get_video_stride_width(pkt, 0, &stride_width);
1054                         media_packet_get_video_stride_height(pkt, 0, &stride_height);
1055
1056                         offset = stride_width*stride_height;
1057
1058                         memcpy(buf_data_ptr, tmp, offset);
1059
1060                         /* UV or U*/
1061                         media_packet_get_video_plane_data_ptr(pkt, 1, &buf_data_ptr);
1062                         media_packet_get_video_stride_width(pkt, 1, &stride_width);
1063                         media_packet_get_video_stride_height(pkt, 1, &stride_height);
1064                         memcpy(buf_data_ptr, tmp + offset, stride_width*stride_height);
1065
1066                         if (app->hardware == FALSE) {
1067                                 /* V */
1068                                 media_packet_get_video_plane_data_ptr(pkt, 2, &buf_data_ptr);
1069                                 media_packet_get_video_stride_width(pkt, 2, &stride_width);
1070                                 media_packet_get_video_stride_height(pkt, 2, &stride_height);
1071
1072                                 offset += stride_width * stride_height;
1073
1074
1075                                 memcpy(buf_data_ptr, tmp + offset, stride_width*stride_height);
1076                         }
1077                 }
1078                 mc_hex_dump("inbuf", tmp, 48);
1079
1080                 ret = mediacodec_process_input(app->mc_handle[0], pkt, 0);
1081                 if (ret != MEDIACODEC_ERROR_NONE)
1082                         return FALSE;
1083
1084                 pts += ES_DEFAULT_VIDEO_PTS_OFFSET;
1085         }
1086
1087         return TRUE;
1088 }
1089
1090 static void start_feed(App *app)
1091 {
1092         if (app->sourceid == 0) {
1093                 app->sourceid = g_idle_add((GSourceFunc)read_data, app);
1094                 g_print("start_feed\n");
1095         }
1096 }
1097
1098 static void stop_feed(App *app)
1099 {
1100         if (app->sourceid != 0) {
1101                 g_source_remove(app->sourceid);
1102                 app->sourceid = 0;
1103                 g_print("stop_feed\n");
1104         }
1105 }
1106
1107 static gboolean _mediacodec_inbuf_used_cb(media_packet_h pkt, void *user_data)
1108 {
1109         g_print("_mediacodec_inbuf_used_cb!!!\n");
1110 #ifdef USE_POOL
1111         media_packet_pool_release_packet(pkt_pool, pkt);
1112 #else
1113         media_packet_destroy(pkt);
1114 #endif
1115
1116         return TRUE;
1117 }
1118
1119 static bool _mediacodec_outbuf_available_cb(media_packet_h pkt, void *user_data)
1120 {
1121         media_packet_h out_pkt = NULL;
1122         int ret;
1123
1124         App *app = (App*)user_data;
1125
1126         g_print("_mediacodec_outbuf_available_cb\n");
1127
1128         g_mutex_lock(&app->lock);
1129
1130         ret = mediacodec_get_output(app->mc_handle[0], &out_pkt, 0);
1131
1132         if (ret != MEDIACODEC_ERROR_NONE)
1133                 g_print("get_output failed\n");
1134
1135         if (app->enable_dump) {
1136                 if (app->type == VIDEO_DEC)
1137                         decoder_output_dump(app, out_pkt);
1138                 else
1139                         output_dump(app, out_pkt);
1140         }
1141
1142         app->frame_count++;
1143
1144
1145         g_mutex_unlock(&app->lock);
1146
1147         media_packet_destroy(out_pkt);
1148         out_pkt = NULL;
1149         g_print("done\n");
1150
1151         return TRUE;
1152 }
1153
1154 static bool _mediacodec_buffer_status_cb(mediacodec_status_e status, void *user_data)
1155 {
1156         g_print("_mediacodec_buffer_status_cb %d\n", status);
1157
1158         App *app = (App*)user_data;
1159
1160         if (status == MEDIACODEC_NEED_DATA)
1161                 start_feed(app);
1162         else if (status == MEDIACODEC_ENOUGH_DATA)
1163                 stop_feed(app);
1164
1165         return TRUE;
1166 }
1167
1168 static bool _mediacodec_error_cb(mediacodec_error_e error, void *user_data)
1169 {
1170         return TRUE;
1171 }
1172
1173 static bool _mediacodec_eos_cb(void *user_data)
1174 {
1175         return TRUE;
1176 }
1177
1178 static void _mediacodec_prepare(App *app, bool frame_all)
1179 {
1180         int ret;
1181
1182         /* create instance */
1183         ret = mediacodec_create(&app->mc_handle[0]);
1184         if (ret  != MEDIACODEC_ERROR_NONE) {
1185                 g_print("mediacodec_create  failed\n");
1186                 return;
1187         }
1188
1189         /* set codec */
1190         ret = mediacodec_set_codec(app->mc_handle[0], app->codecid, app->flag);
1191         if (ret  != MEDIACODEC_ERROR_NONE) {
1192                 g_print("mediacodec_set_codec failed\n");
1193                 return;
1194         }
1195
1196         app->mime = _mediacodec_set_codec(app, app->codecid, app->flag, &app->hardware);
1197
1198         /* set codec info */
1199         ret = media_format_create(&fmt);
1200
1201         switch (app->type) {
1202         case VIDEO_DEC:
1203                 ret = mediacodec_set_vdec_info(app->mc_handle[0], app->width, app->height);
1204                 media_format_set_video_mime(fmt, app->mime);
1205                 media_format_set_video_width(fmt, app->width);
1206                 media_format_set_video_height(fmt, app->height);
1207                 break;
1208         case VIDEO_ENC:
1209                 ret = mediacodec_set_venc_info(app->mc_handle[0], app->width, app->height, app->fps, app->target_bits);
1210                 media_format_set_video_mime(fmt, app->mime);
1211                 media_format_set_video_width(fmt, app->width);
1212                 media_format_set_video_height(fmt, app->height);
1213                 media_format_set_video_avg_bps(fmt, app->target_bits);
1214                 break;
1215         case AUDIO_DEC:
1216                 ret = mediacodec_set_adec_info(app->mc_handle[0], app->samplerate, app->channel, app->bit);
1217                 media_format_set_audio_mime(fmt, app->mime);
1218                 media_format_set_audio_channel(fmt, app->channel);
1219                 media_format_set_audio_samplerate(fmt, app->samplerate);
1220                 media_format_set_audio_bit(fmt, app->bit);
1221                 break;
1222         case AUDIO_ENC:
1223                 ret = mediacodec_set_aenc_info(app->mc_handle[0], app->samplerate, app->channel, app->bit, app->bitrate);
1224                 media_format_set_audio_mime(fmt, app->mime);
1225                 media_format_set_audio_channel(fmt, app->channel);
1226                 media_format_set_audio_samplerate(fmt, app->samplerate);
1227                 media_format_set_audio_bit(fmt, app->bit);
1228                 break;
1229         default:
1230                 g_print("invaild type\n");
1231                 break;
1232         }
1233
1234         if (ret  != MEDIACODEC_ERROR_NONE) {
1235                 g_print("mediacodec_set_xxxc(%d)_info failed\n", app->type);
1236                 return;
1237         }
1238
1239         /* set callback */
1240         mediacodec_set_input_buffer_used_cb(app->mc_handle[0], (mediacodec_input_buffer_used_cb)_mediacodec_inbuf_used_cb, NULL);
1241         mediacodec_set_output_buffer_available_cb(app->mc_handle[0], (mediacodec_output_buffer_available_cb) _mediacodec_outbuf_available_cb, app);
1242         if (frame_all)
1243                 mediacodec_set_buffer_status_cb(app->mc_handle[0], (mediacodec_buffer_status_cb) _mediacodec_buffer_status_cb, app);
1244         mediacodec_set_eos_cb(app->mc_handle[0], (mediacodec_eos_cb)_mediacodec_eos_cb, NULL);
1245         mediacodec_set_error_cb(app->mc_handle[0], (mediacodec_error_cb)_mediacodec_error_cb, NULL);
1246
1247         /* prepare */
1248         ret = mediacodec_prepare(app->mc_handle[0]);
1249         if (ret  != MEDIACODEC_ERROR_NONE) {
1250                 g_print("mediacodec_prepare failed\n");
1251                 return;
1252         }
1253
1254
1255 /* get packet pool instance */
1256         ret = mediacodec_get_packet_pool(app->mc_handle[0], &pkt_pool);
1257         if (ret != MEDIA_PACKET_ERROR_NONE) {
1258                 g_print("mediacodec_get_packet_pool failed\n");
1259                 return;
1260         }
1261         return;
1262 }
1263
1264 static void _mediacodec_unprepare(App *app)
1265 {
1266         mediacodec_unprepare(app->mc_handle[0]);
1267 }
1268
1269 static void _mediacodec_destroy(App *app)
1270 {
1271 #ifdef USE_POOL
1272         if (media_packet_pool_deallocate(pkt_pool) != MEDIA_PACKET_ERROR_NONE) {
1273
1274                 fprintf(stderr, "media_packet_pool_deallocatet failed\n");
1275                 g_print("PKT POOL deallocation failed \n");
1276                 return;
1277         }
1278         g_print("PKT POOL deallocated! \n");
1279
1280         if (media_packet_pool_destroy(pkt_pool) != MEDIA_PACKET_ERROR_NONE) {
1281
1282                 fprintf(stderr, " media_packet_pool_destroy failed\n");
1283                 g_print("PKT POOL destroy failed \n");
1284                 return;
1285         }
1286         g_print("PKT POOL destroyed! \n");
1287 #endif
1288         mediacodec_destroy(app->mc_handle[0]);
1289 }
1290
1291 static void input_filepath(char *filename, App *app)
1292 {
1293         GError *error = NULL;
1294
1295         app->obj++;
1296         app->file = g_mapped_file_new(filename, FALSE, &error);
1297         if (error) {
1298                 g_print("failed to open file : %s\n", error->message);
1299                 g_error_free(error);
1300                 return;
1301         }
1302
1303         app->length = g_mapped_file_get_length(app->file);
1304         app->data = (guint8 *)g_mapped_file_get_contents(app->file);
1305         app->offset = 0;
1306         g_print("len : %d, offset : %d, obj : %d", app->length, app->offset, app->obj);
1307
1308         return;
1309 }
1310
1311 void quit_program(App *app)
1312 {
1313                 media_format_unref(fmt);
1314                 g_main_loop_quit(app->loop);
1315                 elm_exit();
1316
1317 }
1318
1319 void reset_menu_state()
1320 {
1321         g_menu_state = CURRENT_STATUS_MAINMENU;
1322         return;
1323 }
1324
1325 void _interpret_main_menu(char *cmd, App *app)
1326 {
1327         int len =  strlen(cmd);
1328         if (len == 1) {
1329                 if (strncmp(cmd, "a", 1) == 0)
1330                         g_menu_state = CURRENT_STATUS_FILENAME;
1331                 else if (strncmp(cmd, "o", 1) == 0)
1332                         g_menu_state = CURRENT_STATUS_GET_OUTPUT;
1333                 else if (strncmp(cmd, "q", 1) == 0)
1334                         quit_program(app);
1335                 else
1336                         g_print("unknown menu \n");
1337         } else if (len == 2) {
1338                 if (strncmp(cmd, "pr", 2) == 0)
1339                         _mediacodec_prepare(app, 0);
1340                 else if (strncmp(cmd, "pa", 2) == 0)
1341                         _mediacodec_prepare(app, 1);
1342                 else if (strncmp(cmd, "sc", 2) == 0)
1343                         g_menu_state = CURRENT_STATUS_SET_CODEC;
1344                 else if (strncmp(cmd, "vd", 2) == 0)
1345                         g_menu_state = CURRENT_STATUS_SET_VDEC_INFO;
1346                 else if (strncmp(cmd, "ve", 2) == 0)
1347                         g_menu_state = CURRENT_STATUS_SET_VENC_INFO;
1348                 else if (strncmp(cmd, "ad", 2) == 0)
1349                         g_menu_state = CURRENT_STATUS_SET_ADEC_INFO;
1350                 else if (strncmp(cmd, "ae", 2) == 0)
1351                         g_menu_state = CURRENT_STATUS_SET_AENC_INFO;
1352                 else if (strncmp(cmd, "pi", 2) == 0)
1353                         g_menu_state = CURRENT_STATUS_PROCESS_INPUT;
1354                 else if (strncmp(cmd, "un", 2) == 0)
1355                         _mediacodec_unprepare(app);
1356                 else if (strncmp(cmd, "dt", 2) == 0)
1357                         _mediacodec_destroy(app);
1358                 else if (strncmp(cmd, "dp", 2) == 0) {
1359                         if (!app->enable_dump) {
1360                                 app->enable_dump = TRUE;
1361                                 g_print("dump enabled\n");
1362                         } else {
1363                                 app->enable_dump = FALSE;
1364                                 g_print("dump disabled\n");
1365                         }
1366                 } else
1367                         display_sub_basic();
1368         } else {
1369                 g_print("unknown menu \n");
1370         }
1371
1372         return;
1373 }
1374
1375 static void displaymenu(void)
1376 {
1377         if (g_menu_state == CURRENT_STATUS_MAINMENU) {
1378                 display_sub_basic();
1379         } else if (g_menu_state == CURRENT_STATUS_FILENAME) {
1380                 g_print("*** input mediapath.\n");
1381         } else if (g_menu_state == CURRENT_STATUS_SET_CODEC) {
1382                 g_print("*** Codec id : Select Codec ID Numbe  (e.g. AAC_LC = 96)\n");
1383                 g_print("               L16    =  16 (0x10)\n");
1384                 g_print("               ALAW   =  32 (0x20)\n");
1385                 g_print("               ULAW   =  48 (0x30)\n");
1386                 g_print("               AMR_NB =  64 (0x40)\n");
1387                 g_print("               AMR_WB =  65 (0x41)\n");
1388                 g_print("               G729   =  80 (0x50)\n");
1389                 g_print("               AAC_LC =  96 (0x60)\n");
1390                 g_print("               AAC_HE =  97 (0x61)\n");
1391                 g_print("               AAC_PS =  98 (0x62)\n");
1392                 g_print("               MP3    = 112 (0x70)\n");
1393                 g_print("               VORBIS = 128 (0x80)\n");
1394                 g_print("               FLAC   = 144 (0x90)\n");
1395                 g_print("               WMAV1  = 160 (0xA0)\n");
1396                 g_print("               WMAV2  = 161 (0xA1)\n");
1397                 g_print("               WMAPRO = 162 (0xA2)\n");
1398                 g_print("               WMALSL = 163 (0xA3)\n");
1399                 g_print("               -------------------\n");
1400                 g_print("               H261   = 101\n");
1401                 g_print("               H263   = 102\n");
1402                 g_print("               H264   = 103\n");
1403                 g_print("               MJPEG  = 104\n");
1404                 g_print("               MPEG1  = 105\n");
1405                 g_print("               MPEG2  = 106\n");
1406                 g_print("               MPEG4  = 107\n");
1407                 g_print("               -------------------\n");
1408                 g_print("*** Flags : Select Combination Number (e.g. DEOCDER + TYPE_SW = 10)\n");
1409                 g_print("               CODEC : ENCODER =  1       DECODER =  2\n");
1410                 g_print("               TYPE  : HW      =  4       SW      =  8\n");
1411                 g_print("*** input codec id, falgs.\n");
1412         } else if (g_menu_state == CURRENT_STATUS_SET_VDEC_INFO) {
1413                 g_print("*** input video decode configure.(width, height)\n");
1414         } else if (g_menu_state == CURRENT_STATUS_SET_VENC_INFO) {
1415                 g_print("*** input video encode configure.(width, height, fps, target_bits)\n");
1416         } else if (g_menu_state == CURRENT_STATUS_SET_ADEC_INFO) {
1417                 g_print("*** input audio decode configure.(samplerate, channel, bit (e.g. 48000,  2, 16))\n");
1418         } else if (g_menu_state == CURRENT_STATUS_SET_AENC_INFO) {
1419                 g_print("*** input audio encode configure.(samplerate, channel, bit, bitrate (e.g. 48000,  2, 16, 128000))\n");
1420         } else if (g_menu_state == CURRENT_STATUS_PROCESS_INPUT) {
1421                 g_print("*** input dec process number\n");
1422         } else if (g_menu_state == CURRENT_STATUS_GET_OUTPUT) {
1423                 g_print("*** input get output buffer number\n");
1424         } else {
1425                 g_print("*** unknown status.\n");
1426         }
1427         g_print(" >>> ");
1428 }
1429
1430 gboolean timeout_menu_display(void* data)
1431 {
1432         displaymenu();
1433         return FALSE;
1434 }
1435
1436
1437 static void interpret(char *cmd, App *app)
1438 {
1439         switch (g_menu_state) {
1440         case CURRENT_STATUS_MAINMENU:
1441                 _interpret_main_menu(cmd, app);
1442                 break;
1443         case CURRENT_STATUS_FILENAME:
1444                 input_filepath(cmd, app);
1445                 reset_menu_state();
1446                 break;
1447         case CURRENT_STATUS_SET_CODEC:
1448         {
1449                 int tmp;
1450                 static int cnt = 0;
1451                 char **ptr = NULL;
1452                 switch (cnt) {
1453                 case 0:
1454                         tmp = atoi(cmd);
1455
1456                         if (tmp > 100 &&
1457                                 (tmp != 112) &&
1458                                 (tmp != 128) &&
1459                                 (tmp != 144) &&
1460                                 (tmp != 160) && (tmp != 161) && (tmp != 162) && (tmp != 163)) {
1461                                         tmp = strtol(cmd, ptr, 16);
1462                                         app->codecid = 0x2000 + ((tmp & 0xFF) << 4);
1463                         } else
1464                                 app->codecid = 0x1000 + tmp;
1465
1466                         cnt++;
1467                         break;
1468                 case 1:
1469                         app->flag = atoi(cmd);
1470                         cnt = 0;
1471                         reset_menu_state();
1472                         break;
1473                 default:
1474                         break;
1475                 }
1476         }
1477         break;
1478         case CURRENT_STATUS_SET_VDEC_INFO:
1479         {
1480                 static int cnt = 0;
1481                 switch (cnt) {
1482                 case 0:
1483                         app->width = atoi(cmd);
1484                         cnt++;
1485                         break;
1486                 case 1:
1487                         app->height = atoi(cmd);
1488                         app->type = VIDEO_DEC;
1489
1490                         reset_menu_state();
1491                         cnt = 0;
1492                         break;
1493                 default:
1494                         break;
1495                 }
1496         }
1497         break;
1498         case CURRENT_STATUS_SET_VENC_INFO:
1499         {
1500                 static int cnt = 0;
1501                 switch (cnt) {
1502                 case 0:
1503                         app->width = atoi(cmd);
1504                         cnt++;
1505                         break;
1506                 case 1:
1507                         app->height = atoi(cmd);
1508                         cnt++;
1509                         break;
1510                 case 2:
1511                         app->fps = atol(cmd);
1512                         cnt++;
1513                         break;
1514                 case 3:
1515                         app->target_bits = atoi(cmd);
1516                         app->type = VIDEO_ENC;
1517
1518                         reset_menu_state();
1519                         cnt = 0;
1520                         break;
1521                 default:
1522                         break;
1523                 }
1524         }
1525         break;
1526         case CURRENT_STATUS_SET_ADEC_INFO:
1527         {
1528                 static int cnt = 0;
1529                 switch (cnt) {
1530                 case 0:
1531                         app->samplerate = atoi(cmd);
1532                         cnt++;
1533                         break;
1534                 case 1:
1535                         app->channel = atoi(cmd);
1536                         cnt++;
1537                         break;
1538                 case 2:
1539                         app->bit = atoi(cmd);
1540                         app->type = AUDIO_DEC;
1541
1542                         reset_menu_state();
1543                         cnt = 0;
1544                         break;
1545                 default:
1546                         break;
1547                 }
1548         }
1549         break;
1550         case CURRENT_STATUS_SET_AENC_INFO:
1551         {
1552                 static int cnt = 0;
1553                 switch (cnt) {
1554                 case 0:
1555                         app->samplerate = atoi(cmd);
1556                         cnt++;
1557                         break;
1558                 case 1:
1559                         app->channel = atoi(cmd);
1560                         cnt++;
1561                         break;
1562                 case 2:
1563                         app->bit = atoi(cmd);
1564                         cnt++;
1565                         break;
1566                 case 3:
1567                         app->bitrate = atoi(cmd);
1568                         app->type = AUDIO_ENC;
1569
1570                         reset_menu_state();
1571                         cnt = 0;
1572                         break;
1573                 default:
1574                         break;
1575                 }
1576         }
1577         break;
1578         case CURRENT_STATUS_PROCESS_INPUT:
1579         {
1580                 app->frame = atoi(cmd);
1581                 _mediacodec_process_input(app);
1582                 reset_menu_state();
1583         }
1584         break;
1585         case CURRENT_STATUS_GET_OUTPUT:
1586         {
1587                 reset_menu_state();
1588         }
1589         break;
1590         default:
1591                 break;
1592         }
1593
1594         g_timeout_add(100, timeout_menu_display, 0);
1595 }
1596
1597 static void display_sub_basic()
1598 {
1599         g_print("\n");
1600         g_print("=========================================================================================\n");
1601         g_print("                                    media codec test\n");
1602         g_print("-----------------------------------------------------------------------------------------\n");
1603         g_print("a. Create \t\t");
1604         g_print("sc. Set codec \n");
1605         g_print("vd. Set vdec info \t");
1606         g_print("ve. Set venc info \n");
1607         g_print("ad. Set adec info \t");
1608         g_print("ae. Set aenc info \n");
1609         g_print("pr. Prepare \t");
1610         g_print("pa. Prepare and process all\t\t");
1611         g_print("pi. process input with num\n");
1612         g_print("o. Get output \t\t");
1613         g_print("rb. Reset output buffer \n");
1614         g_print("un. Unprepare \t\t");
1615         g_print("dt. Destroy \t\t");
1616         g_print("q. quite test suite \n");
1617         g_print("dp. enable dump \n");
1618         g_print("\n");
1619         g_print("=========================================================================================\n");
1620 }
1621
1622 gboolean input(GIOChannel *channel, GIOCondition cond, gpointer data)
1623 {
1624         gchar buf[MAX_STRING_LEN];
1625         gsize read;
1626         GError *error = NULL;
1627         App *context = (App*)data;
1628
1629         g_io_channel_read_chars(channel, buf, MAX_STRING_LEN, &read, &error);
1630         buf[read] = '\0';
1631         g_strstrip(buf);
1632         interpret(buf, context);
1633
1634         return TRUE;
1635 }
1636
1637 int main(int argc, char *argv[])
1638 {
1639         App *app = &s_app;
1640
1641         GIOChannel *stdin_channel;
1642         stdin_channel = g_io_channel_unix_new(0);
1643         g_io_channel_set_flags(stdin_channel, G_IO_FLAG_NONBLOCK, NULL);
1644         g_io_add_watch(stdin_channel, G_IO_IN, (GIOFunc)input, app);
1645
1646
1647         displaymenu();
1648         app->loop = g_main_loop_new(NULL, TRUE);
1649         app->timer = g_timer_new();
1650         g_main_loop_run(app->loop);
1651
1652
1653
1654         ops.data = app;
1655
1656         return appcore_efl_main(PACKAGE, &argc, &argv, &ops);
1657 }
1658
1659
1660
1661 void mc_hex_dump(char *desc, void *addr, int len)
1662 {
1663         int i;
1664         unsigned char buff[17];
1665         unsigned char *pc = (unsigned char *)addr;
1666
1667         if (desc != NULL)
1668                 printf("%s:\n", desc);
1669
1670         for (i = 0; i < len; i++) {
1671
1672                 if ((i % 16) == 0) {
1673                         if (i != 0)
1674                                 printf("  %s\n", buff);
1675
1676                         printf("  %04x ", i);
1677                 }
1678
1679                 printf(" %02x", pc[i]);
1680
1681                 if ((pc[i] < 0x20) || (pc[i] > 0x7e))
1682                         buff[i % 16] = '.';
1683                 else
1684                         buff[i % 16] = pc[i];
1685                 buff[(i % 16) + 1] = '\0';
1686         }
1687
1688         while ((i % 16) != 0) {
1689                 printf("   ");
1690                 i++;
1691         }
1692         printf("  %s\n", buff);
1693 }
1694
1695 static void decoder_output_dump(App *app, media_packet_h pkt)
1696 {
1697         void *temp;
1698         int i = 0;
1699         int stride_width, stride_height;
1700         char filename[100] = {0};
1701         FILE *fp = NULL;
1702         int ret = 0;
1703
1704         sprintf(filename, "/tmp/dec_output_dump_%d_%d.yuv", app->width, app->height);
1705         fp = fopen(filename, "ab");
1706
1707         media_packet_get_video_plane_data_ptr(pkt, 0, &temp);
1708         media_packet_get_video_stride_width(pkt, 0, &stride_width);
1709         media_packet_get_video_stride_height(pkt, 0, &stride_height);
1710         printf("stride : %d, %d\n", stride_width, stride_height);
1711
1712         for (i = 0; i < app->height; i++) {
1713                 ret = fwrite(temp, app->width, 1, fp);
1714                 temp += stride_width;
1715         }
1716
1717         if (app->hardware == TRUE) {
1718                 media_packet_get_video_plane_data_ptr(pkt, 1, &temp);
1719                 media_packet_get_video_stride_width(pkt, 1, &stride_width);
1720                 for (i = 0; i < app->height/2; i++) {
1721                         ret = fwrite(temp, app->width, 1, fp);
1722                         temp += stride_width;
1723                 }
1724         } else {
1725                 media_packet_get_video_plane_data_ptr(pkt, 1, &temp);
1726                 media_packet_get_video_stride_width(pkt, 1, &stride_width);
1727                 for (i = 0; i < app->height/2; i++) {
1728                         ret = fwrite(temp, app->width/2, 1, fp);
1729                         temp += stride_width;
1730                 }
1731
1732                 media_packet_get_video_plane_data_ptr(pkt, 2, &temp);
1733                 media_packet_get_video_stride_width(pkt, 2, &stride_width);
1734                 for (i = 0; i < app->height/2; i++) {
1735                         ret = fwrite(temp, app->width/2, 1, fp);
1736                         temp += stride_width;
1737                 }
1738         }
1739
1740         g_print("codec dec output dumped!!%d\n", ret);
1741         fclose(fp);
1742
1743 }
1744
1745 /**
1746  *  Add ADTS header at the beginning of each and every AAC packet.
1747  *  This is needed as MediaCodec encoder generates a packet of raw AAC data.
1748  *  Note the packetLen must count in the ADTS header itself.
1749  **/
1750 void add_adts_header_for_aacenc(App *app, char *buffer, int packetLen)
1751 {
1752         int profile = 2;    /* AAC LC (0x01) */
1753         int freqIdx = 3;    /* 48KHz (0x03) */
1754         int chanCfg = 2;    /* CPE (0x02) */
1755
1756         if (app->samplerate == 96000) freqIdx = 0;
1757         else if (app->samplerate == 88200) freqIdx = 1;
1758         else if (app->samplerate == 64000) freqIdx = 2;
1759         else if (app->samplerate == 48000) freqIdx = 3;
1760         else if (app->samplerate == 44100) freqIdx = 4;
1761         else if (app->samplerate == 32000) freqIdx = 5;
1762         else if (app->samplerate == 24000) freqIdx = 6;
1763         else if (app->samplerate == 22050) freqIdx = 7;
1764         else if (app->samplerate == 16000) freqIdx = 8;
1765         else if (app->samplerate == 12000) freqIdx = 9;
1766         else if (app->samplerate == 11025) freqIdx = 10;
1767         else if (app->samplerate == 8000) freqIdx = 11;
1768
1769         if ((app->channel == 1) || (app->channel == 2))
1770                 chanCfg = app->channel;
1771
1772         /* fill in ADTS data */
1773         buffer[0] = (char)0xFF;
1774         buffer[1] = (char)0xF1;
1775         buffer[2] = (char)(((profile-1)<<6) + (freqIdx<<2) +(chanCfg>>2));
1776         buffer[3] = (char)(((chanCfg&3)<<6) + (packetLen>>11));
1777         buffer[4] = (char)((packetLen&0x7FF) >> 3);
1778         buffer[5] = (char)(((packetLen&7)<<5) + 0x1F);
1779         buffer[6] = (char)0xFC;
1780 }
1781
1782 static void output_dump(App *app, media_packet_h pkt)
1783 {
1784         void *temp;
1785         uint64_t buf_size;
1786         char filename[100] = {0};
1787         FILE *fp = NULL;
1788         int ret = 0;
1789         char adts[100] = {0, };
1790
1791         sprintf(filename, "/tmp/dec_output_dump_%d.out", app->type);
1792         fp = fopen(filename, "ab");
1793
1794         media_packet_get_buffer_data_ptr(pkt, &temp);
1795         media_packet_get_buffer_size(pkt, &buf_size);
1796         g_print("output data : %p, size %d\n", temp, (int)buf_size);
1797
1798         if (app->is_encoder && buf_size > 0 && app->codecid == MEDIACODEC_AAC_LC) {
1799                 add_adts_header_for_aacenc(app, adts, (buf_size + ADTS_HEADER_SIZE));
1800                 fwrite(&adts, 1, ADTS_HEADER_SIZE, fp);
1801                 g_print("adts appended\n");
1802         } else if (app->is_encoder && buf_size > 0 && app->codecid == MEDIACODEC_AMR_NB && write_amr_header == 1)       {
1803                 /* This is used only AMR encoder case for adding AMR masic header in only first frame */
1804                 g_print("%s - AMR_header write in first frame\n", __func__);
1805                 fwrite(&AMR_header[0], 1, sizeof(AMR_header)   - 1, fp);         /* AMR-NB magic number */
1806                 write_amr_header = 0;
1807         }
1808
1809         fwrite(temp, (int)buf_size, 1, fp);
1810
1811         g_print("codec dec output dumped!!%d\n", ret);
1812         fclose(fp);
1813
1814 }