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