Support avi file format
[platform/core/api/mediademuxer.git] / test / mediademuxer_test.c
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /*=======================================================================
18 |  INCLUDE FILES                                                                        |
19 ========================================================================*/
20 #include <unistd.h>
21 #include <string.h>
22 #include <sys/time.h>
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <inttypes.h>
26 #include <glib.h>
27 #include <mm_error.h>
28 #include <mm_debug.h>
29 #include <mediademuxer.h>
30 #include <media_format.h>
31 #include <media_packet.h>
32 #include <media_codec.h>
33
34 /*-----------------------------------------------------------------------
35 |    GLOBAL CONSTANT DEFINITIONS:                                       |
36 -----------------------------------------------------------------------*/
37 #define MAX_STRING_LEN 100
38 #define PACKAGE "mediademuxer_test"
39
40 enum {
41         CURRENT_STATUS_MAINMENU,
42         CURRENT_STATUS_FILENAME,
43         CURRENT_STATUS_SET_DATA
44 };
45
46 /*-----------------------------------------------------------------------
47 |    GLOBAL VARIABLE DEFINITIONS:                                       |
48 -----------------------------------------------------------------------*/
49 mediademuxer_h demuxer = NULL;
50 media_format_mimetype_e v_mime;
51 media_format_mimetype_e a_mime;
52 media_format_mimetype_e t_mime;
53 media_format_text_type_e t_type;
54 int g_menu_state = CURRENT_STATUS_MAINMENU;
55 int num_tracks = 0;
56 int aud_track = -1;
57 int vid_track = -1;
58 int txt_track = -1;
59 int w;
60 int h;
61 int channel = 0;
62 int samplerate = 0;
63 int bit = 0;
64 bool is_adts = 0;
65 bool vid_eos_track = 0;
66 bool aud_eos_track = 0;
67 bool text_eos_track = 0;
68
69 /*-----------------------------------------------------------------------
70 |    DEBUG DEFINITIONS                                                            |
71 -----------------------------------------------------------------------*/
72 /*
73  * D E B U G   M E S S A G E
74  */
75 #define MMF_DEBUG                       "** (demuxer testsuite) DEBUG: "
76 #define MMF_ERR                         "** (demuxer testsuite) ERROR: "
77 #define MMF_INFO                        "** (demuxer testsuite) INFO: "
78 #define MMF_WARN                        "** (demuxer testsuite) WARNING: "
79
80 #define CHECK_MM_ERROR(expr) \
81         do {\
82                 int ret = 0; \
83                 ret = expr; \
84                 if (ret != MEDIADEMUXER_ERROR_NONE) {\
85                         printf("[%s:%d] error code : %x \n", __func__, __LINE__, ret); \
86                         return; \
87                 } \
88         } while (0)
89
90 #define debug_msg_t(fmt, arg...)\
91         do { \
92                 fprintf(stderr, MMF_DEBUG"[%s:%05d]  " fmt "\n", __func__, __LINE__, ##arg); \
93         } while (0)
94
95 #define err_msg_t(fmt, arg...)\
96         do { \
97                 fprintf(stderr, MMF_ERR"[%s:%05d]  " fmt "\n", __func__, __LINE__, ##arg); \
98         } while (0)
99
100 #define info_msg_t(fmt, arg...)\
101         do { \
102                 fprintf(stderr, MMF_INFO"[%s:%05d]  " fmt "\n", __func__, __LINE__, ##arg); \
103         } while (0)
104
105 #define warn_msg_t(fmt, arg...)\
106         do { \
107                 fprintf(stderr, MMF_WARN"[%s:%05d]  " fmt "\n", __func__, __LINE__, ##arg); \
108         } while (0)
109
110
111 /*-----------------------------------------------------------------------
112 |    TEST VARIABLE DEFINITIONS:                                        |
113 -----------------------------------------------------------------------*/
114 #define DEMUXER_OUTPUT_DUMP         1
115
116 #if DEMUXER_OUTPUT_DUMP
117 FILE *fp_audio_out = NULL;
118 FILE *fp_video_out = NULL;
119 FILE *fp_text_out = NULL;
120 bool validate_dump = false;
121
122 #define ADTS_HEADER_SIZE            7
123 unsigned char buf_adts[ADTS_HEADER_SIZE];
124
125 #define AMR_NB_MIME_HDR_SIZE          6
126 #define AMR_WB_MIME_HDR_SIZE          9
127 static const char AMRNB_HDR[] = "#!AMR\n";
128 static const char AMRWB_HDR[] = "#!AMR-WB\n";
129 int write_amrnb_header = 0;     /* write  magic number for AMR-NB Header at one time */
130 int write_amrwb_header = 0;     /* write  magic number for AMR-WB Header at one time */
131 #endif
132
133 bool validate_with_codec = false;
134 mediacodec_h g_media_codec = NULL;
135 FILE *fp_out_codec_audio = NULL;
136 mediacodec_h g_media_codec_1 = NULL;
137 FILE *fp_out_codec_video = NULL;
138
139 /*-----------------------------------------------------------------------
140 |    HELPER  FUNCTION                                                                 |
141 -----------------------------------------------------------------------*/
142
143 #if DEMUXER_OUTPUT_DUMP
144 /**
145  *  Add ADTS header at the beginning of each and every AAC packet.
146  *  This is needed as MediaCodec encoder generates a packet of raw AAC data.
147  *  Note the packetLen must count in the ADTS header itself.
148  **/
149 void generate_header_aac_adts(unsigned char *buffer, int packetLen)
150 {
151         int profile = 2;        /* AAC LC (0x01) */
152         int freqIdx = 4;        /* 44KHz (0x04) */
153         int chanCfg = 1;        /* CPE (0x01) */
154
155         if (samplerate == 96000) freqIdx = 0;
156         else if (samplerate == 88200) freqIdx = 1;
157         else if (samplerate == 64000) freqIdx = 2;
158         else if (samplerate == 48000) freqIdx = 3;
159         else if (samplerate == 44100) freqIdx = 4;
160         else if (samplerate == 32000) freqIdx = 5;
161         else if (samplerate == 24000) freqIdx = 6;
162         else if (samplerate == 22050) freqIdx = 7;
163         else if (samplerate == 16000) freqIdx = 8;
164         else if (samplerate == 12000) freqIdx = 9;
165         else if (samplerate == 11025) freqIdx = 10;
166         else if (samplerate == 8000) freqIdx = 11;
167
168         if ((channel == 1) || (channel == 2))
169                 chanCfg = channel;
170
171         /* Make ADTS header */
172         buffer[0] = (char)0xFF;
173         buffer[1] = (char)0xF1;
174         buffer[2] = (char)(((profile - 1) << 6) + (freqIdx << 2) + (chanCfg >> 2));
175         buffer[3] = (char)(((chanCfg & 3) << 6) + (packetLen >> 11));
176         buffer[4] = (char)((packetLen & 0x7FF) >> 3);
177         buffer[5] = (char)(((packetLen & 7) << 5) + 0x1F);
178         buffer[6] = (char)0xFC;
179 }
180 #endif
181
182 /*-----------------------------------------------------------------------
183 |    LOCAL FUNCTION                                                                 |
184 -----------------------------------------------------------------------*/
185
186 int test_mediademuxer_create()
187 {
188         int ret = 0;
189         g_print("test_mediademuxer_create\n");
190         ret = mediademuxer_create(&demuxer);
191         return ret;
192 }
193
194 int test_mediademuxer_set_data_source(mediademuxer_h demuxer, const char *path)
195 {
196         int ret = 0;
197         g_print("test_mediademuxer_set_data_source\n");
198
199 #if DEMUXER_OUTPUT_DUMP
200         fp_audio_out = fopen("/tmp/dump_audio.out", "wb");
201         if (fp_audio_out != NULL) {
202                 validate_dump = true;
203                 fp_video_out = fopen("/tmp/dump_video.out", "wb");
204                 fp_text_out = fopen("/tmp/dump_text.out", "wb");
205         } else {
206                 g_print("Error - Cannot open file for file dump, Please chek root\n");
207         }
208 #endif
209
210         ret = mediademuxer_set_data_source(demuxer, path);
211         return ret;
212 }
213
214 int test_mediademuxer_prepare()
215 {
216         int ret = 0;
217         g_print("test_mediademuxer_prepare\n");
218         ret = mediademuxer_prepare(demuxer);
219         return ret;
220 }
221
222 int test_mediademuxer_get_track_count()
223 {
224         g_print("test_mediademuxer_get_track_count\n");
225         mediademuxer_get_track_count(demuxer, &num_tracks);
226         g_print("Number of total tracks [%d]\n", num_tracks);
227         return 0;
228 }
229
230 int test_mediademuxer_select_track()
231 {
232         int track = 0;
233         g_print("test_mediademuxer_select_track\n");
234         for (track = 0; track < num_tracks; track++) {
235                 if (mediademuxer_select_track(demuxer, track)) {
236                         g_print("mediademuxer_select_track index [%d] failed\n", track);
237                         return -1;
238                 }
239                 g_print("select track index is [%d] of the total track [%d]\n", track, num_tracks);
240         }
241         return 0;
242 }
243
244 int test_mediademuxer_start()
245 {
246         int ret = 0;
247         g_print("test_mediademuxer_start\n");
248         ret = mediademuxer_start(demuxer);
249         return ret;
250 }
251
252 int test_mediademuxer_get_track_info()
253 {
254         int ret = 0;
255         int track = 0;
256
257         g_print("test_mediademuxer_get_track_info\n");
258         for (; track < num_tracks; track++) {
259                 media_format_h g_media_format;
260                 ret = mediademuxer_get_track_info(demuxer, track, &g_media_format);
261                 if (ret == 0) {
262                         if (media_format_get_video_info(g_media_format, &v_mime,
263                                         &w, &h, NULL, NULL) == MEDIA_FORMAT_ERROR_NONE) {
264                                 g_print("media_format_get_video_info is sucess!\n");
265                                 g_print("\t\t[media_format_get_video]mime:%x, width :%d, height :%d\n",
266                                                         v_mime, w, h);
267                                 vid_track = track;
268                         } else if (media_format_get_audio_info(g_media_format, &a_mime,
269                                                         &channel, &samplerate, &bit, NULL) == MEDIA_FORMAT_ERROR_NONE) {
270                                 g_print("media_format_get_audio_info is sucess!\n");
271                                 g_print("\t\t[media_format_get_audio]mime:%x, channel :%d, samplerate :%d, bit :%d\n",
272                                                         a_mime, channel, samplerate, bit);
273                                 if (a_mime == MEDIA_FORMAT_AAC_LC)
274                                         media_format_get_audio_aac_type(g_media_format, &is_adts);
275                                 aud_track = track;
276                         } else if (media_format_get_text_info(g_media_format, &t_mime, &t_type) == MEDIA_FORMAT_ERROR_NONE) {
277                                         g_print("media_format_get_text_info is sucess!\n");
278                                         g_print("\t\t[media_format_get_text]mime:%x, type:%x\n", t_mime, t_type);
279                                         txt_track = track;
280                         } else {
281                                         g_print("Not Supported YET\n");
282                         }
283                         media_format_unref(g_media_format);
284                         g_media_format = NULL;
285                 } else {
286                         g_print("Error while getting mediademuxer_get_track_info\n");
287                 }
288         }
289
290 #if DEMUXER_OUTPUT_DUMP
291         if ((a_mime == MEDIA_FORMAT_AAC_LC) && (is_adts == 0)) {
292                 g_print("MIME : MEDIA_FORMAT_AAC_LC ------Need to add header for dump test \n");
293         } else if (a_mime == MEDIA_FORMAT_AMR_NB) {
294                 g_print("MIME : MEDIA_FORMAT_AMR_NB ------Need to add header for dump test \n");
295                 write_amrnb_header = 1;
296         } else if (a_mime == MEDIA_FORMAT_AMR_WB) {
297                 g_print("MIME : MEDIA_FORMAT_AMR_WB ------Need to add header for dump test \n");
298                 write_amrwb_header = 1;
299         } else
300                 g_print("--------------------------- Don't Need to add header for dump test\n");
301 #endif
302
303         return ret;
304 }
305
306 static void mediacodec_finish(mediacodec_h handle, FILE *fp)
307 {
308         int err = 0;
309         fclose(fp);
310         mediacodec_unset_output_buffer_available_cb(handle);
311         err = mediacodec_unprepare(handle);
312         if (err != MEDIACODEC_ERROR_NONE) {
313                 g_print("mediacodec_unprepare failed error = %d \n", err);
314                 return;
315         }
316         err = mediacodec_destroy(handle);
317         if (err != MEDIACODEC_ERROR_NONE)
318                 g_print("mediacodec_destory failed error = %d \n", err);
319         return;
320 }
321
322 static void _mediacodec_fill_audio_buffer_cb(media_packet_h pkt, void *user_data)
323 {
324         int err = 0;
325         uint64_t buf_size = 0;
326         void *data = NULL;
327         media_packet_h output_buf;
328
329         if (pkt != NULL) {
330                 err = mediacodec_get_output(g_media_codec, &output_buf, 0);
331                 if (err == MEDIACODEC_ERROR_NONE) {
332                         media_packet_get_buffer_size(output_buf, &buf_size);
333                         media_packet_get_buffer_data_ptr(output_buf, &data);
334                         if (data != NULL)
335                                 fwrite(data, 1, buf_size, fp_out_codec_audio);
336                         else
337                                 g_print("Data is null inside _mediacodec_fill_audio_buffer_cb\n");
338
339                         media_packet_destroy(output_buf);
340                 } else {
341                         g_print("mediacodec_get_output failed inside _mediacodec_fill_audio_buffer_cb err = %d\n", err);
342                         return;
343                 }
344         } else {
345                 g_print("audio pkt from mediacodec is null\n");
346         }
347         return;
348 }
349
350 static void mediacodec_init_audio(int codecid, int flag, int samplerate, int channel, int bit)
351 {
352         /* This file will be used to dump the audio data coming out from mediacodec */
353         fp_out_codec_audio = fopen("/opt/usr/codec_dump_audio.out", "wb");
354         g_print("Create dumped file as codec_dump_audio.out\n");
355
356         if (g_media_codec != NULL) {
357                 mediacodec_unprepare(g_media_codec);
358                 mediacodec_destroy(g_media_codec);
359                 g_media_codec = NULL;
360         }
361         if (mediacodec_create(&g_media_codec) != MEDIACODEC_ERROR_NONE) {
362                 g_print("mediacodec_create is failed\n");
363                 return;
364         }
365         /* Now set the code info */
366         if ((mediacodec_set_codec(g_media_codec, (mediacodec_codec_type_e)codecid,
367                 (mediacodec_support_type_e)flag) != MEDIACODEC_ERROR_NONE)) {
368                 g_print("mediacodec_set_codec is failed\n");
369                 return;
370         }
371         /* set the audio dec info */
372         if ((mediacodec_set_adec_info(g_media_codec, samplerate, channel, bit)) != MEDIACODEC_ERROR_NONE) {
373                 g_print("mediacodec_set_adec is failed\n");
374                 return;
375         }
376         /* Set the callback for output data, which will be used to write the data to file */
377         mediacodec_set_output_buffer_available_cb(g_media_codec,
378                                                                                         _mediacodec_fill_audio_buffer_cb,
379                                                                                         g_media_codec);
380
381         if (MEDIACODEC_ERROR_NONE !=  mediacodec_prepare(g_media_codec)) {
382                 g_print("mediacodec prepare is failed\n");
383                 return;
384         }
385 }
386
387 static void mediacodec_process_audio_pkt(media_packet_h in_buf)
388 {
389         if (g_media_codec != NULL) {
390                 /* process the media packet */
391                 if (MEDIACODEC_ERROR_NONE != mediacodec_process_input(g_media_codec, in_buf, 0)) {
392                         g_print("mediacodec_process_input is failed inside mediacodec_process_audio_pkt\n");
393                         return;
394                 }
395         }
396 }
397
398 void *_fetch_audio_data(void *ptr)
399 {
400         int ret = MEDIADEMUXER_ERROR_NONE;
401         int *status = (int *)g_malloc(sizeof(int) * 1);
402         if (!status) {
403                 g_print("Fail malloc fetch audio data retur status value\n");
404                 return NULL;
405         }
406         media_packet_h audbuf;
407         int count = 0;
408         uint64_t buf_size = 0;
409         void *data = NULL;
410
411         *status = -1;
412         g_print("Audio Data function\n");
413
414         if (validate_with_codec) {
415                 int flag = 0;
416                 if (a_mime == MEDIA_FORMAT_AAC_LC || a_mime == MEDIA_FORMAT_AAC_HE ||
417                         a_mime == MEDIA_FORMAT_AAC_HE_PS) {
418                         flag = 10;
419                         g_print("mediacodec_init_audio() for MEDIACODEC_AAC\n");
420                         mediacodec_init_audio(MEDIACODEC_AAC, flag, samplerate, channel, bit);
421                 } else if (a_mime == MEDIA_FORMAT_MP3) {
422                         flag = 10;
423                         g_print("mediacodec_init_audio() for MEDIACODEC_MP3\n");
424                         mediacodec_init_audio(MEDIACODEC_MP3, flag, samplerate, channel, bit);
425                 } else if (a_mime == MEDIA_FORMAT_AMR_NB) {
426                         flag = 10;
427                         g_print("mediacodec_init_audio() for MEDIACODEC_AMR_NB\n");
428                         mediacodec_init_audio(MEDIACODEC_AMR_NB, flag, samplerate, channel, bit);
429                 } else if (a_mime == MEDIA_FORMAT_AMR_WB) {
430                         flag = 10;
431                         g_print("mediacodec_init_audio() for MEDIACODEC_AMR_WB\n");
432                         mediacodec_init_audio(MEDIACODEC_AMR_WB, flag, samplerate, channel, bit);
433                 } else if (a_mime == MEDIA_FORMAT_FLAC) {
434                         flag = 10;
435                         g_print("mediacodec_init_audio() for MEDIACODEC_FLAC\n");
436                         mediacodec_init_audio(MEDIACODEC_FLAC, flag, samplerate, channel, bit);
437                 } else if (a_mime == MEDIA_FORMAT_VORBIS) {
438                         flag = 10;
439                         g_print("mediacodec_init_audio() for MEDIACODEC_VORBIS\n");
440                         mediacodec_init_audio(MEDIACODEC_VORBIS, flag, samplerate, channel, bit);
441                 } else {
442                         g_print("Not Supported YET- Need to add mime for validating with audio codec\n");
443                         return (void *)status;
444                 }
445         }
446
447         while (1) {
448                 ret = mediademuxer_read_sample(demuxer, aud_track, &audbuf);
449                 if (ret != MEDIADEMUXER_ERROR_NONE) {
450                         g_print("Error (%d) return of mediademuxer_read_sample()\n", ret);
451                         pthread_exit(NULL);
452                 }
453                 if (aud_eos_track)
454                         break;
455                 count++;
456                 media_packet_get_buffer_size(audbuf, &buf_size);
457                 media_packet_get_buffer_data_ptr(audbuf, &data);
458                 g_print("Audio Read Count::[%4d] frame - get_buffer_size = %"PRIu64"\n", count, buf_size);
459
460 #if DEMUXER_OUTPUT_DUMP
461                 if (validate_dump) {
462                         if ((a_mime == MEDIA_FORMAT_AAC_LC) && (is_adts == 0)) {
463                                 /* This is used only AAC raw case for adding each ADTS frame header */
464                                 generate_header_aac_adts(buf_adts, (buf_size+ADTS_HEADER_SIZE));
465                                 fwrite(&buf_adts[0], 1, ADTS_HEADER_SIZE, fp_audio_out);
466                         } else if ((a_mime == MEDIA_FORMAT_AMR_NB) && (write_amrnb_header == 1)) {
467                                 /* This is used only AMR-NB case for adding magic header in only first frame */
468                                 g_print("%s - AMRNB_HDR write in first frame\n", __func__);
469                                 fwrite(&AMRNB_HDR[0], 1, sizeof(AMRNB_HDR)  - 1, fp_audio_out);
470                                 write_amrnb_header = 0;
471                         } else if ((a_mime == MEDIA_FORMAT_AMR_WB) && (write_amrwb_header == 1)) {
472                                 /* This is used only AMR-WB case for adding magic header in only first frame */
473                                 g_print("%s - AMRWB_HDR write in first frame\n", __func__);
474                                 fwrite(&AMRWB_HDR[0], 1, sizeof(AMRWB_HDR)  - 1, fp_audio_out);
475                                 write_amrwb_header = 0;
476                         }
477
478                         if (data != NULL)
479                                 fwrite(data, 1, buf_size, fp_audio_out);
480                         else
481                                 g_print("DUMP : write(audio data) fail for NULL\n");
482                 }
483 #endif
484
485                 if (validate_with_codec)
486                         mediacodec_process_audio_pkt(audbuf);
487                 else
488                         media_packet_destroy(audbuf);
489         }
490
491         g_print("EOS return of mediademuxer_read_sample() for audio\n");
492         *status = 0;
493         if (validate_with_codec)
494                 mediacodec_finish(g_media_codec, fp_out_codec_audio);
495         return (void *)status;
496 }
497
498 static void _mediacodec_fill_video_buffer_cb(media_packet_h pkt, void *user_data)
499 {
500         int err = 0;
501         uint64_t buf_size = 0;
502         void *data = NULL;
503         media_packet_h output_buf;
504
505         if (pkt != NULL) {
506                 err = mediacodec_get_output(g_media_codec_1, &output_buf, 0);
507                 if (err == MEDIACODEC_ERROR_NONE) {
508                         media_packet_get_buffer_size(output_buf, &buf_size);
509                         /* g_print("%s - output_buf size = %lld\n", __func__, buf_size); */
510                         media_packet_get_buffer_data_ptr(output_buf, &data);
511                         if (data != NULL)
512                                 fwrite(data, 1, buf_size, fp_out_codec_video);
513                         else
514                                 g_print("Data is null inside _mediacodec_fill_video_buffer_cb\n");
515                         media_packet_destroy(output_buf);
516                 } else {
517                         g_print("mediacodec_get_output failed inside _mediacodec_fill_video_buffer_cb lerr = %d\n", err);
518                         return;
519                 }
520         } else {
521                 g_print("video pkt from mediacodec is null\n");
522         }
523         return;
524 }
525
526 static void mediacodec_init_video(int codecid, int flag, int width, int height)
527 {
528         /* This file  will be used to dump the data */
529         fp_out_codec_video = fopen("/opt/usr/codec_dump_video.out", "wb");
530         g_print("Create dumped file as codec_dump_video.out\n");
531
532         if (g_media_codec_1 != NULL) {
533                 mediacodec_unprepare(g_media_codec_1);
534                 mediacodec_destroy(g_media_codec_1);
535                 g_media_codec_1 = NULL;
536         }
537         if (mediacodec_create(&g_media_codec_1) != MEDIACODEC_ERROR_NONE) {
538                 g_print("mediacodec_create is failed\n");
539                 return;
540         }
541         /* Now set the code info */
542         if ((mediacodec_set_codec(g_media_codec_1, (mediacodec_codec_type_e)codecid,
543                 (mediacodec_support_type_e)flag) != MEDIACODEC_ERROR_NONE)) {
544                 g_print("mediacodec_set_codec is failed\n");
545                 return;
546         }
547         /* set the video dec info */
548         if ((mediacodec_set_vdec_info(g_media_codec_1, width, height)) != MEDIACODEC_ERROR_NONE) {
549                 g_print("mediacodec_set_vdec is failed\n");
550                 return;
551         }
552         /* Set the callback for output data, which will be used to write the data to file */
553         mediacodec_set_output_buffer_available_cb(g_media_codec_1,
554                                                                                         _mediacodec_fill_video_buffer_cb,
555                                                                                         g_media_codec_1);
556
557         if (MEDIACODEC_ERROR_NONE !=  mediacodec_prepare(g_media_codec_1)) {
558                 g_print("mediacodec_prepare is failed\n");
559                 return;
560         }
561 }
562
563 static void mediacodec_process_video_pkt(media_packet_h in_buf)
564 {
565         if (g_media_codec_1 != NULL) {
566                 /* process the media packet */
567                 if (MEDIACODEC_ERROR_NONE != mediacodec_process_input(g_media_codec_1, in_buf, 0)) {
568                         g_print("mediacodec process input is failed inside mediacodec_process_video_pkt\n");
569                         return;
570                 }
571         } else {
572                 g_print("mediacodec handle is invalid inside mediacodec_process_video_pkt()\n");
573         }
574 }
575
576 #if 0
577 static void _local_media_packet_get_codec_data(media_packet_h pkt)
578 {
579         unsigned char* get_codec_data;
580         unsigned int get_codec_data_size;
581
582         if (media_packet_get_codec_data(pkt, (void**) &get_codec_data, &get_codec_data_size) == MEDIA_PACKET_ERROR_NONE) {
583                 g_print("media_packet_get_codec_data is sucess ... !\n");
584                 g_print("codec_data_size = %u\n", get_codec_data_size);
585                 get_codec_data[get_codec_data_size] = '\0';
586                 if (get_codec_data_size == 0)
587                         return;
588                 g_print("media packet codec_data is [%s] \n", get_codec_data);
589         } else {
590                 g_print("media_packet_get_codec_data is failed...\n");
591         }
592 }
593 #endif
594
595 void *_fetch_video_data(void *ptr)
596 {
597         int ret = MEDIADEMUXER_ERROR_NONE;
598         int *status = (int *)g_malloc(sizeof(int) * 1);
599         if (!status) {
600                 g_print("Fail malloc fetch video data retur status value\n");
601                 return NULL;
602         }
603         media_packet_h vidbuf;
604         int count = 0;
605         uint64_t buf_size = 0;
606         void *data = NULL;
607
608         *status = -1;
609         g_print("Video Data function\n");
610
611         if (validate_with_codec) {
612                 int flag = 0;
613                 if (v_mime == MEDIA_FORMAT_H264_SP || v_mime == MEDIA_FORMAT_H264_MP ||
614                         v_mime == MEDIA_FORMAT_H264_HP) {
615                         flag = 10;
616                         g_print("mediacodec_init_video() for MEDIACODEC_H264\n");
617                         mediacodec_init_video(MEDIACODEC_H264, flag, w, h);
618                 } else if (v_mime == MEDIA_FORMAT_H263) {
619                         g_print("mediacodec_init_video() for MEDIACODEC_H263\n");
620                         flag = 10;
621                         mediacodec_init_video(MEDIACODEC_H263, flag, w, h);
622                 } else {
623                         g_print("Not Supported YET- Need to add mime for validating with video codec\n");
624                         return (void *)status;
625                 }
626         }
627         while (1) {
628                 ret = mediademuxer_read_sample(demuxer, vid_track, &vidbuf);
629                 if (ret != MEDIADEMUXER_ERROR_NONE) {
630                         g_print("Error (%d) return of mediademuxer_read_sample()\n", ret);
631                         pthread_exit(NULL);
632                 }
633                 if (vid_eos_track)
634                         break;
635                 count++;
636                 media_packet_get_buffer_size(vidbuf, &buf_size);
637                 media_packet_get_buffer_data_ptr(vidbuf, &data);
638                 g_print("Video Read Count::[%4d] frame - get_buffer_size = %"PRIu64"\n", count, buf_size);
639 #if 0
640                 /* This is used for debugging purpose */
641                 _local_media_packet_get_codec_data(vidbuf);
642 #endif
643 #if DEMUXER_OUTPUT_DUMP
644                 if (validate_dump) {
645                         if (data != NULL)
646                                 fwrite(data, 1, buf_size, fp_video_out);
647                         else
648                                 g_print("DUMP : write(video data) fail for NULL\n");
649                 }
650 #endif
651
652                 if (validate_with_codec)
653                         mediacodec_process_video_pkt(vidbuf);
654                 else
655                         media_packet_destroy(vidbuf);
656         }
657         g_print("EOS return of mediademuxer_read_sample() for video\n");
658         *status = 0;
659         if (validate_with_codec)
660                 mediacodec_finish(g_media_codec_1, fp_out_codec_video);
661
662         return (void *)status;
663 }
664
665 void *_fetch_text_data(void *ptr)
666 {
667         int ret = MEDIADEMUXER_ERROR_NONE;
668         int *status = (int *)g_malloc(sizeof(int) * 1);
669         if (!status) {
670                 g_print("Fail malloc fetch video data retur status value\n");
671                 return NULL;
672         }
673         media_packet_h txtbuf;
674         int count = 0;
675         uint64_t buf_size = 0;
676         void *data = NULL;
677
678         *status = -1;
679         g_print("text Data function\n");
680         g_print("Text track number is :%d\n", txt_track);
681         while (1) {
682                 ret = mediademuxer_read_sample(demuxer, txt_track, &txtbuf);
683                 if (ret != MEDIADEMUXER_ERROR_NONE) {
684                         g_print("Error (%d) return of mediademuxer_read_sample()\n", ret);
685                         pthread_exit(NULL);
686                 }
687                 if (text_eos_track)
688                         break;
689                 count++;
690                 media_packet_get_buffer_size(txtbuf, &buf_size);
691                 media_packet_get_buffer_data_ptr(txtbuf, &data);
692                 g_print("Text Read Count::[%4d] frame - get_buffer_size = %"PRIu64"\n", count, buf_size);
693 #if DEMUXER_OUTPUT_DUMP
694                 if (validate_dump) {
695                         if (data != NULL)
696                                 fwrite(data, 1, buf_size, fp_text_out);
697                         else
698                                 g_print("DUMP : write(text data) fail for NULL\n");
699                 }
700 #endif
701         }
702         g_print("EOS return of mediademuxer_read_sample()\n");
703         *status = 0;
704         return (void *)status;
705 }
706
707 int test_mediademuxer_read_sample()
708 {
709         pthread_t thread[3];
710         pthread_attr_t attr;
711         /* Initialize and set thread detached attribute */
712         pthread_attr_init(&attr);
713         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
714         if (vid_track != -1) {
715                 g_print("In main: creating thread  for video\n");
716                 pthread_create(&thread[0], &attr, _fetch_video_data, NULL);
717         }
718         if (aud_track != -1) {
719                 g_print("In main: creating thread  for audio\n");
720                 pthread_create(&thread[1], &attr, _fetch_audio_data, NULL);
721         }
722         if (txt_track != -1) {
723                 g_print("In main: creating thread  for text\n");
724                 pthread_create(&thread[2], &attr, _fetch_text_data, NULL);
725         }
726         pthread_attr_destroy(&attr);
727         return 0;
728 }
729
730 int test_mediademuxer_seek_to()
731 {
732         g_print("test_mediademuxer_seek_to\n");
733         int64_t pos = 1;
734         mediademuxer_seek(demuxer, pos);
735         g_print("Number of tracks [%d]\n", num_tracks);
736         return 0;
737 }
738
739 int test_mediademuxer_unselect_track()
740 {
741         g_print("test_mediademuxer_select_track\n");
742         if (mediademuxer_unselect_track(demuxer, 0)) {
743                 g_print("mediademuxer_select track 0 failed\n");
744                 return -1;
745         }
746         return 0;
747 }
748
749 int test_mediademuxer_stop()
750 {
751         int ret = 0;
752         g_print("test_mediademuxer_stop\n");
753         ret = mediademuxer_stop(demuxer);
754         return ret;
755 }
756
757 int test_mediademuxer_unprepare()
758 {
759         int ret = 0;
760         g_print("test_mediademuxer_unprepare\n");
761         ret = mediademuxer_unprepare(demuxer);
762         return ret;
763 }
764
765 int test_mediademuxer_destroy()
766 {
767         int ret = 0;
768         g_print("test_mediademuxer_destroy\n");
769         ret = mediademuxer_destroy(demuxer);
770         demuxer = NULL;
771
772 #if DEMUXER_OUTPUT_DUMP
773         if (fp_audio_out)
774                 fclose(fp_audio_out);
775         if (fp_video_out)
776                 fclose(fp_video_out);
777 #endif
778         return ret;
779 }
780
781 int test_mediademuxer_get_state()
782 {
783         g_print("test_mediademuxer_get_state\n");
784         mediademuxer_state state;
785         if (mediademuxer_get_state(demuxer, &state) == MEDIADEMUXER_ERROR_NONE) {
786                 if (state == MEDIADEMUXER_STATE_NONE)
787                         g_print("Mediademuxer_state = NONE\n");
788                 else if (state == MEDIADEMUXER_STATE_IDLE)
789                         g_print("Mediademuxer_state = IDLE\n");
790                 else if (state == MEDIADEMUXER_STATE_READY)
791                         g_print("Mediademuxer_state = READY\n");
792                 else if (state == MEDIADEMUXER_STATE_DEMUXING)
793                         g_print("Mediademuxer_state = DEMUXING\n");
794                 else
795                         g_print("Mediademuxer_state = NOT SUPPORT STATE\n");
796         } else {
797                 g_print("Mediademuxer_state call failed\n");
798         }
799         return 0;
800 }
801
802 void app_err_cb(mediademuxer_error_e error, void *user_data)
803 {
804         printf("Got Error %d from Mediademuxer\n", error);
805 }
806
807 void app_eos_cb(int track_index, void *user_data)
808 {
809         printf("Got EOS for track -- %d from Mediademuxer\n", track_index);
810         if (track_index == vid_track)
811                 vid_eos_track = true;
812         else if (track_index == aud_track)
813                 aud_eos_track = true;
814         else if (track_index == txt_track)
815                 text_eos_track = true;
816         else
817                 g_print("EOS for invalid track number\n");
818 }
819
820 int test_mediademuxer_set_error_cb()
821 {
822         int ret = 0;
823         g_print("test_mediademuxer_set_error_cb\n");
824         ret = mediademuxer_set_error_cb(demuxer, app_err_cb, demuxer);
825         return ret;
826 }
827
828 int test_mediademuxer_set_eos_cb()
829 {
830         int ret = 0;
831         g_print("test_mediademuxer_set_eos_cb\n");
832         ret = mediademuxer_set_eos_cb(demuxer, app_eos_cb, demuxer);
833         return ret;
834 }
835
836 /*-----------------------------------------------------------------------
837 |    EXTRA FUNCTION                                                                 |
838 -----------------------------------------------------------------------*/
839 int test_mediademuxer_get_sample_track_index()
840 {
841         g_print("test_mediademuxer_get_sample_track_index\n");
842         return 0;
843 }
844
845 int test_mediademuxer_get_sample_track_time()
846 {
847         g_print("test_mediademuxer_get_sample_track_time\n");
848         return 0;
849 }
850
851 int test_mediademuxer_advance()
852 {
853         g_print("test_mediademuxer_advance\n");
854         return 0;
855 }
856
857 int test_mediademuxer_is_key_frame()
858 {
859         g_print("test_mediademuxer_is_key_frame\n");
860         return 0;
861 }
862
863 int test_mediademuxer_is_encrypted()
864 {
865         g_print("test_mediademuxer_is_encrypted\n");
866         return 0;
867 }
868
869 int test_mediademuxer_audio_only()
870 {
871         g_print("AUDIO ONLY\n");
872         return 0;
873 }
874
875 int test_mediademuxer_video_only()
876 {
877         g_print("VIDEO ONLY\n");
878         return 0;
879 }
880
881 int test_mediademuxer_audio_video_only()
882 {
883         g_print("AUDIO & VIDEO ONLY\n");
884         return 0;
885 }
886
887 /*-----------------------------------------------------------------------
888 |    TEST  FUNCTION                                                                 |
889 -----------------------------------------------------------------------*/
890 static void display_sub_basic()
891 {
892         g_print("\n");
893         g_print("===========================================================================\n");
894         g_print("                     media demuxer test\n");
895         g_print(" SELECT : c -> (s) -> e -> p -> (goto submenu) -> d -> q \n");
896         g_print("---------------------------------------------------------------------------\n");
897         g_print("c. Create \t");
898         g_print("s. Set callback \t");
899         g_print("e. Set eos callback \t");
900         g_print("p. Path \t");
901         g_print("d. Destroy \t");
902         g_print("q. Quit \n");
903         g_print("---------------------------------------------------------------------------\n");
904         if (validate_with_codec)
905                 g_print("[Validation with Media codec]\n");
906         else
907                 g_print("[validation as stand alone. To validate with media codec, run mediademuxertest with -c option]\n");
908 }
909
910 void _interpret_main_menu(char *cmd)
911 {
912         int len = strlen(cmd);
913         if (len == 1) {
914                 if (strncmp(cmd, "c", 1) == 0) {
915                         test_mediademuxer_create();
916                 } else if (strncmp(cmd, "s", 1) == 0) {
917                         test_mediademuxer_set_error_cb();
918                 } else if (strncmp(cmd, "e", 1) == 0) {
919                         test_mediademuxer_set_eos_cb();
920                 } else if (strncmp(cmd, "p", 1) == 0) {
921                         g_menu_state = CURRENT_STATUS_FILENAME;
922                 } else if (strncmp(cmd, "d", 1) == 0) {
923                         test_mediademuxer_unprepare();
924                         test_mediademuxer_destroy();
925                 } else if (strncmp(cmd, "q", 1) == 0) {
926                         exit(0);
927                 } else {
928                         g_print("unknown menu \n");
929                 }
930         }
931         return;
932 }
933
934 static void displaymenu(void)
935 {
936         if (g_menu_state == CURRENT_STATUS_MAINMENU) {
937                 display_sub_basic();
938         } else if (g_menu_state == CURRENT_STATUS_FILENAME) {
939                 g_print("*** input media path.\n");
940         } else if (g_menu_state == CURRENT_STATUS_SET_DATA) {
941                 g_print("\n");
942                 g_print("=============================================================\n");
943                 g_print("                     media demuxer submenu\n");
944                 g_print(" SELECT from 1 to 9, others are option \n");
945                 g_print("-------------------------------------------------------------\n");
946                 g_print(" 1. Get Track\t");
947                 g_print(" 2. Select Track\n");
948                 g_print(" 3. Start\t");
949                 g_print(" 4. Get Info\n");
950                 g_print(" 5. Read Sample\n");
951                 g_print(" 6. Stop\t");
952                 g_print(" 7. Unprepare\t");
953                 g_print(" 8. Get state\n");
954                 g_print(" 9. Go Back to main menu\n");
955                 g_print(" a. Seek\t");
956                 g_print(" b. Uselect Track\n");
957                 g_print(" c. Get Sample Track Index\t");
958                 g_print(" d. Get Sample Track Time\n");
959                 g_print(" e. Advance\t");
960                 g_print(" f. Is Key Frame\t");
961                 g_print(" g. Is Key encrypted\n");
962                 g_print("-------------------------------------------------------------\n");
963         } else {
964                 g_print("*** unknown status.\n");
965                 /*  exit(0); */
966         }
967         g_print(" >>> ");
968 }
969
970 void reset_menu_state()
971 {
972         g_menu_state = CURRENT_STATUS_MAINMENU;
973         return;
974 }
975
976 gboolean timeout_menu_display(void *data)
977 {
978         displaymenu();
979         return FALSE;
980 }
981
982 static void interpret(char *cmd)
983 {
984         switch (g_menu_state) {
985         case CURRENT_STATUS_MAINMENU: {
986                         _interpret_main_menu(cmd);
987                         break;
988                 }
989         case CURRENT_STATUS_FILENAME: {
990                         int ret = 0;
991                         ret = test_mediademuxer_set_data_source(demuxer, cmd);
992                         if (ret == MEDIADEMUXER_ERROR_NONE) {
993                                 ret = test_mediademuxer_prepare();
994                                 if (ret == MEDIADEMUXER_ERROR_NONE) {
995                                         g_menu_state = CURRENT_STATUS_SET_DATA;
996                                 } else {
997                                         g_print("test_mediademuxer_prepare failed \n");
998                                         if (ret == MEDIADEMUXER_ERROR_INVALID_OPERATION)
999                                                 g_menu_state = CURRENT_STATUS_MAINMENU;
1000                                         else
1001                                                 g_menu_state = CURRENT_STATUS_FILENAME;
1002                                 }
1003                         } else {
1004                                 if (ret == MEDIADEMUXER_ERROR_INVALID_PATH)
1005                                         g_print("Invalid path, file does not exist\n");
1006                                 g_menu_state = CURRENT_STATUS_FILENAME;
1007                         }
1008                         break;
1009                 }
1010         case CURRENT_STATUS_SET_DATA: {
1011                         int len = strlen(cmd);
1012                         if (len == 1) {
1013                                 if (strncmp(cmd, "1", len) == 0)
1014                                         test_mediademuxer_get_track_count();
1015                                 else if (strncmp(cmd, "2", len) == 0)
1016                                         test_mediademuxer_select_track();
1017                                 else if (strncmp(cmd, "3", len) == 0)
1018                                         test_mediademuxer_start();
1019                                 else if (strncmp(cmd, "4", len) == 0)
1020                                         test_mediademuxer_get_track_info();
1021                                 else if (strncmp(cmd, "5", len) == 0)
1022                                         test_mediademuxer_read_sample();
1023                                 else if (strncmp(cmd, "6", len) == 0)
1024                                         test_mediademuxer_stop();
1025                                 else if (strncmp(cmd, "7", len) == 0)
1026                                         test_mediademuxer_unprepare();
1027                                 else if (strncmp(cmd, "8", len) == 0)
1028                                         test_mediademuxer_get_state();
1029                                 else if (strncmp(cmd, "9", len) == 0)
1030                                         reset_menu_state();
1031                                 else if (strncmp(cmd, "a", len) == 0)
1032                                         test_mediademuxer_seek_to();
1033                                 else if (strncmp(cmd, "b", len) == 0)
1034                                         test_mediademuxer_unselect_track();
1035                                 else if (strncmp(cmd, "c", len) == 0)
1036                                         test_mediademuxer_get_sample_track_index();
1037                                 else if (strncmp(cmd, "d", len) == 0)
1038                                         test_mediademuxer_get_sample_track_time();
1039                                 else if (strncmp(cmd, "e", len) == 0)
1040                                         test_mediademuxer_advance();
1041                                 else if (strncmp(cmd, "f", len) == 0)
1042                                         test_mediademuxer_is_key_frame();
1043                                 else if (strncmp(cmd, "g", len) == 0)
1044                                         test_mediademuxer_is_encrypted();
1045                                 else
1046                                         g_print("UNKNOW COMMAND\n");
1047                         } else if (len == 2) {
1048                                 if (strncmp(cmd, "10", len) == 0)
1049                                         g_print("UNKNOW COMMAND\n");
1050                                 else
1051                                         g_print("UNKNOW COMMAND\n");
1052                         } else {
1053                                 g_print("UNKNOW COMMAND\n");
1054                         }
1055                         break;
1056                 }
1057         default:
1058                         break;
1059         }
1060         g_timeout_add(100, timeout_menu_display, 0);
1061 }
1062
1063 /**
1064  * This function is to execute command.
1065  *
1066  * @param       channel [in]    1st parameter
1067  *
1068  * @return      This function returns TRUE/FALSE
1069  * @remark
1070  * @see
1071  */
1072 gboolean input(GIOChannel *channel)
1073 {
1074         gchar buf[MAX_STRING_LEN];
1075         gsize read;
1076         GError *error = NULL;
1077         g_io_channel_read_chars(channel, buf, MAX_STRING_LEN, &read, &error);
1078         buf[read] = '\0';
1079         g_strstrip(buf);
1080         interpret(buf);
1081         return TRUE;
1082 }
1083
1084 /**
1085  * This function is the example main function for mediademuxer API.
1086  *
1087  * @param
1088  *
1089  * @return      This function returns 0.
1090  * @remark
1091  * @see         other functions
1092  */
1093 int main(int argc, char *argv[])
1094 {
1095         GIOChannel *stdin_channel;
1096         GMainLoop *loop = g_main_loop_new(NULL, 0);
1097         stdin_channel = g_io_channel_unix_new(0);
1098         g_io_channel_set_flags(stdin_channel, G_IO_FLAG_NONBLOCK, NULL);
1099         g_io_add_watch(stdin_channel, G_IO_IN, (GIOFunc) input, NULL);
1100
1101         if (argc > 1) {
1102                 /* Check whether validation with media codec is required */
1103                 if (argv[1][0] == '-' && argv[1][1] == 'c')
1104                         validate_with_codec = true;
1105         }
1106         displaymenu();
1107
1108         g_print("RUN main loop\n");
1109         g_main_loop_run(loop);
1110         g_print("STOP main loop\n");
1111
1112         g_main_loop_unref(loop);
1113         return 0;
1114 }