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>
25 #include <tbm_surface.h>
28 #include <media_codec.h>
29 #include <media_packet.h>
30 #include <media_packet_internal.h>
31 #include <media_packet_pool.h>
32 #include <media_codec_internal.h>
33 #ifdef TIZEN_FEATURE_INTEGRATION
35 #include <mediademuxer.h>
36 #include <mediamuxer.h>
39 #define PACKAGE "media_codec_test"
41 #define TEST_FILE_SIZE (10 * 1024 * 1024)
42 #define MAX_STRING_LEN 256
44 #define DEFAULT_SAMPPLERATE 44100
45 #define DEFAULT_CHANNEL 2
46 #define DEFAULT_BIT 16
47 #define DEFAULT_BITRATE 128
48 #define DEFAULT_SAMPLEBYTE 1024
49 #define ADTS_HEADER_SIZE 7
50 #define AMRNB_PCM_INPUT_SIZE 320
51 #define AMRWB_PCM_INPUT_SIZE 640
53 #define CHECK_BIT(x, y) (((x) >> (y)) & 0x01)
54 #define GET_IS_ENCODER(x) CHECK_BIT(x, 0)
55 #define GET_IS_DECODER(x) CHECK_BIT(x, 1)
56 #define GET_IS_HW(x) CHECK_BIT(x, 2)
57 #define ES_DEFAULT_VIDEO_PTS_OFFSET 33000000
58 #define CHECK_VALID_PACKET(state, expected_state) \
59 ((state & (expected_state)) == (expected_state))
61 #define AAC_CODECDATA_SIZE 16
63 guint8 buf_adts[ADTS_HEADER_SIZE];
66 MC_EXIST_SPS = 1 << 0,
67 MC_EXIST_PPS = 1 << 1,
68 MC_EXIST_IDR = 1 << 2,
69 MC_EXIST_SLICE = 1 << 3,
71 MC_VALID_HEADER = (MC_EXIST_SPS | MC_EXIST_PPS),
72 MC_VALID_FIRST_SLICE = (MC_EXIST_SPS | MC_EXIST_PPS | MC_EXIST_IDR)
75 typedef struct _App App;
78 CURRENT_STATUS_MAINMENU,
79 CURRENT_STATUS_FILENAME,
80 CURRENT_STATUS_CREATE,
81 CURRENT_STATUS_DESTROY,
82 CURRENT_STATUS_SET_CODEC,
83 CURRENT_STATUS_SET_VDEC_INFO,
84 CURRENT_STATUS_SET_VENC_INFO,
85 CURRENT_STATUS_SET_ADEC_INFO,
86 CURRENT_STATUS_SET_AENC_INFO,
87 CURRENT_STATUS_PREPARE,
88 CURRENT_STATUS_UNPREPARE,
89 CURRENT_STATUS_PROCESS_INPUT,
90 CURRENT_STATUS_GET_OUTPUT,
91 CURRENT_STATUS_RESET_OUTPUT_BUFFER,
92 CURRENT_STATUS_SET_SIZE,
93 CURRENT_STATUS_AUTO_TEST,
97 NAL_SLICE_NO_PARTITIONING = 1,
103 NAL_SEQUENCE_PARAMETER_SET,
104 NAL_PICTURE_PARAMETER_SET,
105 NAL_PICTURE_DELIMITER,
143 gboolean enable_dump;
144 gboolean enable_muxer;
148 #ifdef TIZEN_FEATURE_INTEGRATION
149 camera_h camera_handle;
150 mediademuxer_h demuxer;
165 media_format_h format[MAX_HANDLE];
167 mediacodec_h mc_handle[MAX_HANDLE];
172 media_format_mimetype_e mime;
189 media_packet_h packet;
202 media_format_h fmt = NULL;
203 media_packet_pool_h pkt_pool = NULL;
205 /* Internal Functions */
206 gint _create_app(void *data);
207 gint _terminate_app(void *data);
208 void displaymenu(void);
209 void display_sub_basic();
211 void _mediacodec_unprepare(App *app);
212 void _mediacodec_destroy(App *app);
213 void _mediacodec_auto_test(App *app, char *path);
214 void input_filepath(char *filename, App *app);
216 void mc_hex_dump(char *desc, void *addr, gint len);
217 void decoder_output_dump(App *app, media_packet_h pkt);
218 void output_dump(App *app, media_packet_h pkt);
220 const char* codec_type_to_string(mediacodec_codec_type_e media_codec_id);
222 void (*extractor)(App *app, guint8** data, gint *size, gboolean *have_frame, gboolean *codec_data);
224 gint g_menu_state = CURRENT_STATUS_MAINMENU;
226 gint _create_app(void *data)
228 g_print("My app is going alive!\n");
229 App *app = (App*)data;
231 g_mutex_init(&app->lock);
235 gint _terminate_app(void *data)
237 g_print("My app is going gone!\n");
238 App *app = (App*)data;
240 g_mutex_clear(&app->lock);
245 struct appcore_ops ops = {
246 .create = _create_app,
247 .terminate = _terminate_app,
250 static const guint mp3types_bitrates[2][3][16] = {
252 {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448,},
253 {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384,},
254 {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320,}
257 {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256,},
258 {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,},
259 {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,}
263 static const guint mp3types_freqs[3][3] = { {44100, 48000, 32000},
264 {22050, 24000, 16000},
268 void h264_extractor(App *app, guint8 **data, gint *size, gboolean *have_frame, gboolean *codec_data)
270 guint8 val, zero_count;
271 guint8 *pNal = app->data + app->offset;
272 gint max = app->length - app->offset;
274 gint nal_unit_type = 0;
302 if ((zero_count >= 2) && (val == 1))
312 read = (index - zero_count - 1);
314 nal_unit_type = *(app->data+app->offset+4) & 0x1F;
315 g_print("nal_unit_type : %x\n", nal_unit_type);
317 switch (nal_unit_type) {
318 case NAL_SEQUENCE_PARAMETER_SET:
319 g_print("nal_unit_type : SPS\n");
320 state |= MC_EXIST_SPS;
322 case NAL_PICTURE_PARAMETER_SET:
323 g_print("nal_unit_type : PPS\n");
324 state |= MC_EXIST_PPS;
328 g_print ("nal_unit_type : IDR\n");
329 state |= MC_EXIST_IDR;
331 case NAL_SLICE_NO_PARTITIONING:
332 case NAL_SLICE_PART_A:
333 case NAL_SLICE_PART_B:
334 case NAL_SLICE_PART_C:
335 state |= MC_EXIST_SLICE;
338 g_print ("nal_unit_type : %x", nal_unit_type);
342 init = CHECK_VALID_PACKET(state, MC_VALID_FIRST_SLICE) ? 1 : 0;
343 slice = CHECK_VALID_PACKET(state, MC_EXIST_SLICE) ? 1 : 0;
344 idr = CHECK_VALID_PACKET(state, MC_EXIST_IDR) ? 1 : 0;
345 g_print("status : %d, slice : %d, idr : %d\n", init, slice, idr);
347 if (init || idr || slice) {
351 *size = app->offset + read;
353 *data = app->data+app->offset;
358 *data = app->data+app->offset;
365 void h263_extractor(App * app, guint8 **data, gint *size, gboolean * have_frame, gboolean *codec_data)
368 int read_size = 1, state = 1, bStart = 0;
370 guint8 *pH263 = app->data + app->offset;
372 int max = app->length - app->offset;
376 read_size = (len - 1);
393 if ((val & 0xFC) == 0x80) {
406 app->offset += read_size;
410 void mpeg4_extractor(App * app, guint8 **data, gint *size, gboolean * have_frame, gboolean *codec_data)
414 int state = 1, bType = 0;
416 guint8 *pMpeg4 = app->data + app->offset;
418 int max = app->length - app->offset;
447 if (val == 0xB0 || val == 0xB6) {
463 app->offset += result;
468 * Extract Input data for AMR-NB/WB decoder
469 * - AMR-NB : mime type ("audio/AMR") / 8Khz / 1 ch / 16 bits
470 * - AMR-WB : mime type ("audio/AMR-WB") / 16Khz / 1 ch / 16 bits
472 gint write_amr_header = 1; /* write magic number for AMR Header at one time */
473 static const gchar AMR_header[] = "#!AMR\n";
474 static const gchar AMRWB_header[] = "#!AMR-WB\n";
475 #define AMR_NB_MIME_HDR_SIZE 6
476 #define AMR_WB_MIME_HDR_SIZE 9
477 static const gint block_size_nb[16] = { 12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0 };
478 static const gint block_size_wb[16] = { 17, 23, 32, 36, 40, 46, 50, 58, 60, 5, -1, -1, -1, -1, 0, 0 };
481 void amrdec_extractor(App * app, guint8 **data, gint *size, gboolean * have_frame, gboolean *codec_data)
483 gint readsize = 0, mode_temp;
485 guint8 *pAmr = app->data + app->offset;
486 /* change the below one to frame count */
487 if (app->offset == 0) {
488 if (!memcmp(pAmr, AMR_header, AMR_NB_MIME_HDR_SIZE)) {
489 blocksize_tbl = (int *)block_size_nb;
490 mode_temp = pAmr[AMR_NB_MIME_HDR_SIZE];
491 pAmr = pAmr + AMR_NB_MIME_HDR_SIZE;
492 app->offset += AMR_NB_MIME_HDR_SIZE;
494 if (!memcmp(pAmr, AMRWB_header, AMR_WB_MIME_HDR_SIZE)) {
495 blocksize_tbl = (int *)block_size_wb;
496 mode_temp = pAmr[AMR_WB_MIME_HDR_SIZE];
497 pAmr = pAmr + AMR_WB_MIME_HDR_SIZE;
498 app->offset += AMR_WB_MIME_HDR_SIZE;
500 g_print("[ERROR] AMR-NB/WB don't detected..\n");
506 if ((mode_temp & 0x83) == 0) {
507 mode = (mode_temp >> 3) & 0x0F; /* Yep. Retrieve the frame size */
508 fsize = blocksize_tbl[mode];
509 readsize = fsize + 1;
512 g_print("[FAIL] Not found amr frame sync.....\n");
516 app->offset += readsize;
521 void nv12_extractor(App *app, guint8 **data, gint *size, gboolean *have_frame, gboolean *codec_data)
524 gint offset = app->length - app->offset;
526 yuv_size = app->width * app->height * 3 / 2;
528 if (offset >= yuv_size)
532 *data = app->data + app->offset;
534 if (yuv_size >= offset)
539 app->offset += *size;
542 void yuv_extractor(App *app, guint8 **data, int *size, gboolean *have_frame, gboolean *codec_data)
545 gint offset = app->length - app->offset;
547 yuv_size = app->width * app->height * 3 / 2;
549 if (yuv_size >= offset)
553 *data = app->data + app->offset;
555 if (yuv_size >= offset)
560 app->offset += *size;
563 void aacenc_extractor(App *app, guint8 **data, int *size, gboolean *have_frame, gboolean *codec_data)
566 gint offset = app->length - app->offset;
568 read_size = ((DEFAULT_SAMPLEBYTE * app->channel)*(app->bit/8) * 2);
571 *data = app->data + app->offset;
573 if (read_size >= offset)
578 app->offset += *size;
581 void amrenc_extractor(App *app, guint8 **data, int *size, gboolean *have_frame, gboolean *codec_data)
584 gint offset = app->length - app->offset;
587 read_size = AMRNB_PCM_INPUT_SIZE;
589 read_size = AMRWB_PCM_INPUT_SIZE;
592 *data = app->data + app->offset;
594 if (read_size >= offset)
599 app->offset += *size;
603 * Extract Input data for AAC decoder
604 * (case of (LC profile) ADTS format)
605 * codec_data : Don't need
607 void aacdec_extractor(App *app, guint8 **data, int *size, gboolean *have_frame, gboolean *codec_data)
610 int offset = app->length - app->offset;
611 guint8 *pData = app->data + app->offset;
613 if ((pData != NULL) && (pData[0] == 0xff) && ((pData[1] & 0xf6) == 0xf0)) {
614 read_size = ((pData[3] & 0x03) << 11) | (pData[4] << 3) | ((pData[5] & 0xe0) >> 5);
617 g_print("[FAIL] Not found aac frame sync.....\n");
621 *data = app->data + app->offset;
623 if (read_size >= offset)
628 app->offset += *size;
631 void mp3dec_extractor(App *app, guint8 **data, int *size, gboolean *have_frame, gboolean *codec_data)
635 guint padding, bitrate, lsf = 0, layer = 0, mpg25 = 0;
636 guint hdr_bitrate = 0, sf = 0;
637 gint offset = app->length - app->offset;
638 guint8 *pData = app->data + app->offset;
640 header = GST_READ_UINT32_BE(pData);
643 g_print ("[ERROR] read header size is 0\n");
648 /* if it's not a valid sync */
649 if ((header & 0xffe00000) != 0xffe00000) {
650 g_print ("[ERROR] invalid sync\n");
655 if (((header >> 19) & 3) == 0x1) {
656 g_print ("[ERROR] invalid MPEG version: %d\n", (header >> 19) & 3);
660 if (header & (1 << 20)) {
661 lsf = (header & (1 << 19)) ? 0 : 1;
669 /* if it's an invalid layer */
670 if (!((header >> 17) & 3)) {
671 g_print("[ERROR] invalid layer: %d\n", (header >> 17) & 3);
675 layer = 4 - ((header >> 17) & 0x3);
678 /* if it's an invalid bitrate */
679 if (((header >> 12) & 0xf) == 0xf) {
680 g_print ("[ERROR] invalid bitrate: %d\n", (header >> 12) & 0xf);
684 bitrate = (header >> 12) & 0xF;
685 hdr_bitrate = mp3types_bitrates[lsf][layer - 1][bitrate] * 1000;
686 /* The caller has ensured we have a valid header, so bitrate can't be zero here. */
687 if (hdr_bitrate == 0) {
693 /* if it's an invalid samplerate */
694 if (((header >> 10) & 0x3) == 0x3) {
695 g_print ("[ERROR] invalid samplerate: %d\n", (header >> 10) & 0x3);
699 sf = (header >> 10) & 0x3;
700 sf = mp3types_freqs[lsf + mpg25][sf];
703 padding = (header >> 9) & 0x1;
707 read_size = 4 * ((hdr_bitrate * 12) / sf + padding);
710 read_size = (hdr_bitrate * 144) / sf + padding;
714 read_size = (hdr_bitrate * 144) / (sf << lsf) + padding;
717 g_print("header : %d, read : %d\n", header, read_size);
720 *data = app->data + app->offset;
722 if (read_size >= offset)
727 app->offset += *size;
731 * Extract Input data for AAC encoder
734 void aacenc_extractor(App *app, guint8 **data, int *size, gboolean *have_frame)
737 int offset = app->length - app->offset;
739 read_size = ((DEFAULT_SAMPLEBYTE*DEFAULT_CHANNEL)*(DEFAULT_BIT/8));
741 if (read_size >= offset)
745 *data = app->data + app->offset;
747 if (read_size >= offset)
752 app->offset += *size;
755 int _configure(App *app, int codecid, int flag, gboolean *hardware, media_format_mimetype_e *codec_mime)
758 media_format_mimetype_e mime = 0;
759 encoder = GET_IS_ENCODER(flag) ? 1 : 0;
760 *hardware = GET_IS_HW(flag) ? 1 : 0;
761 app->is_encoder = encoder;
764 case MEDIACODEC_H264:
766 extractor = yuv_extractor;
767 mime = *hardware ? MEDIA_FORMAT_NV12 : MEDIA_FORMAT_I420;
768 *codec_mime = MEDIA_FORMAT_H264_SP;
770 extractor = h264_extractor;
771 mime = MEDIA_FORMAT_H264_SP;
774 case MEDIACODEC_MPEG4:
776 extractor = yuv_extractor;
777 mime = *hardware ? MEDIA_FORMAT_NV12 : MEDIA_FORMAT_I420;
778 *codec_mime = MEDIA_FORMAT_MPEG4_SP;
780 extractor = mpeg4_extractor;
781 mime = MEDIA_FORMAT_MPEG4_SP;
784 case MEDIACODEC_H263:
786 extractor = yuv_extractor;
787 mime = *hardware ? MEDIA_FORMAT_NV12 : MEDIA_FORMAT_I420;
788 *codec_mime = MEDIA_FORMAT_H263;
790 extractor = h263_extractor;
791 mime = MEDIA_FORMAT_H263;
796 extractor = aacenc_extractor;
797 mime = MEDIA_FORMAT_PCM_F32LE; /* FIXME need to check according to verdor */
798 *codec_mime = MEDIA_FORMAT_AAC;
800 extractor = aacdec_extractor;
801 mime = MEDIA_FORMAT_AAC;
804 case MEDIACODEC_AAC_HE:
806 extractor = aacenc_extractor;
807 mime = MEDIA_FORMAT_PCM_F32LE; /* FIXME need to check according to verdor */
808 *codec_mime = MEDIA_FORMAT_AAC_HE;
811 case MEDIACODEC_AAC_HE_PS:
814 extractor = mp3dec_extractor;
815 mime = MEDIA_FORMAT_MP3;
817 case MEDIACODEC_VORBIS:
819 case MEDIACODEC_FLAC:
821 case MEDIACODEC_WMAV1:
823 case MEDIACODEC_WMAV2:
825 case MEDIACODEC_WMAPRO:
827 case MEDIACODEC_WMALSL:
829 case MEDIACODEC_AMR_NB:
831 extractor = amrenc_extractor;
832 mime = MEDIA_FORMAT_PCM_F32LE; /* FIXME need to check according to verdor */
833 app->is_amr_nb = TRUE;
835 extractor = amrdec_extractor;
836 mime = MEDIA_FORMAT_AMR_NB;
839 case MEDIACODEC_AMR_WB:
841 extractor = amrenc_extractor;
842 mime = MEDIA_FORMAT_PCM_F32LE; /* FIXME need to check according to verdor */
843 app->is_amr_nb = FALSE;
845 extractor = amrdec_extractor;
846 mime = MEDIA_FORMAT_AMR_WB;
850 LOGE("NOT SUPPORTED!!!!");
856 void _mediacodec_process_input(App *app)
859 gboolean have_frame = FALSE;
861 static guint64 pts = 0L;
862 guint8 *buf_data_ptr = NULL;
863 media_packet_h pkt = NULL;
869 gboolean codec_config = FALSE;
871 for (i = 0; i < app->frame; i++) {
872 g_print("----------read data------------\n");
874 extractor(app, &tmp, &read, &have_frame, &codec_config);
878 if (media_packet_pool_acquire_packet(pkt_pool, &pkt, -1) != MEDIA_PACKET_ERROR_NONE) {
879 g_print("media_packet_pool_aquire_packet failed\n");
883 if (media_packet_create_alloc(fmt, NULL, NULL, &pkt) != MEDIA_PACKET_ERROR_NONE) {
884 g_print("media_packet_create_alloc failed\n");
889 if (media_packet_set_pts(pkt, (uint64_t)(pts)) != MEDIA_PACKET_ERROR_NONE) {
890 g_print("media_packet_set_pts failed\n");
894 if (app->type != VIDEO_ENC) {
895 media_packet_get_buffer_data_ptr(pkt, (void **)&buf_data_ptr);
896 media_packet_set_buffer_size(pkt, (uint64_t)read);
897 memcpy(buf_data_ptr, tmp, read);
898 g_print("tmp:%p, read:%d\n", tmp, read);
901 media_packet_get_video_plane_data_ptr(pkt, 0, (void **)&buf_data_ptr);
902 media_packet_get_video_stride_width(pkt, 0, &stride_width);
903 offset = app->width*app->height;
905 for (j = 0; j < app->height; j++) {
906 memcpy(buf_data_ptr, tmp, app->width);
907 buf_data_ptr += stride_width;
911 if (app->hardware == TRUE) {
912 media_packet_get_video_plane_data_ptr(pkt, 1, (void **)&buf_data_ptr);
913 media_packet_get_video_stride_width(pkt, 1, &stride_width);
914 size = app->width * app->height / 2;
916 for (j = 0; j < app->height / 2; j++) {
917 memcpy(buf_data_ptr, tmp, app->width);
918 buf_data_ptr += stride_width;
923 media_packet_get_video_plane_data_ptr(pkt, 1, (void **)&buf_data_ptr);
924 media_packet_get_video_stride_width(pkt, 1, &stride_width);
925 size = (app->width>>1) * (app->height>>1);
927 for (j = 0; j < app->height/2; j++) {
928 memcpy(buf_data_ptr, tmp, app->width/2);
929 buf_data_ptr += stride_width;
934 media_packet_get_video_plane_data_ptr(pkt, 2, (void **)&buf_data_ptr);
935 media_packet_get_video_stride_width(pkt, 2, &stride_width);
938 for (j = 0; j < app->height/2; j++) {
939 memcpy(buf_data_ptr, tmp, app->width/2);
940 buf_data_ptr += stride_width;
946 mc_hex_dump("inbuf", tmp, 48);
948 ret = mediacodec_process_input(app->mc_handle[0], pkt, 1000);
949 if (ret != MEDIACODEC_ERROR_NONE)
952 pts += ES_DEFAULT_VIDEO_PTS_OFFSET;
957 gboolean read_data(App *app)
960 gboolean have_frame = FALSE;
961 gboolean codec_config = FALSE;
963 static guint64 pts = 0L;
964 guint8 *buf_data_ptr = NULL;
965 media_packet_h pkt = NULL;
973 if (app->offset == 0) {
974 app->frame_count = 0;
975 app->start = clock();
978 g_print("----------read data------------\n");
979 extractor(app, &tmp, &read, &have_frame, &codec_config);
981 if (app->offset >= app->length - 4) {
984 app->finish = clock();
985 g_print("Average FPS = %3.3f\n", ((double)app->frame_count*1000000/(app->finish - app->start)));
986 g_print("---------------------------\n");
989 g_print("length : %d, offset : %d\n", app->length, app->offset);
991 if (app->offset + len > app->length)
992 len = app->length - app->offset;
994 g_print("%p, %d, have_frame :%d, read: %d\n", tmp, (int)read, have_frame, read);
998 if (media_packet_pool_acquire_packet(pkt_pool, &pkt, -1) != MEDIA_PACKET_ERROR_NONE) {
999 g_print("media_packet_pool_aquire_packet failed\n");
1003 if (media_packet_create_alloc(fmt, NULL, NULL, &pkt) != MEDIA_PACKET_ERROR_NONE) {
1004 g_print("media_packet_create_alloc failed\n");
1008 if (media_packet_set_pts(pkt, (uint64_t)(pts)) != MEDIA_PACKET_ERROR_NONE) {
1009 g_print("media_packet_set_pts failed\n");
1014 if (app->type != VIDEO_ENC) {
1015 media_packet_get_buffer_data_ptr(pkt, (void **)&buf_data_ptr);
1016 media_packet_set_buffer_size(pkt, (uint64_t)read);
1018 memcpy(buf_data_ptr, tmp, read);
1019 g_print("tmp:%p, read:%d\n", tmp, read);
1022 media_packet_get_video_plane_data_ptr(pkt, 0, (void **)&buf_data_ptr);
1023 media_packet_get_video_stride_width(pkt, 0, &stride_width);
1024 offset = app->width*app->height;
1026 for (i = 0; i < app->height; i++) {
1027 memcpy(buf_data_ptr, tmp, app->width);
1028 buf_data_ptr += stride_width;
1032 if (app->hardware == TRUE) {
1033 media_packet_get_video_plane_data_ptr(pkt, 1, (void **)&buf_data_ptr);
1034 media_packet_get_video_stride_width(pkt, 1, &stride_width);
1035 size = app->width * app->height>>1;
1037 for (i = 0; i < app->height>>1; i++) {
1038 memcpy(buf_data_ptr, tmp, app->width);
1039 buf_data_ptr += stride_width;
1045 media_packet_get_video_plane_data_ptr(pkt, 1, (void **)&buf_data_ptr);
1046 media_packet_get_video_stride_width(pkt, 1, &stride_width);
1047 size = (app->width>>1) * (app->height>>1);
1049 for (i = 0; i < app->height/2; i++) {
1050 memcpy(buf_data_ptr, tmp, app->width>>1);
1051 buf_data_ptr += stride_width;
1052 tmp += (app->width>>1);
1056 media_packet_get_video_plane_data_ptr(pkt, 2, (void **)&buf_data_ptr);
1057 media_packet_get_video_stride_width(pkt, 2, &stride_width);
1060 for (i = 0; i < app->height/2; i++) {
1061 memcpy(buf_data_ptr, tmp, app->width>>1);
1062 buf_data_ptr += stride_width;
1063 tmp += (app->width>>1);
1068 mc_hex_dump("inbuf", tmp, 48);
1070 ret = mediacodec_process_input(app->mc_handle[0], pkt, 0);
1071 if (ret != MEDIACODEC_ERROR_NONE)
1074 pts += ES_DEFAULT_VIDEO_PTS_OFFSET;
1080 void av_feed_suspend(App *app)
1082 g_mutex_lock(&app->thread_mutex);
1084 g_print("suspend thread\n");
1085 g_mutex_unlock(&app->thread_mutex);
1088 void av_feed_resume(App *app)
1090 g_mutex_lock(&app->thread_mutex);
1092 g_print("resume thread\n");
1093 g_cond_broadcast(&app->thread_cond);
1094 g_mutex_unlock(&app->thread_mutex);
1097 #ifdef TIZEN_FEATURE_INTEGRATION
1098 gpointer av_feed_thread(gpointer data)
1100 App *app = (App *)data;
1104 media_packet_h packet = NULL;
1105 track = app->audio_track;
1108 g_mutex_lock(&app->thread_mutex);
1110 while (app->suspend != 0) g_cond_wait(&app->thread_cond, &app->thread_mutex);
1112 g_mutex_unlock(&app->thread_mutex);
1114 if (app->demux_eos == 1) {
1115 g_print("got eos!!!\n");
1119 ret = mediademuxer_read_sample(app->demuxer, track, &packet);
1120 if (ret != MEDIACODEC_ERROR_NONE)
1123 ret = mediacodec_process_input(app->mc_handle[track], packet, 0);
1124 if (ret != MEDIACODEC_ERROR_NONE)
1134 gboolean feed_audio(App *app)
1139 media_packet_h packet = NULL;
1140 track = app->audio_track;
1142 g_print("read audio sample!!!\n");
1143 ret = mediademuxer_read_sample(app->demuxer, track, &packet);
1144 if (ret != MEDIACODEC_ERROR_NONE)
1147 ret = mediacodec_process_input(app->mc_handle[track], packet, 0);
1148 if (ret != MEDIACODEC_ERROR_NONE)
1154 gboolean feed_video(App *app)
1159 media_packet_h packet = NULL;
1160 track = app->video_track;
1162 g_print("read video sample!!!\n");
1163 ret = mediademuxer_read_sample(app->demuxer, track, &packet);
1164 if (ret != MEDIACODEC_ERROR_NONE)
1167 ret = mediacodec_process_input(app->mc_handle[track], packet, 0);
1168 if (ret != MEDIACODEC_ERROR_NONE)
1175 void start_feed(App *app)
1177 if (app->sourceid == 0) {
1178 app->sourceid = g_idle_add((GSourceFunc)read_data, app);
1179 g_print("start_feed\n");
1183 void stop_feed(App *app)
1185 if (app->sourceid != 0) {
1186 g_source_remove(app->sourceid);
1188 g_print("stop_feed\n");
1192 void _mediacodec_inbuf_used_cb(media_packet_h pkt, void *user_data)
1194 App *app = (App *)user_data;
1196 g_print("_mediacodec_inbuf_used_cb!!!\n");
1198 media_packet_pool_release_packet(pkt_pool, pkt);
1200 media_packet_destroy(pkt);
1207 void _audio_outbuf_available_cb(media_packet_h pkt, void *user_data)
1209 media_packet_h out_pkt = NULL;
1212 App *app = (App*)user_data;
1214 g_print("_audio_outbuf_available_cb\n");
1216 g_mutex_lock(&app->lock);
1218 ret = mediacodec_get_output(app->mc_handle[app->audio_track], &out_pkt, 0);
1220 if (ret != MEDIACODEC_ERROR_NONE)
1221 g_print("get_output failed\n");
1223 if (app->enable_dump)
1224 output_dump(app, out_pkt);
1230 g_mutex_unlock(&app->lock);
1232 media_packet_destroy(out_pkt);
1239 void _video_outbuf_available_cb(media_packet_h pkt, void *user_data)
1241 media_packet_h out_pkt = NULL;
1244 App *app = (App*)user_data;
1246 g_print("_video_outbuf_available_cb\n");
1248 g_mutex_lock(&app->lock);
1250 ret = mediacodec_get_output(app->mc_handle[app->video_track], &out_pkt, 0);
1252 if (ret != MEDIACODEC_ERROR_NONE)
1253 g_print("get_output failed\n");
1255 if (app->enable_dump)
1256 decoder_output_dump(app, out_pkt);
1262 g_mutex_unlock(&app->lock);
1264 media_packet_destroy(out_pkt);
1271 void _mediacodec_outbuf_available_cb(media_packet_h pkt, void *user_data)
1273 media_packet_h out_pkt = NULL;
1276 App *app = (App*)user_data;
1278 g_print("_mediacodec_outbuf_available_cb\n");
1280 g_mutex_lock(&app->lock);
1282 ret = mediacodec_get_output(app->mc_handle[0], &out_pkt, 0);
1284 if (ret != MEDIACODEC_ERROR_NONE)
1285 g_print("get_output failed\n");
1287 if (app->enable_dump) {
1288 if (app->type == VIDEO_DEC)
1289 decoder_output_dump(app, out_pkt);
1291 output_dump(app, out_pkt);
1293 #ifdef TIZEN_FEATURE_INTEGRATION
1294 if (app->enable_muxer) {
1295 if (mediamuxer_write_sample(app->muxer, app->track, out_pkt) != MEDIAMUXER_ERROR_NONE)
1296 g_print("mediamuxer_write_sample failed\n");
1297 g_print("write sample!!!\n");
1304 g_mutex_unlock(&app->lock);
1306 media_packet_destroy(out_pkt);
1313 void _mediacodec_buffer_status_cb(mediacodec_status_e status, void *user_data)
1315 g_print("_mediacodec_buffer_status_cb %d\n", status);
1317 App *app = (App*)user_data;
1319 if (status == MEDIACODEC_NEED_DATA)
1321 else if (status == MEDIACODEC_ENOUGH_DATA)
1327 void _av_buffer_status_cb(mediacodec_status_e status, void *user_data)
1329 g_print("_av_buffer_status_cb %d\n", status);
1331 App *app = (App*)user_data;
1333 if (status == MEDIACODEC_NEED_DATA)
1334 av_feed_resume(app);
1335 else if (status == MEDIACODEC_ENOUGH_DATA)
1336 av_feed_suspend(app);
1341 void _mediacodec_error_cb(mediacodec_error_e error, void *user_data)
1347 void _mediacodec_eos_cb(void *user_data)
1349 App *app = (App *)user_data;
1351 g_print("mediacodec eos\n");
1352 g_mutex_lock(&app->eos_mutex);
1354 g_mutex_unlock(&app->eos_mutex);
1355 g_cond_broadcast(&app->dst_eos_cond);
1359 #ifdef TIZEN_FEATURE_INTEGRATION
1360 void demuxer_error_cb(mediademuxer_error_e error, void *user_data)
1362 g_print("Got Error %d from Mediademuxer\n", error);
1366 void _mediademuxer_eos_cb(int track, void *user_data)
1368 App *app = (App *)user_data;
1370 g_print("eos track : %d\n", track);
1371 av_feed_suspend(app);
1372 g_print("suspended\n");
1374 av_feed_resume(app);
1375 g_cond_broadcast(&app->eos_cond);
1380 void _mediamuxer_eos_cb(void *user_data)
1382 if (user_data == NULL) {
1383 g_print("invalid param");
1387 App *app = (App *)user_data;
1389 g_print("muxer eos\n");
1391 if (mediamuxer_stop(app->muxer) != MEDIAMUXER_ERROR_NONE)
1392 g_print(" mediamuxer_stop failed\n");
1394 if (mediamuxer_unprepare(app->muxer) != MEDIAMUXER_ERROR_NONE)
1395 g_print(" mediamuxer_unprepare failed\n");
1397 if (mediamuxer_destroy(app->muxer) != MEDIAMUXER_ERROR_NONE)
1398 g_print(" mediamuxer_destory failed\n");
1400 g_print("mediamuxer destroyed\n");
1404 gboolean _foreach_cb(mediacodec_codec_type_e codec_type, void *user_data)
1406 g_print("codec type : %x %s\n", codec_type, codec_type_to_string(codec_type));
1410 void _mediacodec_prepare(App *app, gboolean frame_all)
1413 media_format_mimetype_e codec_mime;
1414 media_format_h codec_format;
1416 g_print("supported codec lists -internal-\n");
1417 mediacodec_foreach_supported_codec_static((mediacodec_supported_codec_cb)_foreach_cb, app);
1419 /* create instance */
1420 ret = mediacodec_create(&app->mc_handle[0]);
1421 if (ret != MEDIACODEC_ERROR_NONE) {
1422 g_print("mediacodec_create failed\n");
1427 ret = mediacodec_set_codec(app->mc_handle[0], app->codecid, app->flag);
1428 if (ret != MEDIACODEC_ERROR_NONE) {
1429 g_print("mediacodec_set_codec failed\n");
1433 /* get mime and link to each codec parser */
1434 app->mime = _configure(app, app->codecid, app->flag, &app->hardware, &codec_mime);
1436 /* set codec info */
1437 ret = media_format_create(&fmt);
1439 switch (app->type) {
1441 media_format_set_video_mime(fmt, app->mime);
1442 media_format_set_video_width(fmt, app->width);
1443 media_format_set_video_height(fmt, app->height);
1445 ret = mediacodec_configure_from_media_format(app->mc_handle[0], fmt, app->flag);
1446 if (ret != MEDIACODEC_ERROR_NONE)
1447 g_print("mediacodec_configure failed\n");
1450 media_format_set_video_mime(fmt, app->mime);
1451 media_format_set_video_width(fmt, app->width);
1452 media_format_set_video_height(fmt, app->height);
1453 media_format_set_video_avg_bps(fmt, app->target_bits);
1455 media_format_create(&codec_format);
1456 media_format_set_video_mime(codec_format, codec_mime);
1457 media_format_set_video_width(codec_format, app->width);
1458 media_format_set_video_height(codec_format, app->height);
1459 media_format_set_video_avg_bps(codec_format, app->target_bits);
1460 media_format_set_video_frame_rate(codec_format, app->fps);
1462 ret = mediacodec_configure_from_media_format(app->mc_handle[0], codec_format, app->flag);
1463 if (ret != MEDIACODEC_ERROR_NONE)
1464 g_print("mediacodec_configure failed\n");
1465 media_format_unref(codec_format);
1468 media_format_set_audio_mime(fmt, app->mime);
1469 media_format_set_audio_channel(fmt, app->channel);
1470 media_format_set_audio_samplerate(fmt, app->samplerate);
1471 media_format_set_audio_bit(fmt, app->bit);
1473 ret = mediacodec_configure_from_media_format(app->mc_handle[0], fmt, app->flag);
1474 if (ret != MEDIACODEC_ERROR_NONE)
1475 g_print("mediacodec_configure failed\n");
1478 media_format_set_audio_mime(fmt, app->mime);
1479 media_format_set_audio_channel(fmt, app->channel);
1480 media_format_set_audio_samplerate(fmt, app->samplerate);
1481 media_format_set_audio_bit(fmt, app->bit);
1483 media_format_create(&codec_format);
1484 media_format_set_audio_mime(codec_format, codec_mime);
1485 media_format_set_audio_channel(codec_format, app->channel);
1486 media_format_set_audio_samplerate(codec_format, app->samplerate);
1487 media_format_set_audio_bit(codec_format, app->bit);
1488 media_format_set_audio_avg_bps(codec_format, app->bitrate);
1490 ret = mediacodec_configure_from_media_format(app->mc_handle[0], codec_format, app->flag);
1491 if (ret != MEDIACODEC_ERROR_NONE)
1492 g_print("mediacodec_set_configure failed\n");
1493 media_format_unref(codec_format);
1496 g_print("invaild type\n");
1500 if (ret != MEDIACODEC_ERROR_NONE) {
1501 g_print("mediacodec_set_xxxc(%d)_info failed\n", app->type);
1506 g_print("supported codec lists\n");
1507 mediacodec_foreach_supported_codec(app->mc_handle[0], (mediacodec_supported_codec_cb)_foreach_cb, app);
1508 mediacodec_set_input_buffer_used_cb(app->mc_handle[0], (mediacodec_input_buffer_used_cb)_mediacodec_inbuf_used_cb, app);
1509 mediacodec_set_output_buffer_available_cb(app->mc_handle[0], (mediacodec_output_buffer_available_cb) _mediacodec_outbuf_available_cb, app);
1511 mediacodec_set_buffer_status_cb(app->mc_handle[0], (mediacodec_buffer_status_cb) _mediacodec_buffer_status_cb, app);
1512 mediacodec_set_eos_cb(app->mc_handle[0], (mediacodec_eos_cb)_mediacodec_eos_cb, app);
1513 mediacodec_set_error_cb(app->mc_handle[0], (mediacodec_error_cb)_mediacodec_error_cb, NULL);
1516 ret = mediacodec_prepare(app->mc_handle[0]);
1517 if (ret != MEDIACODEC_ERROR_NONE) {
1518 g_print("mediacodec_prepare failed\n");
1522 #ifdef TIZEN_FEATURE_INTEGRATION
1523 if (app->enable_muxer) {
1524 if (mediamuxer_create(&app->muxer) != MEDIAMUXER_ERROR_NONE)
1525 g_print("mediamuxer_create failed\n");
1527 if (mediamuxer_set_data_sink(app->muxer, "/tmp/muxtest.mp4", MEDIAMUXER_CONTAINER_FORMAT_MP4) != MEDIAMUXER_ERROR_NONE)
1528 g_print("mediamuxer_set_data_sink failed\n");
1530 media_format_create(&app->format[0]);
1531 if (app->type == AUDIO_ENC)
1532 media_format_set_audio_mime(app->format[0], codec_mime);
1533 else if (app->type == VIDEO_ENC)
1534 media_format_set_video_mime(app->format[0], codec_mime);
1536 g_print("invalid format\n");
1538 if (mediamuxer_set_eos_cb(app->muxer, _mediamuxer_eos_cb, app) != MEDIAMUXER_ERROR_NONE)
1539 g_print("mediamuxer_set_eos_cb failed\n");
1541 if (mediamuxer_add_track(app->muxer, app->format[0], &app->track) != MEDIAMUXER_ERROR_NONE)
1542 g_print("mediamuxer_add_track failed\n");
1544 if (mediamuxer_prepare(app->muxer) != MEDIAMUXER_ERROR_NONE)
1545 g_print("mediamuxer_prepare failed\n");
1547 if (mediamuxer_start(app->muxer) != MEDIAMUXER_ERROR_NONE)
1548 g_print("mediamuxer_start failed\n");
1553 /* get packet pool instance */
1554 ret = mediacodec_get_packet_pool(app->mc_handle[0], &pkt_pool);
1555 if (ret != MEDIA_PACKET_ERROR_NONE) {
1556 g_print("mediacodec_get_packet_pool failed\n");
1559 g_print("\n\nmediacodec start\n\n");
1564 void _mediacodec_enc_input_buffer_used_cb(media_packet_h pkt, void *user_data)
1566 /* release input raw packet */
1567 media_packet_destroy(pkt);
1570 /* this callback is called when the input buffer for codec has done to use */
1571 void _mediacodec_dec_input_buffer_used_cb(media_packet_h pkt, void *user_data)
1573 /* release input encoded packet */
1574 media_packet_destroy(pkt);
1577 void _mediacodec_enc_output_buffer_available_cb(media_packet_h pkt, void *user_data)
1579 App *app = (App*)user_data;
1581 mediacodec_h media_codec_handle = app->mc_handle[1];
1582 media_packet_h output_buf = NULL;
1583 mediacodec_get_output(media_codec_handle, &output_buf, 0);
1584 /* decode encoded camera preview */
1585 mediacodec_process_input(app->mc_handle[0], output_buf, 0);
1588 void _mediacodec_dec_output_buffer_available_cb(media_packet_h pkt, void *user_data)
1590 App *app = (App*)user_data;
1592 mediacodec_h media_codec_handle = app->mc_handle[0];
1593 media_packet_h output_buf = NULL;
1595 mediacodec_get_output(media_codec_handle, &output_buf, 0);
1597 if (app->enable_dump)
1598 decoder_output_dump(app, output_buf);
1600 media_packet_destroy(output_buf);
1603 void _media_packet_preview_cb(media_packet_h packet, void *user_data)
1605 App *app = user_data;
1606 g_mutex_lock(&app->lock);
1607 mediacodec_process_input(app->mc_handle[1], packet, 0);
1608 g_mutex_unlock(&app->lock);
1613 #ifdef TIZEN_FEATURE_INTEGRATION
1614 void _mediacodec_camera_start(App *app)
1616 int default_format = CAMERA_PIXEL_FORMAT_NV12;
1619 app->hardware = TRUE;
1621 /*create decoder instance and setup */
1622 mediacodec_create(&app->mc_handle[0]);
1623 mediacodec_set_codec(app->mc_handle[0], MEDIACODEC_H264, MEDIACODEC_DECODER | MEDIACODEC_SUPPORT_TYPE_HW);
1624 mediacodec_set_vdec_info(app->mc_handle[0], app->width, app->height);
1626 mediacodec_set_input_buffer_used_cb(app->mc_handle[0], _mediacodec_dec_input_buffer_used_cb, NULL);
1627 mediacodec_set_output_buffer_available_cb(app->mc_handle[0], _mediacodec_dec_output_buffer_available_cb, app);
1628 mediacodec_prepare(app->mc_handle[0]);
1630 /*create encoder instance and setup */
1631 mediacodec_create(&app->mc_handle[1]);
1632 mediacodec_set_codec(app->mc_handle[1], MEDIACODEC_H264, MEDIACODEC_ENCODER | MEDIACODEC_SUPPORT_TYPE_HW);
1633 mediacodec_set_venc_info(app->mc_handle[1], app->width, app->height, 30, 1000);
1635 mediacodec_set_input_buffer_used_cb(app->mc_handle[1], _mediacodec_enc_input_buffer_used_cb, NULL);
1636 mediacodec_set_output_buffer_available_cb(app->mc_handle[1], _mediacodec_enc_output_buffer_available_cb, app);
1637 mediacodec_prepare(app->mc_handle[1]);
1639 /* create camera instance and setup and then start preview */
1640 camera_create(CAMERA_DEVICE_CAMERA0, &app->camera_handle);
1641 camera_set_media_packet_preview_cb(app->camera_handle, _media_packet_preview_cb, app);
1642 camera_get_preview_format(app->camera_handle, &default_format);
1643 camera_set_preview_format(app->camera_handle, default_format);
1644 camera_set_preview_resolution(app->camera_handle, app->width, app->height);
1645 camera_set_display(app->camera_handle, CAMERA_DISPLAY_TYPE_NONE, NULL);
1646 camera_start_preview(app->camera_handle);
1652 void _mediacodec_camera_stop(App *app)
1654 camera_state_e camera_state = CAMERA_STATE_NONE;
1656 camera_get_state(app->camera_handle, &camera_state);
1657 camera_stop_preview(app->camera_handle);
1658 camera_destroy(app->camera_handle);
1660 mediacodec_unprepare(app->mc_handle[0]);
1661 mediacodec_unprepare(app->mc_handle[1]);
1662 mediacodec_destroy(app->mc_handle[0]);
1663 mediacodec_destroy(app->mc_handle[1]);
1668 #ifdef TIZEN_FEATURE_INTEGRATION
1669 void _mediacodec_auto_test(App *app, char *path)
1672 gint num_tracks = 0;
1677 gint samplerate = 0;
1679 media_format_type_e formattype;
1680 media_format_mimetype_e video_mime;
1681 media_format_mimetype_e audio_mime;
1682 gint codec_mask = 0xFFF0;
1691 ret = mediademuxer_create(&app->demuxer);
1692 if (ret != MEDIACODEC_ERROR_NONE) {
1693 g_print("failed to create demuxer\n");
1697 ret = mediademuxer_set_data_source(app->demuxer, path);
1698 if (ret != MEDIACODEC_ERROR_NONE) {
1699 g_print("failed to mediademuxer_set_data_source\n");
1703 ret = mediademuxer_set_error_cb(app->demuxer, demuxer_error_cb, app->demuxer);
1704 if (ret != MEDIACODEC_ERROR_NONE) {
1705 g_print("failed to mediademuxer_set_error_cb\n");
1709 mediademuxer_set_eos_cb(app->demuxer, _mediademuxer_eos_cb, app);
1711 ret = mediademuxer_prepare(app->demuxer);
1712 if (ret != MEDIACODEC_ERROR_NONE) {
1713 g_print("failed to prepare\n");
1718 ret = mediademuxer_get_track_count(app->demuxer, &num_tracks);
1719 if (ret != MEDIACODEC_ERROR_NONE) {
1720 g_print("failed to get track\n");
1724 for (track = 0; track < num_tracks; track++) {
1725 ret = mediademuxer_get_track_info(app->demuxer, track, &app->format[track]);
1726 if (ret != MEDIACODEC_ERROR_NONE) {
1727 g_print("failed to get track info\n");
1731 media_format_get_type(app->format[track], &formattype);
1733 if (!app->is_video && formattype == MEDIA_FORMAT_AUDIO) {
1734 app->audio_track = track;
1735 app->type = AUDIO_DEC;
1736 media_format_get_audio_info(app->format[track], &audio_mime, &channel, &samplerate, &bit, NULL);
1738 mediademuxer_select_track(app->demuxer, track);
1740 ret = mediacodec_create(&app->mc_handle[track]);
1741 if (ret != MEDIACODEC_ERROR_NONE) {
1742 g_print("failed to create mediacocec\n");
1746 codec_id = audio_mime & codec_mask;
1747 g_print("auido codec_id : %x\n", codec_id);
1749 ret = mediacodec_set_codec(app->mc_handle[track], codec_id, MEDIACODEC_DECODER | MEDIACODEC_SUPPORT_TYPE_SW);
1750 if (ret != MEDIACODEC_ERROR_NONE) {
1751 g_print("failed to set codec\n");
1755 ret = mediacodec_set_adec_info(app->mc_handle[track], samplerate, channel, bit);
1756 if (ret != MEDIACODEC_ERROR_NONE) {
1757 g_print("failed to set adec info\n");
1761 mediacodec_set_buffer_status_cb(app->mc_handle[track], _av_buffer_status_cb, app);
1762 mediacodec_set_input_buffer_used_cb(app->mc_handle[track], _mediacodec_inbuf_used_cb, app);
1763 mediacodec_set_output_buffer_available_cb(app->mc_handle[track], _audio_outbuf_available_cb, app);
1764 mediacodec_set_eos_cb(app->mc_handle[track], _mediacodec_eos_cb, app);
1765 mediacodec_set_error_cb(app->mc_handle[track], _mediacodec_error_cb, NULL);
1767 } else if (app->is_video && formattype == MEDIA_FORMAT_VIDEO) {
1768 app->video_track = track;
1769 app->type = VIDEO_DEC;
1770 media_format_get_video_info(app->format[track], &video_mime, &width, &height, NULL, NULL);
1772 mediademuxer_select_track(app->demuxer, track);
1774 ret = mediacodec_create(&app->mc_handle[track]);
1775 if (ret != MEDIACODEC_ERROR_NONE) {
1776 g_print("failed to create mediacocec\n");
1781 app->height = height;
1783 codec_id = video_mime & codec_mask;
1784 g_print("video codec_id : %x\n", codec_id);
1786 ret = mediacodec_set_codec(app->mc_handle[track], codec_id, MEDIACODEC_DECODER | MEDIACODEC_SUPPORT_TYPE_HW);
1787 if (ret != MEDIACODEC_ERROR_NONE) {
1788 g_print("failed to set codec\n");
1792 ret = mediacodec_set_vdec_info(app->mc_handle[track], width, height);
1793 if (ret != MEDIACODEC_ERROR_NONE) {
1794 g_print("failed to set vdec info\n");
1798 mediacodec_set_buffer_status_cb(app->mc_handle[track], _av_buffer_status_cb, app);
1799 mediacodec_set_input_buffer_used_cb(app->mc_handle[track], _mediacodec_inbuf_used_cb, app);
1800 mediacodec_set_output_buffer_available_cb(app->mc_handle[track], _video_outbuf_available_cb, app);
1801 mediacodec_set_eos_cb(app->mc_handle[track], _mediacodec_eos_cb, app);
1802 mediacodec_set_error_cb(app->mc_handle[track], _mediacodec_error_cb, NULL);
1806 ret = mediademuxer_start(app->demuxer);
1807 if (ret != MEDIACODEC_ERROR_NONE) {
1808 g_print("failed to start mediademuxer\n");
1812 track = app->is_video ? app->video_track : app->audio_track;
1813 ret = mediacodec_prepare(app->mc_handle[track]);
1814 if (ret != MEDIACODEC_ERROR_NONE) {
1815 g_print("failed to prepare mediacodec\n");
1819 g_cond_init(&app->thread_cond);
1820 g_cond_init(&app->eos_cond);
1821 g_cond_init(&app->dst_eos_cond);
1822 g_mutex_init(&app->thread_mutex);
1823 g_mutex_init(&app->eos_mutex);
1825 app->thread = g_thread_new("feed thread", &av_feed_thread, app);
1826 app->start = clock();
1828 g_mutex_lock(&app->eos_mutex);
1829 while (app->codec_eos != 1) g_cond_wait(&app->dst_eos_cond, &app->eos_mutex);
1830 g_mutex_unlock(&app->eos_mutex);
1831 g_print("now try to destroy thread!!\n");
1832 g_thread_join(app->thread);
1833 app->finish = clock();
1835 ret = mediademuxer_stop(app->demuxer);
1836 if (ret != MEDIACODEC_ERROR_NONE) {
1837 g_print("failed to stop mediademuxer\n");
1841 ret = mediademuxer_unselect_track(app->demuxer, track);
1842 if (ret != MEDIACODEC_ERROR_NONE) {
1843 g_print("failed to unselect mediademuxer\n");
1847 ret = mediacodec_unprepare(app->mc_handle[track]);
1848 if (ret != MEDIACODEC_ERROR_NONE) {
1849 g_print("failed to unprepare mediacodec\n");
1853 ret = mediacodec_destroy(app->mc_handle[track]);
1854 if (ret != MEDIACODEC_ERROR_NONE) {
1855 g_print("failed to destroy mediacodec\n");
1859 ret = mediademuxer_unprepare(app->demuxer);
1860 if (ret != MEDIACODEC_ERROR_NONE) {
1861 g_print("failed to unprepare mediademuxer\n");
1865 ret = mediademuxer_destroy(app->demuxer);
1866 if (ret != MEDIACODEC_ERROR_NONE) {
1867 g_print("failed to destroy mediademuxer\n");
1871 g_cond_clear(&app->thread_cond);
1872 g_cond_clear(&app->eos_cond);
1873 g_cond_clear(&app->dst_eos_cond);
1874 g_mutex_clear(&app->thread_mutex);
1875 g_mutex_clear(&app->eos_mutex);
1877 g_print("resources are released!!!\n\n\n");
1878 g_print("-----------------------------------------------------\n");
1879 g_print("Input - queued packets : %d, finalized packets : %d\n", app->etb, app->ebd);
1880 g_print("Output - queued packets : %d, finalized packets : %d\n", app->fbd, app->fbd);
1881 g_print("Average FPS = %3.3f\n", ((double)app->fbd*1000000/(app->finish - app->start)));
1882 g_print("-----------------------------------------------------\n");
1888 void _mediacodec_unprepare(App *app)
1890 mediacodec_unprepare(app->mc_handle[0]);
1893 void _mediacodec_destroy(App *app)
1896 g_print("invalid param");
1900 if (media_packet_pool_deallocate(pkt_pool) != MEDIA_PACKET_ERROR_NONE) {
1902 g_print("media_packet_pool_deallocatet failed\n");
1906 if (media_packet_pool_destroy(pkt_pool) != MEDIA_PACKET_ERROR_NONE) {
1908 g_print(" media_packet_pool_destroy failed\n");
1911 g_print("media packet pool destroyed! \n");
1913 mediacodec_destroy(app->mc_handle[0]);
1914 #ifdef TIZEN_FEATURE_INTEGRATION
1915 if (app->enable_muxer) {
1916 if (mediamuxer_close_track(app->muxer, app->track) != MEDIAMUXER_ERROR_NONE)
1917 g_print("mediamuxer_close_track failed\n");
1922 void input_filepath(char *filename, App *app)
1924 GError *error = NULL;
1927 app->file = g_mapped_file_new(filename, FALSE, &error);
1929 g_print("failed to open file : %s\n", error->message);
1930 g_error_free(error);
1934 app->length = g_mapped_file_get_length(app->file);
1935 app->data = (guint8 *)g_mapped_file_get_contents(app->file);
1937 g_print("len : %d, offset : %d, obj : %d", app->length, app->offset, app->obj);
1942 void quit_program(App *app)
1944 media_format_unref(fmt);
1945 g_main_loop_quit(app->loop);
1949 void reset_menu_state()
1951 g_menu_state = CURRENT_STATUS_MAINMENU;
1955 void _interpret_main_menu(char *cmd, App *app)
1957 gint len = strlen(cmd);
1959 if (strncmp(cmd, "a", 1) == 0)
1960 g_menu_state = CURRENT_STATUS_FILENAME;
1961 else if (strncmp(cmd, "o", 1) == 0)
1962 g_menu_state = CURRENT_STATUS_GET_OUTPUT;
1963 else if (strncmp(cmd, "q", 1) == 0)
1966 g_print("unknown menu \n");
1967 } else if (len == 2) {
1968 if (strncmp(cmd, "pr", 2) == 0)
1969 _mediacodec_prepare(app, 0);
1970 else if (strncmp(cmd, "pa", 2) == 0)
1971 _mediacodec_prepare(app, 1);
1972 else if (strncmp(cmd, "sc", 2) == 0)
1973 g_menu_state = CURRENT_STATUS_SET_CODEC;
1974 else if (strncmp(cmd, "vd", 2) == 0)
1975 g_menu_state = CURRENT_STATUS_SET_VDEC_INFO;
1976 else if (strncmp(cmd, "ve", 2) == 0)
1977 g_menu_state = CURRENT_STATUS_SET_VENC_INFO;
1978 else if (strncmp(cmd, "ad", 2) == 0)
1979 g_menu_state = CURRENT_STATUS_SET_ADEC_INFO;
1980 else if (strncmp(cmd, "ae", 2) == 0)
1981 g_menu_state = CURRENT_STATUS_SET_AENC_INFO;
1982 else if (strncmp(cmd, "pi", 2) == 0)
1983 g_menu_state = CURRENT_STATUS_PROCESS_INPUT;
1984 else if (strncmp(cmd, "un", 2) == 0)
1985 _mediacodec_unprepare(app);
1986 else if (strncmp(cmd, "dt", 2) == 0)
1987 _mediacodec_destroy(app);
1988 #ifdef TIZEN_FEATURE_INTEGRATION
1989 else if (strncmp(cmd, "cr", 2) == 0)
1990 _mediacodec_camera_start(app);
1991 else if (strncmp(cmd, "ct", 2) == 0)
1992 _mediacodec_camera_stop(app);
1993 else if (strncmp(cmd, "au", 2) == 0)
1994 g_menu_state = CURRENT_STATUS_AUTO_TEST;
1995 else if (strncmp(cmd, "mp", 2) == 0) {
1996 if (!app->enable_muxer) {
1997 app->enable_muxer = TRUE;
1998 g_print("muxer enabled\n");
2000 app->enable_dump = FALSE;
2001 g_print("dump disabled\n");
2005 else if (strncmp(cmd, "dp", 2) == 0) {
2006 if (!app->enable_dump) {
2007 app->enable_dump = TRUE;
2008 g_print("dump enabled\n");
2010 app->enable_dump = FALSE;
2011 g_print("dump disabled\n");
2014 display_sub_basic();
2016 g_print("unknown menu \n");
2022 void displaymenu(void)
2024 if (g_menu_state == CURRENT_STATUS_MAINMENU) {
2025 display_sub_basic();
2026 } else if (g_menu_state == CURRENT_STATUS_FILENAME) {
2027 g_print("*** input mediapath.\n");
2028 } else if (g_menu_state == CURRENT_STATUS_SET_CODEC) {
2029 g_print("*** Codec id : Select Codec ID Numbe (e.g. AAC_LC = 96)\n");
2030 g_print(" L16 = 16 (0x10)\n");
2031 g_print(" ALAW = 32 (0x20)\n");
2032 g_print(" ULAW = 48 (0x30)\n");
2033 g_print(" AMR_NB = 64 (0x40)\n");
2034 g_print(" AMR_WB = 65 (0x41)\n");
2035 g_print(" G729 = 80 (0x50)\n");
2036 g_print(" AAC_LC = 96 (0x60)\n");
2037 g_print(" AAC_HE = 97 (0x61)\n");
2038 g_print(" AAC_PS = 98 (0x62)\n");
2039 g_print(" MP3 = 112 (0x70)\n");
2040 g_print(" VORBIS = 128 (0x80)\n");
2041 g_print(" FLAC = 144 (0x90)\n");
2042 g_print(" WMAV1 = 160 (0xA0)\n");
2043 g_print(" WMAV2 = 161 (0xA1)\n");
2044 g_print(" WMAPRO = 162 (0xA2)\n");
2045 g_print(" WMALSL = 163 (0xA3)\n");
2046 g_print(" -------------------\n");
2047 g_print(" H261 = 101\n");
2048 g_print(" H263 = 102\n");
2049 g_print(" H264 = 103\n");
2050 g_print(" MJPEG = 104\n");
2051 g_print(" MPEG1 = 105\n");
2052 g_print(" MPEG2 = 106\n");
2053 g_print(" MPEG4 = 107\n");
2054 g_print(" -------------------\n");
2055 g_print("*** Flags : Select Combination Number (e.g. DEOCDER + TYPE_SW = 10)\n");
2056 g_print(" CODEC : ENCODER = 1 DECODER = 2\n");
2057 g_print(" TYPE : HW = 4 SW = 8\n");
2058 g_print("*** input codec id, falgs.\n");
2059 } else if (g_menu_state == CURRENT_STATUS_SET_VDEC_INFO) {
2060 g_print("*** input video decode configure.(width, height)\n");
2061 } else if (g_menu_state == CURRENT_STATUS_SET_VENC_INFO) {
2062 g_print("*** input video encode configure.(width, height, fps, target_bits)\n");
2063 } else if (g_menu_state == CURRENT_STATUS_SET_ADEC_INFO) {
2064 g_print("*** input audio decode configure.(samplerate, channel, bit (e.g. 48000, 2, 16))\n");
2065 } else if (g_menu_state == CURRENT_STATUS_SET_AENC_INFO) {
2066 g_print("*** input audio encode configure.(samplerate, channel, bit, bitrate (e.g. 48000, 2, 16, 128000))\n");
2067 } else if (g_menu_state == CURRENT_STATUS_PROCESS_INPUT) {
2068 g_print("*** input dec process number\n");
2069 } else if (g_menu_state == CURRENT_STATUS_GET_OUTPUT) {
2070 g_print("*** input get output buffer number\n");
2071 #ifdef TIZEN_FEATURE_INTEGRATION
2072 } else if (g_menu_state == CURRENT_STATUS_AUTO_TEST) {
2073 g_print("*** enter media path and select the track to decode (0 : audio, 1 : video).\n");
2076 g_print("*** unknown status.\n");
2081 gboolean timeout_menu_display(void* data)
2087 void interpret(char *cmd)
2092 switch (g_menu_state) {
2093 case CURRENT_STATUS_MAINMENU:
2094 _interpret_main_menu(cmd, app);
2096 case CURRENT_STATUS_FILENAME:
2097 input_filepath(cmd, app);
2100 case CURRENT_STATUS_SET_CODEC:
2102 static gint cnt = 0;
2112 (tmp != 160) && (tmp != 161) && (tmp != 162) && (tmp != 163)) {
2113 tmp = strtol(cmd, ptr, 16);
2114 app->codecid = 0x2000 + ((tmp & 0xFF) << 4);
2116 app->codecid = 0x1000 + tmp;
2121 app->flag = atoi(cmd);
2130 case CURRENT_STATUS_SET_VDEC_INFO:
2132 static gint cnt = 0;
2135 app->width = atoi(cmd);
2139 app->height = atoi(cmd);
2140 app->type = VIDEO_DEC;
2150 case CURRENT_STATUS_SET_VENC_INFO:
2152 static gint cnt = 0;
2155 app->width = atoi(cmd);
2159 app->height = atoi(cmd);
2163 app->fps = atol(cmd);
2167 app->target_bits = atoi(cmd);
2168 app->type = VIDEO_ENC;
2178 case CURRENT_STATUS_SET_ADEC_INFO:
2180 static gint cnt = 0;
2183 app->samplerate = atoi(cmd);
2187 app->channel = atoi(cmd);
2191 app->bit = atoi(cmd);
2192 app->type = AUDIO_DEC;
2202 case CURRENT_STATUS_SET_AENC_INFO:
2209 if (tmp <= 0 || tmp > 96000) {
2210 g_print("Invalid value\n");
2214 app->samplerate = tmp;
2220 if (tmp <= 0 || tmp > 6) {
2221 g_print("Invalid value\n");
2231 if (tmp <= 0 || tmp > 32) {
2232 g_print("Invalid value\n");
2242 if (tmp <= 0 || tmp >= INT_MAX) {
2243 g_print(";;Invalid value\n");
2247 app->type = AUDIO_ENC;
2258 case CURRENT_STATUS_PROCESS_INPUT:
2262 if (tmp <= 0 || tmp >= 10) {
2263 g_print("Invalid value\n");
2269 _mediacodec_process_input(app);
2273 case CURRENT_STATUS_GET_OUTPUT:
2278 #ifdef TIZEN_FEATURE_INTEGRATION
2279 case CURRENT_STATUS_AUTO_TEST:
2286 strncpy(app->filepath, cmd, len + 1);
2287 g_print("%s, %d\n", app->filepath, len);
2291 app->is_video = atoi(cmd) ? 1 : 0;
2292 _mediacodec_auto_test(app, app->filepath);
2304 g_timeout_add(100, timeout_menu_display, 0);
2307 void display_sub_basic()
2310 g_print("=========================================================================================\n");
2311 g_print(" media codec test\n");
2312 g_print("-----------------------------------------------------------------------------------------\n");
2313 g_print("a. Create \t\t");
2314 g_print("sc. Set codec \n");
2315 g_print("vd. Set vdec info \t");
2316 g_print("ve. Set venc info \n");
2317 g_print("ad. Set adec info \t");
2318 g_print("ae. Set aenc info \n");
2319 g_print("pr. Prepare \t");
2320 g_print("pa. Prepare and process all\t\t");
2321 g_print("pi. process input with num\n");
2322 g_print("o. Get output \t\t");
2323 g_print("rb. Reset output buffer \n");
2324 g_print("un. Unprepare \t\t");
2325 g_print("dt. Destroy \t\t");
2326 g_print("q. quit test suite \n");
2327 g_print("dp. enable dump \n");
2328 #ifdef TIZEN_FEATURE_INTEGRATION
2329 g_print("mp. enable muxer \n");
2330 g_print("-----------------------------------------------------------------------------------------\n");
2331 g_print("cr. camera preview -> encoder -> decoder\n");
2332 g_print("au. integration test with mediademuxer\n");
2333 g_print("ct. quit camera test\n");
2336 g_print("=========================================================================================\n");
2339 gboolean input(GIOChannel *channel, GIOCondition cond, gpointer data)
2341 gchar buf[MAX_STRING_LEN];
2343 GError *error = NULL;
2345 g_io_channel_read_chars(channel, buf, MAX_STRING_LEN, &read, &error);
2353 void mc_hex_dump(char *desc, void *addr, gint len)
2357 guint8 *pc = (guint8 *)addr;
2360 g_print("%s:\n", desc);
2362 for (i = 0; i < len; i++) {
2364 if ((i % 16) == 0) {
2366 g_print(" %s\n", buff);
2368 g_print(" %04x ", i);
2371 g_print(" %02x", pc[i]);
2373 if ((pc[i] < 0x20) || (pc[i] > 0x7e))
2376 buff[i % 16] = pc[i];
2377 buff[(i % 16) + 1] = '\0';
2380 while ((i % 16) != 0) {
2384 g_print(" %s\n", buff);
2387 void decoder_output_dump(App *app, media_packet_h pkt)
2391 int stride_width, stride_height;
2392 gchar filename[100] = {0};
2396 g_snprintf(filename, MAX_STRING_LEN, "/tmp/dec_output_dump_%d_%d.yuv", app->width, app->height);
2397 fp = fopen(filename, "ab");
2399 media_packet_get_video_plane_data_ptr(pkt, 0, (void **)&temp);
2400 media_packet_get_video_stride_width(pkt, 0, &stride_width);
2401 media_packet_get_video_stride_height(pkt, 0, &stride_height);
2402 g_print("stride : %d, %d\n", stride_width, stride_height);
2404 for (i = 0; i < app->height; i++) {
2405 ret = fwrite(temp, app->width, 1, fp);
2406 temp += stride_width;
2409 if (app->hardware == TRUE) {
2410 media_packet_get_video_plane_data_ptr(pkt, 1, (void **)&temp);
2411 media_packet_get_video_stride_width(pkt, 1, &stride_width);
2412 for (i = 0; i < app->height/2; i++) {
2413 ret = fwrite(temp, app->width, 1, fp);
2414 temp += stride_width;
2417 media_packet_get_video_plane_data_ptr(pkt, 1, (void **)&temp);
2418 media_packet_get_video_stride_width(pkt, 1, &stride_width);
2419 for (i = 0; i < app->height/2; i++) {
2420 ret = fwrite(temp, app->width/2, 1, fp);
2421 temp += stride_width;
2424 media_packet_get_video_plane_data_ptr(pkt, 2, (void **)&temp);
2425 media_packet_get_video_stride_width(pkt, 2, &stride_width);
2426 for (i = 0; i < app->height/2; i++) {
2427 ret = fwrite(temp, app->width/2, 1, fp);
2428 temp += stride_width;
2432 g_print("codec dec output dumped!!%d\n", ret);
2438 * Add ADTS header at the beginning of each and every AAC packet.
2439 * This is needed as MediaCodec encoder generates a packet of raw AAC data.
2440 * Note the packetLen must count in the ADTS header itself.
2442 void add_adts_header_for_aacenc(App *app, char *buffer, int packetLen)
2444 int profile = 2; /* AAC LC (0x01) */
2445 int freqIdx = 3; /* 48KHz (0x03) */
2446 int chanCfg = 2; /* CPE (0x02) */
2448 if (app->samplerate == 96000) freqIdx = 0;
2449 else if (app->samplerate == 88200) freqIdx = 1;
2450 else if (app->samplerate == 64000) freqIdx = 2;
2451 else if (app->samplerate == 48000) freqIdx = 3;
2452 else if (app->samplerate == 44100) freqIdx = 4;
2453 else if (app->samplerate == 32000) freqIdx = 5;
2454 else if (app->samplerate == 24000) freqIdx = 6;
2455 else if (app->samplerate == 22050) freqIdx = 7;
2456 else if (app->samplerate == 16000) freqIdx = 8;
2457 else if (app->samplerate == 12000) freqIdx = 9;
2458 else if (app->samplerate == 11025) freqIdx = 10;
2459 else if (app->samplerate == 8000) freqIdx = 11;
2461 if ((app->channel == 1) || (app->channel == 2))
2462 chanCfg = app->channel;
2464 /* fill in ADTS data */
2465 buffer[0] = (char)0xFF;
2466 buffer[1] = (char)0xF1;
2467 buffer[2] = (char)(((profile-1)<<6) + (freqIdx<<2) +(chanCfg>>2));
2468 buffer[3] = (char)(((chanCfg&3)<<6) + (packetLen>>11));
2469 buffer[4] = (char)((packetLen&0x7FF) >> 3);
2470 buffer[5] = (char)(((packetLen&7)<<5) + 0x1F);
2471 buffer[6] = (char)0xFC;
2474 void output_dump(App *app, media_packet_h pkt)
2478 gchar filename[100] = {0};
2481 char adts[100] = {0, };
2483 g_snprintf(filename, MAX_STRING_LEN, "/tmp/dec_output_dump_%d.out", app->type);
2484 fp = fopen(filename, "ab");
2486 media_packet_get_buffer_data_ptr(pkt, &temp);
2487 media_packet_get_buffer_size(pkt, &buf_size);
2488 g_print("output data : %p, size %d\n", temp, (int)buf_size);
2490 if (app->is_encoder && buf_size > 0 && app->codecid == MEDIACODEC_AAC_LC) {
2491 add_adts_header_for_aacenc(app, adts, (buf_size + ADTS_HEADER_SIZE));
2492 fwrite(&adts, 1, ADTS_HEADER_SIZE, fp);
2493 g_print("adts appended\n");
2494 } else if (app->is_encoder && buf_size > 0 && app->codecid == MEDIACODEC_AMR_NB && write_amr_header == 1) {
2495 /* This is used only AMR encoder case for adding AMR masic header in only first frame */
2496 g_print("%s - AMR_header write in first frame\n", __func__);
2497 fwrite(&AMR_header[0], 1, sizeof(AMR_header) - 1, fp); /* AMR-NB magic number */
2498 write_amr_header = 0;
2501 fwrite(temp, (int)buf_size, 1, fp);
2503 g_print("codec dec output dumped!!%d\n", ret);
2508 const char* codec_type_to_string(mediacodec_codec_type_e media_codec_id)
2510 guint media_codec_id_u = (guint)media_codec_id;
2512 switch (media_codec_id_u) {
2513 case MEDIACODEC_L16:
2515 case MEDIACODEC_ALAW:
2517 case MEDIACODEC_ULAW:
2519 case MEDIACODEC_AMR_NB:
2521 case MEDIACODEC_AMR_WB:
2523 case MEDIACODEC_G729:
2525 case MEDIACODEC_AAC_LC:
2527 case MEDIACODEC_AAC_HE:
2529 case MEDIACODEC_AAC_HE_PS:
2531 case MEDIACODEC_MP3:
2533 case MEDIACODEC_VORBIS:
2535 case MEDIACODEC_FLAC:
2537 case MEDIACODEC_WMAV1:
2539 case MEDIACODEC_WMAV2:
2541 case MEDIACODEC_WMAPRO:
2543 case MEDIACODEC_WMALSL:
2545 case MEDIACODEC_H261:
2547 case MEDIACODEC_H263:
2549 case MEDIACODEC_H264:
2551 case MEDIACODEC_MJPEG:
2553 case MEDIACODEC_MPEG1:
2555 case MEDIACODEC_MPEG2:
2557 case MEDIACODEC_MPEG4:
2559 case MEDIACODEC_HEVC:
2561 case MEDIACODEC_VP8:
2563 case MEDIACODEC_VP9:
2565 case MEDIACODEC_VC1:
2573 int main(int argc, char *argv[])
2575 GIOChannel *stdin_channel;
2576 stdin_channel = g_io_channel_unix_new(0);
2577 g_io_channel_set_flags(stdin_channel, G_IO_FLAG_NONBLOCK, NULL);
2578 g_io_add_watch(stdin_channel, G_IO_IN, (GIOFunc)input, NULL);
2583 app->loop = g_main_loop_new(NULL, TRUE);
2584 app->timer = g_timer_new();
2585 g_main_loop_run(app->loop);
2589 return appcore_efl_main(PACKAGE, &argc, &argv, &ops);