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