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