2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
20 #include <Elementary.h>
21 #include <appcore-efl.h>
24 #include <media_codec.h>
25 #include <media_packet.h>
26 #include <tbm_surface.h>
30 #define PACKAGE "media_codec_test"
35 #define TEST_FILE_SIZE (10 * 1024 * 1024)
36 #define MAX_STRING_LEN 256
38 #define DEFAULT_SAMPPLERATE 44100
39 #define DEFAULT_CHANNEL 2
40 #define DEFAULT_BIT 16
41 #define DEFAULT_BITRATE 128
42 #define DEFAULT_SAMPLEBYTE 1024
43 #define ADTS_HEADER_SIZE 7
44 #define AMRNB_PCM_INPUT_SIZE 320
45 #define AMRWB_PCM_INPUT_SIZE 640
47 #define CHECK_BIT(x, y) (((x) >> (y)) & 0x01)
48 #define GET_IS_ENCODER(x) CHECK_BIT(x, 0)
49 #define GET_IS_DECODER(x) CHECK_BIT(x, 1)
50 #define GET_IS_HW(x) CHECK_BIT(x, 2)
51 #define ES_DEFAULT_VIDEO_PTS_OFFSET 33000000
52 #define CHECK_VALID_PACKET(state, expected_state) \
53 ((state & (expected_state)) == (expected_state))
55 #define AAC_CODECDATA_SIZE 16
56 static int samplerate = DEFAULT_SAMPPLERATE;
57 static int channel = DEFAULT_CHANNEL;
58 static int bit = DEFAULT_BIT;
59 static int bitrate = DEFAULT_BITRATE;
60 static int samplebyte = DEFAULT_SAMPLEBYTE;
61 unsigned char buf_adts[ADTS_HEADER_SIZE];
64 MC_EXIST_SPS = 1 << 0,
65 MC_EXIST_PPS = 1 << 1,
66 MC_EXIST_IDR = 1 << 2,
67 MC_EXIST_SLICE = 1 << 3,
69 MC_VALID_HEADER = (MC_EXIST_SPS | MC_EXIST_PPS),
70 MC_VALID_FIRST_SLICE = (MC_EXIST_SPS | MC_EXIST_PPS | MC_EXIST_IDR)
73 typedef struct _App App;
76 CURRENT_STATUS_MAINMENU,
77 CURRENT_STATUS_FILENAME,
78 CURRENT_STATUS_CREATE,
79 CURRENT_STATUS_DESTROY,
80 CURRENT_STATUS_SET_CODEC,
81 CURRENT_STATUS_SET_VDEC_INFO,
82 CURRENT_STATUS_SET_VENC_INFO,
83 CURRENT_STATUS_SET_ADEC_INFO,
84 CURRENT_STATUS_SET_AENC_INFO,
85 CURRENT_STATUS_PREPARE,
86 CURRENT_STATUS_UNPREPARE,
87 CURRENT_STATUS_PROCESS_INPUT,
88 CURRENT_STATUS_GET_OUTPUT,
89 CURRENT_STATUS_RESET_OUTPUT_BUFFER,
90 CURRENT_STATUS_SET_SIZE,
94 NAL_SLICE_NO_PARTITIONING = 1,
100 NAL_SEQUENCE_PARAMETER_SET,
101 NAL_PICTURE_PARAMETER_SET,
102 NAL_PICTURE_DELIMITER,
135 bool is_video[MAX_HANDLE];
136 bool is_encoder[MAX_HANDLE];
140 mediacodec_h mc_handle[MAX_HANDLE];
145 media_format_mimetype_e mime;
160 media_packet_h packet;
168 media_format_h aenc_fmt = NULL;
169 media_format_h adec_fmt = NULL;
170 media_format_h vdec_fmt = NULL;
171 media_format_h venc_fmt = NULL;
177 /* Internal Functions */
178 static int _create_app(void *data);
179 static int _terminate_app(void *data);
180 static void displaymenu(void);
181 static void display_sub_basic();
184 static void mc_hex_dump(char *desc, void *addr, int len);
185 static void decoder_output_dump(App *app, media_packet_h pkt);
189 void (*extractor)(App *app, unsigned char** data, int *size, bool *have_frame);
191 int g_menu_state = CURRENT_STATUS_MAINMENU;
193 static int _create_app(void *data)
195 printf("My app is going alive!\n");
196 App *app = (App*)data;
198 g_mutex_init(&app->lock);
202 static int _terminate_app(void *data)
204 printf("My app is going gone!\n");
205 App *app = (App*)data;
207 g_mutex_clear(&app->lock);
212 struct appcore_ops ops = {
213 .create = _create_app,
214 .terminate = _terminate_app,
217 static const guint mp3types_bitrates[2][3][16] = {
219 {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448,},
220 {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384,},
221 {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320,}
224 {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256,},
225 {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,},
226 {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,}
230 static const guint mp3types_freqs[3][3] = { {44100, 48000, 32000},
231 {22050, 24000, 16000},
235 void h264_extractor(App *app, unsigned char **data, int *size, bool *have_frame)
238 unsigned char val, zero_count;
239 unsigned char *pNal = app->data + app->offset;
240 int max = app->length - app->offset;
243 int nal_unit_type = 0;
271 if ((zero_count >= 2) && (val == 1))
281 read = (index - zero_count - 1);
283 nal_unit_type = *(app->data+app->offset+4) & 0x1F;
284 g_print("nal_unit_type : %x\n", nal_unit_type);
286 switch (nal_unit_type) {
287 case NAL_SEQUENCE_PARAMETER_SET:
288 g_print("nal_unit_type : SPS\n");
289 state |= MC_EXIST_SPS;
291 case NAL_PICTURE_PARAMETER_SET:
292 g_print("nal_unit_type : PPS\n");
293 state |= MC_EXIST_PPS;
297 g_print ("nal_unit_type : IDR\n");
298 state |= MC_EXIST_IDR;
300 case NAL_SLICE_NO_PARTITIONING:
301 case NAL_SLICE_PART_A:
302 case NAL_SLICE_PART_B:
303 case NAL_SLICE_PART_C:
304 state |= MC_EXIST_SLICE;
307 g_print ("nal_unit_type : %x", nal_unit_type);
311 init = CHECK_VALID_PACKET(state, MC_VALID_FIRST_SLICE) ? 1 : 0;
312 slice = CHECK_VALID_PACKET(state, MC_EXIST_SLICE) ? 1 : 0;
313 idr = CHECK_VALID_PACKET(state, MC_EXIST_IDR) ? 1 : 0;
314 g_print("status : %d, slice : %d, idr : %d\n", init, slice, idr);
316 if (init || idr || slice) {
320 *size = app->offset + read;
322 *data = app->data+app->offset;
327 *data = app->data+app->offset;
334 void h263_extractor(App * app, unsigned char **data, int *size, bool * have_frame)
338 int read_size = 1, state = 1, bStart = 0;
340 unsigned char *pH263 = app->data + app->offset;
342 int max = app->length - app->offset;
347 read_size = (len - 1);
365 if ((val & 0xFC) == 0x80) {
378 app->offset += read_size;
381 void mpeg4_extractor(App * app, unsigned char **data, int *size, bool * have_frame)
386 int read_size = 1, state = 1, bType = 0, bStart = 0;
388 unsigned char *pMpeg4 = app->data + app->offset;
390 int max = app->length - app->offset;
394 read_size = (len - 1);
420 if (val == 0xB0 || val == 0xB6) {
426 if (have_frame && val == 0xB0)
436 app->offset += result;
441 * Extract Input data for AMR-NB/WB decoder
442 * - AMR-NB : mime type ("audio/AMR") / 8Khz / 1 ch / 16 bits
443 * - AMR-WB : mime type ("audio/AMR-WB") / 16Khz / 1 ch / 16 bits
445 static const char AMR_header[] = "#!AMR\n";
446 static const char AMRWB_header[] = "#!AMR-WB\n";
447 #define AMR_NB_MIME_HDR_SIZE 6
448 #define AMR_WB_MIME_HDR_SIZE 9
449 static const int block_size_nb[16] = { 12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0 };
450 static const int block_size_wb[16] = { 17, 23, 32, 36, 40, 46, 50, 58, 60, 5, -1, -1, -1, -1, 0, 0 };
453 void amrdec_extractor(App * app, unsigned char **data, int *size, bool * have_frame)
455 int readsize = 0, mode_temp;
457 unsigned int mime_size = AMR_NB_MIME_HDR_SIZE;
458 unsigned int fsize, mode;
459 unsigned char *pAmr = app->data + app->offset;
460 int max = app->length - app->offset;
461 //change the below one to frame count
462 if (app->offset == 0) {
463 if (!memcmp(pAmr, AMR_header, AMR_NB_MIME_HDR_SIZE)) {
464 blocksize_tbl = (int *)block_size_nb;
465 mode_temp = pAmr[AMR_NB_MIME_HDR_SIZE];
466 pAmr = pAmr + AMR_NB_MIME_HDR_SIZE;
467 app->offset += AMR_NB_MIME_HDR_SIZE;
469 if (!memcmp(pAmr, AMRWB_header, AMR_WB_MIME_HDR_SIZE)) {
470 mime_size = AMR_WB_MIME_HDR_SIZE;
471 blocksize_tbl = (int *)block_size_wb;
472 mode_temp = pAmr[AMR_WB_MIME_HDR_SIZE];
473 pAmr = pAmr + AMR_WB_MIME_HDR_SIZE;
474 app->offset += AMR_WB_MIME_HDR_SIZE;
476 g_print("[ERROR] AMR-NB/WB don't detected..\n");
482 if ((mode_temp & 0x83) == 0) {
483 mode = (mode_temp >> 3) & 0x0F; /* Yep. Retrieve the frame size */
484 fsize = blocksize_tbl[mode];
485 readsize = fsize + 1;
488 g_print("[FAIL] Not found amr frame sync.....\n");
493 app->offset += readsize;
498 void nv12_extractor(App *app, unsigned char **data, int *size, bool *have_frame)
501 int offset = app->length - app->offset;
503 yuv_size = app->width * app->height * 3 / 2;
505 if (offset >= yuv_size)
509 *data = app->data + app->offset;
511 if (offset >= yuv_size)
517 void yuv_extractor(App *app, unsigned char **data, int *size, bool *have_frame)
520 int offset = app->length - app->offset;
522 yuv_size = app->width * app->height * 3 / 2;
524 if (yuv_size >= offset)
528 *data = app->data + app->offset;
530 if (yuv_size >= offset)
535 app->offset += *size;
539 void aacenc_extractor(App *app, unsigned char **data, int *size, bool *have_frame)
542 int offset = app->length - app->offset;
544 read_size = ((samplebyte*app->channel)*(app->bit/8));
549 if (offset >= read_size)
554 app->offset += *size;
557 void amrenc_extractor(App *app, unsigned char **data, int *size, bool *have_frame)
560 int offset = app->length - app->offset;
563 read_size = AMRNB_PCM_INPUT_SIZE;
565 read_size = AMRWB_PCM_INPUT_SIZE;
569 if (offset >= read_size)
574 app->offset += *size;
578 * Extract Input data for AAC decoder
579 * (case of (LC profile) ADTS format)
580 * codec_data : Don't need
582 void aacdec_extractor(App *app, unsigned char **data, int *size, bool *have_frame)
585 int offset = app->length - app->offset;
586 unsigned char *pData = app->data + app->offset;
588 if ((pData != NULL) && (pData[0] == 0xff) && ((pData[1] & 0xf6) == 0xf0)) {
589 read_size = ((pData[3] & 0x03) << 11) | (pData[4] << 3) | ((pData[5] & 0xe0) >> 5);
592 g_print("[FAIL] Not found aac frame sync.....\n");
596 *data = app->data + app->offset;
598 if (read_size >= offset)
603 app->offset += *size;
607 void mp3dec_extractor(App *app, unsigned char **data, int *size, bool *have_frame)
611 guint padding, bitrate, lsf, layer, mpg25;
612 guint hdr_bitrate, sf;
613 int offset = app->length - app->offset;
614 unsigned char *pData = app->data + app->offset;
616 header = GST_READ_UINT32_BE(pData);
619 g_print ("[ERROR] read header size is 0\n");
623 /* if it's not a valid sync */
624 if ((header & 0xffe00000) != 0xffe00000) {
625 g_print ("[ERROR] invalid sync\n");
629 if (((header >> 19) & 3) == 0x1) {
630 g_print ("[ERROR] invalid MPEG version: %d\n", (header >> 19) & 3);
633 if (header & (1 << 20)) {
634 lsf = (header & (1 << 19)) ? 0 : 1;
642 /* if it's an invalid layer */
643 if (!((header >> 17) & 3)) {
644 g_print("[ERROR] invalid layer: %d\n", (header >> 17) & 3);
647 layer = 4 - ((header >> 17) & 0x3);
650 /* if it's an invalid bitrate */
651 if (((header >> 12) & 0xf) == 0xf) {
652 g_print ("[ERROR] invalid bitrate: %d\n", (header >> 12) & 0xf);
655 bitrate = (header >> 12) & 0xF;
656 hdr_bitrate = mp3types_bitrates[lsf][layer - 1][bitrate] * 1000;
657 /* The caller has ensured we have a valid header, so bitrate can't be zero here. */
658 if (hdr_bitrate == 0)
662 /* if it's an invalid samplerate */
663 if (((header >> 10) & 0x3) == 0x3) {
664 g_print ("[ERROR] invalid samplerate: %d\n", (header >> 10) & 0x3);
667 sf = (header >> 10) & 0x3;
668 sf = mp3types_freqs[lsf + mpg25][sf];
671 padding = (header >> 9) & 0x1;
675 read_size = 4 * ((hdr_bitrate * 12) / sf + padding);
678 read_size = (hdr_bitrate * 144) / sf + padding;
682 read_size = (hdr_bitrate * 144) / (sf << lsf) + padding;
685 g_print("header : %d, read : %d\n", header, read_size);
688 *data = app->data + app->offset;
690 if (read_size >= offset)
695 app->offset += *size;
699 void extract_input_aacdec_m4a_test(App * app, unsigned char **data, int *size, bool * have_frame)
701 int readsize = 0, read_size = 0;
703 unsigned int header_size = ADTS_HEADER_SIZE;
704 unsigned char buffer[1000000];
705 unsigned char codecdata[AAC_CODECDATA_SIZE] = { 0, };
706 int offset = app->length - app->offset;
707 unsigned char *pData = app->data + app->offset;
709 * It is not support full parsing MP4 container box.
710 * So It MUST start as RAW valid frame sequence.
711 * Testsuit that are not guaranteed to be available on functionality of all General DEMUXER/PARSER.
714 //change the below one later
715 if (app->offset == 0) {
717 * CAUTION : Codec data is needed only once in first time
718 * Codec data is made(or extracted) by MP4 demuxer in 'esds' box.
719 * So I use this data (byte) as hard coding for temporary our testing.
723 * The codec_data data is according to AudioSpecificConfig,
724 * ISO/IEC 14496-3, 1.6.2.1
726 * below example is test for using "test.aac" or "TestSample-AAC-LC.m4a"
727 * case : M4A - LC profile
728 * codec_data=(buffer)119056e5000000000000000000000000
729 * savs aac decoder get codec_data. size: 16 (Tag size : 5 byte)
730 * - codec data: profile : 2
731 * - codec data: samplrate: 48000
732 * - codec data: channels : 2
734 /* 2 bytes are mandatory */
735 codecdata[0] = 0x11; /* ex) (5bit) 2 (LC) / (4bit) 3 (48khz)*/
736 codecdata[1] = 0x90; /* ex) (4bit) 2 (2ch) */
737 /* othter bytes are (optional) epconfig information */
743 * below example is test for using "TestSample-EAAC+.m4a"
745 * case : M4A - HE-AAC v1 and v2 profile
746 * codec_data=(buffer)138856e5a54880000000000000000000
747 * savs aac decoder get codec_data. size: 16 (Tag size : 7 byte)
748 * - codec data: profile : 2
749 * - codec data: samplrate: 22050
750 * - codec data: channels : 1
752 /* 2 bytes are mandatory */
753 codecdata[0] = 0x13; /* ex) (5bit) 2 (LC) / (4bit) 9 (22khz) */
754 codecdata[1] = 0x88; /* ex) (4bit) 1 (1ch) */
755 /* othter bytes are (optional) epconfig information */
763 memcpy(buffer, codecdata, AAC_CODECDATA_SIZE);
764 if ((pData != NULL) && (pData[0] == 0xff) && ((pData[1] & 0xf6) == 0xf0)) {
765 read_size = ((pData[3] & 0x03) << 11) | (pData[4] << 3) | ((pData[5] & 0xe0) >> 5);
768 g_print("[FAIL] Not found aac frame sync.....\n");
770 readsize = read_size - header_size;
771 memcpy(buffer + AAC_CODECDATA_SIZE, pData + 7, readsize);
772 read_size = readsize + AAC_CODECDATA_SIZE; //return combination of (codec_data + raw_data)
773 app->offset += header_size + readsize;
777 if ((pData != NULL) && (pData[0] == 0xff) && ((pData[1] & 0xf6) == 0xf0)) {
778 read_size = ((pData[3] & 0x03) << 11) | (pData[4] << 3) | ((pData[5] & 0xe0) >> 5);
779 readsize = read_size - header_size;
780 memcpy(buffer, pData + 7, readsize); //Make only RAW data, so exclude header 7 bytes
781 read_size = readsize;
782 app->offset += header_size + readsize;
786 g_print("[FAIL] Not found aac frame sync. \n");
791 if (read_size >= offset)
799 * Extract Input data for AAC encoder
802 void aacenc_extractor(App *app, unsigned char **data, int *size, bool *have_frame)
805 int offset = app->length - app->offset;
807 read_size = ((DEFAULT_SAMPLEBYTE*DEFAULT_CHANNEL)*(DEFAULT_BIT/8));
809 if (read_size >= offset)
813 *data = app->data + app->offset;
815 if (read_size >= offset)
820 app->offset += *size;
823 static void _mediacodec_empty_buffer_cb(media_packet_h pkt, void *user_data)
826 g_print("Used input buffer = %p\n", pkt);
827 media_packet_destroy(pkt);
832 int _mediacodec_set_codec(int codecid, int flag, int *hardware)
835 media_format_mimetype_e mime;
836 encoder = GET_IS_ENCODER(flag) ? 1 : 0;
837 *hardware = GET_IS_HW(flag) ? 1 : 0;
840 case MEDIACODEC_H264:
842 extractor = yuv_extractor;
843 mime = *hardware ? MEDIA_FORMAT_NV12 : MEDIA_FORMAT_I420;
845 extractor = h264_extractor;
846 mime = MEDIA_FORMAT_H264_SP;
849 case MEDIACODEC_MPEG4:
851 extractor = yuv_extractor;
852 mime = *hardware ? MEDIA_FORMAT_NV12 : MEDIA_FORMAT_I420;
854 extractor = mpeg4_extractor;
855 mime = MEDIA_FORMAT_MPEG4_SP;
858 case MEDIACODEC_H263:
860 extractor = h263_extractor;
861 mime = *hardware ? MEDIA_FORMAT_NV12 : MEDIA_FORMAT_I420;
863 extractor = h263_extractor;
864 mime = MEDIA_FORMAT_H263P;
869 extractor = aacenc_extractor;
870 mime = MEDIA_FORMAT_PCM;
872 extractor = aacdec_extractor;
873 mime = MEDIA_FORMAT_AAC;
876 case MEDIACODEC_AAC_HE:
878 extractor = aacenc_extractor;
879 mime = MEDIA_FORMAT_PCM;
881 extractor = extract_input_aacdec_m4a_test;
882 mime = MEDIA_FORMAT_AAC_HE;
885 case MEDIACODEC_AAC_HE_PS:
888 extractor = mp3dec_extractor;
889 mime = MEDIA_FORMAT_MP3;
891 case MEDIACODEC_VORBIS:
893 case MEDIACODEC_FLAC:
895 case MEDIACODEC_WMAV1:
897 case MEDIACODEC_WMAV2:
899 case MEDIACODEC_WMAPRO:
901 case MEDIACODEC_WMALSL:
903 case MEDIACODEC_AMR_NB:
904 extractor = amrdec_extractor;
905 mime = MEDIA_FORMAT_AMR_NB;
907 case MEDIACODEC_AMR_WB:
908 extractor = amrdec_extractor;
909 mime = MEDIA_FORMAT_AMR_WB;
912 LOGE("NOT SUPPORTED!!!!");
918 static gboolean read_data(App *app)
921 bool have_frame = FALSE;
923 static guint64 pts = 0L;
924 void *buf_data_ptr = NULL;
925 media_packet_h pkt = NULL;
930 int stride_width, stride_height;
932 g_print("----------read data------------\n");
933 extractor(app, &tmp, &read, &have_frame);
935 if (app->offset >= app->length - 1) {
938 app->finish = clock();
939 g_main_loop_quit(app->loop);
942 g_print("length : %d, offset : %d\n", app->length, app->offset);
944 if (app->offset + len > app->length)
945 len = app->length - app->offset;
947 g_print("%p, %d, have_frame :%d, read: %d\n", tmp, (int)read, have_frame, read);
950 if (media_packet_create_alloc(vdec_fmt, NULL, NULL, &pkt) != MEDIA_PACKET_ERROR_NONE) {
951 fprintf(stderr, "media_packet_create_alloc failed\n");
955 if (media_packet_set_pts(pkt, (uint64_t)(pts)) != MEDIA_PACKET_ERROR_NONE) {
956 fprintf(stderr, "media_packet_set_pts failed\n");
960 if (app->type != VIDEO_ENC) {
961 media_packet_get_buffer_data_ptr(pkt, &buf_data_ptr);
962 media_packet_set_buffer_size(pkt, (uint64_t)read);
964 memcpy(buf_data_ptr, tmp, read);
965 g_print("tmp:%p, read:%d\n", tmp, read);
968 media_packet_get_video_plane_data_ptr(pkt, 0, &buf_data_ptr);
969 media_packet_get_video_stride_width(pkt, 0, &stride_width);
970 media_packet_get_video_stride_height(pkt, 0, &stride_height);
972 offset = stride_width*stride_height;
974 memcpy(buf_data_ptr, tmp, offset);
977 media_packet_get_video_plane_data_ptr(pkt, 1, &buf_data_ptr);
978 media_packet_get_video_stride_width(pkt, 1, &stride_width);
979 media_packet_get_video_stride_height(pkt, 1, &stride_height);
980 memcpy(buf_data_ptr, tmp + offset, stride_width*stride_height);
982 if (app->hardware == FALSE) {
984 media_packet_get_video_plane_data_ptr(pkt, 2, &buf_data_ptr);
985 media_packet_get_video_stride_width(pkt, 2, &stride_width);
986 media_packet_get_video_stride_height(pkt, 2, &stride_height);
988 offset += stride_width * stride_height;
991 memcpy(buf_data_ptr, tmp + offset, stride_width*stride_height);
994 mc_hex_dump("inbuf", tmp, 48);
996 ret = mediacodec_process_input(app->mc_handle[0], pkt, 0);
997 if (ret != MEDIACODEC_ERROR_NONE)
1000 pts += ES_DEFAULT_VIDEO_PTS_OFFSET;
1006 static void start_feed(App *app)
1008 if (app->sourceid == 0) {
1009 app->sourceid = g_idle_add((GSourceFunc)read_data, app);
1010 g_print("start_feed\n");
1014 static void stop_feed(App *app)
1016 if (app->sourceid != 0) {
1017 g_source_remove(app->sourceid);
1019 g_print("stop_feed\n");
1023 static bool _mediacodec_inbuf_used_cb(media_packet_h pkt, void *user_data)
1025 g_print("_mediacodec_inbuf_used_cb!!!\n");
1026 media_packet_destroy(pkt);
1030 static bool _mediacodec_outbuf_available_cb(media_packet_h pkt, void *user_data)
1032 media_packet_h out_pkt = NULL;
1035 App *app = (App*)user_data;
1037 g_print("_mediacodec_outbuf_available_cb\n");
1039 g_mutex_lock(&app->lock);
1041 ret = mediacodec_get_output(app->mc_handle[0], &out_pkt, 0);
1043 if (ret != MEDIACODEC_ERROR_NONE)
1044 g_print("get_output failed\n");
1046 //decoder_output_dump(app, out_pkt);
1051 int stride_width, stride_height;
1053 media_packet_get_buffer_data_ptr(out_pkt, &data);
1054 media_packet_get_buffer_size(out_pkt, &buf_size);
1055 g_print("output data : %p, size %d\n", data, (int)buf_size);
1057 fwrite(data, 1, buf_size, fp_out);
1064 g_mutex_unlock(&app->lock);
1066 media_packet_destroy(out_pkt);
1073 static bool _mediacodec_buffer_status_cb(mediacodec_status_e status, void *user_data)
1075 g_print("_mediacodec_buffer_status_cb %d\n", status);
1077 App *app = (App*)user_data;
1079 if (status == MEDIACODEC_NEED_DATA)
1081 else if (status == MEDIACODEC_ENOUGH_DATA)
1087 static bool _mediacodec_error_cb(mediacodec_error_e error, void *user_data)
1092 static bool _mediacodec_eos_cb(void *user_data)
1097 static void _mediacodec_prepare(App *app)
1100 media_format_mimetype_e mime;
1103 fp_out = fopen("/tmp/codec_dump.out", "wb");
1105 /* create instance */
1106 ret = mediacodec_create(&app->mc_handle[0]);
1107 if (ret != MEDIACODEC_ERROR_NONE) {
1108 g_print("mediacodec_create failed\n");
1113 ret = mediacodec_set_codec(app->mc_handle[0], app->codecid, app->flag);
1114 if (ret != MEDIACODEC_ERROR_NONE) {
1115 g_print("mediacodec_set_codec failed\n");
1120 app->mime = _mediacodec_set_codec(app->codecid, app->flag, &app->hardware);
1122 /* set codec info */
1123 ret = media_format_create(&vdec_fmt);
1125 switch (app->type) {
1127 ret = mediacodec_set_vdec_info(app->mc_handle[0], app->width, app->height);
1128 media_format_set_video_mime(vdec_fmt, app->mime);
1129 media_format_set_video_width(vdec_fmt, app->width);
1130 media_format_set_video_height(vdec_fmt, app->height);
1133 ret = mediacodec_set_venc_info(app->mc_handle[0], app->width, app->height, app->fps, app->target_bits);
1134 media_format_set_video_mime(vdec_fmt, app->mime);
1135 media_format_set_video_width(vdec_fmt, app->width);
1136 media_format_set_video_height(vdec_fmt, app->height);
1137 media_format_set_video_avg_bps(vdec_fmt, app->target_bits);
1140 ret = mediacodec_set_adec_info(app->mc_handle[0], app->samplerate, app->channel, app->bit);
1141 media_format_set_audio_mime(vdec_fmt, app->mime);
1142 media_format_set_audio_channel(vdec_fmt, app->channel);
1143 media_format_set_audio_samplerate(vdec_fmt, app->samplerate);
1144 media_format_set_audio_bit(vdec_fmt, app->bit);
1147 ret = mediacodec_set_aenc_info(app->mc_handle[0], app->samplerate, app->channel, app->bit, app->bitrate);
1148 media_format_set_audio_mime(vdec_fmt, app->mime);
1149 media_format_set_audio_channel(vdec_fmt, app->channel);
1150 media_format_set_audio_samplerate(vdec_fmt, app->samplerate);
1151 media_format_set_audio_bit(vdec_fmt, app->bit);
1154 g_print("invaild type\n");
1158 if (ret != MEDIACODEC_ERROR_NONE) {
1159 g_print("mediacodec_set_xxxc(%d)_info failed\n", app->type);
1164 mediacodec_set_input_buffer_used_cb(app->mc_handle[0], _mediacodec_inbuf_used_cb, NULL);
1165 mediacodec_set_output_buffer_available_cb(app->mc_handle[0], _mediacodec_outbuf_available_cb, app);
1166 mediacodec_set_buffer_status_cb(app->mc_handle[0], _mediacodec_buffer_status_cb, app);
1167 mediacodec_set_eos_cb(app->mc_handle[0], _mediacodec_eos_cb, NULL);
1168 mediacodec_set_error_cb(app->mc_handle[0], _mediacodec_error_cb, NULL);
1171 ret = mediacodec_prepare(app->mc_handle[0]);
1172 if (ret != MEDIACODEC_ERROR_NONE) {
1173 g_print("mediacodec_prepare failed\n");
1177 app->frame_count = 0;
1178 app->start = clock();
1179 g_main_loop_run(app->loop);
1181 g_print("Average FPS = %3.3f\n", ((double)app->frame_count*1000000/(app->finish - app->start)));
1183 g_print("---------------------------\n");
1188 static void input_filepath(char *filename, App *app)
1190 GError *error = NULL;
1193 app->file = g_mapped_file_new(filename, FALSE, &error);
1195 g_print("failed to open file : %s\n", error->message);
1196 g_error_free(error);
1200 app->length = g_mapped_file_get_length(app->file);
1201 app->data = (guint8 *)g_mapped_file_get_contents(app->file);
1203 g_print("len : %d, offset : %d, obj : %d", app->length, (int)app->offset, app->obj);
1218 void reset_menu_state()
1220 g_menu_state = CURRENT_STATUS_MAINMENU;
1224 void _interpret_main_menu(char *cmd, App *app)
1226 int len = strlen(cmd);
1228 if (strncmp(cmd, "a", 1) == 0)
1229 g_menu_state = CURRENT_STATUS_FILENAME;
1230 else if (strncmp(cmd, "o", 1) == 0)
1231 g_menu_state = CURRENT_STATUS_GET_OUTPUT;
1232 else if (strncmp(cmd, "q", 1) == 0)
1235 g_print("unknown menu \n");
1236 } else if (len == 2) {
1237 if (strncmp(cmd, "pr", 2) == 0)
1238 _mediacodec_prepare(app);
1239 else if (strncmp(cmd, "sc", 2) == 0)
1240 g_menu_state = CURRENT_STATUS_SET_CODEC;
1241 else if (strncmp(cmd, "vd", 2) == 0)
1242 g_menu_state = CURRENT_STATUS_SET_VDEC_INFO;
1243 else if (strncmp(cmd, "ve", 2) == 0)
1244 g_menu_state = CURRENT_STATUS_SET_VENC_INFO;
1245 else if (strncmp(cmd, "ad", 2) == 0)
1246 g_menu_state = CURRENT_STATUS_SET_ADEC_INFO;
1247 else if (strncmp(cmd, "ae", 2) == 0)
1248 g_menu_state = CURRENT_STATUS_SET_AENC_INFO;
1249 else if (strncmp(cmd, "pi", 2) == 0)
1250 g_menu_state = CURRENT_STATUS_PROCESS_INPUT;
1252 display_sub_basic();
1254 g_print("unknown menu \n");
1260 static void displaymenu(void)
1262 if (g_menu_state == CURRENT_STATUS_MAINMENU) {
1263 display_sub_basic();
1264 } else if (g_menu_state == CURRENT_STATUS_FILENAME) {
1265 g_print("*** input mediapath.\n");
1266 } else if (g_menu_state == CURRENT_STATUS_SET_CODEC) {
1267 g_print("*** Codec id : Select Codec ID Numbe (e.g. AAC_LC = 96)\n");
1268 g_print(" L16 = 16 (0x10)\n");
1269 g_print(" ALAW = 32 (0x20)\n");
1270 g_print(" ULAW = 48 (0x30)\n");
1271 g_print(" AMR_NB = 64 (0x40)\n");
1272 g_print(" AMR_WB = 65 (0x41)\n");
1273 g_print(" G729 = 80 (0x50)\n");
1274 g_print(" AAC_LC = 96 (0x60)\n");
1275 g_print(" AAC_HE = 97 (0x61)\n");
1276 g_print(" AAC_PS = 98 (0x62)\n");
1277 g_print(" MP3 = 112 (0x70)\n");
1278 g_print(" VORBIS = 128 (0x80)\n");
1279 g_print(" FLAC = 144 (0x90)\n");
1280 g_print(" WMAV1 = 160 (0xA0)\n");
1281 g_print(" WMAV2 = 161 (0xA1)\n");
1282 g_print(" WMAPRO = 162 (0xA2)\n");
1283 g_print(" WMALSL = 163 (0xA3)\n");
1284 g_print(" -------------------\n");
1285 g_print(" H261 = 101\n");
1286 g_print(" H263 = 102\n");
1287 g_print(" H264 = 103\n");
1288 g_print(" MJPEG = 104\n");
1289 g_print(" MPEG1 = 105\n");
1290 g_print(" MPEG2 = 106\n");
1291 g_print(" MPEG4 = 107\n");
1292 g_print(" -------------------\n");
1293 g_print("*** Flags : Select Combination Number (e.g. DEOCDER + TYPE_SW = 10)\n");
1294 g_print(" CODEC : ENCODER = 1 DECODER = 2\n");
1295 g_print(" TYPE : HW = 4 SW = 8\n");
1296 g_print("*** input codec id, falgs.\n");
1297 } else if (g_menu_state == CURRENT_STATUS_SET_VDEC_INFO) {
1298 g_print("*** input video decode configure.(width, height)\n");
1299 } else if (g_menu_state == CURRENT_STATUS_SET_VENC_INFO) {
1300 g_print("*** input video encode configure.(width, height, fps, target_bits)\n");
1301 } else if (g_menu_state == CURRENT_STATUS_SET_ADEC_INFO) {
1302 g_print("*** input audio decode configure.(samplerate, channel, bit (e.g. 48000, 2, 16))\n");
1303 } else if (g_menu_state == CURRENT_STATUS_SET_AENC_INFO) {
1304 g_print("*** input audio encode configure.(samplerate, channel, bit, bitrate (e.g. 48000, 2, 16, 128000))\n");
1305 } else if (g_menu_state == CURRENT_STATUS_PROCESS_INPUT) {
1306 g_print("*** input dec process number\n");
1307 } else if (g_menu_state == CURRENT_STATUS_GET_OUTPUT) {
1308 g_print("*** input get output buffer number\n");
1310 g_print("*** unknown status.\n");
1315 gboolean timeout_menu_display(void* data)
1322 static void interpret(char *cmd, App *app)
1324 switch (g_menu_state) {
1325 case CURRENT_STATUS_MAINMENU:
1326 _interpret_main_menu(cmd, app);
1328 case CURRENT_STATUS_FILENAME:
1329 input_filepath(cmd, app);
1332 case CURRENT_STATUS_SET_CODEC:
1345 (tmp != 160) && (tmp != 161) && (tmp != 162) && (tmp != 163)) {
1346 tmp = strtol(cmd, ptr, 16);
1347 app->codecid = 0x2000 + ((tmp & 0xFF) << 4);
1349 app->codecid = 0x1000 + tmp;
1354 app->flag = atoi(cmd);
1363 case CURRENT_STATUS_SET_VDEC_INFO:
1368 app->width = atoi(cmd);
1372 app->height = atoi(cmd);
1373 app->type = VIDEO_DEC;
1383 case CURRENT_STATUS_SET_VENC_INFO:
1388 app->width = atoi(cmd);
1392 app->height = atoi(cmd);
1396 app->fps = atol(cmd);
1400 app->target_bits = atoi(cmd);
1401 app->type = VIDEO_ENC;
1411 case CURRENT_STATUS_SET_ADEC_INFO:
1416 app->samplerate = atoi(cmd);
1420 app->channel = atoi(cmd);
1424 app->bit = atoi(cmd);
1425 app->type = AUDIO_DEC;
1435 case CURRENT_STATUS_SET_AENC_INFO:
1440 app->samplerate = atoi(cmd);
1444 app->channel = atoi(cmd);
1448 app->bit = atoi(cmd);
1452 app->bitrate = atoi(cmd);
1453 app->type = AUDIO_ENC;
1463 case CURRENT_STATUS_PROCESS_INPUT:
1470 case CURRENT_STATUS_GET_OUTPUT:
1481 g_timeout_add(100, timeout_menu_display, 0);
1484 static void display_sub_basic()
1487 g_print("=========================================================================================\n");
1488 g_print(" media codec test\n");
1489 g_print("-----------------------------------------------------------------------------------------\n");
1490 g_print("a. Create \t\t");
1491 g_print("sc. Set codec \n");
1492 g_print("vd. Set vdec info \t");
1493 g_print("ve. Set venc info \n");
1494 g_print("ad. Set adec info \t");
1495 g_print("ae. Set aenc info \n");
1496 g_print("pr. Prepare \t\t");
1497 g_print("pi. Process input \n");
1498 g_print("o. Get output \t\t");
1499 g_print("rb. Reset output buffer \n");
1500 g_print("pa. Process all frames \n");
1501 g_print("un. Unprepare \t\t");
1502 g_print("dt. Destroy \t\t");
1503 g_print("q. quite test suite \t");
1505 g_print("=========================================================================================\n");
1508 gboolean input(GIOChannel *channel, GIOCondition cond, gpointer data)
1510 gchar buf[MAX_STRING_LEN];
1512 GError *error = NULL;
1513 App *context = (App*)data;
1515 g_io_channel_read_chars(channel, buf, MAX_STRING_LEN, &read, &error);
1518 interpret(buf, context);
1523 int main(int argc, char *argv[])
1527 GError *error = NULL;
1528 GIOChannel *stdin_channel;
1529 stdin_channel = g_io_channel_unix_new(0);
1530 g_io_channel_set_flags(stdin_channel, G_IO_FLAG_NONBLOCK, NULL);
1531 g_io_add_watch(stdin_channel, G_IO_IN, (GIOFunc)input, app);
1534 app->loop = g_main_loop_new(NULL, TRUE);
1535 app->timer = g_timer_new();
1541 return appcore_efl_main(PACKAGE, &argc, &argv, &ops);
1546 void mc_hex_dump(char *desc, void *addr, int len)
1549 unsigned char buff[17];
1550 unsigned char *pc = (unsigned char *)addr;
1553 printf("%s:\n", desc);
1555 for (i = 0; i < len; i++) {
1557 if ((i % 16) == 0) {
1559 printf(" %s\n", buff);
1561 printf(" %04x ", i);
1564 printf(" %02x", pc[i]);
1566 if ((pc[i] < 0x20) || (pc[i] > 0x7e))
1569 buff[i % 16] = pc[i];
1570 buff[(i % 16) + 1] = '\0';
1573 while ((i % 16) != 0) {
1577 printf(" %s\n", buff);
1581 static void decoder_output_dump(App *app, media_packet_h pkt)
1583 unsigned char *temp;
1585 int stride_width, stride_height;
1586 char filename[100] = {0};
1590 sprintf(filename, "/tmp/dec_output_dump_%d_%d.yuv", app->width, app->height);
1591 fp = fopen(filename, "ab");
1593 media_packet_get_video_plane_data_ptr(pkt, 0, &temp);
1594 media_packet_get_video_stride_width(pkt, 0, &stride_width);
1595 media_packet_get_video_stride_height(pkt, 0, &stride_height);
1596 g_printf("stride : %d, %d\n", stride_width, stride_height);
1598 for (i = 0; i < app->height; i++) {
1599 ret = fwrite(temp, app->width, 1, fp);
1600 temp += stride_width;
1603 if (app->hardware == TRUE) {
1604 media_packet_get_video_plane_data_ptr(pkt, 1, &temp);
1605 media_packet_get_video_stride_width(pkt, 1, &stride_width);
1606 for (i = 0; i < app->height/2; i++) {
1607 ret = fwrite(temp, app->width, 1, fp);
1608 temp += stride_width;
1611 media_packet_get_video_plane_data_ptr(pkt, 1, &temp);
1612 media_packet_get_video_stride_width(pkt, 1, &stride_width);
1613 for (i = 0; i < app->height/2; i++) {
1614 ret = fwrite(temp, app->width/2, 1, fp);
1615 temp += stride_width;
1618 media_packet_get_video_plane_data_ptr(pkt, 2, &temp);
1619 media_packet_get_video_stride_width(pkt, 2, &stride_width);
1620 for (i = 0; i < app->height/2; i++) {
1621 ret = fwrite(temp, app->width/2, 1, fp);
1622 temp += stride_width;
1626 g_print("codec dec output dumped!!%d\n", ret);